Reputation: 41488
Say I'm working on a feature in a branch oldFeature
. I've done commits A
and B1
and sent it for the code review. In B1
I changed some existing files but also added newfile.txt
.
In the meantime I started working in a branch newFeature
, forked from oldFeature
(HEAD
== B1
). I've added C
, D
, E
.
Meanwhile, I got code review results and had to amend B1
, changing newfile.txt
, and also changing some existing files. After the fixes, it became B2
.
So to illustrate it:
newFeature oldFeature
A A
B1 B2 [B1 with some fixes]
C
D
E
Now I'm in newFeature
and I want to rebase newFeature
to have B2
instead of B1
. When I simply do the rebase, I have rebase a conflict due to newfile.txt
being added in both parts of the rebase.
I want to keep the version from oldFeature
(B2
).
I can't move B1
to the HEAD
, because C
, D
, E
depend on it.
I know I can do the following workaround:
git checkout --theirs
git add
Then I'll have a situation like this:
newFeature oldFeature
A A
B2 B2
BX
C
D
E
where BX
is more or less B2\B1
on the files that existed in A
.
Now I can do interactive rebase and remove BX
.
However my workaround is kind of convoluted. Is there a simpler way to do it? By simpler I mean, that I either have
newFeature oldFeature
A A
B2 B2
B2\B1
C
D
E
without any rebase conflicts, and then I can get rid of that B2\B1
commit, or to replace them automatically so I get
newFeature oldFeature
A A
B2 B2
C
D
E
Using Git 1.8.0.
Upvotes: 31
Views: 13355
Reputation: 2526
I made a small script in case you don't want to do an interactive rebase :
COMMIT_HASH_TO_REPLACE=$1
NEW_COMMIT_HASH=$2
GIT_SEQUENCE_EDITOR="sed -i -re 's/^pick $COMMIT_HASH_TO_REPLACE/pick $NEW_COMMIT_HASH/'" git rebase -i --reapply-cherry-picks $COMMIT_HASH_TO_REPLACE~
It is a little bit faster, because you just need to run this small command if you want to replace c6e9cdb4
by 558332c
:
replace c6e9cdb4 558332c
Upvotes: 2
Reputation: 1330082
You could do a rebase interactive:
git checkout new_feature
git rebase --interactive old_feature
and drop B1
: you simply delete the line with B1:
# If you remove a line here THAT COMMIT WILL BE LOST
Upvotes: 32