Wip/quieter sequencer status parsing
cover Wip/quieter sequencer status parsing
If we cannot parse the oid in the sequencer todo file do not show an error when running git status but instead report that a cherry-pick or revert is in progress. This addresses a confusing error message reported in
https://public-inbox.org/git/[email protected]/
These patches are based on maint
Phillip Wood (3):
sequencer: always allow tab after command name
sequencer: factor out todo command name parsing
status: do not report errors in sequencer/todo
sequencer.c | 43 +++++++++++++++++++++--------------------- t/t7512-status-help.sh | 16 ++++++++++++++++ 2 files changed, 37 insertions(+), 22 deletions(-)
base-commit: b697d92f56511e804b8ba20ccbe7bdc85dc66810
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-275%2Fphillipwood%2Fwip%2Fquieter%C2%A0sequencer%C2%A0status%C2%A0parsing-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-275/phillipwood/wip/quieter sequencer status parsing-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/275
Signature · 1 line
gitgitgadget
PATCH 1/3 sequencer: always allow tab after command name
From: Phillip Wood <[email protected]>
The code that parses the todo list allows an unabbreviated command name to be followed by a space or a tab, but if the command name is abbreviated it only allows a space after it. Fix this inconsistency.
--- sequencer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sequencer.c +1 -1
@@ -2100,7 +2100,7 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,if (skip_prefix (bol, todo_command_info[i].str, &bol)) { item->command = i;break ; - }else if ((bol +1 == eol || bol[1 ] ==' ' ) && + }else if ((bol +1 == eol || bol[1 ] ==' ' || bol[1 ] =='\t' ) && *bol == todo_command_info[i].c) { bol++; item->command = i;
Signature · 1 line
gitgitgadget
PATCH 2/3 sequencer: factor out todo command name parsing
In reply to Phillip Wood via GitGitGadgetFrom: Phillip Wood <[email protected]>
Factor out the code that parses the name of the command at the start of each line in the todo file into it's own function so that it can be used in the next commit.
--- sequencer.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
sequencer.c +13 -6
@@ -2076,6 +2076,18 @@ const char *todo_item_get_arg(struct todo_list *todo_list,return todo_list->buf.buf + item->arg_offset; } +static int is_command (enum todo_command command,const char **bol) +{ +const char *str = todo_command_info[command].str; +const char nick = todo_command_info[command].c; +const char *p = *bol +1 ; + +return skip_prefix (*bol, str, bol) || + ((nick && **bol == nick) && + (*p ==' ' || *p =='\t' || *p =='\n' || *p =='\r' || !*p) && + (*bol = p)); +} +static int parse_insn_line (struct repository *r,struct todo_item *item,const char *buf,const char *bol,char *eol) {
@@ -2097,12 +2109,7 @@ static int parse_insn_line(struct repository *r, struct todo_item *item, }for (i =0 ; i <TODO_COMMENT ; i++) -if (skip_prefix (bol, todo_command_info[i].str, &bol)) { - item->command = i; -break ; - }else if ((bol +1 == eol || bol[1 ] ==' ' || bol[1 ] =='\t' ) && - *bol == todo_command_info[i].c) { - bol++; +if (is_command (i, &bol)) { item->command = i;break ; }
Signature · 1 line
gitgitgadget
PATCH 3/3 status: do not report errors in sequencer/todo
In reply to Phillip Wood via GitGitGadgetFrom: Phillip Wood <[email protected]>
commit 4a72486de9 ("fix cherry-pick/revert status after commit", 2019-04-16) used parse_insn_line() to parse the first line of the todo list to check if it was a pick or revert. However if the todo list is left over from an old cherry-pick or revert and references a commit that no longer exists then parse_insn_line() prints an error message which is confusing for users [1]. Instead parse just the command name so that the user is alerted to the presence of stale sequencer state by status reporting that a cherry-pick or revert is in progress.
Note that we should not be leaving stale sequencer state lying around (or at least not as often) after commit b07d9bfd17 ("commit/reset: try to clean up sequencer state", 2019-04-16). However the user may still have stale state that predates that commit.
Also avoid printing an error message if for some reason the user has a file called sequencer in $GIT_DIR.
[1] https://public-inbox.org/git/[email protected]/
--- sequencer.c | 24 ++++++++---------------- t/t7512-status-help.sh | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 16 deletions(-)
sequencer.c +8 -16
@@ -2177,34 +2177,26 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,int sequencer_get_last_command (struct repository *r,enum replay_action *action) { -struct todo_item item; -char *eol; -const char *todo_file; +const char *todo_file, *bol;struct strbuf buf =STRBUF_INIT ; -int ret =-1 ; +int ret =0 ; todo_file =git_path_todo_file ();if (strbuf_read_file (&buf, todo_file,0 ) <0 ) { -if (errno ==ENOENT ) +if (errno ==ENOENT || errno ==ENOTDIR )return -1 ;else return error_errno ("unable to open '%s'" , todo_file); } - eol =strchrnul (buf.buf,'\n' ); -if (buf.buf != eol && eol[-1 ] =='\r' ) - eol--;/* strip Carriage Return */ -if (parse_insn_line (r, &item, buf.buf, buf.buf, eol)) - goto fail; -if (item.command ==TODO_PICK ) + bol = buf.buf +strspn (buf.buf," \t\r\n" ); +if (is_command (TODO_PICK , &bol) && (*bol ==' ' || *bol =='\t' )) *action =REPLAY_PICK ; -else if (item.command ==TODO_REVERT ) +else if (is_command (TODO_REVERT , &bol) && + (*bol ==' ' || *bol =='\t' )) *action =REPLAY_REVERT ;else - goto fail; - - ret =0 ; + ret =-1 ; - fail:strbuf_release (&buf);return ret;
t/t7512-status-help.sh +16 -0
@@ -798,6 +798,22 @@ EOF test_i18ncmp expected actual ' +test_expect_success 'status shows cherry-pick with invalid oid' ' + mkdir .git/sequencer && + test_write_lines "pick invalid-oid" >.git/sequencer/todo && + git status --untracked-files=no >actual 2>err && + git cherry-pick --quit && + test_must_be_empty err && + test_i18ncmp expected actual +' + +test_expect_success 'status does not show error if .git/sequencer is a file' ' + test_when_finished "rm .git/sequencer" && + test_write_lines hello >.git/sequencer && + git status --untracked-files=no 2>err && + test_must_be_empty err +' + test_expect_success 'status showing detached at and from a tag' ' test_commit atag tagging && git checkout atag &&
Signature · 1 line
gitgitgadget
Re: [PATCH 3/3] status: do not report errors in sequencer/todo
Hi Phillip,
Quoted 16 lines · Phillip Wood via GitGitGadget
From: Phillip Wood <[email protected]>
commit
4a72486de9("fix cherry-pick/revert status after commit", 2019-04-16) usedparse_insn_line()to parse the first line of the todo list to check if it was a pick or revert. However if the todo list is left over from an old cherry-pick or revert and references a commit that no longer exists thenparse_insn_line()prints an error message which is confusing for users [1]. Instead parse just the command name so that the user is alerted to the presence of stale sequencer state by status reporting that a cherry-pick or revert is in progress.Note that we should not be leaving stale sequencer state lying around (or at least not as often) after commit
b07d9bfd17("commit/reset: try to clean up sequencer state", 2019-04-16). However the user may still have stale state that predates that commit.
Quoted 4 lines
Also avoid printing an error message if for some reason the user has a file called
sequencerin $GIT_DIR.
Very nice, I particularly like the simplicity of the code in sequencer.c after this patch.
The entire patch series looks good to me.
Thanks,
Dscho
Quoted 85 lines
Reported-by Espen Antonsen <[email protected]>Signed-off-by Phillip Wood <[email protected]>--- sequencer.c | 24 ++++++++---------------- t/t7512-status-help.sh | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 16 deletions(-)sequencer.c +8
-16@@ -2177,34 +2177,26 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,int sequencer_get_last_command (struct repository *r,enum replay_action *action) { -struct todo_item item; -char *eol; -const char *todo_file; +const char *todo_file, *bol;struct strbuf buf =STRBUF_INIT ; -int ret =-1 ; +int ret =0 ; todo_file =git_path_todo_file ();if (strbuf_read_file (&buf, todo_file,0 ) <0 ) { -if (errno ==ENOENT ) +if (errno ==ENOENT || errno ==ENOTDIR )return -1 ;else return error_errno ("unable to open '%s'" , todo_file); } - eol =strchrnul (buf.buf,'\n' ); -if (buf.buf != eol && eol[-1 ] =='\r' ) - eol--;/* strip Carriage Return */ -if (parse_insn_line (r, &item, buf.buf, buf.buf, eol)) - goto fail; -if (item.command ==TODO_PICK ) + bol = buf.buf +strspn (buf.buf," \t\r\n" ); +if (is_command (TODO_PICK , &bol) && (*bol ==' ' || *bol =='\t' )) *action =REPLAY_PICK ; -else if (item.command ==TODO_REVERT ) +else if (is_command (TODO_REVERT , &bol) && + (*bol ==' ' || *bol =='\t' )) *action =REPLAY_REVERT ;else - goto fail; - - ret =0 ; + ret =-1 ; - fail:strbuf_release (&buf);return ret;t/t7512-status-help.sh +16
-1@@ -798,6 +798,22 @@ EOF test_i18ncmp expected actual ' +test_expect_success 'status shows cherry-pick with invalid oid' ' + mkdir .git/sequencer && + test_write_lines "pick invalid-oid" >.git/sequencer/todo && + git status --untracked-files=no >actual 2>err && + git cherry-pick --quit && + test_must_be_empty err && + test_i18ncmp expected actual +' + +test_expect_success 'status does not show error if .git/sequencer is a file' ' + test_when_finished "rm .git/sequencer" && + test_write_lines hello >.git/sequencer && + git status --untracked-files=no 2>err && + test_must_be_empty err +' + test_expect_success 'status showing detached at and from a tag' ' test_commit atag tagging && git checkout atag && --gitgitgadget
Please ignore the 'Wip' in the title, I forget to edit it on gitgitgadget
Best Wishes
Phillip
Quoted 22 lines · Phillip Wood via GitGitGadget
If we cannot parse the oid in the sequencer todo file do not show an error when running git status but instead report that a cherry-pick or revert is in progress. This addresses a confusing error message reported in
https://public-inbox.org/git/[email protected]/These patches are based on maint
Phillip Wood (3):
sequencer: always allow tab after command name
sequencer: factor out todo command name parsing
status: do not report errors in sequencer/todosequencer.c | 43 +++++++++++++++++++++--------------------- t/t7512-status-help.sh | 16 ++++++++++++++++ 2 files changed, 37 insertions(+), 22 deletions(-)base-commit:
b697d92f56511e804b8ba20ccbe7bdc85dc66810
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-275%2Fphillipwood%2Fwip%2Fquieter%C2%A0sequencer%C2%A0status%C2%A0parsing-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-275/phillipwood/wip/quieter sequencer status parsing-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/275
Re: [PATCH 2/3] sequencer: factor out todo command name parsing
In reply to Phillip Wood via GitGitGadgetAm 25.06.19 um 12:11 schrieb Phillip Wood via GitGitGadget:
Quoted 5 lines
From: Phillip Wood <[email protected]>
Factor out the code that parses the name of the command at the start of each line in the todo file into it's own function so that it can be used in the next commit.
"Factor out" sounds like functionality is intended to not be changed...
Quoted 13 lines
Signed-off-by Phillip Wood <[email protected]>--- sequencer.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)sequencer.c +0
-0@@ -2076,6 +2076,18 @@ const char *todo_item_get_arg(struct todo_list *todo_list,return todo_list->buf.buf + item->arg_offset; }
sequencer.c const char *todo_item_get_arg(struct todo_list *todo_list, · line 2087
Quoted 10 lines
sequencer.c +9
-0+static int is_command (enum todo_command command,const char **bol) +{ +const char *str = todo_command_info[command].str; +const char nick = todo_command_info[command].c; +const char *p = *bol +1 ; + + return skip_prefix(*bol, str, bol) || + ((nick && **bol == nick) && + (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r' || !*p) &&
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
... but this adds support for LF, CR and NUL as separators after short commands...
Quoted 7 lines
sequencer.c +3
-0+ (*bol = p)); +} +static int parse_insn_line (struct repository *r,struct todo_item *item,const char *buf,const char *bol,char *eol) {
sequencer.c static int parse_insn_line(struct repository *r, struct todo_item *item, · line 2103
Quoted 7 lines
sequencer.c +0
-4@@ -2097,12 +2109,7 @@ static int parse_insn_line(struct repository *r, struct todo_item *item, }for (i =0 ; i <TODO_COMMENT ; i++) -if (skip_prefix (bol, todo_command_info[i].str, &bol)) { - item->command = i; -break ; - } else if ((bol + 1 == eol || bol[1] == ' ' || bol[1] == '\t') &&
^^^^^^^^^^^^^^
... while this removes the check against the string's length.
Is this safe? It probably (hopefully?) is, as skip_prefix() requires bol to point to a NUL-terminated string already.
But is_command() could do the old (and shorter) eol check just as well, so the next question is: Why this change?
Quoted 7 lines
sequencer.c +1
-2- *bol == todo_command_info[i].c) { - bol++; +if (is_command (i, &bol)) { item->command = i;break ; }
Re: [PATCH 2/3] sequencer: factor out todo command name parsing
Hi René
Quoted 8 lines · René Scharfe
Am 25.06.19 um 12:11 schrieb Phillip Wood via GitGitGadget:
Quoted 5 lines
From: Phillip Wood <[email protected]>
Factor out the code that parses the name of the command at the start of each line in the todo file into it's own function so that it can be used in the next commit.
"Factor out" sounds like functionality is intended to not be changed...
Indeed, I thought I should have explained a bit more in the commit message after I sent it. I think it is unchanged but it's not immediately obvious.
Quoted 24 lines
Quoted 13 lines
Signed-off-by Phillip Wood <[email protected]>--- sequencer.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)sequencer.c +0
-0@@ -2076,6 +2076,18 @@ const char *todo_item_get_arg(struct todo_list *todo_list,return todo_list->buf.buf + item->arg_offset; }sequencer.c const char *todo_item_get_arg(struct todo_list *todo_list, · line 2087
Quoted 10 lines
sequencer.c +9
-0+static int is_command (enum todo_command command,const char **bol) +{ +const char *str = todo_command_info[command].str; +const char nick = todo_command_info[command].c; +const char *p = *bol +1 ; + + return skip_prefix(*bol, str, bol) || + ((nick && **bol == nick) && + (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r' || !*p) &&^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Quoted 2 lines
... but this adds support for LF, CR and NUL as separators after short commands...
They're there to detect the end of the line, as I don't want to have to pass in eol from other callers. The check that the nick name is not '\0' means that if we pass in an empty string we do not read past the end as the test will fail before it gets to the "*p == ..." part.
Quoted 16 lines
Quoted 8 lines
sequencer.c +3
-0+ (*bol = p)); +} +static int parse_insn_line (struct repository *r,struct todo_item *item,const char *buf,const char *bol,char *eol) {sequencer.c static int parse_insn_line(struct repository *r, struct todo_item *item, · line 2103
Quoted 7 lines
sequencer.c +0
-4@@ -2097,12 +2109,7 @@ static int parse_insn_line(struct repository *r, struct todo_item *item, }for (i =0 ; i <TODO_COMMENT ; i++) -if (skip_prefix (bol, todo_command_info[i].str, &bol)) { - item->command = i; -break ; - } else if ((bol + 1 == eol || bol[1] == ' ' || bol[1] == '\t') &&^^^^^^^^^^^^^^
Quoted 4 lines
... while this removes the check against the string's length.
Is this safe? It probably (hopefully?) is, as
skip_prefix()requires bol to point to a NUL-terminated string already.
Yes the string is NUL-terminated
Quoted 2 lines
But
is_command()could do the old (and shorter) eol check just as well, so the next question is: Why this change?
For the next patch so other callers don't have to find the end of the line if they don't need it. The new checks for '\n' etc. replace the 'bol + 1 == eol' part.
I'll reroll with a better commit message
Best Wishes
Phillip
Quoted 9 lines
Quoted 8 lines
sequencer.c +1
-2- *bol == todo_command_info[i].c) { - bol++; +if (is_command (i, &bol)) { item->command = i;break ; }
Re: [PATCH 3/3] status: do not report errors in sequencer/todo
In reply to Phillip Wood via GitGitGadgetQuoted 10 lines · Phillip Wood via GitGitGadget
From: Phillip Wood <[email protected]>
commit
4a72486de9("fix cherry-pick/revert status after commit", 2019-04-16) usedparse_insn_line()to parse the first line of the todo list to check if it was a pick or revert. However if the todo list is left over from an old cherry-pick or revert and references a commit that no longer exists thenparse_insn_line()prints an error message which is confusing for users [1]. Instead parse just the command name so that the user is alerted to the presence of stale sequencer state by status reporting that a cherry-pick or revert is in progress.
I have to wonder what would happen when "git cherry-pick --continue" is given from such a stale state. It would have to fail as it would not know the shape of the change to be replayed, no?
Is it easy to detect and say "there is an abandoned state file from stale cherry-pick" and optionally offer to remove it (as we have no chance of continuing anyway)?
Or is it likely that such an effort would end up being wasted, as...
Quoted 3 lines
Note that we should not be leaving stale sequencer state lying around (or at least not as often) after commit
b07d9bfd17("commit/reset: try to clean up sequencer state", 2019-04-16).
...this already happened?
Quoted 2 lines
Also avoid printing an error message if for some reason the user has a file called
sequencerin $GIT_DIR.
I agree that it is not a good place for giving diagnostics, but getting ENOTDIR would be an indication that next time when the user wants to do a rebase, range pick or range revert, it would not work unless somebody removes that sequencer file, right? Are our users sufficiently covered on that front (e.g. giving "we cannot do this operation as $GIT_DIR/sequencer is in the way. please remove that file" would be OK, but silently removing and possibly losing info we didn't even look at may be bad)?
In any case, the "unable to open 'sequencer/todo'" you are removing with this patch was *not* about helping the issue above which is an unrelated tangent, so let me not be distracted by that ;-)
t/t7512-status-help.sh EOF · line 811
Quoted 11 lines
t/t7512-status-help.sh +11
-0+test_expect_success 'status shows cherry-pick with invalid oid' ' + mkdir .git/sequencer && + test_write_lines "pick invalid-oid" >.git/sequencer/todo && + git status --untracked-files=no >actual 2>err && + git cherry-pick --quit && + test_must_be_empty err && + test_i18ncmp expected actual +' + +test_expect_success 'status does not show error if .git/sequencer is a file' ' + test_when_finished "rm .git/sequencer" &&
In short, I was wondering what happens if we lose this line, and then we later had a command that needs to use .git/sequencer/todo or something.
Quoted 8 lines
t/t7512-status-help.sh +5
-0+ test_write_lines hello >.git/sequencer && + git status --untracked-files=no 2>err && + test_must_be_empty err +' + test_expect_success 'status showing detached at and from a tag' ' test_commit atag tagging && git checkout atag &&
Re: [PATCH 3/3] status: do not report errors in sequencer/todo
Hi Junio
Thanks for the comments
Quoted 13 lines · Junio C Hamano
Quoted 10 lines · Phillip Wood via GitGitGadget
From: Phillip Wood <[email protected]>
commit
4a72486de9("fix cherry-pick/revert status after commit", 2019-04-16) usedparse_insn_line()to parse the first line of the todo list to check if it was a pick or revert. However if the todo list is left over from an old cherry-pick or revert and references a commit that no longer exists thenparse_insn_line()prints an error message which is confusing for users [1]. Instead parse just the command name so that the user is alerted to the presence of stale sequencer state by status reporting that a cherry-pick or revert is in progress.
Quoted 3 lines
I have to wonder what would happen when "git cherry-pick --continue" is given from such a stale state. It would have to fail as it would not know the shape of the change to be replayed, no?
Yes it would fail with
error: invalid line <line-no>: <line>
error: unusable instruction sheet: '.git/sequencer/todo'
fatal: cherry-pick failed
Quoted 3 lines
Is it easy to detect and say "there is an abandoned state file from stale cherry-pick" and optionally offer to remove it (as we have no chance of continuing anyway)?
I guess we could have a specific error return if get_oid() failed and suggest that then
Quoted 7 lines
Or is it likely that such an effort would end up being wasted, as...
Quoted 3 lines
Note that we should not be leaving stale sequencer state lying around (or at least not as often) after commit
b07d9bfd17("commit/reset: try to clean up sequencer state", 2019-04-16)....this already happened?
Probably. It is still possible for the user to run checkout in the middle of a cherry-pick and forget to finish it but if they're using a prompt with git support it should tell them that a cherry-pick is in progress as git status detects that it is.
Quoted 11 lines
Quoted 2 lines
Also avoid printing an error message if for some reason the user has a file called
sequencerin $GIT_DIR.I agree that it is not a good place for giving diagnostics, but getting ENOTDIR would be an indication that next time when the user wants to do a rebase, range pick or range revert, it would not work unless somebody removes that
sequencerfile, right? Are our users sufficiently covered on that front (e.g. giving "we cannot do this operation as $GIT_DIR/sequencer is in the way. please remove that file" would be OK, but silently removing and possibly losing info we didn't even look at may be bad)?
mkdir() will fail with ENOTDIR which should be reported with error_errno() I think.
Best Wishes
Phillip
Quoted 28 lines
In any case, the "unable to open 'sequencer/todo'" you are removing with this patch was *not* about helping the issue above which is an unrelated tangent, so let me not be distracted by that ;-)
t/t7512-status-help.sh EOF · line 811
Quoted 11 lines
t/t7512-status-help.sh +11
-0+test_expect_success 'status shows cherry-pick with invalid oid' ' + mkdir .git/sequencer && + test_write_lines "pick invalid-oid" >.git/sequencer/todo && + git status --untracked-files=no >actual 2>err && + git cherry-pick --quit && + test_must_be_empty err && + test_i18ncmp expected actual +' + +test_expect_success 'status does not show error if .git/sequencer is a file' ' + test_when_finished "rm .git/sequencer" &&In short, I was wondering what happens if we lose this line, and then we later had a command that needs to use .git/sequencer/todo or something.
Quoted 8 lines
t/t7512-status-help.sh +5
-0+ test_write_lines hello >.git/sequencer && + git status --untracked-files=no 2>err && + test_must_be_empty err +' + test_expect_success 'status showing detached at and from a tag' ' test_commit atag tagging && git checkout atag &&
PATCH v2 1/3 sequencer: always allow tab after command name
In reply to Phillip Wood via GitGitGadgetFrom: Phillip Wood <[email protected]>
The code that parses the todo list allows an unabbreviated command name to be followed by a space or a tab, but if the command name is abbreviated it only allows a space after it. Fix this inconsistency.
--- sequencer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sequencer.c +1 -1
@@ -2100,7 +2100,7 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,if (skip_prefix (bol, todo_command_info[i].str, &bol)) { item->command = i;break ; - }else if ((bol +1 == eol || bol[1 ] ==' ' ) && + }else if ((bol +1 == eol || bol[1 ] ==' ' || bol[1 ] =='\t' ) && *bol == todo_command_info[i].c) { bol++; item->command = i;
Signature · 1 line
gitgitgadget
PATCH v2 2/3 sequencer: factor out todo command name parsing
In reply to Phillip Wood via GitGitGadgetFrom: Phillip Wood <[email protected]>
Factor out the code that parses the name of the command at the start of each line in the todo file into its own function so that it can be used in the next commit.
As I don't want to burden other callers with having to pass in a pointer to the end of the line the test for an abbreviated command is changed. This change should not affect the behavior. Instead of testing eol == bol + 1 the new code checks for the end of the line by testing for '\n', '\r' or '\0' following the abbreviated name. To avoid reading past the end of an empty string it also checks that there is actually a single character abbreviation before testing if it matches. This prevents it from matching '\0' as the abbreviated name and then trying to read another character.
--- sequencer.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
sequencer.c +13 -6
@@ -2076,6 +2076,18 @@ const char *todo_item_get_arg(struct todo_list *todo_list,return todo_list->buf.buf + item->arg_offset; } +static int is_command (enum todo_command command,const char **bol) +{ +const char *str = todo_command_info[command].str; +const char nick = todo_command_info[command].c; +const char *p = *bol +1 ; + +return skip_prefix (*bol, str, bol) || + ((nick && **bol == nick) && + (*p ==' ' || *p =='\t' || *p =='\n' || *p =='\r' || !*p) && + (*bol = p)); +} +static int parse_insn_line (struct repository *r,struct todo_item *item,const char *buf,const char *bol,char *eol) {
@@ -2097,12 +2109,7 @@ static int parse_insn_line(struct repository *r, struct todo_item *item, }for (i =0 ; i <TODO_COMMENT ; i++) -if (skip_prefix (bol, todo_command_info[i].str, &bol)) { - item->command = i; -break ; - }else if ((bol +1 == eol || bol[1 ] ==' ' || bol[1 ] =='\t' ) && - *bol == todo_command_info[i].c) { - bol++; +if (is_command (i, &bol)) { item->command = i;break ; }
Signature · 1 line
gitgitgadget
v2 cover Quieter sequencer status parsing
In reply to Phillip Wood via GitGitGadgetThanks for the comments on v1. I've updated the commit message of the second patch to try and explain why the new function is not a straight-forward copy of the old code
If we cannot parse the oid in the sequencer todo file do not show an error when running git status but instead report that a cherry-pick or revert is in progress. This addresses a confusing error message reported in
https://public-inbox.org/git/[email protected]/
These patches are based on maint
Phillip Wood (3):
sequencer: always allow tab after command name
sequencer: factor out todo command name parsing
status: do not report errors in sequencer/todo
sequencer.c | 43 +++++++++++++++++++++--------------------- t/t7512-status-help.sh | 16 ++++++++++++++++ 2 files changed, 37 insertions(+), 22 deletions(-)
base-commit: b697d92f56511e804b8ba20ccbe7bdc85dc66810
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-275%2Fphillipwood%2Fwip%2Fquieter%C2%A0sequencer%C2%A0status%C2%A0parsing-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-275/phillipwood/wip/quieter sequencer status parsing-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/275
Range-diff vs v1:
1: a5bede1cf9 = 1: a5bede1cf9 sequencer: always allow tab after command name 2: ebe8a2b3a1 ! 2: c3885c0b8f sequencer: factor out todo command name parsing
@@ -3,9 +3,19 @@
sequencer: factor out todo command name parsing
Factor out the code that parses the name of the command at the start of
- each line in the todo file into it's own function so that it can be used
+ each line in the todo file into its own function so that it can be used
in the next commit.
+ As I don't want to burden other callers with having to pass in a pointer
+ to the end of the line the test for an abbreviated command is
+ changed. This change should not affect the behavior. Instead of testing
+ eol == bol + 1 the new code checks for the end of the line by testing
+ for '\n', '\r' or '\0' following the abbreviated name. To avoid reading
+ past the end of an empty string it also checks that there is actually a
+ single character abbreviation before testing if it matches. This
+ prevents it from matching '\0' as the abbreviated name and then trying
+ to read another character.
+
diff --git a/sequencer.c b/sequencer.c
3: af4b823caa = 3: 3e8fb61fb8 status: do not report errors in sequencer/todo
Signature · 1 line
gitgitgadget
PATCH v2 3/3 status: do not report errors in sequencer/todo
From: Phillip Wood <[email protected]>
commit 4a72486de9 ("fix cherry-pick/revert status after commit", 2019-04-16) used parse_insn_line() to parse the first line of the todo list to check if it was a pick or revert. However if the todo list is left over from an old cherry-pick or revert and references a commit that no longer exists then parse_insn_line() prints an error message which is confusing for users [1]. Instead parse just the command name so that the user is alerted to the presence of stale sequencer state by status reporting that a cherry-pick or revert is in progress.
Note that we should not be leaving stale sequencer state lying around (or at least not as often) after commit b07d9bfd17 ("commit/reset: try to clean up sequencer state", 2019-04-16). However the user may still have stale state that predates that commit.
Also avoid printing an error message if for some reason the user has a file called sequencer in $GIT_DIR.
[1] https://public-inbox.org/git/[email protected]/
--- sequencer.c | 24 ++++++++---------------- t/t7512-status-help.sh | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 16 deletions(-)
sequencer.c +8 -16
@@ -2177,34 +2177,26 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,int sequencer_get_last_command (struct repository *r,enum replay_action *action) { -struct todo_item item; -char *eol; -const char *todo_file; +const char *todo_file, *bol;struct strbuf buf =STRBUF_INIT ; -int ret =-1 ; +int ret =0 ; todo_file =git_path_todo_file ();if (strbuf_read_file (&buf, todo_file,0 ) <0 ) { -if (errno ==ENOENT ) +if (errno ==ENOENT || errno ==ENOTDIR )return -1 ;else return error_errno ("unable to open '%s'" , todo_file); } - eol =strchrnul (buf.buf,'\n' ); -if (buf.buf != eol && eol[-1 ] =='\r' ) - eol--;/* strip Carriage Return */ -if (parse_insn_line (r, &item, buf.buf, buf.buf, eol)) - goto fail; -if (item.command ==TODO_PICK ) + bol = buf.buf +strspn (buf.buf," \t\r\n" ); +if (is_command (TODO_PICK , &bol) && (*bol ==' ' || *bol =='\t' )) *action =REPLAY_PICK ; -else if (item.command ==TODO_REVERT ) +else if (is_command (TODO_REVERT , &bol) && + (*bol ==' ' || *bol =='\t' )) *action =REPLAY_REVERT ;else - goto fail; - - ret =0 ; + ret =-1 ; - fail:strbuf_release (&buf);return ret;
t/t7512-status-help.sh +16 -0
@@ -798,6 +798,22 @@ EOF test_i18ncmp expected actual ' +test_expect_success 'status shows cherry-pick with invalid oid' ' + mkdir .git/sequencer && + test_write_lines "pick invalid-oid" >.git/sequencer/todo && + git status --untracked-files=no >actual 2>err && + git cherry-pick --quit && + test_must_be_empty err && + test_i18ncmp expected actual +' + +test_expect_success 'status does not show error if .git/sequencer is a file' ' + test_when_finished "rm .git/sequencer" && + test_write_lines hello >.git/sequencer && + git status --untracked-files=no 2>err && + test_must_be_empty err +' + test_expect_success 'status showing detached at and from a tag' ' test_commit atag tagging && git checkout atag &&
Signature · 1 line
gitgitgadget
Re: [PATCH v2 1/3] sequencer: always allow tab after command name
In reply to Phillip Wood via GitGitGadgetQuoted 5 lines · Phillip Wood via GitGitGadget
From: Phillip Wood <[email protected]>
The code that parses the todo list allows an unabbreviated command name to be followed by a space or a tab, but if the command name is abbreviated it only allows a space after it. Fix this inconsistency.
Makes sense.
Quoted 19 lines
Signed-off-by Phillip Wood <[email protected]>--- sequencer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)sequencer.c +1
-1@@ -2100,7 +2100,7 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,if (skip_prefix (bol, todo_command_info[i].str, &bol)) { item->command = i;break ; - }else if ((bol +1 == eol || bol[1 ] ==' ' ) && + }else if ((bol +1 == eol || bol[1 ] ==' ' || bol[1 ] =='\t' ) && *bol == todo_command_info[i].c) { bol++; item->command = i;
Re: [PATCH v2 2/3] sequencer: factor out todo command name parsing
In reply to Phillip Wood via GitGitGadgetQuoted 3 lines · Phillip Wood via GitGitGadget
As I don't want to burden other callers with having to pass in a pointer to the end of the line the test for an abbreviated command is changed.
A comma missing somewhere between "As <<REASON>>, <<CONSEQUENCE>>", perhaps after "end of the line"?
Quoted 18 lines
This change should not affect the behavior. Instead of testing
eol == bol + 1the new code checks for the end of the line by testing for '\n', '\r' or '\0' following the abbreviated name. To avoid reading past the end of an empty string it also checks that there is actually a single character abbreviation before testing if it matches. This prevents it from matching '\0' as the abbreviated name and then trying to read another character.Signed-off-by Phillip Wood <[email protected]>--- sequencer.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)sequencer.c +0
-0
sequencer.c const char *todo_item_get_arg(struct todo_list *todo_list, · line 2080
Quoted 5 lines
sequencer.c +2
-0@@ -2076,6 +2076,18 @@ const char *todo_item_get_arg(struct todo_list *todo_list,return todo_list->buf.buf + item->arg_offset; } +static int is_command (enum todo_command command,const char **bol) +{
This is a tangent, but the reason why the caller of this function is named parse_insn_line() (and not parse_command_line()) is because a "command" often refers "rebase", "cherry-pick" etc., and we need a word to differenciate these from what is to be done as an individual step. Once the codebase stabilizes (read: I am excluding this kind of change outside the scope of a series like this one), we'd need to clean up the names in this file, I think.
sequencer.c const char *todo_item_get_arg(struct todo_list *todo_list, · line 2086
Quoted 6 lines
sequencer.c +6
-0+const char *str = todo_command_info[command].str; +const char nick = todo_command_info[command].c; +const char *p = *bol +1 ; + + return skip_prefix(*bol, str, bol) || + ((nick && **bol == nick) &&
OK, making sure that nick is not NUL is the key to avoid stepping past the NUL after the line that begins at *bol, as explained in the additional paragraph in the proposed log message.
Looking good.
Quoted 21 lines
sequencer.c +5
-6+ (*p ==' ' || *p =='\t' || *p =='\n' || *p =='\r' || !*p) && + (*bol = p)); +} +static int parse_insn_line (struct repository *r,struct todo_item *item,const char *buf,const char *bol,char *eol) {@@ -2097,12 +2109,7 @@ static int parse_insn_line(struct repository *r, struct todo_item *item, }for (i =0 ; i <TODO_COMMENT ; i++) -if (skip_prefix (bol, todo_command_info[i].str, &bol)) { - item->command = i; -break ; - }else if ((bol +1 == eol || bol[1 ] ==' ' || bol[1 ] =='\t' ) && - *bol == todo_command_info[i].c) { - bol++; +if (is_command (i, &bol)) { item->command = i;break ; }
Re: [PATCH 3/3] status: do not report errors in sequencer/todo
In reply to Phillip WoodQuoted 16 lines · Phillip Wood
Quoted 15 lines · Junio C Hamano
Quoted 10 lines · Phillip Wood via GitGitGadget
From: Phillip Wood <[email protected]>
commit
4a72486de9("fix cherry-pick/revert status after commit", 2019-04-16) usedparse_insn_line()to parse the first line of the todo list to check if it was a pick or revert. However if the todo list is left over from an old cherry-pick or revert and references a commit that no longer exists thenparse_insn_line()prints an error message which is confusing for users [1]. Instead parse just the command name so that the user is alerted to the presence of stale sequencer state by status reporting that a cherry-pick or revert is in progress.Or is it likely that such an effort would end up being wasted, as...
Quoted 7 lines
Quoted 5 lines
Quoted 3 lines
Note that we should not be leaving stale sequencer state lying around (or at least not as often) after commit
b07d9bfd17("commit/reset: try to clean up sequencer state", 2019-04-16)....this already happened?
Probably. It is still possible for the user to run checkout in the middle of a cherry-pick and forget to finish it but if they're using a prompt with git support it should tell them that a cherry-pick is in progress as
git statusdetects that it is.
Unfortunately it is not true that the prompt will see the in-progress cherry-pick as it does not use git status - see https://public-inbox.org/git/0f04fa2930d5cc7dfd2a5c5185573f7ecefa6055.1561990865.git.gitgitgadget@gmail.com/T/#u for a fix
Best Wishes
Phillip