how is it that your current branch is not moved during rebasing?

Why dev pointer is not moved to top with HEAD? — because it is not the current branch during the rebase.

Read the documentation of git rebase carefully. It explains in the first paragraph:

git rebase [-i | --interactive] [<options>] [--exec <cmd>]
        [--onto <newbase> | --keep-base] [<upstream> [<branch>]]`

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

In plain English, if git rebase is invoked with two branches (<upstream> and <branch>), it first switches to the second branch then rebase it on top of the first branch.*

This means that:

git rebase dev local/dev

is a shortcut for:

git switch local/dev
git rebase dev

The current branch during the rebase is local/dev; it is the only branch that is affected by the rebase.

* <upstream> does not need to be a branch. Any reference that identifies a commit (branch, tag, commit, HEAD, HEAD^2, [email protected]{1} etc) can be used as <upstream>.

<branch>, on the other hand, needs to be a branch because, as a result of the rebase, it will move to a different commit.


You interpret the documentation incorrectly. You say in the question:

The current branch is reset to <upstream>

** upstream is dev. So I am on dev at this point

The current branch on that point is not necessarily dev (it is, in fact, local/dev as explained above).

“The current branch is reset to <upstream> does not mean that <upstream> becomes the current branch but that the current branch (local/dev) is moved to the commit identified by <upstream>. What Git does at this point is equivalent to git reset --hard <upstream>.

Update #2

The analysis above ignores the fact that local/dev is a remote branch. I didn’t notice that initially.
What’s the point of naming a remote local? It is misleading.

Because local/dev is not a local branch, git switch local/dev brings the repo in a detached HEAD state. The rest of the rebase happens as described in the documentation but in the end you have a new history line and no branch that points to it (except for HEAD). If you switch the branch the result of the rebase is lost.

There are two ways to fix the things:

  • Move the branch dev on the current commit. There are several ways to do this but the easiest way is to use git branch -f dev.

  • Abandon the changes, switch to the dev branch and do the rebase correctly:

    git switch dev
    git rebase local/dev

The real solution

All in all, the entire situation appeared because you put the branches in the incorrect order in the command line. It should be:

git rebase local/dev dev

This checks out the dev branch then moves the commits accessible from dev and not accessible from local/dev on top of local/dev while it preserves the dev branch on top of the moved commits. On a quick glance it looks like the branch dev is cut from where it forks from branch local/dev and the piece is then grafted on top of local/dev.

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top