revert: make commit subjects in insn sheet optional

Change the instruction sheet format subtly so that the subject of the
commit message that follows the object name is optional.  As a result,
an instruction sheet like this is now perfectly valid:

  pick 35b0426
  pick fbd5bbcbc2e
  pick 7362160f

While at it, also fix a bug: currently, we use a commit-id-shaped
buffer to store the word after "pick" in '.git/sequencer/todo'.  This
is both wasteful and wrong because it places an artificial limit on
the line length.  Eliminate the need for the buffer altogether, and
add a test demonstrating this.

[jc: simplify parsing]

Suggested-by: Jonathan Nieder <jrnieder@gmail.com>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Ramkumar Ramachandra
2011-10-23 00:43:44 +05:30
committed by Junio C Hamano
parent e6010ee77a
commit 300f5e81b2
2 changed files with 44 additions and 21 deletions

View File

@@ -694,31 +694,27 @@ static int format_todo(struct strbuf *buf, struct commit_list *todo_list,
return 0;
}
static struct commit *parse_insn_line(char *start, struct replay_opts *opts)
static struct commit *parse_insn_line(char *bol, char *eol, struct replay_opts *opts)
{
unsigned char commit_sha1[20];
char sha1_abbrev[40];
enum replay_action action;
int insn_len = 0;
char *p, *q;
char *end_of_object_name;
int saved, status;
if (!prefixcmp(start, "pick ")) {
if (!prefixcmp(bol, "pick ")) {
action = CHERRY_PICK;
insn_len = strlen("pick");
p = start + insn_len + 1;
} else if (!prefixcmp(start, "revert ")) {
bol += strlen("pick ");
} else if (!prefixcmp(bol, "revert ")) {
action = REVERT;
insn_len = strlen("revert");
p = start + insn_len + 1;
bol += strlen("revert ");
} else
return NULL;
q = strchr(p, ' ');
if (!q)
return NULL;
q++;
strlcpy(sha1_abbrev, p, q - p);
end_of_object_name = bol + strcspn(bol, " \n");
saved = *end_of_object_name;
*end_of_object_name = '\0';
status = get_sha1(bol, commit_sha1);
*end_of_object_name = saved;
/*
* Verify that the action matches up with the one in
@@ -731,7 +727,7 @@ static struct commit *parse_insn_line(char *start, struct replay_opts *opts)
return NULL;
}
if (get_sha1(sha1_abbrev, commit_sha1) < 0)
if (status < 0)
return NULL;
return lookup_commit_reference(commit_sha1);
@@ -746,13 +742,12 @@ static int parse_insn_buffer(char *buf, struct commit_list **todo_list,
int i;
for (i = 1; *p; i++) {
commit = parse_insn_line(p, opts);
char *eol = strchrnul(p, '\n');
commit = parse_insn_line(p, eol, opts);
if (!commit)
return error(_("Could not parse line %d."), i);
next = commit_list_append(commit, next);
p = strchrnul(p, '\n');
if (*p)
p++;
p = *eol ? eol + 1 : eol;
}
if (!*todo_list)
return error(_("No commits parsed."));

View File

@@ -12,6 +12,9 @@ test_description='Test cherry-pick continuation features
. ./test-lib.sh
# Repeat first match 10 times
_r10='\1\1\1\1\1\1\1\1\1\1'
pristine_detach () {
git cherry-pick --reset &&
git checkout -f "$1^0" &&
@@ -211,4 +214,29 @@ test_expect_success 'malformed instruction sheet 2' '
test_must_fail git cherry-pick --continue
'
test_expect_success 'malformed instruction sheet 3' '
pristine_detach initial &&
test_must_fail git cherry-pick base..anotherpick &&
echo "resolved" >foo &&
git add foo &&
git commit &&
sed "s/pick \([0-9a-f]*\)/pick $_r10/" .git/sequencer/todo >new_sheet &&
cp new_sheet .git/sequencer/todo &&
test_must_fail git cherry-pick --continue
'
test_expect_success 'commit descriptions in insn sheet are optional' '
pristine_detach initial &&
test_must_fail git cherry-pick base..anotherpick &&
echo "c" >foo &&
git add foo &&
git commit &&
cut -d" " -f1,2 .git/sequencer/todo >new_sheet &&
cp new_sheet .git/sequencer/todo &&
git cherry-pick --continue &&
test_path_is_missing .git/sequencer &&
git rev-list HEAD >commits
test_line_count = 4 commits
'
test_done