why should I delete feature branches when merged to master

Max Koretskyi picture Max Koretskyi · Mar 28, 2015 · Viewed 8.5k times · Source

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:

# Incorporating a finished feature on develop 
$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff myfeature
Updating ea1b82a..05e9557
(Summary of changes)
$ git branch -d myfeature
Deleted branch myfeature (was 05e9557).
$ git push origin develop

Why should I delete the branch? I'm also curious what to do when later a bug is discovered that was introduced by the feature - should I create the branch with the same name again, fix bug there, merge into master and again delete the branch?

Answer

Schwern picture Schwern · Mar 28, 2015

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.