Search code examples
gitgit-rebase

After successfully recovering from a mangled git rebase, calling git rebase again does not work properly


After mangling a git rebase -i, I eventually got the code into the state I want.

$ git log
55c602ed1c (HEAD -> main) 
6c3fa102c2 (detached-branch) 
6ec87486d1 
89dd40a86a 
f6f4b6edb2 
77742d9d69 
32b67d2a01 
...

The commit 55c602ed1c is exactly correct.

However, when I now call git rebase -i 6c3fa102c2 I get unexpected editor content:

pick 77742d9d69
pick f6f4b6edb2
pick 89dd40a86a

# Rebase 6c3fa102c2..55c602ed1c onto 6c3fa102c2 (3 commands)
#
# Commands:
# ...

Of course I was expecting to see

pick 6c3fa102c2
pick 55c602ed1c

# Rebase 6c3fa102c2..55c602ed1c onto 6c3fa102c2 (3 commands)
#
# Commands:
# ...

Now I quit the editor without saving and get a message and errors:

Auto-merging ...
CONFLICT ... 
<more conflicts>

so I do git rebase --abort to get out of that, which leaves the branch in the correct state, but still unable to rebase.

How can I get back the normal rebasing function?


EDIT:
Removing reflog output, and removing the question, while adding new content and question.

$ git log --oneline --graph
*   55c602ed1c (HEAD -> main)
r|g\  
r|   * 6c3fa102c2 (detached-branch) 
r|   * 6ec87486d1
 *  g| 89dd40a86a
 *  g| f6f4b6edb2
 *  g| 77742d9d69 
r|g/  
* 32b67d2a01

The actual graph output is color coded red and green , so I prefixed |,/, and \ with a letter to indicate actual color.

For the record, the command used to create the final, good, commit 55c602ed1c were:

git checkout main
git merge detached-branch

and it required manual conflict resolution.

I have tried rebasing to the common ancestor 32b67d2a01, which is suggested in this answer to a similar question, but oddly neither the HEAD commit 55c602ed1c nor the common ancestor 32b67d2a01 appear in the list shown in the editor:

git rebase -i 32b67d2a01

pops up editor with

pick 77742d9d69 
pick f6f4b6edb2 
pick 89dd40a86a 
pick 6ec87486d1 
pick 6c3fa102c2

# Rebase 32b67d2a01..55c602ed1c onto 6ec87486d1 (5 commands)
#
# Commands:

Using a tilde as in the hint given by @eftshift0 (without understanding the principle behind it and not seeing it on the git man mage for rebase)

git rebase -i 32b67d2a01~

gives

pick 32b67d2a01
pick 77742d9d69 
pick f6f4b6edb2 
pick 89dd40a86a 
pick 6ec87486d1 
pick 6c3fa102c2

# Rebase db737eb68b..55c602ed1c onto 89dd40a86a (6 commands)
#
# Commands:

but still, the HEAD commit 55c602ed1c is not listed on the bottom. If I go ahead and do the rebase with that selection, 55c602ed1c is ignored and I am asked to resolve conflicts all over again, which obviously I don't want to do because 55c602ed1c is already merged and satisfactory.

The new question is how can I remove the commits between but not including HEAD and the common ancestor, while keeping HEAD (obviously)?


Solution

  • Here is an answer to the final question:

    git reset --soft 32b67d2a01
    git commit -m "everything past 32b67d2a01 in a single shot"
    

    That should work, no conflict to resolve. You are losing (and rewriting) history, of course, but I think that is the ultimate goal, right?