43

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?

InteXX
  • 6,135
  • 6
  • 43
  • 80
Max Koretskyi
  • 101,079
  • 60
  • 333
  • 488
  • 3
    Because your feature is finished. What would be the need to retain the branch, thereby cluttering the result of git branch -a etc? – Oliver Charlesworth Mar 28 '15 at 10:50
  • 3
    @OliverCharlesworth history – Bernardo Dal Corno Mar 04 '18 at 18:44
  • 1
    @Z.Khullah - The commits would still be in the history. – Oliver Charlesworth Mar 04 '18 at 18:52
  • 1
    Yep, I mean that is the reason people ask this question, because they don't know thay – Bernardo Dal Corno Mar 04 '18 at 21:25
  • Deleting code is never a good idea (unless it was total garbage/a total fuck up). Let's suppose the feature was very complex, there were 3 different solutions/code paths tried. The first one seemed to be the best only to discover later that solution 2 should have been used instead. Depending on if solution 2 was a subbranch of solution 1 or not, it might now be gone, losing that work on solution 2 and 3. Features could also be developed in modules. This is kinda weird to think of it as a branch instead of a new module or so. The module could have been completed seperated from the code base. – oOo Dec 02 '20 at 01:10

2 Answers2

64

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.

Schwern
  • 153,029
  • 25
  • 195
  • 336
  • thanks for your answer! Can you please move the part which starts with _why delete the branch_ before the explanation of what a git branch is so that someone looking for the same answer gets the response right at the top :). `VonC`'s answer is very helpful as well, maybe you could incorporate some part of his answer into your answer to make is one complete source of information. Thanks! – Max Koretskyi Mar 28 '15 at 18:35
  • @Maximus IMO without an understanding of how Git branches work, my reasoning for deleting the branch doesn't make sense. As for VonC's answer, I don't see what's in his that I didn't cover; could you elaborate? – Schwern Mar 28 '15 at 18:42
  • Probably you're right, maybe because I know all that I didn't see it as pre-required knowledge. I find this piece of VonC's answer very helpful: _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,_ – Max Koretskyi Mar 28 '15 at 18:53
  • @Maximus I feel my illustrations expressed that. Maybe I can make it more explicit. – Schwern Mar 28 '15 at 19:31
  • Illustrations are good, but one has to infer this _this strategy keeps only one commit in master_, whereas I'd put it explicitly to make someone's learning easier :) – Max Koretskyi Mar 28 '15 at 19:34
  • @Maximus I understand what VonC was expressing, he was comparing merging to fast-forwarding, but phrasing it like that betrays an assumption of linear history, or implies the more common false assumption that merging interleaves the branches. `master` is now the sum total of its history. D, E, G and I are now as much a part of master as C, F and H. IMO in order to really understand Git you have to unlearn the linear view of change history that CVS and SVN have taught us. – Schwern Mar 28 '15 at 20:09
1

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).

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Thanks. What do you mean by short-lived branches? Are there any different from feature branches? Also, as I understand, the information about the branch should be stored in the merge commit when feature branch is merged into master? – Max Koretskyi Mar 28 '15 at 10:57
  • Can you also please take a look at the comment I left for your answer [here](http://stackoverflow.com/a/29296584/2545680)? – Max Koretskyi Mar 28 '15 at 10:59
  • 1
    @Maximus http://stackoverflow.com/a/2850413/6309 illustrates a shot-live branch (just a few commits quickly merged in master), as opposed to a long-live branch, where many commits will be done (with trials and errors) before being merged *eventually* to master: in the latter case, it is cleaner to keep just one commit in master. – VonC Mar 28 '15 at 11:08
  • Got you, thanks! I've read somewhere that it's not a good idea to commit directly into master, but it seems that this is exactly the case with fast-forwarded short-lived branches. So as I understand it's not a bad practice, right? – Max Koretskyi Mar 28 '15 at 18:31
  • Recently stumbled across your pretty basic questions on git dating 6 years ago on some git related forum... it's hard to imagine that you were once not as good with git as I am :) – Max Koretskyi Mar 28 '15 at 18:32
  • @Maximus no, it is not a bad practice. – VonC Mar 28 '15 at 18:36