git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Bug with rebase and commit hashes

From
Michael McClimon <michael@mcclimon.org>
Date
Mar 10, 2022, 16:16 UTC
Message-ID
<YiokTm3GxIZQQUow@newk>

I have run into a bug with rebase when operating with commit hashes directly (rather than branch names).

Say that I have two branches, main and topic. Branch topic consists of a single commit whose parent is main. If I'm on main, and I run 'git rebase main topic', I end up on branch topic, as expected (my prompt here displays the current branch):

[~/scratch on main] $ git rebase main topic Successfully rebased and updated refs/heads/topic. [~/scratch on topic] $

If I do exactly the same thing, but substitute the commit shas for those branches, git _doesn't_ leave me on branch topic, but instead fast-forwards main to topic. This is very surprising to me!

[~/scratch on main] $ git rev-parse main 464adc6a6f8aa0a943dbf886df1eb6497f70f6e6 [~/scratch on main] $ git rev-parse topic c3c862105dfbb2f30137a0875e8e5d9dfec334f8 [~/scratch on main] $ git rebase $(git rev-parse main) $(git rev-parse topic) Current branch c3c862105dfbb2f30137a0875e8e5d9dfec334f8 is up to date. [~/scratch on main] $ git rev-parse main c3c862105dfbb2f30137a0875e8e5d9dfec334f8

Part of the reason this is surprising is that in the case when topic is not a fast-forward from main (i.e., does need to be rebased), git does what I'd expect, and leaves me detached on the newly rebased head.

[~/scratch on main] $ git rev-parse main 464adc6a6f8aa0a943dbf886df1eb6497f70f6e6 [~/scratch on main] $ git rev-parse topic 8d7d712bad0c32cd87aa814730317178b2e46b93 [~/scratch on main] $ git rebase $(git rev-parse main) $(git rev-parse topic) Successfully rebased and updated detached HEAD. [~/scratch at 1477bc43] $ git rev-parse HEAD 1477bc43a3bc7868ba1da8a919a60432bedbd34a

I ran into this because I was writing some software to enforce semilinear history (all commits on main are merge commits, and the topic branches are all rebased on main before merge). That workflow is: for every branch, rebase $main_sha $topic_sha, then checkout main and merge --no-ff $topic_sha. Because of this bug, when we got to the merge --no-ff, git didn't do anything at all, because it had already fast-forwarded main! I worked around this in my program by just passing --force-rebase to my rebase invocation, which fixes this particular problem by leaving me in a detached head (as in the last case above).

I hit this in production on git 2.30.2 (debian bullseye), but reproduced locally using the latest git main, which is git version 2.35.1.415.gc2162907. In both cases I wiped my user gitconfig, so I'm using only the defaults. (If it helps: with my rebase.autosquash = true, the bad case above does not behave badly and leaves me in detached head as I'd expect.) It's totally possible this isn't _meant_ to work, in which case I think the docs could use an update.

Thanks!
-- 
Michael McClimon
michael@mcclimon.org
Next: John Cai
Message 1 of 7 in “Bug with rebase and commit hashes”
  1. Michael McClimonMar 10, 2022
  2. John CaiMar 10, 2022
  3. John CaiMar 10, 2022
  4. Michael McClimonMar 12, 2022
  5. John CaiMar 12, 2022
  6. Michael McClimonMar 12, 2022
  7. Junio C HamanoMar 10, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.