Search code examples
gitgit-detached-headgit-interactive-rebase

Why recently, git rebase -i squash results in detached head


Why does git rebase -i with squashes recently result in a detached head? It used to to update my current branch with the result of the interactive rebase. How do I get interactive rebase to stop going to detached HEAD?

I've always used git rebase -i to squash my commits before I pull from a remote repository to simplify handling any merge conflicts from the git pull. Instead of having to resolve conflicts over potentially multiple of my commits, I will only have to resolve one commit.

Sample command I use

# git rebase -i <tip of public branch> <my latest commit>
git rebase -i 380647533da 82f5ee67bed

After editing the rebase interactive in vim:

pick 3ec7c211c49 version1
s 82f5ee67bed some significant refactoring

Output after editting and saving the commit:

[detached HEAD ea50304796c] version1
 Date: Thu Jun 6 17:04:36 2019 -0400
 14 files changed, 213 insertions(+), 52 deletions(-)
 create mode 100644     some file
 create mode 100644     some file
 create mode 100644     some file
Successfully rebased and updated detached HEAD.

This differs from similar post git rebase -i develop HEAD leads to Detached Head because the asker wants to know HOW to resolve the issue for that ONE instance. the answer is git checkout -b branchName. In this question, I want to know WHY it started happening recently to me and HOW to resolve it for all FUTURE instances.

This differs from the similar post git rebase -i with squash cannot detach HEAD because the error message there is could not detach HEAD


Solution

  • The syntax guide for git rebase shows:

    git rebase [-i | --interactive] [<options>] [--exec ] [--onto <newbase>] [<upstream> [<branch>]] git rebase [-i | --interactive] [<options>] [--exec <cmd>] [--onto <newbase>] --root [<branch>] git rebase --continue | --skip | --abort | --quit | --edit-todo | --show-current-patch

    so your command:

    git rebase -i 380647533da 82f5ee67bed
    

    is providing 380647533da as the <upstream> and 82f5ee67bed as the <branch>.

    The first paragraph in the description section says:

    If <branch> is specified, git rebase will perform an automatic git checkout <branch> before doing anything else. Otherwise it remains on the current branch.

    So, your git rebase is equivalent to:

    git checkout 82f5ee67bed
    git rebase 380647533da
    

    The first command results in a detached HEAD. That detached HEAD remains that way when the rebase finishes.