187

I am currently learning to use Git by reading Pro Git. Right now I'm learning about branching and tags. My question is when should I use a branch and when should I use a tag?

For example, say I create a branch for version 1.1 of a project. When I finish and release this version, should I leave the branch to mark the release version? Or should I add a tag? If I add a tag, should I delete the version branch (assuming that it is merged into master or some other branch)?

2 Answers 2

218

In short: Best practice is branch out, merge often and keep always in sync.

There are pretty clear conventions about keeping your code in a separate branches from master branch:

  1. You are about to make an implementation of major or disruptive change
  2. You are about to make some changes that might not be used
  3. You want to experiment on something that you are not sure it will work
  4. When you are told to branch out, others might have something they need to do in master

Rule of thumb is after branching out, you should keep in sync with the master branch. Because eventually you need to merge it back to master. In order to avoid a huge complicated mess of conflicts when merging back, you should commit often, merge often.

Good practices to follow

A successful Git branching model by Vincent Driessen has good suggestions. If this branching model appeals to you consider the flow extension to git. Others have commented about flow.

Tagging practices

As you already know, Git gives you commit identifiers like 1.0-2-g1ab3183 but those are not tags! Tagging is done with git tag, and the tags that are created using git tag are the base for the commit identifiers git describe creates. In another words, in Git you don't tag branches. You are tagging commits. It is correct to say that tag is just an annotated pointer to a commit.

Lets look at practical example that demonstrated it,

                        /-- [v1.0]
                       v
---.---.---.---S---.---A     <-- master
                         \ 
                           \-.---B     <-- test

Let's commit 'S' be commit pointed by tag 'v1.0'. This commit is both on branch 'master' and on branch 'test'. If you run "git describe" on top of commit 'A' (top of 'master' branch) you would get something like v1.0-2-g9c116e9. If you run "git describe" on top of commit 'B' ( aka the 'test' branch) you would get something like v1.0-2-g3f55e41 , that is the case with default git-describe configuration. Note that this result is slightly different. v1.0-2-g9c116e9 means that we are at commit with sortened SHA-1 id of 9c116e9, 2 commits after tag v1.0. There is no tag v1.0-2!

If you want your tag to appear only on branch 'master', you can create new commit (e.g. only update default / fallback version information in GIT-VERSION-FILE) after branching point of 'test' branch. If you tag commits on 'test' branch with e.g. 'v1.0.3` it would be visible only from 'test'.

References

I have found many, many, useful blogs and posts to learn from. However, the ones that are professionally illustrated are rare ones. Thus, I would like to recommend a post - A successful Git branching model by @nvie. I have borrowed his illustration :)

enter image description here

8
  • 6
    1.0-2-g1ab3183 is an identifier constructed by git describe from information available from git, but calling it a git identifier is a little too much. Git identifies by SHA hash; tags and branches are human constructs that git helpfully keeps track of. As such, make a tag when you think some human will one day wish to find a convenient bookmark to a commit.
    – mabraham
    Commented Apr 21, 2014 at 23:52
  • 5
    a wonderful illustration of multi-dimensionality in the git universe. beautiful. thanks
    – Tope
    Commented Jan 19, 2019 at 6:08
  • 1
    It is worth noting that many projects do not have a need for some of the lanes shown in this diagram. Some projects only need what's called develop and feature here. This is often true for web apps that can be deployed at will.
    – usr
    Commented Sep 1, 2019 at 11:51
  • 1
    Even the author of git flow no longer recommends it for many project types, such as web development. Many people believe it is much more complex than the vast majority of projects need, making it troublesome to execute and easy to get wrong. At the other end of the spectrum, some advanced practitioners advocate teams use 'trunk based development', which almost never uses branches at all, and deliver successful projects like that. For something intermediate, consider "anti-gitflow' Commented Oct 16, 2020 at 3:38
  • 1
    @NeilG I suspect I was thinking of the link you provide, or one very like it, in which the author of git-flow says "If your team is doing continuous delivery of software, I would suggest to adopt a much simpler workflow (like GitHub flow) instead of [...] git-flow." Commented Nov 18, 2022 at 5:28
54

A branch is used if you have 2 different versions of repository at the same time. A tag is a way to mark a point in time in your repository.

You should add a tag to mark a released version. If you then need to make bug fixes to that release you would create a branch at the tag.

You only want to delete branches that have been merged back into the HEAD [or some other branch].

2
  • 4
    oh...and I assume you mean that the branch is merged into another branch, such as master. HEAD moves every time I do a checkout, right?
    – Code-Guru
    Commented Sep 21, 2012 at 18:55
  • 1
    HEAD usually points to a branch (unless you're in detached HEAD mode), so HEAD moves with the branch it points to
    – LoicAG
    Commented Sep 23, 2019 at 8:18

Not the answer you're looking for? Browse other questions tagged or ask your own question.