Martin Martin - 3 months ago 9
Git Question

Git, how to "force" a squash rebase

I need to "squash" some commits together. Normally I am used to do something like this:

git rebase -i HEAD~10


However, now I am getting the error below:


error: could not apply 2009972... fixes

When you have resolved this problem, run "git rebase --continue". If
you prefer to skip this patch, run "git rebase --skip" instead. To
check out the original branch and stop rebasing, run "git rebase
--abort".


As you can see
git
pretends that I resolve all the conflicts. Now, I do not want and cannot resolve any conflicts.

What I need is a way to tell
git
something like: "Hey, I do not want to merge anything: just take all the tracked files in this branch - as they appear in the last commit/HEAD, discard/remove the previous 10 commits before the latest one, and finally "apply" these files as a new commit":

For example, suppose this is a list of all commits hashes:

1-2-3-4-5-6-7-8-9-10-11-12
, where HEAD points to 12.

I want to squash/remove/whatever this operation is called all the commits from 2-11 included, so that the final result after a
git log
gives:

1-12


where the files before and after the operation must be the same.

What are the commands to obtain what I need?

Answer

The simplest solution (after aborting the current rebase) is:

$ git reset --soft HEAD~10

Now, your HEAD has moved ten commits back, but none of your files changed: they'll all show up as new changes to be committed.

Then, just commit them as normal.


The downside to this approach is that you lose access to the intermediate commit messages when you're writing your new commit message.

The alternative is to make the original rebase -i command work for you by by specifying conflict resolution strategy theirs:

$ git rebase -i -s theirs HEAD~10

It would be interesting to know how you've managed to get conflicts in the first place though, rebase -i should usually apply cleanly. Unless some of those ten commits are themselves merges?

Comments