I have a branch called staging
that contains old commits that I would like to move to two separate branches.
A - B - C - D - E - F - G - H - I staging
I would like to move commits B
and C
to a new branch: feature-a
. Then move commits D
, E
, and F
to a new branch: feature-b
.
In the end my branches would look like this:
A - G - H - I staging
A - B - C feature-a
A - D - E - F feature-b
The staging
branch is public and other developers may have local versions of it. How can I accomplish this?
NB: There is probably a better way, but here's one way to do it.
Creating feature-a
is easy:
git branch feature-a C
We can create feature-b
by creating a new branch based on A
and then using cherry-pick
:
git checkout -b feature-b A
git cherry-pick feature-a..F
That r1..r2
expression is documented in the git-rev-parse
man page:
The .. (two-dot) Range Notation
The
^r1 r2
set operation appears so often that there is a shorthand for it. When you have two commitsr1
andr2
(named according to the syntax explained in SPECIFYING REVISIONS above), you can ask for commits that are reachable fromr2
excluding those that are reachable fromr1
by^r1 r2
and it can be written asr1..r2
.
Lastly, we can use git rebase -i --root
on the staging
branch to remove commits B-F:
git checkout staging
git rebase -i --root
In my test repository, this results in:
$ git log --oneline staging
15326ce (HEAD -> staging) This is commit I
3862020 This is commit H
a26f0bb This is commit G
9bc662c This is commit A
$ git log --oneline feature-a
b390f07 (feature-a) This is commit C
1489cd1 This is commit B
9bc662c This is commit A
$ git log --oneline feature-b
f8f3c18 (feature-b) This is commit F
0eb0b08 This is commit E
4e2ed05 This is commit D
9bc662c This is commit A