Drupal 8 Git

 

Much has been written on the theory and practice of agile (or Agile, if you prefer—the debate is real) including books, blog posts, and formal training.

What this guide aims to cover in depth is how to apply that theory to branch management in git, specifically for those working with Drupal 7, Drupal 8 or Drupal 9.

Drupal 8 git apply patch

When trying to composer install, and it reaches one of the modules using a Dev version, I get: - Installing drupal/paragraphs (dev-1.x 42842d5): Authentication required (git.drupalcode.org): Userna. One of the new key features of Drupal 8 is the possibility to deal with configuration in code. Since configuration is now in text files, we want to put it under version control in Git to enjoy the many advantages this brings: comparing configuration states, keeping a history of configuration changes and even moving configuration between sites. How to use Git with Drupal 8 when using composer. Ask Question Asked 3 years, 10 months ago. Active 3 years, 10 months ago. Viewed 1k times 1. I am working on an OpenSocial project and its installed via composer. I am having a folder structure as below: - composer.json - composer.lock - html (Drupal Installation.) - vendor (Dependencies).

The following content is based on the work of our talented friend and former colleague Matt Corks.

Who is this guide for?

This guide is for you if:

  • You're using an agile workflow, with sprints and regular deployments
  • You have a team of multiple developers, a scrum master (project maintainer), and a product owner (client representative)
  • You want to do regular releases of whatever tickets are ready
  • You review releases (continuous integration, user acceptance testing, change approval board, etc.) before deployment
  • You occasionally need to do hotfixes for urgent problems directly on the production site
  • Before a deployment, you occasionally need to revert from a release branch a ticket that didn't pass review

Contents

  • Working with branches: code snippets

Prerequisites and Prep

To make this work, it's best to use an issue tracker with a ticket for each user story, and to make all changes to your site on a separate git branch labelled with that ticket number.

The changesets should be self-contained, and perform all necessary database changes in code via update hooks, features (Drupal 7), or the configuration management system (Drupal 8/9). Any further steps necessary to test or deploy the new version should be clearly described in the ticket description.

Once all your updates are in code, you're ready to use git to prepare for and manage your testing and deployment process. You'll need to adopt specific git practices to make this work smoothly.

Drupal

Drupal with Git: Best Practices

Drupal 7 + Git best practices

In Drupal 7, the best practice is to export all possible configurations using the Features module, so that it can be tracked and versioned in git. After setting up your site's views, content types, variables, and other configuration, you would use the Features module to export these to code as a series of special modules in sites/all/modules/features/ and from there commit them to git. It's simplest to group these by functionality (for example, you could create one features module which contains all the configuration necessary for the blog section of your site).

After making changes, run drush features-update-all to export the configuration from the database to code. To bring in changes after doing git pull you would run the command drush features-revert-all to import from the version in code to the database. You'll need to return to the Features module to add new components of your site (such as a new view) before they will be included in the set of configuration saved in a features module.

To learn more about exporting the configuration of your Drupal 7 site using features, see the documentation.

Drupal 8/9 + Git best practices

In Drupal 8 and higher, most configuration is stored in YAML files, making this much simpler.

By default D8 configuration is stored in the public files/ directory under a difficult-to-guess directory name. Wherever possible, add the following to settings.php or settings.local.php to define the config directory, which should be someplace outside the webserver docroot. (This means your website docroot will be a subdirectory of your git root folder, giving you a place above that to store test scripts and other files outside the docroot.)

Once this is done, run the following after making local changes on dev machines: drush config-export

You can now commit and push these changes to your git repository. To import these on test, staging, and production environments, do a git pull and then run the following: drush config-import -y

Like with D7 features, the suggested workflow is to avoid making changes to these files directly on the production website, but instead to deploy by importing from YAML. Changes made directly on prod will be discarded.

You can read more about the basics of configuration management in Drupal 8 here.

It's also possible to use configuration files during site install to spin up a site instance without a database, as described in this article.

You should also have a convenient way to fetch a copy of the production database from dev & staging environments (eg via drush aliases), and use the Stage File Proxy module to avoid having to sync public files from prod back to dev and stage environments until they're needed.

Use drush sql-sync --sanitize to reset passwords and email addresses in the user tables when copying the database (note that you can also capture all mail sent from dev and stage by sending it to a utility such as MailHog for local review).

Git Branching Strategies

To explain our preferred git workflow, we'll start by explaining some other, simpler workflows that can be used by smaller teams. My reference for this is the tutorial from Atlassian.

We're assuming knowledge of basic git concepts like branching, committing, and pulling. If these are new to you, we suggest taking the time to read an introductory tutorial such as this one, again from Atlassian.

Method 1: Centralized workflow

This is the simplest possible git workflow.

  • There are no branches: everyone always commits to master
  • Works best when each part of project has only one developer (i.e. one front-end, one back-end)

Method 2: Feature branches, aka GitHub-style pull requests

Once multiple people are working on a codebase at the same time, it's necessary to use a more sophisticated model. Many open source projects on GitHub work this way, with one person responsible for testing and approving all proposed changes.

  • Developers start a new branch to work on each feature, sending a pull request when ready for review
  • Developers merge the master branch back into their dev branches on a regular basis during development to keep up with other changes
  • Maintainer reviews proposed changes and merges (pulls) feature branches into master when ready
  • Maintainer occasionally tags a commit as a named/numbered release
  • Works best for simpler projects without a need for external reviewers from outside the dev team

Method 3: GitFlow

Once your project requires a review process for each set of new features, some of which may depend on others to be completed at the same time, it's necessary to create branches for each release so that these can be tested as a group. It follows that you might need to remove a feature from a release if it isn't accepted during testing, and that you'll occasionally need to urgently fix the production version of the code without waiting for your usual release cycle.

  • Naming convention allows for dev, feature, hotfix, and release branches, with defined procedures for updating them
  • Works best for multiple developers using an agile process as described above

Git branching best practices

Make sure every commit message includes the ticket number, both to create pointers from your issue tracker, and to allow you to find commits related to a given ticket at a later date. You can even set up your CI/automated testing scripts to reject commits without numbers, and create a script in .git/hooks/prepare-commit-msg.sh to insert this automatically in the commit message template. Here's one such script.

Drupal 8 Gitlab

Set mergeoptions = --no-ff for the master and dev branches in .git/config so that every merge to those branches has a merge commit for later tracking.

Managing multiple remotes

You might want to use multiple remotes, for example a local GitLab instance, GitHub for automated integration with Circle CI, and a git instance at your hosting provider (e.g. Pantheon). You can do this by creating a placeholder remote called 'all' with multiple pushurl URLs defined.

Working with Branches

Git

Naming conventions

  • master: used only on the production website
  • dev/123 or feature/123: used to add a feature or fix a bug, as defined in ticket 123 in your issue tracker (branched off of dev; will be merged back into dev and deleted when resolved)
  • dev: used to stage all completed feature branches before they're released (was initially branched off of master)
  • release/03: used to stage a set of features (a snapshot of the dev branch) for review and deployment (branched off of dev; will be merged into master and deleted when deployed)
  • hotfix/234: used to fix an urgent bug (branched off of master; will be merged back into master and deleted when resolved)

List all branches

Start working on a feature

Drupal 8 Git

Note: on rebasing

Rebase when you want to rewrite history (e.g. remove commits of debugging code); merge when you want to preserve history. You should only rebase a local branch that isn't yet pushed to origin and shared with others! If you're not already familiar with rebasing, ignore this section. If you really want to learn about this, this tutorial is helpful.

If your goal for rebasing is simply to reduce clutter in your git log, consider using git merge --squash when merging feature branches into dev to combine all changes into one new commit. This is safer than rebasing, and won't cause problems for others.

Review and accept a feature

Prepare release branch

Once enough tickets have been closed and their corresponding feature branches merged into the dev branch, create a release branch and deploy to your staging environment for review.

On local machine

On staging server

Deploy release

On local machine

Drupal 8 Gitignore

On production server

Hotfix production site

On local machine

On production server

Resolve merge conflicts

Your tickets should be small enough in scope that merge conflicts don't happen very often. Here are three things you can do when they come up:

  1. Run git status to list files with conflicts, then edit each one manually
  2. Configure a merge tool which can help with three-way merges (see git mergetool --tool-help for supported options on your platform)
  3. If you get lost halfway through: git merge --abort

There are lots of resources on resolving conflicts online. Here's one good intro-level tutorial.

Here's an example of working with a three-way merge using vim.

Remove a feature that didn't pass review

A lengthy description of this process is available here.

Find the commit that made a given change

A common complaint about gitflow is that it fills your git history with merge commits, but in fact git allows you to exclude these with git log --no-merges (or to show only merges with git log --merges).

Need help?

Leave your comments and questions in the comments, and we'll get back to you ASAP!

For more in-depth assistance, reach out to our team of Drupal experts about personalized training options for your team.