Skip to content

Instantly share code, notes, and snippets.

@joshuajabbour
Created March 10, 2011 18:38
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save joshuajabbour/864614 to your computer and use it in GitHub Desktop.
Save joshuajabbour/864614 to your computer and use it in GitHub Desktop.
Git(Hub) Drupal Project Development Model

Setup

Configure git by using the template for .gitconfig, and adding commands for a Git-aware prompt to .profile.

To clone the repository (the "template" parameter is important):
git clone git@github.com:user/repo.git --template=/PATH/TO/TEMPLATES

Also run (this will set up the repository so a branch can be pushed only while on that branch):
git config remote.origin.push HEAD

Note: Commit messages should always be meaningful, and follow these conventions.

Branching Model

The basis for this model comes from this document, with a few key changes:

Build Branches

A branch must exist for each build environment onto which code will be deployed.

  • prod: production-ready code branch
    This branch must remain sacrosanct at all times. Only release branches may be merged into this branch, and only after they have undergone full testing.

  • dev: primary development branch
    This branch is to serve as the primary integration branch. Anyone may merge code into this branch, but only after this code has been tested thoroughly on its own feature branch.

  • qa/stage/etc: other build environment branches, as necessary
    code should only ever be deployed from an build branch directly onto that server.

Work Branches

  • Note: All work branches have a limited lifespan, and will be deleted once all code has been merged into the appropriate build branches.

Feature Branches

A feature branch is where 99% of development will occur.

In an agile-based process, a new feature branch should be created for each story, and typically named like "XXXX-DESC", with "XXXX" being the story ID and "DESC" being a one or two word name of the feature. Feature branches are branched from the development branch at the start of the story.

A feature branch should be merged back into into development only after work is 100% complete on that feature, the code has been thoroughly tested, and the story can be marked as completed.

Release Branches

A release branch supports preparations of a new production release.

Release branches are typically created during sprint reviews, and are branched from the development branch. They will be named "release-XXXX", with "XXXX" being the release ID (such as 1.0.0).

All code targeted for the release must have been merged into development from feature branches before the release branch is created. Only bug fixes can be committed to a release branch in preparation for build, thereby opening up the development branch for new feature development.

Release branches must be merged into both the development and production branches once complete, and will become release tags when merged into the production branch.

Hotfix Branches

A hotfix branch supports mandatory bugfixes when development is not ready for release.

Hotfix branches are created anytime an urgent bug crops up in production, and are branched from the production branch. They will be named "hotfix-XXXX", with "XXXX" being the story ID describing the bug.

Hotfix branches must be merged into both the development and production branches once complete, and will become release tags when merged into the production branch.

Collaboration

In order to collaborate on development work, a centralized remote branching model will be employed.

Developer 1 starts work on the feature locally, naming the local branch "123-nav" (per the naming schema above). Once she is ready to collaborate on the branch, she must push it to GitHub using git push origin 123-nav. Developer 2 can now checkout the branch using git checkout -t origin/123-nav (or git checkout -b 123-nav origin/123-nav).

Both developers can now share their work by pulling from the remote branch (git pull), committing to it locally (git commit), and pushing changes to the remote branch (git push).

Rebasing

Rebasing reapplies local work on top of the upstream branch's new base commit. This is necessary in order to keep feature work in sync with the parent branch, and should be done regularly during development.

However, rebasing can be dangerous for branches that have been shared, and must be done carefully and deliberately, as it changes the branch's history. Other users who have pulled the branch will now have a different tree.

  • Rebasing should only ever be done while on feature branches, and only when changes need to be brought in from that branch's parent (which is usually dev).
  • After rebasing, other users who may have that branch will need to be told that is was rebased, so that they may update their history.
  • Before rebasing, always do git pull to make sure the branch is up-to-date.
  • git rebase origin/<parent> will update the current branch with any changes from the parent (again, usually dev). The "origin/" part is only necessary if the local copy of the parent is not up-to-date. It's usually better to first pull that branch, however since no work will be done directly on the build branches, it's not a problem to rebase from the origin copy.
  • After rebasing, git push should be attempted, but most likely git will complain and block it. In this case, git push --force is necessary. This causes the upstream history to be forcibly rewritten, and rebasing feature branches is the only time this argument should be used.
  • When another user has been informed that a branch has been rebased, they have one of two options. If they have done no local work, a simple git pull should suffice. If they do have local commits, git pull --rebase will pull the branch and reapply the local commits afterwards.

Interactive rebasing is another type of rebasing that allows a user to rewrite their commit history. It is invoked via git rebase --interactive, and should only be done on local branches that have never been pushed. It's not recommended to use interactive rebasing unless absolutely necessary.

Rule: The word "rebase" should only ever be typed on a branch that is a feature branch! And even then, only with care.

Integration

By default, commit access to the "dev" and "prod" branches is limited (if it was cloned using the correct templates). This is just a safety, so please don't try to commit/push to either of these branches.

In order to get a work branch merged into a build branch, a pull request must be initiated (for now we are following the "Shared Repository Model").

Note: When merging into any of the build branches, the "no fast forwards" flag (git merge --no-ff) must always be used to create a merge commit (for tracking purposes). When merging between feature branches, it's not necessary, but may be useful depending on the circumstances.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment