Most of the git workflows I\'ve seen suggest to delete a branch
after it\'s been merged into master. For example, this gitflow suggests the following:
Because the myfeature
branch history represents all the intermediate commits done to implement myfeature
.
This strategy keeps only one commit in master
, and forget about the intermediate steps, which makes sense for long-lived branches, as I explained in "Why does git fast-forward merges by default?".
The commit message of the one commit done (merged) in master
should make it clear it is done for implementing 'myfeature
'.
If it needs to be fixed, the branch name can be reused (since it was deleted before).
Something important to realize is Git branches are nothing more than a label pointing to a commit. Branching in Git is literally branching. Here's what a repository looks like if feature
branched off master
when master
was a commit B.
A - B - C - F - H [master]
\
D - E - G - I[feature]
See? Actual branch. When you git merge feature
into master, you get this.
A - B - C - F - H - J [master]
\ /
D - E - G - I [feature]
And once you git branch -d feature
the branch history remains!
A - B - C - F - H - J [master]
\ /
D - E - G - I
J has the parents H and I. J cannot exist without them, it's baked into how Git works. I cannot exist without G. G cannot exist without E. And so on. The branch must remain
J is a merge commit which will typically contain the name of the branch being merged. Its like any other commit, so you can even add more information to it, like a link back to your issue tracker.
git merge --no-ff
is used to prevent Git from doing a "fast forward" and losing the branch history. This happens if no work has been done on master
since the branch was created. A fast-forward looks like this.
A - B[master]- D - E - G - I [feature]
git checkout master
git merge feature
A - B - D - E - G - I [feature] [master]
Since master
is a direct ancestor of feature
, no merge is required. Git can just move the master
label. Your branch history is lost, it looks like D, E, G and I were all done as individual commits on master. git merge --no-ff
tells Git to never do this, to always perform a merge.
In the future, when it's noticed a bug was introduced in G, anyone browsing the repository can see it was done as part of the branch, look ahead to find the merge commit, and get information about the branch from there.
Even so, why delete the branch? Two reasons. First, it will clutter up your list of branches with dead branches.
Second, and more important, it prevents you from reusing the branch. Branching and merging are complicated. Single use, short lived feature branches simplify the process by ensuring you only ever merge the branch back into master once. This eliminates many technical and management problems. When you merge a branch, it is done. If you need to fix a problem introduced in that branch, just treat it as a bug in master and make a new branch to fix it.
Unfortunately, git log
lies to the user and presents a linear representation of history that is not linear. To fix this, use git log --graph --decorate
. This will draw lines as in my examples above, and show you any branches and tags on each commit. You'll get a much truer view of the repository.
If you're on a Mac, GitX will visualize the repository for you. gitk is the generic version.