threads / bug / 63279

Bug: being stuck in rebase mode when accidently typing `git am`

Subject: Bug: being stuck in rebase mode when accidently typing `git am`

## tl;dr

4 messages between Apr 10, 2025 and Apr 11, 2025.

replies: 3people: 3as markdown or json

Ludo Pulles· Apr 10, 2025, 14:35 UTC · lore

Thank you for filling out a Git bug report! Please answer the following questions to help us understand your issue.

What did you do before the bug happened? (Steps to reproduce your issue)
1. Run `git init` in an empty directory, and commit once.
2. Run `git am` and press Ctrl-C.
3. Run `git status`. It will say: 'You are currently rebasing. (all 
conflicts fixed: run "git rebase --continue")'.
4. Run `git rebase --continue`

What did you expect to happen? (Expected behavior) I expected to go out of the rebase mode such that `git status` would say: "nothing to commit, working tree clean"

What happened instead? (Actual behavior) It outputs: "warning: could not read '.git/rebase-apply/head-name': File does not exist." Moreover, you are in rebase mode forever, and you cannot escape from it!

What's different between what you expected and what actually happened? Instead of going out of rebase mode (expected), you are still in rebase mode and you cannot escape it (actual).

Anything else you want to add: `rmdir .git/rebase-apply` fixes the issue

Please review the rest of the bug report below. You can delete any lines you don't wish to share.

[System Info]
git version:
git version 2.49.0
cpu: x86_64
built from commit: 683c54c999c301c2cd6f715c411407c413b1d84e
sizeof-long: 8
sizeof-size_t: 8
shell-path: /bin/sh
libcurl: 8.12.1
OpenSSL: OpenSSL 3.4.1 11 Feb 2025
zlib: 1.3.1
uname: Linux 6.12.22-1-lts #1 SMP PREEMPT_DYNAMIC Tue, 08 Apr 2025 
06:20:12 +0000 x86_64
compiler info: gnuc: 14.2
libc info: glibc: 2.41
$SHELL (typically, interactive shell): /bin/bash
[Enabled Hooks]
D. Ben Knoble· Apr 11, 2025, 18:23 UTC · re: Ludo Pulles · lore

Re: Bug: being stuck in rebase mode when accidently typing `git am`

On Thu, Apr 10, 2025 at 10:35 AM Ludo Pulles <ludo.pulles@gmail.com> wrote:
Show 8 quoted lines
>
> Thank you for filling out a Git bug report!
> Please answer the following questions to help us understand your issue.
>
> What did you do before the bug happened? (Steps to reproduce your issue)
>
> 1. Run `git init` in an empty directory, and commit once.
> 2. Run `git am` and press Ctrl-C.

Doesn't `git am` print a warning about how it's reading from stdin? Pressing C-d at this point to send EOF just exits "normally."

> 3. Run `git status`. It will say: 'You are currently rebasing. (all
> conflicts fixed: run "git rebase --continue")'.

Yes, this is odd: my shell prompt (using the contrib script) says "AM/REBASE", so I know better: git am --abort does the trick.

This seems like a failure of git-status more than anything; I wonder if there's some difference in how the prompt script checks for in-progress am vs. how git-status does it?

Show 43 quoted lines
> 4. Run `git rebase --continue`
>
> What did you expect to happen? (Expected behavior)
> I expected to go out of the rebase mode such that `git status` would
> say: "nothing to commit, working tree clean"
>
> What happened instead? (Actual behavior)
> It outputs: "warning: could not read '.git/rebase-apply/head-name': File
> does not exist."
> Moreover, you are in rebase mode forever, and you cannot escape from it!
>
> What's different between what you expected and what actually happened?
> Instead of going out of rebase mode (expected), you are still in rebase
> mode and you cannot escape it (actual).
>
> Anything else you want to add:
> `rmdir .git/rebase-apply` fixes the issue
>
> Please review the rest of the bug report below.
> You can delete any lines you don't wish to share.
>
>
> [System Info]
> git version:
> git version 2.49.0
> cpu: x86_64
> built from commit: 683c54c999c301c2cd6f715c411407c413b1d84e
> sizeof-long: 8
> sizeof-size_t: 8
> shell-path: /bin/sh
> libcurl: 8.12.1
> OpenSSL: OpenSSL 3.4.1 11 Feb 2025
> zlib: 1.3.1
> uname: Linux 6.12.22-1-lts #1 SMP PREEMPT_DYNAMIC Tue, 08 Apr 2025
> 06:20:12 +0000 x86_64
> compiler info: gnuc: 14.2
> libc info: glibc: 2.41
> $SHELL (typically, interactive shell): /bin/bash
>
>
> [Enabled Hooks]
>
>
-- 
D. Ben Knoble
D. Ben Knoble· Apr 11, 2025, 18:32 UTC · re: D. Ben Knoble · lore

Re: Bug: being stuck in rebase mode when accidently typing `git am`

On Fri, Apr 11, 2025 at 2:23 PM D. Ben Knoble <ben.knoble@gmail.com> wrote:
Show 11 quoted lines
>
> On Thu, Apr 10, 2025 at 10:35 AM Ludo Pulles <ludo.pulles@gmail.com> wrote:
> > 3. Run `git status`. It will say: 'You are currently rebasing. (all
> > conflicts fixed: run "git rebase --continue")'.
>
> Yes, this is odd: my shell prompt (using the contrib script) says
> "AM/REBASE", so I know better: git am --abort does the trick.
>
> This seems like a failure of git-status more than anything; I wonder
> if there's some difference in how the prompt script checks for
> in-progress am vs. how git-status does it?

Ok, looks like the prompt script checks for rebase, apply, and then gives up (its ambiguous):

if [ -d "$g/rebase-apply" ]; then __git_eread "$g/rebase-apply/next" step __git_eread "$g/rebase-apply/last" total if [ -f "$g/rebase-apply/rebasing" ]; then __git_eread "$g/rebase-apply/head-name" b r="|REBASE" elif [ -f "$g/rebase-apply/applying" ]; then r="|AM" else r="|AM/REBASE" fi

(with apologies for GMail stripping leading tabs :eyeroll:—source code link [1])
Meantime, wt-status just assumes it must be a rebase if it isn't an apply:

if (!stat(worktree_git_path(the_repository, wt, "rebase-apply"), &st)) { if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/applying"), &st)) { state->am_in_progress = 1; if (!stat(worktree_git_path(the_repository, wt, "rebase-apply/patch"), &st) && !st.st_size) state->am_empty_patch = 1; } else { state->rebase_in_progress = 1; state->branch = get_branch(wt, "rebase-apply/head-name"); state->onto = get_branch(wt, "rebase-apply/onto"); }

(source: [2])

The shell distinction was contributed in e75201963f (Improve bash prompt to detect various states like an unfinished merge, 2007-09-30), author CC'd. I think the logic in wt-status.c is largely unchanged from 83c750acde (wt-status.*: better advices for git status added, 2012-06-05), author CC'd as well.

Maybe we can omit a "You might be rebasing or applying; we're not sure which?" type of message?

[1]: https://github.com/git/git/blob/08bdfd453584e489d5a551aecbdcb77584e1b958/contrib/completion/git-prompt.sh#L517-L527 [2]: https://github.com/git/git/blob/08bdfd453584e489d5a551aecbdcb77584e1b958/wt-status.c#L1725-L1734

-- 
D. Ben Knoble
Phillip Wood· Apr 11, 2025, 19:13 UTC · re: D. Ben Knoble · lore

Re: Bug: being stuck in rebase mode when accidently typing `git am`

On 11/04/2025 19:23, D. Ben Knoble wrote:
Show 12 quoted lines
> On Thu, Apr 10, 2025 at 10:35 AM Ludo Pulles <ludo.pulles@gmail.com> wrote:
>>
>> Thank you for filling out a Git bug report!
>> Please answer the following questions to help us understand your issue.
>>
>> What did you do before the bug happened? (Steps to reproduce your issue)
>>
>> 1. Run `git init` in an empty directory, and commit once.
>> 2. Run `git am` and press Ctrl-C.
> 
> Doesn't `git am` print a warning about how it's reading from stdin?
> Pressing C-d at this point to send EOF just exits "normally."
Indeed
Show 9 quoted lines
>> 3. Run `git status`. It will say: 'You are currently rebasing. (all
>> conflicts fixed: run "git rebase --continue")'.
> 
> Yes, this is odd: my shell prompt (using the contrib script) says
> "AM/REBASE", so I know better: git am --abort does the trick.
> 
> This seems like a failure of git-status more than anything; I wonder
> if there's some difference in how the prompt script checks for
> in-progress am vs. how git-status does it?

I think the issue is that "git am" does not write the ".git/rebase-apply/applying" which "git status" uses to distinguish between "git am" and "git rebase" until it has read the patch files. We could instead check for ".git/rebase-apply/rebased-patches" which is written by "git rebase" but that file gets deleted when "git am" exits for the user to fix merge conflicts. I think the best solution is to move where "git am" writes ".git/rebase-apply/applying" so it gets created before the patch files are read - see the diff below.

Best Wishes
Phillip

[Apologies for the line wrapping the thunderbird plugin I was using to disable that has stopped working in recent versions] ---- >8 ----

diff --git a/builtin/am.c b/builtin/am.c
index 3b61bd4c333..e884ac39b23 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -1006,6 +1006,11 @@
          refs_delete_ref(get_main_ref_store(the_repository), NULL,
                          "REBASE_HEAD", NULL, REF_NO_DEREF);

+        if (state->rebasing)
+                write_state_text(state, "rebasing", "");
+        else
+                write_state_text(state, "applying", "");
+
          if (split_mail(state, patch_format, paths, keep_cr) < 0) {
                  am_destroy(state);
                  die(_("Failed to split patches."));
@@ -1076,11 +1081,6 @@
          sq_quote_argv(&sb, state->git_apply_opts.v);
          write_state_text(state, "apply-opt", sb.buf);

-        if (state->rebasing)
-                write_state_text(state, "rebasing", "");
-        else
-                write_state_text(state, "applying", "");
-
          if (!repo_get_oid(the_repository, "HEAD", &curr_head)) {
                  write_state_text(state, "abort-safety", 
oid_to_hex(&curr_head));
                  if (!state->rebasing)

← back to recent threads