I'm not sure what your first question is, but I can answer the second question for you.
Just tag each release. 'v1.0', 'v1.1', 'v2.0'. Tags are completely separate from branches, so how you choose to handle tags doesn't depend on how you choose to handle branches.
For example, if your repo looks like this:
A--B--C--D--E <- master
\
--C'-D'-E' <- test_branch
You can apply a tag to branch E'
and safely delete test_branch
, without losing the code in E'
. For this reason, it's fairly uncommon for people to maintain git branches for historical releases. Tag the release with a version number and feel free to remove any branches you no longer need.
FWIW, I also use this technique to keep my branches to a minimum. If I go down a dead-end development path on a new branch I can tag that branch (just in case) and remove the branch. If I ever need that code again, I can grab it through the tag.
Edit re: your comments.
Exactly my point: "one tag references one commit"? That kinda sucks, no?
I don't think it sucks at all. If you want to keep a reference a point in time, you use a tag, if you want to keep a reference to set of changesets, you use a branch.
@VonC's mention of git-describe is right on. It's what I use to inject version numbers into all my code. Anything released to the public will always get a tag, so git describe
returns something like, "v1.0". Internal testing releases will be labeled with something like "v1.0-10-abcd1234", which indicates that I'm 10 commits ahead of the v1.0 tag and gives hash so I can easily access that commit directly.