I incorrectly branched in the past and one commit was left in the start of another branch:
* 03431cb (HEAD -> bar) a2
| * d332e4d (foo) b2
| * 9b29ae3 b1
| * 4656a98 a1
|/
* 6ebca20 (master) root
How can I move a1
out of foo
into bar
, so that bar
's history is root -> a1 -> a2
and a1
is not in foo
? Is it possible to do it with one single git commit?
This is not pushed so no need to worry about breaking others' local repos.
I first thought about doing a cherry pick of a1
and then correcting the order between a2
and a1
. The issue with this is that those two commits conflicts in my real case scenario and I would have to correct the conflict both when doing the cherry pick and when switching their order.
mwe in bash:
#!/bin/bash
set -e
rm -rf .git
git init -b master
echo content > my-file
git add my-file
git commit -m root
git checkout -B foo
echo asd >> my-file
git add my-file
git commit -m a1
echo qwe >> my-file
git add my-file
git commit -m b1
echo zxc >> my-file
git add my-file
git commit -m b2
git checkout master
git checkout -B bar
echo jkl >> my-file
git add my-file
git commit -m a2
I'm a big fan of the syntax git rebase --onto x y z
, which means:
Starting at z, look back thru the parent chain until you are about to come to y and stop. Now rebase those commits, ie everything after y up to and including z, onto x.
In other words, using this syntax, you get to say clearly where to snip the chain. Plus you don't have to switch branches before rebasing. The syntax takes some getting used to, but once you get fluent at it, you'll find yourself using it all the time.
So:
git branch temp 4656a98
git rebase --onto master temp foo
git rebase --onto temp master bar
git branch -D temp
Sure, we could save two steps and just do 2 and 3 using SHA number 4656a98 instead of the name temp, but names are nicer.
Proof.
Starting position:
* 9a97622 (HEAD -> bar) a2
| * 83638ec (foo) b2
| * 7e7cbd0 b1
| * 931632a a1
|/
* 6976e30 (master) root
Now:
% git branch temp 931632a
% git rebase --onto master temp foo
% git rebase --onto temp master bar
% git branch -D temp
Result:
* 3a87b61 (HEAD -> bar) a2
* 931632a a1
| * bbb83d0 (foo) b2
| * 5fa70af b1
|/
* 6976e30 (master) root
I believe that's what you said you wanted.