* [PATCH 01/11] t3400: restore coverage for note copying with apply backend
2026-06-30 15:28 ` [PATCH 00/11] sequencer: do not record dropped commits as rewritten Phillip Wood
@ 2026-06-30 15:28 ` Phillip Wood
2026-06-30 15:28 ` [PATCH 02/11] sequencer: move definition of is_final_fixup() Phillip Wood
` (11 subsequent siblings)
12 siblings, 0 replies; 28+ messages in thread
From: Phillip Wood @ 2026-06-30 15:28 UTC (permalink / raw)
To: git; +Cc: Uwe Kleine-König, Junio C Hamano, Phillip Wood
From: Phillip Wood <phillip.wood@dunelm.org.uk>
Now that the merge backend is the default we have lost coverage for
"git rebase --apply" copying notes. Fix this by replacing "-m" with
"--apply" as the previous test which uses the default backend now
checks the merge backend.
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
---
t/t3400-rebase.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index c0c00fbb7b1..f0e7fcf649a 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -270,9 +270,9 @@ test_expect_success 'rebase can copy notes' '
test "a note" = "$(git notes show HEAD)"
'
-test_expect_success 'rebase -m can copy notes' '
+test_expect_success 'rebase --apply can copy notes' '
git reset --hard n3 &&
- git rebase -m --onto n1 n2 &&
+ git rebase --apply --onto n1 n2 &&
test "a note" = "$(git notes show HEAD)"
'
--
2.54.0.200.gfd8d68259e3
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PATCH 02/11] sequencer: move definition of is_final_fixup()
2026-06-30 15:28 ` [PATCH 00/11] sequencer: do not record dropped commits as rewritten Phillip Wood
2026-06-30 15:28 ` [PATCH 01/11] t3400: restore coverage for note copying with apply backend Phillip Wood
@ 2026-06-30 15:28 ` Phillip Wood
2026-06-30 15:28 ` [PATCH 03/11] sequencer: be more careful with external merge Phillip Wood
` (10 subsequent siblings)
12 siblings, 0 replies; 28+ messages in thread
From: Phillip Wood @ 2026-06-30 15:28 UTC (permalink / raw)
To: git; +Cc: Uwe Kleine-König, Junio C Hamano, Phillip Wood
From: Phillip Wood <phillip.wood@dunelm.org.uk>
Move this function earlier in the file in preparation for adding a
new caller in a later commit.
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
---
sequencer.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index 57855b0066a..32a09b6e87d 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -4627,21 +4627,6 @@ static int do_update_refs(struct repository *r, int quiet)
strbuf_release(&update_msg);
strbuf_release(&error_msg);
return res;
-}
-
-static int is_final_fixup(struct todo_list *todo_list)
-{
- int i = todo_list->current;
-
- if (!is_fixup(todo_list->items[i].command))
- return 0;
-
- while (++i < todo_list->nr)
- if (is_fixup(todo_list->items[i].command))
- return 0;
- else if (!is_noop(todo_list->items[i].command))
- break;
- return 1;
}
static enum todo_command peek_command(struct todo_list *todo_list, int offset)
@@ -4925,6 +4910,21 @@ static int reread_todo_if_changed(struct repository *r,
strbuf_release(&buf);
return 0;
+}
+
+static int is_final_fixup(struct todo_list *todo_list)
+{
+ int i = todo_list->current;
+
+ if (!is_fixup(todo_list->items[i].command))
+ return 0;
+
+ while (++i < todo_list->nr)
+ if (is_fixup(todo_list->items[i].command))
+ return 0;
+ else if (!is_noop(todo_list->items[i].command))
+ break;
+ return 1;
}
static const char rescheduled_advice[] =
--
2.54.0.200.gfd8d68259e3
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PATCH 03/11] sequencer: be more careful with external merge
2026-06-30 15:28 ` [PATCH 00/11] sequencer: do not record dropped commits as rewritten Phillip Wood
2026-06-30 15:28 ` [PATCH 01/11] t3400: restore coverage for note copying with apply backend Phillip Wood
2026-06-30 15:28 ` [PATCH 02/11] sequencer: move definition of is_final_fixup() Phillip Wood
@ 2026-06-30 15:28 ` Phillip Wood
2026-06-30 15:28 ` [PATCH 04/11] sequencer: never reschedule on failed commit Phillip Wood
` (9 subsequent siblings)
12 siblings, 0 replies; 28+ messages in thread
From: Phillip Wood @ 2026-06-30 15:28 UTC (permalink / raw)
To: git; +Cc: Uwe Kleine-König, Junio C Hamano, Phillip Wood
From: Phillip Wood <phillip.wood@dunelm.org.uk>
If an external merge strategy cannot merge (for example because it
would overwrite an untracked file) it exits with a non-zero exit
code other than 1. This should be treated differently to a merge
with conflicts which is signalled by an exit code of 1 because as
the merge failed we need to reschedule the last pick. The caller
expects us to return -1 in this case. Also reschedule without trying
to merge if the commit message cannot be written as that prevents us
from successfully picking the commit.
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
---
sequencer.c | 19 +++++++++++++++----
t/t3404-rebase-interactive.sh | 11 +++++++++++
2 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index 32a09b6e87d..e6626c4db4e 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -2453,14 +2453,25 @@ static int do_pick_commit(struct repository *r,
struct commit_list *common = NULL;
struct commit_list *remotes = NULL;
- res = write_message(ctx->message.buf, ctx->message.len,
- git_path_merge_msg(r), 0);
+ if (write_message(ctx->message.buf, ctx->message.len,
+ git_path_merge_msg(r), 0)) {
+ res = -1;
+ goto leave;
+ }
commit_list_insert(base, &common);
commit_list_insert(next, &remotes);
- res |= try_merge_command(r, opts->strategy,
- opts->xopts.nr, opts->xopts.v,
+ res = try_merge_command(r, opts->strategy,
+ opts->xopts.nr, opts->xopts.v,
common, oid_to_hex(&head), remotes);
+ /*
+ * If the there were conflicts, try_merge_command() returns 1,
+ * any other no-zero return code means that either the merge
+ * command could not be run, or it failed to merge.
+ */
+ if (res && res != 1)
+ res = -1;
+
commit_list_free(common);
commit_list_free(remotes);
}
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 58b3bb0c271..297b84e60d5 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -1249,6 +1249,17 @@ test_expect_success 'interrupted rebase -i with --strategy and -X' '
git rebase --continue &&
test $(git show conflict-branch:conflict) = $(cat conflict) &&
test $(cat file1) = Z
+'
+
+test_expect_success 'failing pick with --strategy is rescheduled' '
+ test_when_finished "rm -rf bin; test_might_fail git rebase --abort" &&
+ mkdir bin &&
+ echo exit 2 | write_script bin/git-merge-fail &&
+ git log -1 --format="pick %H # %s" HEAD >expect &&
+ test_must_fail env PATH="$PWD/bin:$PATH" \
+ git rebase --no-ff --strategy fail HEAD^ &&
+ test_cmp expect .git/rebase-merge/git-rebase-todo &&
+ test_cmp expect .git/rebase-merge/done
'
test_expect_success 'rebase -i error on commits with \ in message' '
--
2.54.0.200.gfd8d68259e3
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PATCH 04/11] sequencer: never reschedule on failed commit
2026-06-30 15:28 ` [PATCH 00/11] sequencer: do not record dropped commits as rewritten Phillip Wood
` (2 preceding siblings ...)
2026-06-30 15:28 ` [PATCH 03/11] sequencer: be more careful with external merge Phillip Wood
@ 2026-06-30 15:28 ` Phillip Wood
2026-06-30 15:28 ` [PATCH 05/11] sequencer: remove unnecessary "or" in pick_one_commit() Phillip Wood
` (8 subsequent siblings)
12 siblings, 0 replies; 28+ messages in thread
From: Phillip Wood @ 2026-06-30 15:28 UTC (permalink / raw)
To: git; +Cc: Uwe Kleine-König, Junio C Hamano, Phillip Wood
From: Phillip Wood <phillip.wood@dunelm.org.uk>
If "git commit" fails to run then run_git_commit() returns -1 which
causes the current command to be rescheduled. This is incorrect as
we have successfully picked the commit and have written all the state
files we need to successfully commit when the user continues. Fix this
by converting -1 to 1 which matches what do_merge() does.
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
---
sequencer.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/sequencer.c b/sequencer.c
index e6626c4db4e..d7e439b1feb 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -2542,6 +2542,12 @@ static int do_pick_commit(struct repository *r,
res = run_git_commit(NULL, reflog_action, opts, flags);
*check_todo = 1;
}
+ /*
+ * If "git commit" failed to run than res == -1 but we dont
+ * want reschedule the last command because the picking the
+ * commit was successful.
+ */
+ res = !!res;
}
--
2.54.0.200.gfd8d68259e3
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PATCH 05/11] sequencer: remove unnecessary "or" in pick_one_commit()
2026-06-30 15:28 ` [PATCH 00/11] sequencer: do not record dropped commits as rewritten Phillip Wood
` (3 preceding siblings ...)
2026-06-30 15:28 ` [PATCH 04/11] sequencer: never reschedule on failed commit Phillip Wood
@ 2026-06-30 15:28 ` Phillip Wood
2026-06-30 15:28 ` [PATCH 06/11] sequencer: simplify handing of fixup with conflicts Phillip Wood
` (7 subsequent siblings)
12 siblings, 0 replies; 28+ messages in thread
From: Phillip Wood @ 2026-06-30 15:28 UTC (permalink / raw)
To: git; +Cc: Uwe Kleine-König, Junio C Hamano, Phillip Wood
From: Phillip Wood <phillip.wood@dunelm.org.uk>
If error_with_patch(..., res, ...) succeeds then it returns "res", if
it fails then it returns -1. This means that or-ing the return value
with "res" is pointless the result is the same as the return value.
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
---
sequencer.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index d7e439b1feb..39cbb7b6e3e 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -5007,9 +5007,8 @@ static int pick_one_commit(struct repository *r,
oideq(&opts->squash_onto, &oid))))
to_amend = 1;
- return res | error_with_patch(r, item->commit,
- arg, item->arg_len, opts,
- res, to_amend);
+ return error_with_patch(r, item->commit, arg, item->arg_len,
+ opts, res, to_amend);
}
return res;
}
--
2.54.0.200.gfd8d68259e3
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PATCH 06/11] sequencer: simplify handing of fixup with conflicts
2026-06-30 15:28 ` [PATCH 00/11] sequencer: do not record dropped commits as rewritten Phillip Wood
` (4 preceding siblings ...)
2026-06-30 15:28 ` [PATCH 05/11] sequencer: remove unnecessary "or" in pick_one_commit() Phillip Wood
@ 2026-06-30 15:28 ` Phillip Wood
2026-06-30 15:28 ` [PATCH 07/11] sequencer: remove unnecessary condition in pick_one_commit() Phillip Wood
` (6 subsequent siblings)
12 siblings, 0 replies; 28+ messages in thread
From: Phillip Wood @ 2026-06-30 15:28 UTC (permalink / raw)
To: git; +Cc: Uwe Kleine-König, Junio C Hamano, Phillip Wood
From: Phillip Wood <phillip.wood@dunelm.org.uk>
Commit e032abd5a0 (rebase: fix rewritten list for failed pick,
2023-09-06) introduced an early return when res == -1, so if we enter
this conditional block then res is positive. After the last couple
of commits the only possible positive value is 1 so we can simplify
the code by removing the conditional call to intend_to_amend() and
call it error_with_patch() instead.
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
---
sequencer.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index 39cbb7b6e3e..bcfbda018a7 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -3874,7 +3874,7 @@ static int error_failed_squash(struct repository *r,
return error(_("could not copy '%s' to '%s'"),
rebase_path_message(),
git_path_merge_msg(r));
- return error_with_patch(r, commit, subject, subject_len, opts, 1, 0);
+ return error_with_patch(r, commit, subject, subject_len, opts, 1, 1);
}
static int do_exec(struct repository *r, const char *command_line, int quiet)
@@ -4986,8 +4986,6 @@ static int pick_one_commit(struct repository *r,
record_in_rewritten(&item->commit->object.oid,
peek_command(todo_list, 1));
if (res && is_fixup(item->command)) {
- if (res == 1)
- intend_to_amend();
return error_failed_squash(r, item->commit, opts,
item->arg_len, arg);
} else if (res && is_rebase_i(opts) && item->commit) {
--
2.54.0.200.gfd8d68259e3
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PATCH 07/11] sequencer: remove unnecessary condition in pick_one_commit()
2026-06-30 15:28 ` [PATCH 00/11] sequencer: do not record dropped commits as rewritten Phillip Wood
` (5 preceding siblings ...)
2026-06-30 15:28 ` [PATCH 06/11] sequencer: simplify handing of fixup with conflicts Phillip Wood
@ 2026-06-30 15:28 ` Phillip Wood
2026-06-30 15:28 ` [PATCH 08/11] sequencer: simplify pick_one_commit() Phillip Wood
` (5 subsequent siblings)
12 siblings, 0 replies; 28+ messages in thread
From: Phillip Wood @ 2026-06-30 15:28 UTC (permalink / raw)
To: git; +Cc: Uwe Kleine-König, Junio C Hamano, Phillip Wood
From: Phillip Wood <phillip.wood@dunelm.org.uk>
item->commit holds the commit to be picked and so it must be non-NULL
otherwise pick_one_commit() would not know which commit to pick.
It is also unconditionally dereferenced in do_pick_commit() which is
called at the top of this function. Therefore the check to see if it
is non-NULL is superfluous.
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
---
sequencer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sequencer.c b/sequencer.c
index bcfbda018a7..ff28873d21c 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -4988,7 +4988,7 @@ static int pick_one_commit(struct repository *r,
if (res && is_fixup(item->command)) {
return error_failed_squash(r, item->commit, opts,
item->arg_len, arg);
- } else if (res && is_rebase_i(opts) && item->commit) {
+ } else if (res && is_rebase_i(opts)) {
int to_amend = 0;
struct object_id oid;
--
2.54.0.200.gfd8d68259e3
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PATCH 08/11] sequencer: simplify pick_one_commit()
2026-06-30 15:28 ` [PATCH 00/11] sequencer: do not record dropped commits as rewritten Phillip Wood
` (6 preceding siblings ...)
2026-06-30 15:28 ` [PATCH 07/11] sequencer: remove unnecessary condition in pick_one_commit() Phillip Wood
@ 2026-06-30 15:28 ` Phillip Wood
2026-07-06 11:06 ` Oswald Buddenhagen
2026-06-30 15:28 ` [PATCH 09/11] sequencer: return early from pick_one_commit() on success Phillip Wood
` (4 subsequent siblings)
12 siblings, 1 reply; 28+ messages in thread
From: Phillip Wood @ 2026-06-30 15:28 UTC (permalink / raw)
To: git; +Cc: Uwe Kleine-König, Junio C Hamano, Phillip Wood
From: Phillip Wood <phillip.wood@dunelm.org.uk>
Unless we're rebasing all we do in pick_one_commit() is call
do_pick_commit() and return its result. Simplify the code by returing
early if we're not rebasing so that we don't have to continually call
is_rebase_i() in the rest of the function. Note that there are a couple
of conditions that do not call is_rebase_i() but they check for either
an "edit" or a "fixup" command, both of which imply we're rebasing.
As the conditional blocks are all mutually exclusive (either the
conditions are mutually exclusive, or an earlier conditional block
that would match a later one contains a "return" statement) chain
them together with "else if" to make that clear.
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
---
sequencer.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index ff28873d21c..416729f30a7 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -4966,12 +4966,14 @@ static int pick_one_commit(struct repository *r,
res = do_pick_commit(r, item, opts, is_final_fixup(todo_list),
check_todo);
- if (is_rebase_i(opts) && res < 0) {
+ if (!is_rebase_i(opts))
+ return res;
+
+ if (res < 0) {
/* Reschedule */
*reschedule = 1;
return -1;
- }
- if (item->command == TODO_EDIT) {
+ } else if (item->command == TODO_EDIT) {
struct commit *commit = item->commit;
if (!res) {
if (!opts->verbose)
@@ -4981,14 +4983,13 @@ static int pick_one_commit(struct repository *r,
}
return error_with_patch(r, commit,
arg, item->arg_len, opts, res, !res);
- }
- if (is_rebase_i(opts) && !res)
+ } else if (!res) {
record_in_rewritten(&item->commit->object.oid,
peek_command(todo_list, 1));
- if (res && is_fixup(item->command)) {
+ } else if (res && is_fixup(item->command)) {
return error_failed_squash(r, item->commit, opts,
item->arg_len, arg);
- } else if (res && is_rebase_i(opts)) {
+ } else if (res) {
int to_amend = 0;
struct object_id oid;
--
2.54.0.200.gfd8d68259e3
^ permalink raw reply related [flat|nested] 28+ messages in thread* Re: [PATCH 08/11] sequencer: simplify pick_one_commit()
2026-06-30 15:28 ` [PATCH 08/11] sequencer: simplify pick_one_commit() Phillip Wood
@ 2026-07-06 11:06 ` Oswald Buddenhagen
2026-07-06 13:40 ` Phillip Wood
0 siblings, 1 reply; 28+ messages in thread
From: Oswald Buddenhagen @ 2026-07-06 11:06 UTC (permalink / raw)
To: Phillip Wood; +Cc: git, Uwe Kleine-König, Junio C Hamano
On Tue, Jun 30, 2026 at 04:28:58PM +0100, Phillip Wood wrote:
>+++ b/sequencer.c
>@@ -4981,14 +4983,13 @@ static int pick_one_commit(struct repository *r,
> }
> return error_with_patch(r, commit,
> arg, item->arg_len, opts, res, !res);
>- }
>- if (is_rebase_i(opts) && !res)
>+ } else if (!res) {
>
because of this ...
> record_in_rewritten(&item->commit->object.oid,
> peek_command(todo_list, 1));
>- if (res && is_fixup(item->command)) {
>+ } else if (res && is_fixup(item->command)) {
>
.. the res conditional is pointless here.
> return error_failed_squash(r, item->commit, opts,
> item->arg_len, arg);
>- } else if (res && is_rebase_i(opts)) {
>+ } else if (res) {
>
and here as well.
> int to_amend = 0;
> struct object_id oid;
>
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH 08/11] sequencer: simplify pick_one_commit()
2026-07-06 11:06 ` Oswald Buddenhagen
@ 2026-07-06 13:40 ` Phillip Wood
0 siblings, 0 replies; 28+ messages in thread
From: Phillip Wood @ 2026-07-06 13:40 UTC (permalink / raw)
To: Oswald Buddenhagen, Phillip Wood
Cc: git, Uwe Kleine-König, Junio C Hamano
On 06/07/2026 12:06, Oswald Buddenhagen wrote:
> On Tue, Jun 30, 2026 at 04:28:58PM +0100, Phillip Wood wrote:
>> +++ b/sequencer.c
>> @@ -4981,14 +4983,13 @@ static int pick_one_commit(struct repository *r,
>> }
>> return error_with_patch(r, commit,
>> arg, item->arg_len, opts, res, !res);
>> - }
>> - if (is_rebase_i(opts) && !res)
>> + } else if (!res) {
>>
> because of this ...
>
>> record_in_rewritten(&item->commit->object.oid,
>> peek_command(todo_list, 1));
>> - if (res && is_fixup(item->command)) {
>> + } else if (res && is_fixup(item->command)) {
>>
> .. the res conditional is pointless here.
>
>> return error_failed_squash(r, item->commit, opts,
>> item->arg_len, arg);
>> - } else if (res && is_rebase_i(opts)) {
>> + } else if (res) {
>>
> and here as well.
I meant to add a comment about that to the commit message. I
deliberately left them alone so that when we convert them to use the
enum it is clear that these arms are handling cases with conflicts.
Thanks
Phillip
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 09/11] sequencer: return early from pick_one_commit() on success
2026-06-30 15:28 ` [PATCH 00/11] sequencer: do not record dropped commits as rewritten Phillip Wood
` (7 preceding siblings ...)
2026-06-30 15:28 ` [PATCH 08/11] sequencer: simplify pick_one_commit() Phillip Wood
@ 2026-06-30 15:28 ` Phillip Wood
2026-07-06 11:08 ` Oswald Buddenhagen
2026-06-30 15:29 ` [PATCH 10/11] sequencer: use an enum to represent result of picking a commit Phillip Wood
` (3 subsequent siblings)
12 siblings, 1 reply; 28+ messages in thread
From: Phillip Wood @ 2026-06-30 15:28 UTC (permalink / raw)
To: git; +Cc: Uwe Kleine-König, Junio C Hamano, Phillip Wood
From: Phillip Wood <phillip.wood@dunelm.org.uk>
The only block that does not return early is the one guarded by
"!res". Move the return into that block to make it clear that after
recording the commit as rewritten all we do is return from the function.
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
---
sequencer.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/sequencer.c b/sequencer.c
index 416729f30a7..655a2e84bef 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -4986,6 +4986,7 @@ static int pick_one_commit(struct repository *r,
} else if (!res) {
record_in_rewritten(&item->commit->object.oid,
peek_command(todo_list, 1));
+ return 0;
} else if (res && is_fixup(item->command)) {
return error_failed_squash(r, item->commit, opts,
item->arg_len, arg);
@@ -5009,7 +5010,8 @@ static int pick_one_commit(struct repository *r,
return error_with_patch(r, item->commit, arg, item->arg_len,
opts, res, to_amend);
}
- return res;
+
+ BUG("Unhandled return value from do_pick_commit()");
}
static int pick_commits(struct repository *r,
--
2.54.0.200.gfd8d68259e3
^ permalink raw reply related [flat|nested] 28+ messages in thread* [PATCH 10/11] sequencer: use an enum to represent result of picking a commit
2026-06-30 15:28 ` [PATCH 00/11] sequencer: do not record dropped commits as rewritten Phillip Wood
` (8 preceding siblings ...)
2026-06-30 15:28 ` [PATCH 09/11] sequencer: return early from pick_one_commit() on success Phillip Wood
@ 2026-06-30 15:29 ` Phillip Wood
2026-07-06 11:12 ` Oswald Buddenhagen
2026-06-30 15:29 ` [PATCH 11/11] sequencer: do not record dropped commits as rewritten Phillip Wood
` (2 subsequent siblings)
12 siblings, 1 reply; 28+ messages in thread
From: Phillip Wood @ 2026-06-30 15:29 UTC (permalink / raw)
To: git; +Cc: Uwe Kleine-König, Junio C Hamano, Phillip Wood
From: Phillip Wood <phillip.wood@dunelm.org.uk>
Rather than using an integer where -1 is an error, 0 is success and
1 means there were conflicts use an enum. This is clearer and lets
us add a separate return value for commits that are dropped because
they become empty in the next commit.
Note we continue to use "return error(...)" to return errors and
take advantage of C's lax typing of enums
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
---
sequencer.c | 61 +++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 45 insertions(+), 16 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index 655a2e84bef..ca005b969c4 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -2260,10 +2260,16 @@ static const char *reflog_message(struct replay_opts *opts,
return buf.buf;
}
-static int do_pick_commit(struct repository *r,
- struct todo_item *item,
- struct replay_opts *opts,
- int final_fixup, int *check_todo)
+enum pick_result {
+ PICK_RESULT_ERROR = -1,
+ PICK_RESULT_OK,
+ PICK_RESULT_CONFLICTS,
+};
+
+static enum pick_result do_pick_commit(struct repository *r,
+ struct todo_item *item,
+ struct replay_opts *opts,
+ int final_fixup, int *check_todo)
{
struct replay_ctx *ctx = opts->ctx;
unsigned int flags = should_edit(opts) ? EDIT_MSG : 0;
@@ -2564,7 +2570,12 @@ static int do_pick_commit(struct repository *r,
free(author);
update_abort_safety_file();
- return res;
+ if (res < 0)
+ return PICK_RESULT_ERROR;
+ else if (res > 0)
+ return PICK_RESULT_CONFLICTS;
+ else
+ return PICK_RESULT_OK;
}
static int prepare_revs(struct replay_opts *opts)
@@ -4960,37 +4971,47 @@ static int pick_one_commit(struct repository *r,
struct replay_opts *opts,
int *check_todo, int* reschedule)
{
- int res;
+ enum pick_result pick_res;
struct todo_item *item = todo_list->items + todo_list->current;
const char *arg = todo_item_get_arg(todo_list, item);
- res = do_pick_commit(r, item, opts, is_final_fixup(todo_list),
- check_todo);
+ pick_res = do_pick_commit(r, item, opts, is_final_fixup(todo_list),
+ check_todo);
if (!is_rebase_i(opts))
- return res;
+ switch (pick_res) {
+ case PICK_RESULT_ERROR:
+ return -1;
+ case PICK_RESULT_CONFLICTS:
+ return 1;
+ default:
+ return 0;
+ }
- if (res < 0) {
+ if (pick_res == PICK_RESULT_ERROR) {
/* Reschedule */
*reschedule = 1;
return -1;
} else if (item->command == TODO_EDIT) {
struct commit *commit = item->commit;
- if (!res) {
+ int res = pick_res == PICK_RESULT_CONFLICTS;
+
+ if (pick_res == PICK_RESULT_OK) {
if (!opts->verbose)
term_clear_line();
fprintf(stderr, _("Stopped at %s... %.*s\n"),
short_commit_name(r, commit), item->arg_len, arg);
}
return error_with_patch(r, commit,
arg, item->arg_len, opts, res, !res);
- } else if (!res) {
+ } else if (pick_res == PICK_RESULT_OK) {
record_in_rewritten(&item->commit->object.oid,
peek_command(todo_list, 1));
return 0;
- } else if (res && is_fixup(item->command)) {
+ } else if (pick_res == PICK_RESULT_CONFLICTS &&
+ is_fixup(item->command)) {
return error_failed_squash(r, item->commit, opts,
item->arg_len, arg);
- } else if (res) {
+ } else if (pick_res == PICK_RESULT_CONFLICTS) {
int to_amend = 0;
struct object_id oid;
@@ -5008,7 +5029,7 @@ static int pick_one_commit(struct repository *r,
to_amend = 1;
return error_with_patch(r, item->commit, arg, item->arg_len,
- opts, res, to_amend);
+ opts, 1, to_amend);
}
BUG("Unhandled return value from do_pick_commit()");
@@ -5547,7 +5568,15 @@ static int single_pick(struct repository *r,
TODO_PICK : TODO_REVERT;
item.commit = cmit;
- return do_pick_commit(r, &item, opts, 0, &check_todo);
+ switch (do_pick_commit(r, &item, opts, 0, &check_todo)) {
+ case PICK_RESULT_ERROR:
+ return -1;
+ case PICK_RESULT_CONFLICTS:
+ return 1;
+ default:
+ return 0;
+ }
+
}
int sequencer_pick_revisions(struct repository *r,
--
2.54.0.200.gfd8d68259e3
^ permalink raw reply related [flat|nested] 28+ messages in thread* Re: [PATCH 10/11] sequencer: use an enum to represent result of picking a commit
2026-06-30 15:29 ` [PATCH 10/11] sequencer: use an enum to represent result of picking a commit Phillip Wood
@ 2026-07-06 11:12 ` Oswald Buddenhagen
2026-07-06 13:39 ` Phillip Wood
0 siblings, 1 reply; 28+ messages in thread
From: Oswald Buddenhagen @ 2026-07-06 11:12 UTC (permalink / raw)
To: Phillip Wood; +Cc: git, Uwe Kleine-König, Junio C Hamano
On Tue, Jun 30, 2026 at 04:29:00PM +0100, Phillip Wood wrote:
>Rather than using an integer where -1 is an error, 0 is success and
>1 means there were conflicts use an enum. This is clearer and lets
>us add a separate return value for commits that are dropped because
>they become empty in the next commit.
>
have you attempted widening the scope of the enum? the three conversions
between the new enum and existing int return values irk me.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 10/11] sequencer: use an enum to represent result of picking a commit
2026-07-06 11:12 ` Oswald Buddenhagen
@ 2026-07-06 13:39 ` Phillip Wood
0 siblings, 0 replies; 28+ messages in thread
From: Phillip Wood @ 2026-07-06 13:39 UTC (permalink / raw)
To: Oswald Buddenhagen, Phillip Wood
Cc: git, Uwe Kleine-König, Junio C Hamano
On 06/07/2026 12:12, Oswald Buddenhagen wrote:
> On Tue, Jun 30, 2026 at 04:29:00PM +0100, Phillip Wood wrote:
>> Rather than using an integer where -1 is an error, 0 is success and
>> 1 means there were conflicts use an enum. This is clearer and lets
>> us add a separate return value for commits that are dropped because
>> they become empty in the next commit.
>>
> have you attempted widening the scope of the enum? the three conversions
> between the new enum and existing int return values irk me.
I know what you mean, but how wide should be go? Using the enum just one
level up the call chain means converting a whole load of functions which
creates a lot of churn that someone needs to review. I decided to keep
the enum limited to this scope for now to avoid that.
Thanks
Phillip
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 11/11] sequencer: do not record dropped commits as rewritten
2026-06-30 15:28 ` [PATCH 00/11] sequencer: do not record dropped commits as rewritten Phillip Wood
` (9 preceding siblings ...)
2026-06-30 15:29 ` [PATCH 10/11] sequencer: use an enum to represent result of picking a commit Phillip Wood
@ 2026-06-30 15:29 ` Phillip Wood
2026-06-30 19:57 ` [PATCH 00/11] " Junio C Hamano
2026-07-01 9:38 ` Uwe Kleine-König
12 siblings, 0 replies; 28+ messages in thread
From: Phillip Wood @ 2026-06-30 15:29 UTC (permalink / raw)
To: git; +Cc: Uwe Kleine-König, Junio C Hamano, Phillip Wood
From: Phillip Wood <phillip.wood@dunelm.org.uk>
If a commit gets dropped because its changes are already upstream
then we should not record it as rewritten. As well as confusing any
post-rewrite hooks this means we end up copying the notes from the
dropped commit to the commit that was picked immediately before the
one that was dropped.
While we do not want to record the dropped commit is rewritten, if
it is the final commit in a chain of fixups then we need to flush
the list of rewritten commits. The behavior of an "edit" command
where the commit is dropped is changed so that "rebase --continue"
will not amend the previous pick. However, as the code comment notes
it will still be erroneously recorded as rewritten when the rebase
continues. That will need to be addressed separately along with not
recording skipped commits as rewritten.
The initialization of "drop_commit" is moved to ensure it is initialized
when rewording a fast-forwarded commit.
Reported-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
---
sequencer.c | 24 +++++++++++++++++++-----
t/t3400-rebase.sh | 12 ++++++++++++
t/t5407-post-rewrite-hook.sh | 23 +++++++++++++++++++++++
3 files changed, 54 insertions(+), 5 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index ca005b969c4..a85f9e8b77d 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -2264,6 +2264,7 @@ enum pick_result {
PICK_RESULT_ERROR = -1,
PICK_RESULT_OK,
PICK_RESULT_CONFLICTS,
+ PICK_RESULT_DROPPED,
};
static enum pick_result do_pick_commit(struct repository *r,
@@ -2279,7 +2280,7 @@ static enum pick_result do_pick_commit(struct repository *r,
const char *base_label, *next_label, *reflog_action;
char *author = NULL;
struct commit_message msg = { NULL, NULL, NULL, NULL };
- int res, unborn = 0, reword = 0, allow, drop_commit;
+ int res, unborn = 0, reword = 0, allow, drop_commit = 0;
enum todo_command command = item->command;
struct commit *commit = item->commit;
@@ -2509,7 +2510,6 @@ static enum pick_result do_pick_commit(struct repository *r,
goto leave;
}
- drop_commit = 0;
allow = allow_empty(r, opts, commit);
if (allow < 0) {
res = allow;
@@ -2574,6 +2574,8 @@ static enum pick_result do_pick_commit(struct repository *r,
return PICK_RESULT_ERROR;
else if (res > 0)
return PICK_RESULT_CONFLICTS;
+ else if (drop_commit)
+ return PICK_RESULT_DROPPED;
else
return PICK_RESULT_OK;
}
@@ -4994,18 +4996,30 @@ static int pick_one_commit(struct repository *r,
} else if (item->command == TODO_EDIT) {
struct commit *commit = item->commit;
int res = pick_res == PICK_RESULT_CONFLICTS;
+ int to_amend = pick_res != PICK_RESULT_CONFLICTS &&
+ pick_res != PICK_RESULT_DROPPED;
- if (pick_res == PICK_RESULT_OK) {
+ /*
+ * NEEDSWORK: Do not record the commit as rewritten when
+ * continuing if it was dropped. Does it even make sense
+ * to stop if the commit was dropped?
+ */
+ if (pick_res == PICK_RESULT_OK ||
+ pick_res == PICK_RESULT_DROPPED) {
if (!opts->verbose)
term_clear_line();
fprintf(stderr, _("Stopped at %s... %.*s\n"),
short_commit_name(r, commit), item->arg_len, arg);
}
- return error_with_patch(r, commit,
- arg, item->arg_len, opts, res, !res);
+ return error_with_patch(r, commit, arg, item->arg_len, opts,
+ res, to_amend);
} else if (pick_res == PICK_RESULT_OK) {
record_in_rewritten(&item->commit->object.oid,
peek_command(todo_list, 1));
+ return 0;
+ } else if (pick_res == PICK_RESULT_DROPPED) {
+ if (is_final_fixup(todo_list))
+ flush_rewritten_pending();
return 0;
} else if (pick_res == PICK_RESULT_CONFLICTS &&
is_fixup(item->command)) {
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index f0e7fcf649a..1d09886ea35 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -274,6 +274,18 @@ test_expect_success 'rebase --apply can copy notes' '
git reset --hard n3 &&
git rebase --apply --onto n1 n2 &&
test "a note" = "$(git notes show HEAD)"
+'
+
+test_expect_success 'rebase drops notes of dropped commits' '
+ git checkout n1 &&
+ echo n3 >n3.t &&
+ echo n4 >n4.t &&
+ git add n3.t n4.t &&
+ git commit -m n34 &&
+ git rebase HEAD n3 &&
+ test_commit_message HEAD -m n2 &&
+ test_must_fail git notes list HEAD >actual &&
+ test_must_be_empty actual
'
test_expect_success 'rebase commit with an ancient timestamp' '
diff --git a/t/t5407-post-rewrite-hook.sh b/t/t5407-post-rewrite-hook.sh
index ad7f8c6f002..51991956d1d 100755
--- a/t/t5407-post-rewrite-hook.sh
+++ b/t/t5407-post-rewrite-hook.sh
@@ -306,6 +306,29 @@ test_expect_success 'git rebase -i (exec)' '
cat >expected.data <<-EOF &&
$(git rev-parse C) $(git rev-parse HEAD^)
$(git rev-parse D) $(git rev-parse HEAD)
+ EOF
+ verify_hook_input
+'
+
+test_expect_success 'rebase with commits that become empty' '
+ cat >todo <<-\EOF &&
+ pick H
+ pick E
+ fixup I
+ fixup H
+ pick G
+ pick I
+ EOF
+ (
+ set_replace_editor todo &&
+ git rebase -i --empty=drop A A
+ ) &&
+ echo rebase >expected.args &&
+ cat >expected.data <<-EOF &&
+ $(git rev-parse H) $(git rev-parse HEAD~2)
+ $(git rev-parse E) $(git rev-parse HEAD~1)
+ $(git rev-parse I) $(git rev-parse HEAD~1)
+ $(git rev-parse G) $(git rev-parse HEAD)
EOF
verify_hook_input
'
--
2.54.0.200.gfd8d68259e3
^ permalink raw reply related [flat|nested] 28+ messages in thread* Re: [PATCH 00/11] sequencer: do not record dropped commits as rewritten
2026-06-30 15:28 ` [PATCH 00/11] sequencer: do not record dropped commits as rewritten Phillip Wood
` (10 preceding siblings ...)
2026-06-30 15:29 ` [PATCH 11/11] sequencer: do not record dropped commits as rewritten Phillip Wood
@ 2026-06-30 19:57 ` Junio C Hamano
2026-07-01 6:00 ` Uwe Kleine-König
2026-07-01 13:31 ` Phillip Wood
2026-07-01 9:38 ` Uwe Kleine-König
12 siblings, 2 replies; 28+ messages in thread
From: Junio C Hamano @ 2026-06-30 19:57 UTC (permalink / raw)
To: Phillip Wood; +Cc: git, Uwe Kleine-König, Konstantin Ryabitsev
Phillip Wood <phillip.wood123@gmail.com> writes:
> On 19/06/2026 11:13, Phillip Wood wrote:
>> I'm happy to take this forward and try and fix at least some of the
>> other bugs I've listed above. Uwe - if I don't cc you on some patches
>> within the next couple of weeks please feel free to send a reminder.
>
> Here is the first batch that fixes the same problem as Uwe's patch. I've
> taken a slightly different approach that uses the return value from
> do_pick_commit() to signal that a commit was dropped rather than
> adding another function argument. That involves a number of preparatory
> patches, but they are hopefully reasonably small and easy to follow.
>
> If a commit gets dropped because its changes are already upstream
> then we should not record it as rewritten. As well as confusing any
> post-rewrite hooks this means we end up copying the notes from the
> dropped commit to the commit that was picked immediately before the
> one that was dropped.
>
> This series is structured as follows:
>
> Patch 1 restores some test coverage that was lost when the default
> rebase backend was changed.
>
> Patch 2 moves a function so it can be called without a forward
> declaration in Patch 11.
>
> Patches 3 & 4 fix the return value of do_pick_commit() when an external
> command fails (this is in preparation for patch 10).
>
> Patches 5-9 try and simplify the control flow in pick_one_commit()
> in preparation for patch 10.
>
> Patch 10 changes the return type of do_pick_commit() to an enum.
>
> Patch 11 adds a new member to the enum from patch 10 for commits that
> are dropped when they become empty and uses that to stop them from
> being recorded as rewritten.
>
> Base-Commit: 6c3d7b73556db708feb3b16232fab1efc4353428
> Published-As: https://github.com/phillipwood/git/releases/tag/pw%2Frebase-drop-notes-with-commit%2Fv1
> View-Changes-At: https://github.com/phillipwood/git/compare/6c3d7b735...26551f268
> Fetch-It-Via: git fetch https://github.com/phillipwood/git pw/rebase-drop-notes-with-commit/v1
Thanks.
A tangent (I Cc'ed Konstantin for this), but
$ b4 am -o- '<cover.1782833268.git.phillip.wood@dunelm.org.uk>' >b4am.mbx
failed to produce a usable mailbox. It somehow did not think [2/11]
existed. I manually examined the References and In-Reply-To headers
of that particular message and compared them with those from other
messages but did not find anything suspicious X-<.
I have a bunch of typofixes queued on top of these 11 patches (made
with "git commit --fixup reword:<sha1>"); please double check when
you reroll after seeing more substantial reviews than mere typofixes,
possibly from others.
Thanks.
Here is the transcript of failed b4 am invocation.
---- >8 ----
Looking up https://lore.kernel.org/all/cover.1782833268.git.phillip.wood@dunelm.org.uk/
Grabbing thread from lore.kernel.org/all/cover.1782833268.git.phillip.wood@dunelm.org.uk/t.mbox.gz
Analyzing 17 messages in the thread
WARNING: duplicate messages found at index 1
Subject 1: sequencer: Skip copying notes for commits that disappear during rebase
Subject 2: t3400: restore coverage for note copying with apply backend
2 is not a reply... assume additional patch
Looking for additional code-review trailers on lore.kernel.org
Analyzing 0 code-review messages
Checking attestation on all messages, may take a moment...
---
✗ [PATCH] sequencer: Skip copying notes for commits that disappear during rebase
✗ No key: openpgp/u.kleine-koenig@baylibre.com
✗ BADSIG: DKIM/baylibre.com
✓ [PATCH 1/11] t3400: restore coverage for note copying with apply backend
✓ Signed: DKIM/gmail.com
✓ [PATCH 3/11] sequencer: be more careful with external merge
✓ Signed: DKIM/gmail.com
✓ [PATCH 4/11] sequencer: never reschedule on failed commit
✓ Signed: DKIM/gmail.com
✓ [PATCH 5/11] sequencer: remove unnecessary "or" in pick_one_commit()
✓ Signed: DKIM/gmail.com
✓ [PATCH 6/11] sequencer: simplify handing of fixup with conflicts
✓ Signed: DKIM/gmail.com
✓ [PATCH 7/11] sequencer: remove unnecessary condition in pick_one_commit()
✓ Signed: DKIM/gmail.com
✓ [PATCH 8/11] sequencer: simplify pick_one_commit()
✓ Signed: DKIM/gmail.com
✓ [PATCH 9/11] sequencer: return early from pick_one_commit() on success
✓ Signed: DKIM/gmail.com
✓ [PATCH 10/11] sequencer: use an enum to represent result of picking a commit
✓ Signed: DKIM/gmail.com
✓ [PATCH 11/11] sequencer: do not record dropped commits as rewritten
✓ Signed: DKIM/gmail.com
ERROR: missing [12/2]!
---
Total patches: 11
---
WARNING: Thread incomplete!
Link: https://patch.msgid.link/cover.1782833268.git.phillip.wood@dunelm.org.uk
:
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH 00/11] sequencer: do not record dropped commits as rewritten
2026-06-30 19:57 ` [PATCH 00/11] " Junio C Hamano
@ 2026-07-01 6:00 ` Uwe Kleine-König
2026-07-01 13:29 ` Phillip Wood
2026-07-01 13:31 ` Phillip Wood
1 sibling, 1 reply; 28+ messages in thread
From: Uwe Kleine-König @ 2026-07-01 6:00 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Phillip Wood, git, Konstantin Ryabitsev
[-- Attachment #1: Type: text/plain, Size: 1767 bytes --]
Hello,
On Tue, Jun 30, 2026 at 12:57:32PM -0700, Junio C Hamano wrote:
> A tangent (I Cc'ed Konstantin for this), but
>
> $ b4 am -o- '<cover.1782833268.git.phillip.wood@dunelm.org.uk>' >b4am.mbx
>
> failed to produce a usable mailbox. It somehow did not think [2/11]
> existed.
FTR: The mail is on lore.kernel.org.
Also to yield a usable mailbox my patch shouldn't be included.
> I manually examined the References and In-Reply-To headers
> of that particular message and compared them with those from other
> messages but did not find anything suspicious X-<.
>
> I have a bunch of typofixes queued on top of these 11 patches (made
> with "git commit --fixup reword:<sha1>"); please double check when
> you reroll after seeing more substantial reviews than mere typofixes,
> possibly from others.
>
> Thanks.
>
>
> Here is the transcript of failed b4 am invocation.
> ---- >8 ----
> Looking up https://lore.kernel.org/all/cover.1782833268.git.phillip.wood@dunelm.org.uk/
> Grabbing thread from lore.kernel.org/all/cover.1782833268.git.phillip.wood@dunelm.org.uk/t.mbox.gz
> Analyzing 17 messages in the thread
> WARNING: duplicate messages found at index 1
> Subject 1: sequencer: Skip copying notes for commits that disappear during rebase
> Subject 2: t3400: restore coverage for note copying with apply backend
> 2 is not a reply... assume additional patch
I think here is the origin of the problem. It guesses that the t3400
should be added, and it takes the place of Phillip's second patch.
> ERROR: missing [12/2]!
This is irritating, I would have expected "[2/12]" here?
b4 am --no-parent cover.1782833268.git.phillip.wood@dunelm.org.uk
works fine for me.
Best regards
Uwe
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 00/11] sequencer: do not record dropped commits as rewritten
2026-07-01 6:00 ` Uwe Kleine-König
@ 2026-07-01 13:29 ` Phillip Wood
0 siblings, 0 replies; 28+ messages in thread
From: Phillip Wood @ 2026-07-01 13:29 UTC (permalink / raw)
To: Uwe Kleine-König, Junio C Hamano; +Cc: git, Konstantin Ryabitsev
On 01/07/2026 07:00, Uwe Kleine-König wrote:
> Hello,
>
> On Tue, Jun 30, 2026 at 12:57:32PM -0700, Junio C Hamano wrote:
>> A tangent (I Cc'ed Konstantin for this), but
>>
>> $ b4 am -o- '<cover.1782833268.git.phillip.wood@dunelm.org.uk>' >b4am.mbx
>>
>> failed to produce a usable mailbox. It somehow did not think [2/11]
>> existed.
>
> FTR: The mail is on lore.kernel.org.
>
> Also to yield a usable mailbox my patch shouldn't be included.
Sorry I had intended to send these as v2 to avoid any confusion, but I
forgot about that when I actually came to send them.
Thanks
Phillip
>> I manually examined the References and In-Reply-To headers
>> of that particular message and compared them with those from other
>> messages but did not find anything suspicious X-<.
>
>
>>
>> I have a bunch of typofixes queued on top of these 11 patches (made
>> with "git commit --fixup reword:<sha1>"); please double check when
>> you reroll after seeing more substantial reviews than mere typofixes,
>> possibly from others.
>>
>> Thanks.
>>
>>
>> Here is the transcript of failed b4 am invocation.
>> ---- >8 ----
>> Looking up https://lore.kernel.org/all/cover.1782833268.git.phillip.wood@dunelm.org.uk/
>> Grabbing thread from lore.kernel.org/all/cover.1782833268.git.phillip.wood@dunelm.org.uk/t.mbox.gz
>> Analyzing 17 messages in the thread
>> WARNING: duplicate messages found at index 1
>> Subject 1: sequencer: Skip copying notes for commits that disappear during rebase
>> Subject 2: t3400: restore coverage for note copying with apply backend
>> 2 is not a reply... assume additional patch
>
> I think here is the origin of the problem. It guesses that the t3400
> should be added, and it takes the place of Phillip's second patch.
>
>> ERROR: missing [12/2]!
>
> This is irritating, I would have expected "[2/12]" here?
>
> b4 am --no-parent cover.1782833268.git.phillip.wood@dunelm.org.uk
>
> works fine for me.
>
> Best regards
> Uwe
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 00/11] sequencer: do not record dropped commits as rewritten
2026-06-30 19:57 ` [PATCH 00/11] " Junio C Hamano
2026-07-01 6:00 ` Uwe Kleine-König
@ 2026-07-01 13:31 ` Phillip Wood
1 sibling, 0 replies; 28+ messages in thread
From: Phillip Wood @ 2026-07-01 13:31 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Uwe Kleine-König, Konstantin Ryabitsev
Hi Junio
On 30/06/2026 20:57, Junio C Hamano wrote:
> Phillip Wood <phillip.wood123@gmail.com> writes:
>
> I have a bunch of typofixes queued on top of these 11 patches (made
> with "git commit --fixup reword:<sha1>"); please double check when
> you reroll after seeing more substantial reviews than mere typofixes,
> possibly from others.
Thanks, I'll squash those locally and wait before resending
Phillip
> Thanks.
>
>
> Here is the transcript of failed b4 am invocation.
> ---- >8 ----
> Looking up https://lore.kernel.org/all/cover.1782833268.git.phillip.wood@dunelm.org.uk/
> Grabbing thread from lore.kernel.org/all/cover.1782833268.git.phillip.wood@dunelm.org.uk/t.mbox.gz
> Analyzing 17 messages in the thread
> WARNING: duplicate messages found at index 1
> Subject 1: sequencer: Skip copying notes for commits that disappear during rebase
> Subject 2: t3400: restore coverage for note copying with apply backend
> 2 is not a reply... assume additional patch
> Looking for additional code-review trailers on lore.kernel.org
> Analyzing 0 code-review messages
> Checking attestation on all messages, may take a moment...
> ---
> ✗ [PATCH] sequencer: Skip copying notes for commits that disappear during rebase
> ✗ No key: openpgp/u.kleine-koenig@baylibre.com
> ✗ BADSIG: DKIM/baylibre.com
> ✓ [PATCH 1/11] t3400: restore coverage for note copying with apply backend
> ✓ Signed: DKIM/gmail.com
> ✓ [PATCH 3/11] sequencer: be more careful with external merge
> ✓ Signed: DKIM/gmail.com
> ✓ [PATCH 4/11] sequencer: never reschedule on failed commit
> ✓ Signed: DKIM/gmail.com
> ✓ [PATCH 5/11] sequencer: remove unnecessary "or" in pick_one_commit()
> ✓ Signed: DKIM/gmail.com
> ✓ [PATCH 6/11] sequencer: simplify handing of fixup with conflicts
> ✓ Signed: DKIM/gmail.com
> ✓ [PATCH 7/11] sequencer: remove unnecessary condition in pick_one_commit()
> ✓ Signed: DKIM/gmail.com
> ✓ [PATCH 8/11] sequencer: simplify pick_one_commit()
> ✓ Signed: DKIM/gmail.com
> ✓ [PATCH 9/11] sequencer: return early from pick_one_commit() on success
> ✓ Signed: DKIM/gmail.com
> ✓ [PATCH 10/11] sequencer: use an enum to represent result of picking a commit
> ✓ Signed: DKIM/gmail.com
> ✓ [PATCH 11/11] sequencer: do not record dropped commits as rewritten
> ✓ Signed: DKIM/gmail.com
> ERROR: missing [12/2]!
> ---
> Total patches: 11
> ---
> WARNING: Thread incomplete!
> Link: https://patch.msgid.link/cover.1782833268.git.phillip.wood@dunelm.org.uk
> :
>
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 00/11] sequencer: do not record dropped commits as rewritten
2026-06-30 15:28 ` [PATCH 00/11] sequencer: do not record dropped commits as rewritten Phillip Wood
` (11 preceding siblings ...)
2026-06-30 19:57 ` [PATCH 00/11] " Junio C Hamano
@ 2026-07-01 9:38 ` Uwe Kleine-König
2026-07-01 13:37 ` Phillip Wood
12 siblings, 1 reply; 28+ messages in thread
From: Uwe Kleine-König @ 2026-07-01 9:38 UTC (permalink / raw)
To: Phillip Wood; +Cc: git, Junio C Hamano, Phillip Wood
[-- Attachment #1: Type: text/plain, Size: 2216 bytes --]
Hello Phillip,
thanks a lot for addressing this, very appreciated!
On Tue, Jun 30, 2026 at 04:28:50PM +0100, Phillip Wood wrote:
> On 19/06/2026 11:13, Phillip Wood wrote:
> > I'm happy to take this forward and try and fix at least some of the
> > other bugs I've listed above. Uwe - if I don't cc you on some patches
> > within the next couple of weeks please feel free to send a reminder.
>
> Here is the first batch that fixes the same problem as Uwe's patch. I've
> taken a slightly different approach that uses the return value from
> do_pick_commit() to signal that a commit was dropped rather than
> adding another function argument. That involves a number of preparatory
> patches, but they are hopefully reasonably small and easy to follow.
>
> If a commit gets dropped because its changes are already upstream
> then we should not record it as rewritten. As well as confusing any
> post-rewrite hooks this means we end up copying the notes from the
> dropped commit to the commit that was picked immediately before the
> one that was dropped.
>
> This series is structured as follows:
>
> Patch 1 restores some test coverage that was lost when the default
> rebase backend was changed.
>
> Patch 2 moves a function so it can be called without a forward
> declaration in Patch 11.
>
> Patches 3 & 4 fix the return value of do_pick_commit() when an external
> command fails (this is in preparation for patch 10).
>
> Patches 5-9 try and simplify the control flow in pick_one_commit()
> in preparation for patch 10.
>
> Patch 10 changes the return type of do_pick_commit() to an enum.
>
> Patch 11 adds a new member to the enum from patch 10 for commits that
> are dropped when they become empty and uses that to stop them from
> being recorded as rewritten.
With my very little knowledge about git internals, this looks
reasonable, and it behaves as I expect in my test case. I installed a
local
Tested-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
> Base-Commit: 6c3d7b73556db708feb3b16232fab1efc4353428
BTW, b4 didn't pick this up, for me it says:
Base: not specified
(and I applied it on top of 2.55.0).
Best regards
Uwe
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 28+ messages in thread* Re: [PATCH 00/11] sequencer: do not record dropped commits as rewritten
2026-07-01 9:38 ` Uwe Kleine-König
@ 2026-07-01 13:37 ` Phillip Wood
0 siblings, 0 replies; 28+ messages in thread
From: Phillip Wood @ 2026-07-01 13:37 UTC (permalink / raw)
To: Uwe Kleine-König, Phillip Wood; +Cc: git, Junio C Hamano
Hi Uwe
On 01/07/2026 10:38, Uwe Kleine-König wrote:
>
> With my very little knowledge about git internals, this looks
> reasonable, and it behaves as I expect in my test case. I installed a
> local
>
> Tested-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Thanks for testing these patches
>> Base-Commit: 6c3d7b73556db708feb3b16232fab1efc4353428
>
> BTW, b4 didn't pick this up, for me it says:
>
> Base: not specified
Oh, my script generates the same trailers as GitGitGadget but I see "git
format-patch" uses "base-commit:" I wonder if b4 expects it to be all
lower case.
Thanks
Phillip
> (and I applied it on top of 2.55.0).
>
> Best regards
> Uwe
^ permalink raw reply [flat|nested] 28+ messages in thread