Skip to content

Commit bd48ccf

Browse files
committed
Merge branch 'pw/status-with-corrupt-sequencer-state'
The code to read state files used by the sequencer machinery for "git status" has been made more robust against a corrupt or stale state files. * pw/status-with-corrupt-sequencer-state: status: do not report errors in sequencer/todo sequencer: factor out todo command name parsing sequencer: always allow tab after command name
2 parents 92b1ea6 + ed5b1ca commit bd48ccf

File tree

2 files changed

+37
-22
lines changed

2 files changed

+37
-22
lines changed

sequencer.c

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2079,6 +2079,18 @@ const char *todo_item_get_arg(struct todo_list *todo_list,
20792079
return todo_list->buf.buf + item->arg_offset;
20802080
}
20812081

2082+
static int is_command(enum todo_command command, const char **bol)
2083+
{
2084+
const char *str = todo_command_info[command].str;
2085+
const char nick = todo_command_info[command].c;
2086+
const char *p = *bol + 1;
2087+
2088+
return skip_prefix(*bol, str, bol) ||
2089+
((nick && **bol == nick) &&
2090+
(*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r' || !*p) &&
2091+
(*bol = p));
2092+
}
2093+
20822094
static int parse_insn_line(struct repository *r, struct todo_item *item,
20832095
const char *buf, const char *bol, char *eol)
20842096
{
@@ -2100,12 +2112,7 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,
21002112
}
21012113

21022114
for (i = 0; i < TODO_COMMENT; i++)
2103-
if (skip_prefix(bol, todo_command_info[i].str, &bol)) {
2104-
item->command = i;
2105-
break;
2106-
} else if ((bol + 1 == eol || bol[1] == ' ') &&
2107-
*bol == todo_command_info[i].c) {
2108-
bol++;
2115+
if (is_command(i, &bol)) {
21092116
item->command = i;
21102117
break;
21112118
}
@@ -2173,34 +2180,26 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,
21732180

21742181
int sequencer_get_last_command(struct repository *r, enum replay_action *action)
21752182
{
2176-
struct todo_item item;
2177-
char *eol;
2178-
const char *todo_file;
2183+
const char *todo_file, *bol;
21792184
struct strbuf buf = STRBUF_INIT;
2180-
int ret = -1;
2185+
int ret = 0;
21812186

21822187
todo_file = git_path_todo_file();
21832188
if (strbuf_read_file(&buf, todo_file, 0) < 0) {
2184-
if (errno == ENOENT)
2189+
if (errno == ENOENT || errno == ENOTDIR)
21852190
return -1;
21862191
else
21872192
return error_errno("unable to open '%s'", todo_file);
21882193
}
2189-
eol = strchrnul(buf.buf, '\n');
2190-
if (buf.buf != eol && eol[-1] == '\r')
2191-
eol--; /* strip Carriage Return */
2192-
if (parse_insn_line(r, &item, buf.buf, buf.buf, eol))
2193-
goto fail;
2194-
if (item.command == TODO_PICK)
2194+
bol = buf.buf + strspn(buf.buf, " \t\r\n");
2195+
if (is_command(TODO_PICK, &bol) && (*bol == ' ' || *bol == '\t'))
21952196
*action = REPLAY_PICK;
2196-
else if (item.command == TODO_REVERT)
2197+
else if (is_command(TODO_REVERT, &bol) &&
2198+
(*bol == ' ' || *bol == '\t'))
21972199
*action = REPLAY_REVERT;
21982200
else
2199-
goto fail;
2200-
2201-
ret = 0;
2201+
ret = -1;
22022202

2203-
fail:
22042203
strbuf_release(&buf);
22052204

22062205
return ret;

t/t7512-status-help.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,22 @@ EOF
798798
test_i18ncmp expected actual
799799
'
800800

801+
test_expect_success 'status shows cherry-pick with invalid oid' '
802+
mkdir .git/sequencer &&
803+
test_write_lines "pick invalid-oid" >.git/sequencer/todo &&
804+
git status --untracked-files=no >actual 2>err &&
805+
git cherry-pick --quit &&
806+
test_must_be_empty err &&
807+
test_i18ncmp expected actual
808+
'
809+
810+
test_expect_success 'status does not show error if .git/sequencer is a file' '
811+
test_when_finished "rm .git/sequencer" &&
812+
test_write_lines hello >.git/sequencer &&
813+
git status --untracked-files=no 2>err &&
814+
test_must_be_empty err
815+
'
816+
801817
test_expect_success 'status showing detached at and from a tag' '
802818
test_commit atag tagging &&
803819
git checkout atag &&

0 commit comments

Comments
 (0)