3

Here's my scenario:

Let's say I want to make a fix to an open source project on github. At a high level, I follow this workflow:

  • fork the source project on github
  • clone the fork locally
  • create a topic branch off master
  • make my fix (hand waving irrelevant details here...)
  • push topic branch to github
  • submit pull request to original source project

OK, now let's say I've done this a couple of times, so I have topic branches called issue#123 and issue#456. The original source project, in addition to the master branch, has release branches, e.g. 1.0, 1.1, etc.

I have my own separate project that uses version 1.1 of this open source project. I don't want to build against the open source project's "master", since it's not stable yet. What I need is a local build of the open source project's 1.1 branch that also includes my fixes to issue#123 and issue#456.

Sorry for the lengthy setup... anyway, what I'm currently doing is creating a local branch called my-1.1 (branched off 1.1), cherry picking the fixes from my topic branches into it, then building it and using the result in my separate, dependent project.

I'm not 100% sure that cherry-picking is the right way to go here, but merging doesn't seem right, since I don't want all the post-1.1 changes from master (which are present in my topic branches) to flow into the "my-1.1" branch. Is this the best approach? Any gotchas to be aware of?

The only other approach I can think of is to create duplicate topic branches for each fix, one in a branch off master, and one in a branch off 1.1. Then I could merge the 1.1-based topic branches into my-1.1, instead of cherry-picking the commits from the master-based topic branches. But that seems like a major hassle.

Andy Dennie
  • 6,012
  • 2
  • 32
  • 51

2 Answers2

1

What you want to do is make your topic branch off of the oldest branch, then you can merge it into both without accidentally including the newer stuff. In other words, make the fix in 1.1 first, then merge it into master, instead of the other way around.

Karl Bielefeldt
  • 47,314
  • 10
  • 60
  • 94
  • Hmm, but I want to push my topic branch to my fork on github, and submit a pull request from there to the original source project's master branch. If my topic branch is 1.1-based, will that work? (Sorry for the possibly dumb question; still trying to get the hang of git...) – Andy Dennie Sep 05 '12 at 23:56
  • It depends on the maintainer. They might accept one based off of 1.1, or you just merge or rebase it onto your `master` and submit that for your pull request. – Karl Bielefeldt Sep 05 '12 at 23:59
  • But isn't it possible that 1.1 contains commits (other than my fixes) that shouldn't go into master? If I merge my 1.1-based topic branch into master, master will get more than just my fixes, right? I.e. it will get everything in 1.1 after it diverged from master, plus my fixes. Sorry if I'm misunderstanding. – Andy Dennie Sep 06 '12 at 00:33
  • Usually everything that goes into a maintenance branch also gets merged into the dev branch, but if not, you can use `git merge-base` to find the last point they had in common and branch from there. – Karl Bielefeldt Sep 06 '12 at 02:51
1

No. This is a perfect usecase for git rebase. Suppose your topic branch is topic123 branched off of master. You instead want it branched off 1.1. Just issue this command:

git rebase --onto 1.1 master topic123

Assuming topic123 doesn't rely on code introduced between 1.1 and master, that'll go just fine. If it does rely on that code, then the whole exercise will fail anyway because you're relying on code after the 1.1 release.

git checkout 1.1 && git merge topic123

Repeat for all your topic branches. You've already issued the pull request on your fork of the remote, so the fact that your local copies of the topic branches have an older merge base isn't really a big deal assuming you're done coding on them. That written, if you want to put them back on top of master, just reverse the arguments:

git rebase --onto master 1.1 topic123

Or alternatively, if you don't want to deal with forced pushes, reset to the remote's copy:

git reset --hard <repo>/topic123
Christopher
  • 42,720
  • 11
  • 81
  • 99
  • OK, I had to do a thorough re-read of the rebase man page, but now I get it (or, I get it more than I did before, anyway). However, wouldn't I still want a separate my-1.1 branch to contain my cumulative 1.1 fixes, distinct from the 1.1 branch? Seems like I'd want to keep a "clean" 1.1 that can be kept in synch with upstream/1.1... although I guess that wouldn't be necessary if it (upstream/1.1) was frozen. But if it's still evolving (1.1 RC1, 1.1 RC2), it might be a pain to keep rebasing to keep my fixes at the 1.1 tip. – Andy Dennie Sep 06 '12 at 00:22
  • @AndyD Nah. Once the merge base is 1.1 (say, today's snapshot), you can use a clean `git merge topic123` into 1.1 no matter where it advances. There's no reason you couldn't just `git pull` the upstream. On the off chance it conflicts you'd *want* to rebase your feature branch or adjudicate the conflict, because your fix might no longer apply. – Christopher Sep 06 '12 at 02:04
  • Thanks, Christopher, I appreciate the detailed response. – Andy Dennie Sep 06 '12 at 13:07