Skip to content

Instantly share code, notes, and snippets.

@kany
Last active December 10, 2015 23:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kany/4511488 to your computer and use it in GitHub Desktop.
Save kany/4511488 to your computer and use it in GitHub Desktop.
Taming Git
Taming GIT
Using Git - and Git Flow
First up: Git for Agile Teams (pdf) should be considered required reading :)
Second, keep this diagram in mind while reading the following text (image source)
Git Flow
There is nothing special about Git Flow - everything is still commits, branches and tags, but the toolset does add some convenient shortcuts for common operations. Examples include making a hotfix for the current production version, and keeping track of multiple features under concurrent development. Git Flow does nothing special to commits, nor are the branches any different from branches you create by other means. A strict naming standard does make things easier to follow, though.
Intro articles:
A successful Git branching model
"Why aren't you using git-flow?:http://jeffkreeftmeijer.com/2010/why-arent-you-using-git-flow/
Installing Git Flow is easy in homebrew:
brew install git-flow
Getting setup There are two main branches of development in each git-repository:
master: features not yet in production are developed and integrated here. Called develop in the graph above.
production: current production release (tagged). Called master in the graph above.
Pull down the latest branches, then run:
git flow init
This will ask a series of questions, the defaults are usually right (note above description of which is the development branch and which is the production release). Each dev has to do this once for each repo, and it adds a bit to your local .git/config:
[gitflow "branch"]
master = production
develop = master
[gitflow "prefix"]
feature = feature/
release = release/
hotfix = hotfix/
support = support/
versiontag =
With this in place, git flow knows what branch to base new features on (and where to merge back).
Feature branches
As a rule, your work should be done on a local feature branch based on master. Create one by doing:
git flow feature start 123_adding_new_theme
This will create a new local branch named features/123_adding_new_theme. Use a good name, as everybody will eventually see it.
Naming standard: Prefix with ticket number, separate terms with underscore.
When you have a few commits, it's time to get everything in line.
git flow feature finish 123_adding_new_theme
This merges your local branch into master and deletes the local features/123_adding_new_theme branch. Run specs and push to the central repository. You are now ready to start work on the next feature.
Tip: git flow <tab tab> shows inline completion and help if your shell supports it (bash-completion).
Shared feature branch
git flow feature publish 123_adding_new_theme
Release
This will be done during QA for us, setting the stage for the next production roll.
One thing to note is that git-flow limits us to one release branch at a time. It will not allow us to begin a release branch if an un-finished one is present! Knowing this, here is what a release cycle looks like...
Assuming the current roll is jovial-jugular-1.3 and we are ready to QA our current iteration, we would start with:
git flow release start kosher-karyotype-1.0
git flow release publish kosher-karyotype-1.0
The first is obvious; we start the new release branch. The second is less clear with a poor command name; publish creates a remote release branch on origin. This is needed so that the dev team has a QA branch to perform bug fixes on. Once the remote branch is pushed, dev can begin tracking the release branch with this:
git flow release track kosher-karyotype-1.0
Once QA finishes and we're ready to roll, it's time to close the release branch!
git flow release finish kosher-karyotype-1.0
This command wraps it all up: merges the release + bug fixes in to master/production, tags it with kosher-karyotype-1.0, and deletes the release branches. Once the release is finished and merged to production, any other necessary changes for production should be done via hotfixes.
Hotfix
A git-flow hotfix should only be used for production code.
Let's assume production currently has the release kosher-karyotype-1.0.0 live. To perform a hotfix, the beginning and end sequence will look something like this:
# Ensure MASTER and PRODUCTION are updated
git checkout master && git pull
git checkout production && git pull
# Begin HOTFIX
git flow hotfix start 1234-descriptive-text-or-something
# hax to fix teh bug
# Finish HOTFIX
git checkout master && git pull
git checkout production && git pull
git flow hotfix finish -n 1234-descriptive-text-or-something
git checkout production
# Check for last tag and apply new tag
git fetch --tags
git tag -l
git tag -a kosher-karyotype-1.0.1
# Push HOTFIX
git push
git push --tags
The biggest thing to note is that the hotfix tag (kosher-karyotype-1.0.1) differs from the hotfix name (1234-descriptive-text-or-something). Also, the tag name is the next sequential number for the last release tag.
Modifying local history
Undo a local commit
If it turns out the latest local commit was in error, simply do:
git reset --hard HEAD^
instead of doing a revert and then pushing both the normal and the revert commit. You have a blank slate, and can try again to get the commit right.
Note: Never do this when you have shared (pushed) a commit. Then revert is the right thing to use.
See also undoing in git in the git book.
Amending your last commit message
Put the wrong reference number? Saying that you fixed the wrong item? Accidentally included a positive comment about Ferf? A quick way to edit the mistake is:
git commit --amend
Like "Undo a local commit" mentioned above, this should not be used when you have shared (pushed) a commit.
Rewriting local history
Sometimes it makes sense to squash together a few commits before pushing. First, you can easily see the commits only on your feature-branch:
git log master..
This shows you a list of the commits not yet merged pushed from your local branch. Let's say there are three and you wish to squish two of them together. Type:
git rebase -i HEAD~3
Up pops your editor with the ability to select what commits to edit, squeeze or delete. Read more about this powerful feature at the git book or watch the gitcast
git-flow.png - Git flow diagram (142 KB) lrud, 04/26/2011 02:58 am
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment