1

What is the "best" (read: "easiest", "preferred", "proper") way to divide up a set of changes among multiple branches in git? For example, assume I have made a set of (uncommitted) changes while working on branch X, but some of the changes really need to be committed to branch Y, others to branch Z, and still others to branch W; normally what I would do instinctively (like recommended here) is to stash the changes, checkout Y, apply the changes, commit only what's relevant to Y, and repeat for the other branches. The problem I run into with this is that applying the stashed changes often results in merge conflicts that have to be handled, and if I do a stash pop instead of apply (which happens often enough to be a real risk for me!), I end up intermingling changes intended for Z in the Y branch and they have to be disentangled manually.

Is there a better way? How better could I handle this situation?

Note that my question is related to questions like this one, but is different in that I seek the best way to divide a current set of changes among multiple branches. Also note that I cannot switch to Y, Z, or W prior to developing the set of changes; I have to start on X and develop the set of changes on X.

Community
  • 1
  • 1
BlueBomber
  • 282
  • 2
  • 11
  • *"Also note that I cannot switch to Y, Z, or W prior to developing the set of changes; I have to start on X and develop the set of changes on X"*: This sounds like those changes are all related. If so, how do you suppose to commit them to different branches when they depend on changes committed to another branch? – Daniel Hilgarth Jul 10 '13 at 11:47
  • @DanielHilgarth, the changes are related, but the reason I want to commit them in different branches is so that others who are using branches Y, Z, and W can use those improvements, as well; some of the changes logically belong in branches Y, Z, and W, and people wanting those improvements can merge them in from those branches. – BlueBomber Jul 10 '13 at 11:56
  • So why can't you develop those changes directly on the respective branches? Just trying to understand your scenario here... – Daniel Hilgarth Jul 10 '13 at 12:02
  • @DanielHilgarth, I have to develop those changes concurrently with the changes in X, just due to the nature of my repo. Think of it like this: X is a feature branch and Y is a branch for testing features, and testing X requires updating the test software in Y, but others should be able to use the improvements to Y, too. – BlueBomber Jul 10 '13 at 12:25
  • How are the branches related with regards to common roots and diverges? BTW: I still don't see why you can't write the improvements in Y *first*, merge them into X and then develop the new feature. – Daniel Hilgarth Jul 10 '13 at 12:27
  • @DanielHilgarth, I'm sorry, but I don't really know how to answer that. The X (and other branches) merge in changes from Y whenever there are changes in Y, but without the merge commits, X and Y have diverged "long ago". With respect to your BTW, can you just run with the assumption that these particular changes to X and Y need to be developed concurrently? I'm not going to be able to give you a completely accurate description of our repository, branches, and their relationships, unfortunately. – BlueBomber Jul 10 '13 at 12:30

2 Answers2

1

The problem with git stash and multiple branches is that once it is popped you have to stash again for the next branch. To get around this it is easy enough to just use a temporary branch.

git checkout -b temp_branch
git commit -a -m 'Changes that will go to several branches.'
git checkout W
git cherry-pick -n temp_branch
(fixup all files here here)
git commit -a -m 'Changes for W.'
git checkout X
git cherry-pick -n temp_branch
(fixup all files here here)
git commit -a -m 'Changes for X.'
git checkout Y
git cherry-pick -n temp_branch
(fixup all files here here)
git commit -a -m 'Changes for Y.'
git checkout Z
git cherry-pick -n temp_branch
(fixup all files here here)
git commit -a -m 'Changes for Z.'
git branch -D temp_branch
cforbish
  • 8,567
  • 3
  • 28
  • 32
  • This strikes me as equivalent to stashing, then applying (but not popping) the stash on each branch and selectively committing changes. Am I missing something? – BlueBomber Jul 10 '13 at 13:50
  • These steps do not help you with merge conflicts. This is something that I do not think is avoidable as you do not want git attempting to do something for you in this situation. – cforbish Jul 10 '13 at 14:16
1

One way to avoid merging issues is to make several commits in original branch, then to cherry-pick them from destination branches and finally rollback changes.

Like so:

git add -i
git commit -m 'changes for X'
git add -i
git commit -m 'changes for Y'
git log -n 2 # to see hashes
git checkout X
git cherry-pick <hash of the first commit>
git checkout Y
git cherry-pick <hash of the second commit>
git checkout original_branch
git reset --hard HEAD~2
Dmitry Vyal
  • 2,347
  • 2
  • 24
  • 24