If you absolutely want to keep this naming scheme, you might:
Decide that you don't care about these warnings
That is, if you're happy with the fact that:
git checkout <ref>
will check out refs/heads/<ref>
over refs/tags/<ref>
(see git-checkout)
- other commands will use
refs/tags/<ref>
over refs/heads/<ref>
(see gitrevisions)
For example, in this test repository, the v1.5.2
branch points to commit B, but the v1.5.2
tag points to commit A.
% git log --oneline --decorate
8060f6f (HEAD, v1.5.2, master) commit B
0e69483 (tag: v1.5.2) commit A
git checkout
prefers branch names:
% git checkout v1.5.2
warning: refname 'v1.5.2' is ambiguous.
Switched to branch 'v1.5.2'
% git log --decorate --oneline -1
8060f6f (HEAD, v1.5.2, master) commit B
but git log
will use the tag name:
% git log --decorate --oneline -1 v1.5.2
warning: refname 'v1.5.2' is ambiguous.
0e69483 (tag: v1.5.2) commit A
This could be confusing.
Train people to delete their local branches when they see a new tag
This might be hard/awkward depending on the size of your organisation.
Write a wrapper around "git pull" and "git fetch"
That is, write a wrapper that checks if there are any tags that shadow branch names, and warn about (or delete) those branches. This sounds painful, and it could be undesirable if the shadowed branch is currently checked out.
Unfortunately, it sounds like the easiest way to solve this problem might be to change the way you name your branches. The link you posted uses different naming schemes for tags and branches: if you're already mostly following that method, adopting its naming scheme might be the easiest solution.
First of all, since your specifications are rather unclear, I'm not sure how much of this really applies. But I'll give it a shot...
If your project has one single release cycle, you only need one repository. If your three teams need to release new version independently, it gets a lot messier. But for that I'd need more specific input. At the moment, it sounds to me like you need to stabilize your API, develop the library and manage your back-end development. If that's part of one project, go ahead and use one repository.
As for the branching, I'd recommend to always have one branch that simply represents the latest released and working version. This branch will probably mostly have merge commits. I like the idea of release branches independent of development branches as a release manager could then easily review everything (after feature freeze if you want so), scratch the last few itches, set the version properly, and merge into your production branch. (You could even bind hooks or deployment strategies to that merge in order to automatically push release onto your build system or something).
As I said above, I'd recommend having one release cycle within one repository. If you can have that, only one production branch will be necessary. If the teams really need to release new versions of the same project independently, it feels like there's something wrong with the project management. But that's again without knowing much about the team and project in general.
A style that I like much is the git flow as described by Atlassian. It suggests having one master (production) and one development branch. On development the actual work happens but, that usually splits up into feature branches. What I like is that a development manager (someone with deep technical insight) can manage the development branch. They decide whether to merge new features or not. At some point they will tell a project/release manager that the team's done and that project/release manager can then (together with the development manager) work out the last few glitches on a release branch before it'll be merged into master (and back into development, of course). It's just an interesting separation of concerns that developers are so keen on regarding different aspects of the very same projects. :)
Hope this helps a bit.
Best Answer
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:
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,
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 likev1.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 of9c116e9
, 2 commits after tagv1.0
. There is no tagv1.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 :)