{"thread":{"id":"63279","subject":"Bug: being stuck in rebase mode when accidently typing `git am`","startedAt":"2025-04-10T14:35:19Z","lastAt":"2025-04-11T19:13:36Z","messageCount":4,"participants":["Ludo Pulles","D. Ben Knoble","Phillip Wood"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"515960","messageId":"76edd34d-3fd1-437e-b8d3-7e64e99644a2@gmail.com","threadId":"63279","inReplyTo":null,"subject":"Bug: being stuck in rebase mode when accidently typing `git am`","fromName":"Ludo Pulles","fromEmail":"ludo.pulles@gmail.com","sentAt":"2025-04-10T14:35:17Z","receivedAt":"2025-04-10T14:35:19Z","isPatch":false,"sender":{"key":"ludo.pulles@gmail.com","avatar":null},"body":"Thank you for filling out a Git bug report!\nPlease answer the following questions to help us understand your issue.\n\nWhat did you do before the bug happened? (Steps to reproduce your issue)\n\n1. Run `git init` in an empty directory, and commit once.\n2. Run `git am` and press Ctrl-C.\n3. Run `git status`. It will say: 'You are currently rebasing. (all \nconflicts fixed: run \"git rebase --continue\")'.\n4. Run `git rebase --continue`\n\nWhat did you expect to happen? (Expected behavior)\nI expected to go out of the rebase mode such that `git status` would \nsay: \"nothing to commit, working tree clean\"\n\nWhat happened instead? (Actual behavior)\nIt outputs: \"warning: could not read '.git/rebase-apply/head-name': File \ndoes not exist.\"\nMoreover, you are in rebase mode forever, and you cannot escape from it!\n\nWhat's different between what you expected and what actually happened?\nInstead of going out of rebase mode (expected), you are still in rebase \nmode and you cannot escape it (actual).\n\nAnything else you want to add:\n`rmdir .git/rebase-apply` fixes the issue\n\nPlease review the rest of the bug report below.\nYou can delete any lines you don't wish to share.\n\n\n[System Info]\ngit version:\ngit version 2.49.0\ncpu: x86_64\nbuilt from commit: 683c54c999c301c2cd6f715c411407c413b1d84e\nsizeof-long: 8\nsizeof-size_t: 8\nshell-path: /bin/sh\nlibcurl: 8.12.1\nOpenSSL: OpenSSL 3.4.1 11 Feb 2025\nzlib: 1.3.1\nuname: Linux 6.12.22-1-lts #1 SMP PREEMPT_DYNAMIC Tue, 08 Apr 2025 \n06:20:12 +0000 x86_64\ncompiler info: gnuc: 14.2\nlibc info: glibc: 2.41\n$SHELL (typically, interactive shell): /bin/bash\n\n\n[Enabled Hooks]\n\n"},{"id":"516004","messageId":"CALnO6CCbzqez9-BvbuV3NRRMvFLHSv57Tfwj3ibadUAMKznWrw@mail.gmail.com","threadId":"63279","inReplyTo":"76edd34d-3fd1-437e-b8d3-7e64e99644a2@gmail.com","subject":"Re: Bug: being stuck in rebase mode when accidently typing `git am`","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2025-04-11T18:23:18Z","receivedAt":"2025-04-11T18:23:30Z","isPatch":false,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"On Thu, Apr 10, 2025 at 10:35 AM Ludo Pulles <ludo.pulles@gmail.com> wrote:\n>\n> Thank you for filling out a Git bug report!\n> Please answer the following questions to help us understand your issue.\n>\n> What did you do before the bug happened? (Steps to reproduce your issue)\n>\n> 1. Run `git init` in an empty directory, and commit once.\n> 2. Run `git am` and press Ctrl-C.\n\nDoesn't `git am` print a warning about how it's reading from stdin?\nPressing C-d at this point to send EOF just exits \"normally.\"\n\n> 3. Run `git status`. It will say: 'You are currently rebasing. (all\n> conflicts fixed: run \"git rebase --continue\")'.\n\nYes, this is odd: my shell prompt (using the contrib script) says\n\"AM/REBASE\", so I know better: git am --abort does the trick.\n\nThis seems like a failure of git-status more than anything; I wonder\nif there's some difference in how the prompt script checks for\nin-progress am vs. how git-status does it?\n\n> 4. Run `git rebase --continue`\n>\n> What did you expect to happen? (Expected behavior)\n> I expected to go out of the rebase mode such that `git status` would\n> say: \"nothing to commit, working tree clean\"\n>\n> What happened instead? (Actual behavior)\n> It outputs: \"warning: could not read '.git/rebase-apply/head-name': File\n> does not exist.\"\n> Moreover, you are in rebase mode forever, and you cannot escape from it!\n>\n> What's different between what you expected and what actually happened?\n> Instead of going out of rebase mode (expected), you are still in rebase\n> mode and you cannot escape it (actual).\n>\n> Anything else you want to add:\n> `rmdir .git/rebase-apply` fixes the issue\n>\n> Please review the rest of the bug report below.\n> You can delete any lines you don't wish to share.\n>\n>\n> [System Info]\n> git version:\n> git version 2.49.0\n> cpu: x86_64\n> built from commit: 683c54c999c301c2cd6f715c411407c413b1d84e\n> sizeof-long: 8\n> sizeof-size_t: 8\n> shell-path: /bin/sh\n> libcurl: 8.12.1\n> OpenSSL: OpenSSL 3.4.1 11 Feb 2025\n> zlib: 1.3.1\n> uname: Linux 6.12.22-1-lts #1 SMP PREEMPT_DYNAMIC Tue, 08 Apr 2025\n> 06:20:12 +0000 x86_64\n> compiler info: gnuc: 14.2\n> libc info: glibc: 2.41\n> $SHELL (typically, interactive shell): /bin/bash\n>\n>\n> [Enabled Hooks]\n>\n>\n\n\n-- \nD. Ben Knoble\n"},{"id":"516005","messageId":"CALnO6CCYqF1QHQzS6DH200cqi6VRmhWjvts87S99a+jqqgHHfw@mail.gmail.com","threadId":"63279","inReplyTo":"CALnO6CCbzqez9-BvbuV3NRRMvFLHSv57Tfwj3ibadUAMKznWrw@mail.gmail.com","subject":"Re: Bug: being stuck in rebase mode when accidently typing `git am`","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2025-04-11T18:32:19Z","receivedAt":"2025-04-11T18:32:33Z","isPatch":false,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"On Fri, Apr 11, 2025 at 2:23 PM D. Ben Knoble <ben.knoble@gmail.com> wrote:\n>\n> On Thu, Apr 10, 2025 at 10:35 AM Ludo Pulles <ludo.pulles@gmail.com> wrote:\n> > 3. Run `git status`. It will say: 'You are currently rebasing. (all\n> > conflicts fixed: run \"git rebase --continue\")'.\n>\n> Yes, this is odd: my shell prompt (using the contrib script) says\n> \"AM/REBASE\", so I know better: git am --abort does the trick.\n>\n> This seems like a failure of git-status more than anything; I wonder\n> if there's some difference in how the prompt script checks for\n> in-progress am vs. how git-status does it?\n\nOk, looks like the prompt script checks for rebase, apply, and then\ngives up (its ambiguous):\n\nif [ -d \"$g/rebase-apply\" ]; then\n__git_eread \"$g/rebase-apply/next\" step\n__git_eread \"$g/rebase-apply/last\" total\nif [ -f \"$g/rebase-apply/rebasing\" ]; then\n__git_eread \"$g/rebase-apply/head-name\" b\nr=\"|REBASE\"\nelif [ -f \"$g/rebase-apply/applying\" ]; then\nr=\"|AM\"\nelse\nr=\"|AM/REBASE\"\nfi\n\n(with apologies for GMail stripping leading tabs :eyeroll:—source code link [1])\n\nMeantime, wt-status just assumes it must be a rebase if it isn't an apply:\n\nif (!stat(worktree_git_path(the_repository, wt, \"rebase-apply\"), &st)) {\nif (!stat(worktree_git_path(the_repository, wt,\n\"rebase-apply/applying\"), &st)) {\nstate->am_in_progress = 1;\nif (!stat(worktree_git_path(the_repository, wt, \"rebase-apply/patch\"),\n&st) && !st.st_size)\nstate->am_empty_patch = 1;\n} else {\nstate->rebase_in_progress = 1;\nstate->branch = get_branch(wt, \"rebase-apply/head-name\");\nstate->onto = get_branch(wt, \"rebase-apply/onto\");\n}\n\n(source: [2])\n\nThe shell distinction was contributed in e75201963f (Improve bash\nprompt to detect various states like an unfinished merge, 2007-09-30),\nauthor CC'd.\nI think the logic in wt-status.c is largely unchanged from 83c750acde\n(wt-status.*: better advices for git status added, 2012-06-05), author\nCC'd as well.\n\nMaybe we can omit a \"You might be rebasing or applying; we're not sure\nwhich?\" type of message?\n\n[1]: https://github.com/git/git/blob/08bdfd453584e489d5a551aecbdcb77584e1b958/contrib/completion/git-prompt.sh#L517-L527\n[2]: https://github.com/git/git/blob/08bdfd453584e489d5a551aecbdcb77584e1b958/wt-status.c#L1725-L1734\n\n-- \nD. Ben Knoble\n"},{"id":"516011","messageId":"c0075b62-34fb-41f6-bc69-e33a403d528c@gmail.com","threadId":"63279","inReplyTo":"CALnO6CCbzqez9-BvbuV3NRRMvFLHSv57Tfwj3ibadUAMKznWrw@mail.gmail.com","subject":"Re: Bug: being stuck in rebase mode when accidently typing `git am`","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2025-04-11T19:13:30Z","receivedAt":"2025-04-11T19:13:36Z","isPatch":false,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 11/04/2025 19:23, D. Ben Knoble wrote:\n> On Thu, Apr 10, 2025 at 10:35 AM Ludo Pulles <ludo.pulles@gmail.com> wrote:\n>>\n>> Thank you for filling out a Git bug report!\n>> Please answer the following questions to help us understand your issue.\n>>\n>> What did you do before the bug happened? (Steps to reproduce your issue)\n>>\n>> 1. Run `git init` in an empty directory, and commit once.\n>> 2. Run `git am` and press Ctrl-C.\n> \n> Doesn't `git am` print a warning about how it's reading from stdin?\n> Pressing C-d at this point to send EOF just exits \"normally.\"\n\nIndeed\n\n>> 3. Run `git status`. It will say: 'You are currently rebasing. (all\n>> conflicts fixed: run \"git rebase --continue\")'.\n> \n> Yes, this is odd: my shell prompt (using the contrib script) says\n> \"AM/REBASE\", so I know better: git am --abort does the trick.\n> \n> This seems like a failure of git-status more than anything; I wonder\n> if there's some difference in how the prompt script checks for\n> in-progress am vs. how git-status does it?\n\nI think the issue is that \"git am\" does not write the \n\".git/rebase-apply/applying\" which \"git status\" uses to distinguish \nbetween \"git am\" and \"git rebase\" until it has read the patch files. We \ncould instead check for \".git/rebase-apply/rebased-patches\" which is \nwritten by \"git rebase\" but that file gets deleted when \"git am\" exits \nfor the user to fix merge conflicts. I think the best solution is to \nmove where \"git am\" writes \".git/rebase-apply/applying\" so it gets \ncreated before the patch files are read - see the diff below.\n\nBest Wishes\n\nPhillip\n\n[Apologies for the line wrapping the thunderbird plugin I was using to \ndisable that has stopped working in recent versions]\n---- >8 ----\n\ndiff --git a/builtin/am.c b/builtin/am.c\nindex 3b61bd4c333..e884ac39b23 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -1006,6 +1006,11 @@\n          refs_delete_ref(get_main_ref_store(the_repository), NULL,\n                          \"REBASE_HEAD\", NULL, REF_NO_DEREF);\n\n+        if (state->rebasing)\n+                write_state_text(state, \"rebasing\", \"\");\n+        else\n+                write_state_text(state, \"applying\", \"\");\n+\n          if (split_mail(state, patch_format, paths, keep_cr) < 0) {\n                  am_destroy(state);\n                  die(_(\"Failed to split patches.\"));\n@@ -1076,11 +1081,6 @@\n          sq_quote_argv(&sb, state->git_apply_opts.v);\n          write_state_text(state, \"apply-opt\", sb.buf);\n\n-        if (state->rebasing)\n-                write_state_text(state, \"rebasing\", \"\");\n-        else\n-                write_state_text(state, \"applying\", \"\");\n-\n          if (!repo_get_oid(the_repository, \"HEAD\", &curr_head)) {\n                  write_state_text(state, \"abort-safety\", \noid_to_hex(&curr_head));\n                  if (!state->rebasing)\n\n"}]}