5

I had a feature branch:

feature

with lets say 10 commits

then some time ago I started doing experiments on it, but wanted to preserve the current functionality just in case, so I started a new branch:

feature-experiment

and then did another 10 commits

today I decided to merge feature-experiment into feature and then I deleted feature-experiment. There were some merge conflicts which I resolved.

then, my 20 commits which were all using the same name and ending in WIP (work in progress), were very ugly, so I decided to

git rebase -p -i HEAD~22

I changed pick to s to squash them all into the oldest commit for this feature, but I had some merge conflicts (the same as before). I resolved them and then

git add -A && git commit

git rebase --continue

but now I get the following error:

error: Commit asd123qsd is a merge but no -m     option was given.
fatal: cherry-pick failed
Could not pick asd123qsd 

This is the last commit (the merge one)

I tried again, but this time I didnt change this particular commit's pick to s, but got the same error.

How can I carry out this dreadful rebase?

I was thinking, as a possible solution, I could I modify the last commit to add -m to it, but how do I do that and what do I do with this -m command? Are there any other options

Kaloyan Roussev
  • 14,515
  • 21
  • 98
  • 180

1 Answers1

3

The problem is likely here:

git rebase -p -i HEAD~22

The -p option is described in the git documentation as the short version of --preserve-merges:

-p

--preserve-merges

Recreate merge commits instead of flattening the history by replaying commits a merge commit introduces. Merge conflict resolutions or manual amendments to merge commits are not preserved.

This uses the --interactive machinery internally, but combining it with the --interactive option explicitly is generally not a good idea unless you know what you are doing (see BUGS below).

Since you're trying to squash commits here, preserving merge commits is almost certainly not what you want. Additionally, the warning about combining the --preserve-merges flag with the --interactive (-i) flag is likely relevant here.

Honestly though, using a rebase to do a squash like this may be introducing a lot more complexity than what you need here. If all you want is to squash all of the changes from this branch into a single commit, you can do that like this:

git checkout feature
git reset --soft <base of feature branch>

At this point all the changes from your feature branch should be staged, and the feature branch should be at the base commit. Now you can simply run git commit to create a new commit containing all the changes from your feature branch, which is basically equivalent to a squash.

Ajedi32
  • 45,670
  • 22
  • 127
  • 172
  • Thank you I will try that! What should I put in the placeholder you used ``? the commit that I want to start with? – Kaloyan Roussev Jun 20 '16 at 15:32
  • 1
    That would be the commit your branch is based off of. For example, if you branched off of master, then `git merge-base master feature` should print the hash of the commit to use for that step. (It should be the parent of the first commit on the feature branch.) – Ajedi32 Jun 20 '16 at 15:35
  • I did this and then pushed. Was rejected, because the other branch had advanced, so I pulled, then pushed. Went to GitHub but all 20 commits are still there and this new one is there as well. What did I do wrong? – Kaloyan Roussev Jun 20 '16 at 15:47
  • @J.K. That's a general problem with _all_ git operations that rewrite history. (Rebase, squash, --amend, etc.) The other branch likely didn't "advance", it just still contained the unsquashed commits that were no longer in your local branch. So when you ran `git pull` it merged all those commits back into your local branch. (Because that's what `pull` is for.) You have to push with `--force` whenever you want to delete commits (i.e. rewrite history) on a remote branch. Assuming that *is* what you intended, `reset --hard` back to the squashed commit and push again with `--force`. – Ajedi32 Jun 20 '16 at 15:53
  • by the `squashed commit` you mean `` or the one that I just uploaded? after that commit, there is some merge commit added as well, so which of those 3 should I reset hard to? I am really sorry for asking so many questions – Kaloyan Roussev Jun 20 '16 at 15:57
  • I would have tried all 3 variants but I dont want to mess up even more @Ajedi32 – Kaloyan Roussev Jun 20 '16 at 16:51
  • @J.K. I mean the squashed commit you just committed. – Ajedi32 Jun 20 '16 at 17:31