Message ID | d12d5469f8cbc21ce1efbffc8e7569c534b5a305.1683759339.git.gitgitgadget@gmail.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Fix two rebase bugs related to total_nr | expand |
"Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com> writes: > diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh > index f351701fec2..8da99a075dc 100755 > --- a/t/t3430-rebase-merges.sh > +++ b/t/t3430-rebase-merges.sh > @@ -517,4 +517,11 @@ test_expect_success '--rebase-merges with message matched with onto label' ' > EOF > ' > > +test_expect_success 'progress shows the correct total' ' > + git checkout -b progress H && > + git rebase --rebase-merges --force-rebase --verbose A 2> err && > + grep "^Rebasing.*14.$" err >progress && > + test_line_count = 14 progress > +' This is trying to find output lines that say "Rebasing (NN/14)"; Clarifying that we mean the denominator by matching "^Rebasing.*/14)$" or even "^Rebasing ([0-9]*/14)$" would have made it easier to grok (even though I know we do not have 114 steps to rebase in this one ;-). Looks good. Will queue. Thanks.
Hi Dscho On 10/05/2023 23:55, Johannes Schindelin via GitGitGadget wrote: > From: Johannes Schindelin <johannes.schindelin@gmx.de> > > For regular, non-`--rebase-merges` runs, there is very little work to do > for the parser when determining the total number of commands in a rebase > script: it is simply the number of lines after stripping the commented > lines and then trimming the trailing empty line, if any. > > The `--rebase-merges` mode complicates things by introducing empty lines > and comments in the middle of the script. These should _not_ be counted > as commands, and indeed, when an interactive rebase is interrupted and > subsequently resumed, the total number of commands can magically shrink, > sometimes dramatically. > > The reason for this strange behavior is that empty lines _are_ counted > in `edit_todo_list()` (but not the comments, as they are stripped via > `strbuf_stripspace(..., 1)`, which is a bug. > > Let's fix this so that the correct total number is shown from the > get-go, by carefully adjusting it according to what's in the rebase > script. Extra care needs to be taken in case the user edits the script: > the number of commands might be different after the user edited than > beforehand. > > Note: Even though commented lines are skipped in `edit_todo_list()`, we > still need to handle `TODO_COMMENT` items by decrementing the > already-incremented `total_nr` again: empty lines are also marked as > `TODO_COMMENT`. > > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> > --- > sequencer.c | 12 ++++++++---- > t/t3430-rebase-merges.sh | 7 +++++++ > 2 files changed, 15 insertions(+), 4 deletions(-) > > diff --git a/sequencer.c b/sequencer.c > index f5d89abdc5e..46dd07df0f2 100644 > --- a/sequencer.c > +++ b/sequencer.c > @@ -2609,7 +2609,7 @@ int todo_list_parse_insn_buffer(struct repository *r, char *buf, > char *p = buf, *next_p; > int i, res = 0, fixup_okay = file_exists(rebase_path_done()); > > - todo_list->current = todo_list->nr = 0; > + todo_list->current = todo_list->nr = todo_list->total_nr = 0; > > for (i = 1; *p; i++, p = next_p) { > char *eol = strchrnul(p, '\n'); > @@ -2628,7 +2628,8 @@ int todo_list_parse_insn_buffer(struct repository *r, char *buf, > item->arg_offset = p - buf; > item->arg_len = (int)(eol - p); > item->commit = NULL; > - } > + } else if (item->command == TODO_COMMENT) > + todo_list->total_nr--; This feels a bit fragile, I think it would be better to count the commands properly in the first place rather than adjusting the total here. We could do that by not incrementing "todo_list->total_nr" in append_new_todo() and then doing if (item->command != TODO_COMMENT) todo_list->total_nr++; here. We may want to stop counting invalid commands as well by only counting commands whre "item->command < TODO_COMMENT". > > if (fixup_okay) > ; /* do nothing */ > @@ -6039,7 +6040,7 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla > struct todo_list new_todo = TODO_LIST_INIT; > struct strbuf *buf = &todo_list->buf, buf2 = STRBUF_INIT; > struct object_id oid = onto->object.oid; > - int res; > + int new_total_nr, res; > > find_unique_abbrev_r(shortonto, &oid, DEFAULT_ABBREV); > > @@ -6066,6 +6067,7 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla > return error(_("nothing to do")); > } > > + new_total_nr = todo_list->total_nr - count_commands(todo_list); > res = edit_todo_list(r, todo_list, &new_todo, shortrevisions, > shortonto, flags); > if (res == -1) > @@ -6088,11 +6090,13 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla > return -1; > } > > + new_total_nr += count_commands(&new_todo); > + new_todo.total_nr = new_total_nr; > + > /* Expand the commit IDs */ > todo_list_to_strbuf(r, &new_todo, &buf2, -1, 0); > strbuf_swap(&new_todo.buf, &buf2); > strbuf_release(&buf2); > - new_todo.total_nr -= new_todo.nr; I think if we just change this line to new_todo.total_nr = 0; we don't need any other changes to this function. This is because complete_action() is only called at the start of a rebase so we don't need to worry about "total_nr" including commands that have already been executed. The reason we need to set it to zero here is that we re-parse the todo list below which increments "total_nr" by the number of commands parsed. Thanks for working on this. Best Wishes Phillip > if (todo_list_parse_insn_buffer(r, new_todo.buf.buf, &new_todo) < 0) > BUG("invalid todo list after expanding IDs:\n%s", > new_todo.buf.buf); > diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh > index f351701fec2..8da99a075dc 100755 > --- a/t/t3430-rebase-merges.sh > +++ b/t/t3430-rebase-merges.sh > @@ -517,4 +517,11 @@ test_expect_success '--rebase-merges with message matched with onto label' ' > EOF > ' > > +test_expect_success 'progress shows the correct total' ' > + git checkout -b progress H && > + git rebase --rebase-merges --force-rebase --verbose A 2> err && > + grep "^Rebasing.*14.$" err >progress && > + test_line_count = 14 progress > +' > + > test_done
Phillip Wood <phillip.wood123@gmail.com> writes: >> @@ -2609,7 +2609,7 @@ int todo_list_parse_insn_buffer(struct repository *r, char *buf, >> char *p = buf, *next_p; >> int i, res = 0, fixup_okay = file_exists(rebase_path_done()); >> - todo_list->current = todo_list->nr = 0; >> + todo_list->current = todo_list->nr = todo_list->total_nr = 0; >> for (i = 1; *p; i++, p = next_p) { >> char *eol = strchrnul(p, '\n'); >> @@ -2628,7 +2628,8 @@ int todo_list_parse_insn_buffer(struct repository *r, char *buf, >> item->arg_offset = p - buf; >> item->arg_len = (int)(eol - p); >> item->commit = NULL; >> - } >> + } else if (item->command == TODO_COMMENT) >> + todo_list->total_nr--; > > This feels a bit fragile, I think it would be better to count the > commands properly in the first place rather than adjusting the total > here. We could do that by not incrementing "todo_list->total_nr" in > append_new_todo() and then doing > > if (item->command != TODO_COMMENT) > todo_list->total_nr++; > > here. We may want to stop counting invalid commands as well by only > counting commands whre "item->command < TODO_COMMENT". OK. >> @@ -6088,11 +6090,13 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla >> return -1; >> } >> + new_total_nr += count_commands(&new_todo); >> + new_todo.total_nr = new_total_nr; >> + >> /* Expand the commit IDs */ >> todo_list_to_strbuf(r, &new_todo, &buf2, -1, 0); >> strbuf_swap(&new_todo.buf, &buf2); >> strbuf_release(&buf2); >> - new_todo.total_nr -= new_todo.nr; > > I think if we just change this line to > > new_todo.total_nr = 0; > > we don't need any other changes to this function. This is because > complete_action() is only called at the start of a rebase so we don't > need to worry about "total_nr" including commands that have already > been executed. The reason we need to set it to zero here is that we > re-parse the todo list below which increments "total_nr" by the number > of commands parsed. > > Thanks for working on this. > Best Wishes > > Phillip Thanks both for working on the fix and reviewing the patch.
diff --git a/sequencer.c b/sequencer.c index f5d89abdc5e..46dd07df0f2 100644 --- a/sequencer.c +++ b/sequencer.c @@ -2609,7 +2609,7 @@ int todo_list_parse_insn_buffer(struct repository *r, char *buf, char *p = buf, *next_p; int i, res = 0, fixup_okay = file_exists(rebase_path_done()); - todo_list->current = todo_list->nr = 0; + todo_list->current = todo_list->nr = todo_list->total_nr = 0; for (i = 1; *p; i++, p = next_p) { char *eol = strchrnul(p, '\n'); @@ -2628,7 +2628,8 @@ int todo_list_parse_insn_buffer(struct repository *r, char *buf, item->arg_offset = p - buf; item->arg_len = (int)(eol - p); item->commit = NULL; - } + } else if (item->command == TODO_COMMENT) + todo_list->total_nr--; if (fixup_okay) ; /* do nothing */ @@ -6039,7 +6040,7 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla struct todo_list new_todo = TODO_LIST_INIT; struct strbuf *buf = &todo_list->buf, buf2 = STRBUF_INIT; struct object_id oid = onto->object.oid; - int res; + int new_total_nr, res; find_unique_abbrev_r(shortonto, &oid, DEFAULT_ABBREV); @@ -6066,6 +6067,7 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla return error(_("nothing to do")); } + new_total_nr = todo_list->total_nr - count_commands(todo_list); res = edit_todo_list(r, todo_list, &new_todo, shortrevisions, shortonto, flags); if (res == -1) @@ -6088,11 +6090,13 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla return -1; } + new_total_nr += count_commands(&new_todo); + new_todo.total_nr = new_total_nr; + /* Expand the commit IDs */ todo_list_to_strbuf(r, &new_todo, &buf2, -1, 0); strbuf_swap(&new_todo.buf, &buf2); strbuf_release(&buf2); - new_todo.total_nr -= new_todo.nr; if (todo_list_parse_insn_buffer(r, new_todo.buf.buf, &new_todo) < 0) BUG("invalid todo list after expanding IDs:\n%s", new_todo.buf.buf); diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh index f351701fec2..8da99a075dc 100755 --- a/t/t3430-rebase-merges.sh +++ b/t/t3430-rebase-merges.sh @@ -517,4 +517,11 @@ test_expect_success '--rebase-merges with message matched with onto label' ' EOF ' +test_expect_success 'progress shows the correct total' ' + git checkout -b progress H && + git rebase --rebase-merges --force-rebase --verbose A 2> err && + grep "^Rebasing.*14.$" err >progress && + test_line_count = 14 progress +' + test_done