Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Do I Implement Semantic Versioning in Git?

Tags:

git

versioning

I've been able to convince my group to use semantic versioning and move to git (from CVS, where all development happened on the trunk).

This is what we've been using for a bit (where the version branches denote the introduction of some kind of new functionality):

master
*
|
*   * version 2.0 branch
|  /
* *
|/
*   * version 1.0 branch
|  /
* *
|/
*
|
...

The problem is that when there's a bugfix that needs to be made on the version 1.0 branch, that fix needs to get echoed up to version 2.0 and master. We've been cherry-picking, but I feel like that's more error-prone than I'd like (and I feel like it'll become unmanageable as time goes on).

There are some limitations to what we're doing--it's legacy code, and there isn't a lot of testing being done (starting to introduce unit testing, very little integration testing), so keeping stability on those version branches (not introducing a lot of regression errors) is important.

Do you guys have a better way to approach this than cherry-picking? Is there a better workflow to use? Really appreciative of any help you can provide.

like image 820
watashi16 Avatar asked Mar 08 '13 18:03

watashi16


People also ask

What is semantic versioning in Git?

Using semantic versioning in your project means being responsible for double-checking your version number before you release your code. As soon as your code is released into a production environment, you have to assume that somebody is using the code, and you should not change the version number.


1 Answers

Cherry-picking can:

  • introduce duplicate commits
  • miss functional dependencies

I prefer merging (which is similar to A successfull Git branching mentioned by desert69):

  • create a branch dedicated to that buxfix_xxx (on top of version1)
  • merge version1 to that buxfix_xxx branch (fast-forward)
  • merge buxfix_xxx to version 2 and master branches

Of course, the trick is to record a merge in those branches (version2 and master) without actually merging all the files: see "How do you merge selective files with git-merge?".

If you have only a few files to merge, here is what I do:

# make git believe we are merging everything
git checkout version2
git merge --no-commit bugfix_xxx

# but reset everything to version2
# (while the merge is still in progress!)
git checkout version2 -- .

# merge only the few files we need:
git checkout --patch bugfix_xxx -- path/to/file1
git checkout --patch bugfix_xxx -- path/to/file2
git checkout --patch bugfix_xxx -- path/to/file3

# add and commit, concluding the merge

The nice thing about those merges is that, the next one (from version1 to version2 and master) will naturally be limited to the next bugfix, because git will believe that everything else was already merge!

So the time you invest in that first backport of a bugfix will pay of for the next ones.

like image 158
VonC Avatar answered Sep 21 '22 14:09

VonC