Simple Git feature branch workflow

After reading A successful Git branching model [nvie.com], which I consider one of the best graphical/textual depictions of the ideal Git model for development teams (and most large projects), I simply wanted to adapt a similar (but way less complex) model for some of my smaller sites and multisite Drupal installs.

Since I'm (almost always) the only developer, and I develop locally, I don't want the complexity of working on many branches at once (master, hotfixes, develop, release, staging, etc...), but I do want to have a clean separation between what I'm working on and the actual live master branch that I deploy to the server.

So, I've adopted a simple 'feature branch model' for my smaller projects:

  • master - the live/production code. Only touch when merging in a feature or simply fixing little bugs or really pressing problems.
  • [issue-number]-feature-branches - Where I work on stuff.

Graphically:

Feature branch model

Any time I work on something more complicated than a simple styling tweak, or a fix for a WSOD or something like that, I simply create a feature branch (usually with an issue number that matches up to my internal tracking system). Something like 374-add-node-wizard:

# create (-b) and checkout the 374-add-node-wizard branch.
$ git checkout -b 374-add-node-wizard

While I'm working on the node wizard (which could take a week or two), I might make a couple little fixes on the master branch. After I make the fixes on master (switch to it using $ git checkout master), I switch back to my feature branch and rebase my feature branch:

$ git checkout 374-add-node-wizard # switch back to the feature branch
$ git rebase master # pull in all the latest code from the master branch

I can also create simple .patch files off a branch to pass my work to another server or a friend if I want (I like using patches instead of pushing around branches, simply because patch files are easier for people to grok than more complicated git maneuvers):

# create a diff/patch file from the checked out branch.
$ git diff master..374-add-node-wizard > 374-add-node-wizard-patch.patch

When I finish my work on the feature branch, I switch back to master, merge in the branch, and delete the branch. All done!

$ git checkout master # switch back to master
$ git merge --no-ff 374-add-node-wizard # merge feature branch back into master
$ git branch -d 374-add-node-wizard # delete the feature branch

Finally, I test everything to make sure it's working fine in master, and then push the code changes up to the server.

Since I'm developing alone, this is a lot easier than a more complicated branching setup, and it allows me to work on as many features as I want, without fear of messing things up on master, or having merge conflicts (I rebase early and often).

(Note: I usually work in the command line, because I'm more comfortable knowing what git is doing that way... but I often open up Tower (imo, the best application for visual Git) to inspect branches, commits, and merges/rebases... some people would probably rather just use Tower for everything).

(Note 2: When creating patches to send to someone that include binary files (like a png or a gif, jpeg, whatever), make sure you use $ git diff --full-index --binary [old]..[new] > patchfile.patch so git doesn't barf when you try applying the patch on someone else's end...).

Jeff Geerling is a Technical Architect at Acquia, owner of Midwestern Mac, LLC, and author of Ansible for DevOps. He is an active contributor in the Drupal community, and has primarily been a Mac user since the 1990s.

Comments

Jeff Geerling's picture

IMO, this is also a good way to submit drupal patches; checkout the project (or drupal core), create a feature branch locally, make changes (and continue to rebase), then when you want to file patches, just make the patches using git diff [main]..[local] > [drupal.org_issue]-[comment].patch

The 'advanced patch contributor guide' says something to this effect, but gets a bit caught up in the details...

Personal site: jeffgeerling.com.

Anonymous's picture

I think this is a great workflow, I use something very similar, thanks for sharing!

ao2's picture

While for just sharing changes git diff is OK, when you send patches for inclusion it is better to use git format-patch IMHO, this way IF the maintainer is kind enough to apply it using git am the authorship is preserved and you get the credit you deserve.

You can put multiple commits in a single patch using git format-patch --stdout but remember to double check what you are actually sending and, if needed, use git rebase -i to cleanup the history of your local branch before producing patches.

Just my 2 cents.

Thanks,
Antonio

Mika ANDRIANARIJAONA's picture

Thanks, It is a simple yet very useful tutorial. It helps me have a better organisation of my branches.

Arne Tietz's picture

I'm was looking for an easy way to make version control for me as the only developer. And your way is a fine cut down of the greater model from nvie.
But what I'm missing, what I'm needing too, is a way to version control the database too.
Is there an easy way to do "git checkout state-before-a-change-that-changes-the-db" and I have that state of the code AND of the db of this branch?

jknight's picture

I use a very similar workflow. In addition I like to tag the feature branch before I delete it:

git checkout 374-add-node-wizard
tag archive/374-add-node-wizard

That way I can always go back to a deleted branch, if I ever need/want to.

Add new comment