6

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.

watashi16
  • 135
  • 2
  • 6
  • When do you branch out your release-branches? Is there a lot of development done on those release-branches? – Patrick B. Mar 08 '13 at 18:56
  • How many release branches do you have simultaneously? I don’t think there should be a `1.x`, `2.x` *and* a general development branch around for semver. You should try to get previous major versions closed as soon as possible. I would actually go as far to say that you shouldn’t do any non-patch updates for any older version, so you would only have a single development branch and one for each still supported version. – poke Mar 08 '13 at 21:30
  • 1
    Try reading [A successful Git branching model](http://nvie.com/posts/a-successful-git-branching-model/) to see if it helps :) – mgarciaisaia Mar 08 '13 at 23:36

1 Answers1

5

Cherry-picking can:

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.

Community
  • 1
  • 1
VonC
  • 1,042,979
  • 435
  • 3,649
  • 4,283
  • You forgot to add "back-|forwardporting may and will be separate task" - you can't merge changes for old code into new codebase (and in inverse direction also) – Lazy Badger Mar 09 '13 at 14:16
  • @LazyBadger so you wouldn't treat "back-|forwardporting" as merges, like I just did for bugfixes? – VonC Mar 09 '13 at 14:19
  • No, they **are** and **must be** merges, but they can be non-trivial merges (if context was changed between releases). I do not disagree with you, I only warn about (possible) troubles in porting changes into "non-native" branches – Lazy Badger Mar 09 '13 at 15:15