Skip to content

Commit 7aed2c0

Browse files
phillipwoodgitster
authored andcommitted
rebase -i: match whole word in is_command()
When matching an unabbreviated command is_command() only does a prefix match which means it parses "pickled" as TODO_PICK. parse_insn_line() does error out because is_command() only advances as far as the end of "pick" so it looks like the command name is not followed by a space but the error message is "missing arguments for pick" rather than telling the user that the "pickled" is not a valid command. Fix this by ensuring the match is follow by whitespace or the end of the string as we already do for abbreviated commands. The (*bol = p) at the end of the condition is a bit cute for my taste but I decided to leave it be for now. Rather than add new tests the existing tests for bad commands are adapted to use a bad command name that triggers the prefix matching bug. Signed-off-by: Phillip Wood <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 768bb23 commit 7aed2c0

File tree

3 files changed

+14
-12
lines changed

3 files changed

+14
-12
lines changed

sequencer.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2469,12 +2469,11 @@ static int is_command(enum todo_command command, const char **bol)
24692469
{
24702470
const char *str = todo_command_info[command].str;
24712471
const char nick = todo_command_info[command].c;
2472-
const char *p = *bol + 1;
2472+
const char *p = *bol;
24732473

2474-
return skip_prefix(*bol, str, bol) ||
2475-
((nick && **bol == nick) &&
2476-
(*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r' || !*p) &&
2477-
(*bol = p));
2474+
return (skip_prefix(p, str, &p) || (nick && *p++ == nick)) &&
2475+
(*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r' || !*p) &&
2476+
(*bol = p);
24782477
}
24792478

24802479
static int parse_insn_line(struct repository *r, struct todo_item *item,
@@ -2503,7 +2502,8 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,
25032502
break;
25042503
}
25052504
if (i >= TODO_COMMENT)
2506-
return -1;
2505+
return error(_("invalid command '%.*s'"),
2506+
(int)strcspn(bol, " \t\r\n"), bol);
25072507

25082508
/* Eat up extra spaces/ tabs before object name */
25092509
padding = strspn(bol, " \t");

t/lib-rebase.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ set_fake_editor () {
6060
">")
6161
echo >> "$1";;
6262
bad)
63-
action="badcmd";;
63+
action="pickled";;
6464
fakesha)
6565
test \& != "$action" || action=pick
6666
echo "$action XXXXXXX False commit" >> "$1"

t/t3404-rebase-interactive.sh

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,14 +1449,15 @@ test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = ig
14491449

14501450
test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = warn' '
14511451
cat >expect <<-EOF &&
1452-
error: invalid line 1: badcmd $(git rev-list --pretty=oneline --abbrev-commit -1 primary~4)
1452+
error: invalid command '\''pickled'\''
1453+
error: invalid line 1: pickled $(git rev-list --pretty=oneline --abbrev-commit -1 primary~4)
14531454
Warning: some commits may have been dropped accidentally.
14541455
Dropped commits (newer to older):
14551456
- $(git rev-list --pretty=oneline --abbrev-commit -1 primary)
14561457
- $(git rev-list --pretty=oneline --abbrev-commit -1 primary~4)
14571458
To avoid this message, use "drop" to explicitly remove a commit.
14581459
EOF
1459-
head -n4 expect >expect.2 &&
1460+
head -n5 expect >expect.2 &&
14601461
tail -n1 expect >>expect.2 &&
14611462
tail -n4 expect.2 >expect.3 &&
14621463
test_config rebase.missingCommitsCheck warn &&
@@ -1467,7 +1468,7 @@ test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = wa
14671468
git rebase -i --root &&
14681469
cp .git/rebase-merge/git-rebase-todo.backup orig &&
14691470
FAKE_LINES="2 3 4" git rebase --edit-todo 2>actual.2 &&
1470-
head -n6 actual.2 >actual &&
1471+
head -n7 actual.2 >actual &&
14711472
test_cmp expect actual &&
14721473
cp orig .git/rebase-merge/git-rebase-todo &&
14731474
FAKE_LINES="1 2 3 4" git rebase --edit-todo 2>actual.2 &&
@@ -1483,7 +1484,8 @@ test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = wa
14831484

14841485
test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = error' '
14851486
cat >expect <<-EOF &&
1486-
error: invalid line 1: badcmd $(git rev-list --pretty=oneline --abbrev-commit -1 primary~4)
1487+
error: invalid command '\''pickled'\''
1488+
error: invalid line 1: pickled $(git rev-list --pretty=oneline --abbrev-commit -1 primary~4)
14871489
Warning: some commits may have been dropped accidentally.
14881490
Dropped commits (newer to older):
14891491
- $(git rev-list --pretty=oneline --abbrev-commit -1 primary)
@@ -1583,7 +1585,7 @@ test_expect_success 'static check of bad command' '
15831585
set_fake_editor &&
15841586
test_must_fail env FAKE_LINES="1 2 3 bad 4 5" \
15851587
git rebase -i --root 2>actual &&
1586-
test_i18ngrep "badcmd $(git rev-list --oneline -1 primary~1)" \
1588+
test_i18ngrep "pickled $(git rev-list --oneline -1 primary~1)" \
15871589
actual &&
15881590
test_i18ngrep "You can fix this with .git rebase --edit-todo.." \
15891591
actual &&

0 commit comments

Comments
 (0)