{"thread":{"id":"64427","subject":"[PATCH 0/3] Fix another crazy rename assertion","startedAt":"2025-11-03T18:01:51Z","lastAt":"2025-11-17T22:10:45Z","messageCount":9,"participants":["Elijah Newren via GitGitGadget","Kristoffer Haugsbakk","Elijah Newren","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"530142","messageId":"pull.1992.git.1762192908.gitgitgadget@gmail.com","threadId":"64427","inReplyTo":null,"subject":"[PATCH 0/3] Fix another crazy rename assertion","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-11-03T18:01:45Z","receivedAt":"2025-11-03T18:01:51Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"This fixes another special corner case that was being triggered at GitHub;\nthe error being triggered is the same as what I submitted a fix for a few\nmonths ago, but the way it was triggered and the fix needed are different in\nthis case. See the final commit message for details. The first two patches\nare just tiny cleanups I noticed while investigating the problem.\n\nI will also note that I first came up with an alternative fix -- checking in\nuse_cached_pairs() whether new_name was contained in the opt->priv->paths\nstrmap, and if not, skipping to the next cached rename instead of adding it\nto pairs. That would also work, but it would mean that if a yet-subsequent\ncommit after that did modify the old/file path, I think we'd have to\nre-detect the rename, which would hurt the effectiveness of the cached\nrenames optimization. Simply avoiding using it in process_renames() allows\nit to avoid being forgotten (and since old/file is NOT modified, the\nupstream rename remains valid). Besides, this fix is nicely symmetrical to\nthe check on !oldinfo, so it seems more aesthetic to me as well as helping\nus preserve performance.\n\nElijah Newren (3):\n  t6429: update comment to mention correct tool\n  merge-ort: remove debugging crud\n  merge-ort: fix failing merges in special corner case\n\n merge-ort.c                              | 31 +++++++-\n t/t6429-merge-sequence-rename-caching.sh | 93 ++++++++++++++++++++++--\n 2 files changed, 114 insertions(+), 10 deletions(-)\n\n\nbase-commit: 4253630c6f07a4bdcc9aa62a50e26a4d466219d1\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1992%2Fnewren%2Ffix-another-crazy-rename-assertion-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1992/newren/fix-another-crazy-rename-assertion-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/1992\n-- \ngitgitgadget\n"},{"id":"530143","messageId":"bbbf2971ab3d70c1d455973c4a1f24b407a56a1b.1762192908.git.gitgitgadget@gmail.com","threadId":"64427","inReplyTo":"pull.1992.git.1762192908.gitgitgadget@gmail.com","subject":"[PATCH 2/3] merge-ort: remove debugging crud","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-11-03T18:01:47Z","receivedAt":"2025-11-03T18:01:55Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nWhile developing commit a16e8efe5c2b (merge-ort: fix\nmerge.directoryRenames=false, 2025-03-13), I was testing things out and\nhad an extra condition on one of the if-blocks that I occasionally\nswapped between '&& 0' and '&& 1' to see the effects of the changes.  I\nforgot to remove it before submitting and it wasn't caught in review.\nRemove it now.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n merge-ort.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/merge-ort.c b/merge-ort.c\nindex 29858074f9..23b55c5b92 100644\n--- a/merge-ort.c\n+++ b/merge-ort.c\n@@ -3438,7 +3438,7 @@ static int collect_renames(struct merge_options *opt,\n \t\t\tcontinue;\n \t\t}\n \t\tif (opt->detect_directory_renames == MERGE_DIRECTORY_RENAMES_NONE &&\n-\t\t    p->status == 'R' && 1) {\n+\t\t    p->status == 'R') {\n \t\t\tpossibly_cache_new_pair(renames, p, side_index, NULL);\n \t\t\tgoto skip_directory_renames;\n \t\t}\n-- \ngitgitgadget\n\n"},{"id":"530144","messageId":"9095098ab22cea89d38d7d538b21e3cf8d834df0.1762192908.git.gitgitgadget@gmail.com","threadId":"64427","inReplyTo":"pull.1992.git.1762192908.gitgitgadget@gmail.com","subject":"[PATCH 3/3] merge-ort: fix failing merges in special corner case","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-11-03T18:01:48Z","receivedAt":"2025-11-03T18:01:57Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nAt GitHub, we had a repository that was triggering\n  git: merge-ort.c:3032: process_renames: Assertion `newinfo && !newinfo->merged.clean` failed.\nduring git replay.\n\nThis sounds similar to the somewhat recent f6ecb603ff8a (merge-ort: fix\ndirectory rename on top of source of other rename/delete, 2025-08-06),\nbut the cause is different.  Unlike that case, there are no\nrename-to-self situations arising in this case, and new to this case it\ncan only be triggered during a replay operation on the 2nd or later\ncommit being replayed, never on the first merge in the sequence.\n\nTo trigger, the repository needs:\n  * an upstream which:\n    * renames a file to a different directory, e.g.\n        old/file -> new/file\n    * leaves other files remaining in the original directory (so that\n      e.g. \"old/\" still exists upstream even though file has been\n      removed from it and placed elsewhere)\n  * a topic branch being rebased where:\n    * a commit in the sequence:\n      * modifies old/file\n    * a subsequent commit in the sequence being replayed:\n      * does NOT touch *anything* under new/\n      * does NOT touch old/file\n      * DOES modify other paths under old/\n      * does NOT have any relevant renames that we need to detect\n        _anywhere_ elsewhere in the tree (meaning this interacts\n        interestingly with both directory renames and cached renames)\n\nIn such a case, the assertion will trigger.  The fix turns out to be\nsurprisingly simple.  I have a very vague recollection that I actually\nconsidered whether to add such an if-check years ago when I added the\nvery similar one for oldinfo in 1b6b902d95a5 (merge-ort:\nprocess_renames() now needs more defensiveness, 2021-01-19), but I think\nI couldn't figure out a possible way to trigger it and was worried at\nthe time that if I didn't know how to trigger it then I wasn't so sure\nthat simply skipping it was correct.  Waiting did give me a chance to\nput more thorough tests and checks into place for the rename-to-self\ncases a few months back, which I might not have found as easily\notherwise.  Anyway, put the check in place now and add a test that\ndemonstrates the fix.\n\nNote that this bug, as demonstrated by the conditions listed above,\nruns at the intersection of relevant renames, trivial directory\nresolutions, and cached renames.  All three of those optimizations are\nones that unfortunately make the code (and testcases!) a bit more\ncomplex, and threading all three makes it a bit more so.  However, the\ntestcase isn't crazy enough that I'd expect no one to ever hit it in\npractice, and was confused why we didn't see it before.  After some\ndigging, I discovered that merge.directoryRenames=false is a workaround\nto this bug, and GitHub used that setting until recently (it was a\n\"temporary\" match-what-libgit2-does piece of code that lasted years\nlonger than intended).  Since the conditions I gave above for triggering\nthis bug rule out the possibility of there being directory renames, one\nmight assume that it shouldn't matter whether you try to detect such\nrenames if there aren't any.  However, due to commit a16e8efe5c2b\n(merge-ort: fix merge.directoryRenames=false, 2025-03-13), the heavy\nhammer used there means that merge.directoryRenames=false ALSO turns off\nrename caching, which is critical to triggering the bug.  This becomes\na bit more than an aside since...\n\nRe-reading that old commit, a16e8efe5c2b (merge-ort: fix\nmerge.directoryRenames=false, 2025-03-13), it appears that the solution\nto this latest bug might have been at least a partial alternative\nsolution to that old commit.  And it may have been an improved\nalternative (or at least help implement one), since it may be able to\navoid the heavy-handed disabling of rename cache.  That might be an\ninteresting future thing to investigate, but is not critical for the\ncurrent fix.  However, since I spent time digging it all up, at least\nleave a small comment tweak breadcrumb to help some future reader\n(myself or others) who wants to dig further to connect the dots a little\nquicker.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n merge-ort.c                              | 29 ++++++++-\n t/t6429-merge-sequence-rename-caching.sh | 78 ++++++++++++++++++++++++\n 2 files changed, 106 insertions(+), 1 deletion(-)\n\ndiff --git a/merge-ort.c b/merge-ort.c\nindex 23b55c5b92..a1f3333e44 100644\n--- a/merge-ort.c\n+++ b/merge-ort.c\n@@ -2912,6 +2912,32 @@ static int process_renames(struct merge_options *opt,\n \t\tif (!oldinfo || oldinfo->merged.clean)\n \t\t\tcontinue;\n \n+\t\t/*\n+\t\t * Rename caching from a previous commit might give us an\n+\t\t * irrelevant rename for the current commit.\n+\t\t *\n+\t\t * Imagine:\n+\t\t *     foo/A -> bar/A\n+\t\t * was a cached rename for the upstream side from the\n+\t\t * previous commit (without the directories being renamed),\n+\t\t * but the next commit being replayed\n+\t\t *     * does NOT add or delete files\n+\t\t *     * does NOT have directory renames\n+\t\t *     * does NOT modify any files under bar/\n+\t\t *     * does NOT modify foo/A\n+\t\t *     * DOES modify other files under foo/ (otherwise the\n+\t\t *       !oldinfo check above would have already exited for\n+\t\t *       us)\n+\t\t * In such a case, our trivial directory resolution will\n+\t\t * have already merged bar/, and our attempt to process\n+\t\t * the cached\n+\t\t *     foo/A -> bar/A\n+\t\t * would be counterproductive, and lack the necessary\n+\t\t * information anyway.  Skip such renames.\n+\t\t */\n+\t\tif (!newinfo)\n+\t\t\tcontinue;\n+\n \t\t/*\n \t\t * diff_filepairs have copies of pathnames, thus we have to\n \t\t * use standard 'strcmp()' (negated) instead of '=='.\n@@ -5118,7 +5144,8 @@ static void merge_check_renames_reusable(struct merge_options *opt,\n \t * optimization\" comment near that case).\n \t *\n \t * This could be revisited in the future; see the commit message\n-\t * where this comment was added for some possible pointers.\n+\t * where this comment was added for some possible pointers, or the\n+\t * later commit where this comment was added.\n \t */\n \tif (opt->detect_directory_renames == MERGE_DIRECTORY_RENAMES_NONE) {\n \t\trenames->cached_pairs_valid_side = 0; /* neither side valid */\ndiff --git a/t/t6429-merge-sequence-rename-caching.sh b/t/t6429-merge-sequence-rename-caching.sh\nindex dcb734b10b..15dd2d94b7 100755\n--- a/t/t6429-merge-sequence-rename-caching.sh\n+++ b/t/t6429-merge-sequence-rename-caching.sh\n@@ -768,4 +768,82 @@ test_expect_success 'avoid assuming we detected renames' '\n \t)\n '\n \n+#\n+# In the following testcase:\n+#   Base:     olddir/{valuesX_1, valuesY_1, valuesZ_1}\n+#             other/content\n+#   Upstream: rename olddir/valuesX_1 -> newdir/valuesX_2\n+#   Topic_1:  modify olddir/valuesX_1 -> olddir/valuesX_3\n+#   Topic_2:  modify olddir/valuesY,\n+#             modify other/content\n+#   Expected Pick1: olddir/{valuesY, valuesZ}, newdir/valuesX, other/content\n+#   Expected Pick2: olddir/{valuesY, valuesZ}, newdir/valuesX, other/content\n+#\n+# This testcase presents no problems for git traditionally, but the fact that\n+#    olddir/valuesX -> newdir/valuesX\n+# gets cached after the first pick presents a problem for the second commit to\n+# be replayed, because it appears to be an irrelevant rename, so the trivial\n+# directory resolution will resolve newdir/ without recursing into it, giving\n+# us no way to apply the cached rename to anything.\n+#\n+test_expect_success 'rename a file, use it on first pick, but irrelevant on second' '\n+\tgit init rename_a_file_use_it_once_irrelevant_on_second &&\n+\t(\n+\t\tcd rename_a_file_use_it_once_irrelevant_on_second &&\n+\n+\t\tmkdir olddir/ other/ &&\n+\t\ttest_seq 3 8 >olddir/valuesX &&\n+\t\ttest_seq 3 8 >olddir/valuesY &&\n+\t\ttest_seq 3 8 >olddir/valuesZ &&\n+\t\tprintf \"%s\\n\" A B C D E F G >other/content &&\n+\t\tgit add olddir other &&\n+\t\tgit commit -m orig &&\n+\n+\t\tgit branch upstream &&\n+\t\tgit branch topic &&\n+\n+\t\tgit switch upstream &&\n+\t\ttest_seq 1 8 >olddir/valuesX &&\n+\t\tgit add olddir &&\n+\t\tmkdir newdir &&\n+\t\tgit mv olddir/valuesX newdir &&\n+\t\tgit commit -m \"Renamed (and modified) olddir/valuesX into newdir/\" &&\n+\n+\t\tgit switch topic &&\n+\n+\t\ttest_seq 3 10 >olddir/valuesX &&\n+\t\tgit add olddir &&\n+\t\tgit commit -m A &&\n+\n+\t\ttest_seq 1 8 >olddir/valuesY &&\n+\t\tprintf \"%s\\n\" A B C D E F G H I >other/content &&\n+\t\tgit add olddir/valuesY other &&\n+\t\tgit commit -m B &&\n+\n+\t\t#\n+\t\t# Actual testing; mostly we want to verify that we do not hit\n+\t\t#     git: merge-ort.c:3032: process_renames: Assertion `newinfo && !newinfo->merged.clean` failed.\n+\t\t#\n+\n+\t\tgit switch upstream &&\n+\t\tgit config merge.directoryRenames true &&\n+\n+\t\tgit replay --onto HEAD upstream~1..topic >out &&\n+\n+\t\t#\n+\t\t# ...but we may as well check that the replay gave us a reasonable result\n+\t\t#\n+\n+\t\tgit update-ref --stdin <out &&\n+\t\tgit checkout topic &&\n+\n+\t\tgit ls-files >tracked &&\n+\t\ttest_line_count = 4 tracked &&\n+\t\ttest_path_is_file newdir/valuesX &&\n+\t\ttest_path_is_file olddir/valuesY &&\n+\t\ttest_path_is_file olddir/valuesZ &&\n+\t\ttest_path_is_file other/content\n+\t)\n+'\n+\n test_done\n-- \ngitgitgadget\n"},{"id":"530145","messageId":"950236f0f812197e260159a688fc6f6fa61046c7.1762192908.git.gitgitgadget@gmail.com","threadId":"64427","inReplyTo":"pull.1992.git.1762192908.gitgitgadget@gmail.com","subject":"[PATCH 1/3] t6429: update comment to mention correct tool","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2025-11-03T18:01:46Z","receivedAt":"2025-11-03T18:02:07Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nA comment at the top of t6429 mentions why the test doesn't exercise git\nrebase or git cherry-pick.  However, it claims that it uses `test-tool\nfast-rebase`.  That was true when the comment was written, but commit\nf920b0289ba3 (replay: introduce new builtin, 2023-11-24) changed it to\nuse git replay without updating this comment.\n\nWe could potentially just strike this second comment, since git replay\nis a bonified built-in, but perhaps the explanation about why it focuses\non git replay is still useful.  Update the comment to make it accurate\nagain.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n t/t6429-merge-sequence-rename-caching.sh | 15 +++++++--------\n 1 file changed, 7 insertions(+), 8 deletions(-)\n\ndiff --git a/t/t6429-merge-sequence-rename-caching.sh b/t/t6429-merge-sequence-rename-caching.sh\nindex 0f39ed0d08..dcb734b10b 100755\n--- a/t/t6429-merge-sequence-rename-caching.sh\n+++ b/t/t6429-merge-sequence-rename-caching.sh\n@@ -11,14 +11,13 @@ test_description=\"remember regular & dir renames in sequence of merges\"\n #         sure that we are triggering rename caching rather than rename\n #         bypassing.\n #\n-# NOTE 2: this testfile uses 'test-tool fast-rebase' instead of either\n-#         cherry-pick or rebase.  sequencer.c is only superficially\n-#         integrated with merge-ort; it calls merge_switch_to_result()\n-#         after EACH merge, which updates the index and working copy AND\n-#         throws away the cached results (because merge_switch_to_result()\n-#         is only supposed to be called at the end of the sequence).\n-#         Integrating them more deeply is a big task, so for now the tests\n-#         use 'test-tool fast-rebase'.\n+# NOTE 2: this testfile uses replay instead of either cherry-pick or rebase.\n+#         sequencer.c is only superficially integrated with merge-ort; it\n+#         calls merge_switch_to_result() after EACH merge, which updates the\n+#         index and working copy AND throws away the cached results (because\n+#         merge_switch_to_result() is only supposed to be called at the end\n+#         of the sequence).  Integrating them more deeply is a big task, so\n+#         for now the tests use 'git replay'.\n #\n \n \n-- \ngitgitgadget\n\n"},{"id":"530370","messageId":"2983385e-daeb-40c0-a8bc-fb8bd3b744a6@app.fastmail.com","threadId":"64427","inReplyTo":"950236f0f812197e260159a688fc6f6fa61046c7.1762192908.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 1/3] t6429: update comment to mention correct tool","fromName":"Kristoffer Haugsbakk","fromEmail":"kristofferhaugsbakk@fastmail.com","sentAt":"2025-11-07T14:36:26Z","receivedAt":"2025-11-07T14:36:47Z","isPatch":true,"sender":{"key":"kristofferhaugsbakk@fastmail.com","avatar":null},"body":"On Mon, Nov 3, 2025, at 19:01, Elijah Newren via GitGitGadget wrote:\n> From: Elijah Newren <newren@gmail.com>\n>\n> A comment at the top of t6429 mentions why the test doesn't exercise git\n> rebase or git cherry-pick.  However, it claims that it uses `test-tool\n> fast-rebase`.  That was true when the comment was written, but commit\n> f920b0289ba3 (replay: introduce new builtin, 2023-11-24) changed it to\n> use git replay without updating this comment.\n>\n> We could potentially just strike this second comment, since git replay\n> is a bonified built-in, but perhaps the explanation about why it focuses\n\ns/bonified/bona fide/ ?\n\n> on git replay is still useful.  Update the comment to make it accurate\n> again.\n>\n> Signed-off-by: Elijah Newren <newren@gmail.com>\n> ---\n"},{"id":"530393","messageId":"CABPp-BGchyC6BB2p7p-6qHvwcu5AV+VCAdTeR247F0VamsJkbQ@mail.gmail.com","threadId":"64427","inReplyTo":"2983385e-daeb-40c0-a8bc-fb8bd3b744a6@app.fastmail.com","subject":"Re: [PATCH 1/3] t6429: update comment to mention correct tool","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2025-11-07T22:40:28Z","receivedAt":"2025-11-07T22:40:40Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Fri, Nov 7, 2025 at 6:36 AM Kristoffer Haugsbakk\n<kristofferhaugsbakk@fastmail.com> wrote:\n>\n> On Mon, Nov 3, 2025, at 19:01, Elijah Newren via GitGitGadget wrote:\n> > From: Elijah Newren <newren@gmail.com>\n> >\n> > A comment at the top of t6429 mentions why the test doesn't exercise git\n> > rebase or git cherry-pick.  However, it claims that it uses `test-tool\n> > fast-rebase`.  That was true when the comment was written, but commit\n> > f920b0289ba3 (replay: introduce new builtin, 2023-11-24) changed it to\n> > use git replay without updating this comment.\n> >\n> > We could potentially just strike this second comment, since git replay\n> > is a bonified built-in, but perhaps the explanation about why it focuses\n>\n> s/bonified/bona fide/ ?\n\nYep, good catch.  Got it fixed locally; will wait to see if any other\nfeedback comes in.\n"},{"id":"530782","messageId":"xmqqfradbhgi.fsf@gitster.g","threadId":"64427","inReplyTo":"CABPp-BGchyC6BB2p7p-6qHvwcu5AV+VCAdTeR247F0VamsJkbQ@mail.gmail.com","subject":"Re: [PATCH 1/3] t6429: update comment to mention correct tool","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-11-17T01:01:17Z","receivedAt":"2025-11-17T01:01:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n>> > We could potentially just strike this second comment, since git replay\n>> > is a bonified built-in, but perhaps the explanation about why it focuses\n>>\n>> s/bonified/bona fide/ ?\n>\n> Yep, good catch.  Got it fixed locally; will wait to see if any other\n> feedback comes in.\n\nAnd nothing seems to have happened since then.  I can amend the typo\naway if you want after the release before starting to merge topics\ndown to 'next' again.\n\n"},{"id":"530835","messageId":"CABPp-BGhU7KfRo9pS-PzRQea3YpU4qxG9iuJzxmWK=mvdhZrsw@mail.gmail.com","threadId":"64427","inReplyTo":"xmqqfradbhgi.fsf@gitster.g","subject":"Re: [PATCH 1/3] t6429: update comment to mention correct tool","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2025-11-17T19:54:13Z","receivedAt":"2025-11-17T19:54:25Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Sun, Nov 16, 2025 at 5:01 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Elijah Newren <newren@gmail.com> writes:\n>\n> >> > We could potentially just strike this second comment, since git replay\n> >> > is a bonified built-in, but perhaps the explanation about why it focuses\n> >>\n> >> s/bonified/bona fide/ ?\n> >\n> > Yep, good catch.  Got it fixed locally; will wait to see if any other\n> > feedback comes in.\n>\n> And nothing seems to have happened since then.  I can amend the typo\n> away if you want after the release before starting to merge topics\n> down to 'next' again.\n\nIf it's easier for you to amend locally, that's great, but if it's\neasier for you to have me send a re-rolled series, I've got it all\nqueued up and ready to go -- it's just this one typofix.  Sorry for\nnot getting it sent out a little sooner.\n"},{"id":"530842","messageId":"xmqq346cia3g.fsf@gitster.g","threadId":"64427","inReplyTo":"CABPp-BGhU7KfRo9pS-PzRQea3YpU4qxG9iuJzxmWK=mvdhZrsw@mail.gmail.com","subject":"Re: [PATCH 1/3] t6429: update comment to mention correct tool","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-11-17T22:10:43Z","receivedAt":"2025-11-17T22:10:45Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n>> And nothing seems to have happened since then.  I can amend the typo\n>> away if you want after the release before starting to merge topics\n>> down to 'next' again.\n>\n> If it's easier for you to amend locally, that's great, but if it's\n> easier for you to have me send a re-rolled series, I've got it all\n> queued up and ready to go -- it's just this one typofix.  Sorry for\n> not getting it sent out a little sooner.\n\nI grew very fond of \"git commit --fixup amend:<that-commit>\"\nfollowed by \"git rebase --keep-base --autosquash\", so it is not a\nproblem for me.\n\nThanks.\n\n"}]}