If you're the person who wants to bring git-flow into your team, this post is for you. Everyone else on the team needs these concepts of git-flow.
Scenario: the team has been developing on a master branch for a while, and now that we've made our first release, it's time to implement git-flow. Each of our local repositories track origin, which is a bare repo living on a server. So far, origin has just one master branch.
Converting an existing repository to git-flow
For the basics, everyone needs a develop branch, origin needs a develop branch, and our develop branches need to track origin.
To set up git-flow, one person runs this:
git flow init
git push -u origin develop
git branch --set-upstream develop origin/develop
Note: if you have any branches lying around other than master, git flow init will not create the develop branch for you; it wants me to use one of these others. Either delete these branches or create the develop branch manually (git branch develop) before initializing git-flow.
git push -u origin develop creates the develop branch on origin. The "-u" option means "set-upstream," which modifies your develop branch to track the develop branch on origin. After this, git status will tell you when your branch is ahead of origin, behind origin, or both.
Everyone else on the team runs this:
git flow init
Note: if these other guys have a branch lying around other than master, git flow will refuse to create the develop branch. Either delete these branches or create the develop branch manually (git branch develop origin/develop) before initializing git flow. The "origin/develop" at the end of that command sets up the tracking branch.
Multiple Branches + Multiple Team MembersNow that origin has two branches, and each team member is tracking both of them, there are a few other considerations.
PullIf you're used to using git pull, please stop. Please use git fetch. This downloads all the new stuff from origin without modifying your local branches or working directory. Decide which local branches you want to update; when you're ready, rebase.
What used to be "git pull" becomes:
Fetch the updates from origin.
Observe whether we have changes.
Rebase to tack my changes on the end of the changes from origin.
Why rebase instead of merge? That's a subject for a whole post (or a presentation! come see me at DevLINK), but the short answer is: non-fast-forward merge creates merge bubbles on the develop branch - evidence that development forked and a merge commit with no story to tell. The git-flow model is cleaner if merges are for features. This is my opinion.
PushI recommend this magic spell:
git config push.default currentRun this once to tell git push that it should (by default) push only the current branch. This way, when you make commits on develop and push them to origin, you won't be confused by error messages that occur because your master branch is behind.
Feature and release branches exist only in the repository of the team member who created them. Chances are good you'll want multiple programmers working on these at some point - for instance, when everyone is fixing bugs found in test on the release branch. There's a detailed post on sharing branches by GitGuys, but I'll give you the quick rundown here.
One person starts the release and pushes it to origin:
git flow release start versionName
git flow release publish versionName
Whoever else wants to work on it does this to set up a tracking branch:
git flow release track versionName
Bonus hint: here's how to list branches on origin you're currently tracking:
git remote show origin
Now everyone can push changes to the release branch. When it's complete, one person finishes the release.
- make sure master, develop, and the release branch are all fully up-to-date in your local, because finishing the release will affect all three of these.
- git flow release finish versionName
- push both master and develop branches
- push the release tag to origin: git push origin versionName
- delete the release branch on origin: git push origin --delete release/versionName
Finally, everyone else should delete their release branch.
git branch -d release/versionName
If nothing else, always remember to push the release tag to origin. Anyone looking for that version of the code is going to look for it there. git push origin versionName
Like anything in git, git-flow is easy until it isn't. Remember that you have the full power of git at your disposal; the git-flow commands are only shortcuts. Wrap your head around the commit graph, know what's going on behind the scenes, and keep your chin up. Easy right?