How not to use rebase with multiple branches
I'm using git in a project with multiple branches used concurrently, that is:
A ---- B ---- C \ \ \ ---- D ---- E
Every named item is used depending on the situation (i.e. I need to have access to both A, B and D...). When I modify the code, I do it in the higher relevant branch I can (mostly A), and then I rebase every branches to the new "A" to propagate differences.
Since I was told that it was a bad habit since it creates problem with push/pull, and now I have to add a new maintainer to my project, I'd like to have another way of doing what I want.
I was proposed to do conditionnal compilation, and it was the way I proceeded in the early development, but now I have many branches (~10 at the moment) and the code became very hard to read, that's why I came to this branching solution...
Cherry-picking looks great, but it makes 10 commits for each commit, and we lose the "visual" representation of the fact that B is a child of A...
Any other idea, suggestion? Thanks!
Just use 'git merge' instead of 'git rebase'.
Suppose a bug appeared in branch A in your graph. It is the most upstream branch that shows the bug, therefore that's what you fix. You check it out, code the fix, test the fix, and confirm it works on A. Then, when you want to propagate it everywhere else, you:
- Checkout B and merge A into B.
- Checkout E and merge A into E.
- Checkout C and merge B into C.
- Checkout D and merge B into D.
If the problem first showed up in B, you'd checkout B, code the fix, test the fix, and then do just steps 3 and 4.
This does result in many merge operations, 10 in your example if you fix A, the parent branch of 10 descendent branches, but it's also the sanest workflow you can use that won't a) drive your collaborators nuts because rebased commits keep getting pushed to the remote, and b) won't completely destroy your ability to merge the branches into one another.
b) by the way is why you don't want 'git cherry-pick' for this. Cherry-pick will propagate your change set from A to 10 other branches, sure, but it'll change that commit's SHA1 hash in every distinct branch it's used. Were you to merge B into A at some later date, for example, you'd end up with redundant history: change sets that are identical in what they do, but with completely different SHA1 hashes. This isn't a terribly big deal on occasion, but if you codify it into your workflow, it will fail you in miserable ways. Redundant merge history also ruins 'git bisect' and 'git rebase', and is nearly impossible to read. Avoid 'git cherry-pick' when you can for this branching model.