Last active
December 10, 2015 23:39
-
-
Save kany/4511488 to your computer and use it in GitHub Desktop.
Taming Git
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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