Yet Another Git Branching Model
This post describes an alternative git branching "model" that is useful if you're dealing with settings files that are part of the repository itself and you would like to be able to have different local settings with which to develop without ever committing these to the public repository.
It is based on the idea that for every feature we develop, we use a feature branch that can be deleted whenever the feature has been fully merged, with the following tweaks:
The model is simple: for every feature, say foobar, we create 3 branches: foobar, foobar_settings and foobar_dev. And yes, this is an immediate drawback: lot's of branches, however, I have not found this to be problematic and it is easy to use a script to delete merged branches.
foobar is the "master" branch, and it is the branch we'll use to push to the remote repository and to create a pull request from in GitHub (say)
foobar_settings is the "settings" branch, and it holds commits that update local settings, changes that should never be visible on the remote repository
foobar_dev is the development branch, it holds commits that update local settings and new development changes, this is where you work
The general workflow is as follows:
- Create feature branch foobar:
git checkout -b foobar origin/master - Create settings branch foobar_settings:
git checkout -b foobar_settings - Update local settings and commit using an easily recognisable commit, e.g.:
git commit -am " *** LOCAL SETTINGS COMMIT ***" - Create the dev branch: git checkout -b foobar_dev
- Perform dev magic
- To release:
git rebase --onto foobar foobar_settings foobar_dev,
What this effectively does is: rebase all commits in foobar_dev except those in foobar_settings to foobar. - git checkout foobar
- And finally: git merge foobar_dev to prepare a pull request (this simply fast-forwards). Now, either the current situation is good or you've made one too many local commits that shouldn't appear publicly, we can "squash" these using a soft reset:
git reset --soft <<sha before dev rebase>>; git commit -am " The one commit message to rule them all" - You're good for a pull request now.
Now all of this seems like a ton of work, however, automating this with (say) PowerShell makes it very easy indeed.
If I'd like to start work on a new feature, I simply type
Git-NewFeature -feature new_awesome_feature
This automatically does git fetch origin followed by steps 1-4 above (also applying a local script to update settings automatically, as part of the process).
To "release" I simply type git-release with optional -squash option, this performs steps 6-7.
Finally the GitHub API makes it very easy to automate doing a pull request, so for that all I have to do is:
Git-PullRequest -title "foobar has landed" -body "Blah blah"
If a pull request is already open, all one needs to do is git push <<remote name>> foobar to push new commits to it.
Staying Up To Date
Finally, in order to stay up to date with the remote master we should do the following when on foobar:- git pull origin master (say), no rebase pull is needed because the merge commit won't be picked up in the pull request
- git checkout foobar_settings; git merge foobar
- git checkout foobar_dev; git merge foobar_settings
Again this is easy to automate, I've called my PowerShell function Git-Update with flag -pull, it does steps 1-3 above automatically.
Tweaking Settings
So you're on dev, and you want to update a settings to work with locally. There are many options but I usually use:- Edit the settings file
- Commit this file only with a clear local commit message (something easy to recognise so that if it makes it to GitHub it is easy to spot and remove (see below))
- git checkout foobar_settings; git cherry-pick <<sha>>
And of course easy to automate.
Fixing A Mistake
Somehow I got my local setting into my pull request.If this happens, it is easy to fix. Simply go to your foobar "master" branch, and find out how many commits since the mistake, say 5, and do an interactive rebase:
git rebase -i HEAD~6
then delete the commit *** LOCAL SETTINGS COMMIT *** in the opened text editor and save and close it. Finally, override the pull request remotely:
git push --force <<remote>> foobar
and Bob's your uncle.
Thoughts? Do tell.
No comments:
Post a Comment