Reputation: 33
For a repository like this:
init---A---A2---...---[D---B---merge]---...---master
\ /
C---B2
where B
and B2
have conflict and was solved in merge commit
.
now I want to join commit A
and A2
to one commit A
. And I tried
git rebase -i <commit id of init>
and change
pick xxxxxxx A
pick xxxxxxx A2
...
to
pick xxxxxxx A
squash xxxxxxx A2
...
but conflicts appeared when applying B2, and I have to deal with the conflicts manually just like what I have done in merge
.
Actually, there are so many structures like or even more complex than in square brackets in the whole commit tree. So it's not realistic to deal with all the conflicts manually.
The problem is that when I use rebase
, the whole commit tree will merged into one line and it will not deal with the conflict automatically by applying the commit merge
.
So what can I do to join only the commits A and A2 but still remain all the commit structure after A2 unchanged so that the repository 'looks' the same after the operation?
To make some further explanation, in commit A
there's some sensitive information added in a test file and it was removed in commit A2
. So I can't publish this project if I can't remove these information permanently. So is there any alternative solution to this situation?
Upvotes: 0
Views: 210
Reputation: 38106
You can also use use steps to join the two early commits together.
Assume the commit you want to join is on master
branch, and the commit history as:
A---B---C---D---…---X master
To join commit B
and commit C
together while keeping the commit history after commit C
(commits from D
to X
), you can use below commands:
git checkout -b temp <commit id for A>
git merge <commit id for C> --squash
git commit -m 'join B and C together'
Now the commit history will be (commit M
is the squash merged commit, join commit B
and commit C
together):
A---B---C---D---…---X master
\
M temp
Then you can rebase the following commits after commit C
:
git rebase --onto temp <commit id for C> master
git push -f origin master
git branch -D temp
Now the commit history on master
branch will be (commit M
is the commit join commit B
and commit C
together):
A---M---D'---…---X' master
Upvotes: 0
Reputation: 990
To join (or 'squash' as it's called) you need to interactively rebase. If the commits you want to alter are the first two, you can rebase from the root of the repo.
This would look a little something like:
git rebase -i --root
pick hash X
squash hash Y
pick hash Z
The -i
means you will be doing it interactively. --root
means starting from the root of the repo.
After that initial command you will see a list of commits with the top one being the first commit. To merge the first two commits you can simply keep the first one (with the pick
keyword) and merge the previous one into it (using the squash
keyword). You could also edit the first commit message by replacing pick
with reword
.
After you've done this, you should leave all the other commits be and confirm.
More information can be found here
Upvotes: 1