2

My team is working on a shared topic branch in git which I will call "topic1." I was working on a refactor of some code on a branch made off of topic1, which I will call "refactor." I have been periodically merging topic1 into refactor so I can stay up to date with changes, but have not merged refactor back into topic1 because the refactor is still in progress.

There is another topic branch, which I'll call "topic2" which was recently created off of master. What I'd like to do is merge only the changes that I've made on "refactor" to a new branch made off of topic2, which I'll call "topic2_refactor." (I.E. the changes in the commits accessible only by refactor but not by topic1.)

I know how to see these just these changes:

git log origin/refactor --not origin/topic1

So what I'd like to do is something like this - but this syntax is not correct:

git checkout topic2
git checkout -b topic2_refactor

And then this:

git merge origin/refactor --not origin/topic1

Or this:

 git cherry-pick origin/refactor --not origin/topic1

(The above seems to be causing merge conflicts that aren't neccessary, due to some changes which occured on master that was later merged back into the refactor branch.)

I was hoping that there is a clean way to do this and avoid unnecessary merge conflicts that were resolved later on in the history of the "refactor" branch. Might this be possible using git rebase, git filter-branch, etc?

Eliot
  • 5,450
  • 3
  • 32
  • 30

1 Answers1

2

You can try git rebase with the --onto option. What this allows is for the rebase operation to grab the diffs it needs to apply from your 'refactor' branch, based off 'topic1', but then apply them to 'topic2'

git co refactor
git co -b topic2_refactor
git rebase --onto topic2 topic1 # bases the diffs off of topic1, but applies them to topic2

Your success may vary. There could still be problematic conflicts that occur. The downside to this is you'll now have two separate refactor branches with the same changes, but since this was a rebase they have different histories that can easily diverge if you're not careful (you'd have to constantly cherry pick from one branch to the other or something similar).

Then you could run into trouble when both topic1 and topic2 (after refactoring) need to be merged into master again, since they'll have all those identical refactor commits. Though git is usually pretty good with that.

Since it seems the refactoring is independent of these topic branches, I'd consider rebasing the refactor branch off of master, so you can merge those changes into both topics when the refactoring is finished.

bobDevil
  • 27,758
  • 3
  • 32
  • 30
  • 3
    Your last paragraph is some of the best advice. Always start branches from the common ancestor of everything you intend to merge them into. – Cascabel Apr 21 '11 at 20:31
  • Thanks, I'm going to try this out on a local branch. The reason the refactor branch was made off of topic1 was that it was an experimental refactor of code introduced in topic1 that had not yet been merged into master at the time the branch was created (topic1 has since been merged into master, but it's intended more as a long-lived development branch so its history has diverged from master once again.) – Eliot Apr 21 '11 at 20:55
  • `git rebase --onto topic2 origin/topic1` seemed to have no effect. After consulting my git book I tried `git rebase --onto new_refactor origin/topic1 origin/refactor` This appears to produce the same merge conflicts I saw when I tried to initially merge the changes using the cherry-pick command in my question - conflicts that I have manually resolved further along in the history. :( – Eliot Apr 21 '11 at 21:05