Let me start by saying that I would rather integrate topic branches often (integration early, collection often ... bell rings?). So, in fact, when there are changes that should eventually happen, I would come back, make changes to a and rebase b on top.
If you need to be stable for any other purpose, I would make a-for-b branch to temporarily save work, and reformat b on top of it.
If you really need to work with theme-a changes within branch b, here is what I will do.
Note. built-in screencasts
How to get to the starting point
This is a simple working tree with a layout from the question:
mkdir /tmp/q cd /tmp/q git init . touch f git add f git commit -am initial git checkout -ba; for a in a{1,2}; do echo $a>$a; git add $a; git commit -am $a; git tag $a; done git checkout -bb; for a in b{1,2} a{3,4} b{3,4} a5 b5; do echo $a>$a; git add $a; git commit -am $a; git tag $a; done git show-branch
See screencast here
Reorganization captures its topic threads
git checkout -b a_new a
Again, see the screencast
Checking Results
Now we can do the comparison before / after the tree:
sehe@natty:/tmp/q$ git show-branch ab ! [a] a2 ! [b] b5 -- + [b] b5 + [b^] a5 + [b~2] b4 + [b~3] b3 + [b~4] a4 + [b~5] a3 + [b~6] b2 + [b~7] b1 ++ [a] a2 sehe@natty:/tmp/q$ git show-branch a_new b_new ! [a_new] a5 * [b_new] b5 -- * [b_new] b5 * [b_new^] b4 * [b_new~2] b3 * [b_new~3] b2 * [b_new~4] b1 +* [a_new] a5
Make it permanent:
for name in ab; do git branch -m $name ${name}_old && git branch -m ${name}_new $name done git branch -D a_old b_old
Notes
I deliberately decided to make conflict-free changes to demonstrate. Of course, in real life you will encounter merge conflicts. Use git mergetool and git rebase --continue .
If your changes are hygienic and truly belong to their respective topics, then the likelihood that conflicts should be small and easily resolved. Otherwise, it's time to review the branching scheme (see Martin Fowler ea)
Discussion
In response to
You also say that āwhen there are changes that should go toā a, āin the end Iāll go back, make changes toā a āand rebaseā b āon top ofā a. āIām not sure that I understand. Not could you explain?
I mean, in any case, I would try to make revisions a3, a4, a5 on branch a and reinstall b on it, therefore
- the person performing the merge is the same person who commits.
- you commit and merge sequentially (this means that you will not mess up due to loss in short memory)
<-- this is the Merge Early/Soon/Frequently mantra - You avoid unnecessary merge conflicts.
- you donāt need to ācome back on timeā later and rewrite the original commits: a3, a4, a5 will simply be merged, not copied (see Git Cherry -pick vs Merge Workflow )
Here is āHow to Get Started,ā but adapted to my idealized workflow. Please note that the end result of this alternative result is exactly what you will finish after all the juggling shown in the section āReorganization is fixed on its branchesā above!
mkdir /tmp/q cd /tmp/q git init . touch f git add f git commit -am initial git checkout -ba;
Note that in practice itās easy to go back to the branch to fix your a3 / a4 / a5:
- If you just realized that you have affected things that belong to this branch, you can simply switch to a branch with pending local changes 2
- then you selectively (!!) put the parts that you want to branch to (
git add -i or similar in git guis or, for example, vim fugitive ) - lock on
- go back to branch b (
git checkout b ) - pass the remaining bits
- rebase b for latest version in
2 if they do not conflict with other changes from a..b; in this case you git stash first and git stash apply if on a branch