Merge branch 'cm/rebase-i-updates'

Follow-up fixes to "cm/rebase-i" topic.

* cm/rebase-i-updates:
  doc/rebase -i: fix typo in the documentation of 'fixup' command
  t/t3437: fixup the test 'multiple fixup -c opens editor once'
  t/t3437: use named commits in the tests
  t/t3437: simplify and document the test helpers
  t/t3437: check the author date of fixed up commit
  t/t3437: remove the dependency of 'expected-message' file from tests
  t/t3437: fixup here-docs in the 'setup' test
  t/lib-rebase: update the documentation of FAKE_LINES
  rebase -i: clarify and fix 'fixup -c' rebase-todo help
  sequencer: rename a few functions
  sequencer: fixup the datatype of the 'flag' argument
This commit is contained in:
Junio C Hamano 2021-03-26 14:59:03 -07:00
commit fde07fc356
5 changed files with 87 additions and 76 deletions

View File

@ -894,7 +894,7 @@ is used. In that case the suggested commit message is only the message
of the "fixup -c" commit, and an editor is opened allowing you to edit
the message. The contents (patch) of the "fixup -c" commit are still
incorporated into the folded commit. If there is more than one "fixup -c"
commit, the message from the last last one is used. You can also use
commit, the message from the final one is used. You can also use
"fixup -C" to get the same behavior as "fixup -c" except without opening
an editor.

View File

@ -44,9 +44,10 @@ void append_todo_help(int command_count,
"r, reword <commit> = use commit, but edit the commit message\n"
"e, edit <commit> = use commit, but stop for amending\n"
"s, squash <commit> = use commit, but meld into previous commit\n"
"f, fixup [-C | -c] <commit> = like \"squash\", but discard this\n"
" commit's log message. Use -C to replace with this\n"
" commit message or -c to edit the commit message\n"
"f, fixup [-C | -c] <commit> = like \"squash\" but keep only the previous\n"
" commit's log message, unless -C is used, in which case\n"
" keep only this commit's message; -c is same as -C but\n"
" opens the editor\n"
"x, exec <command> = run command (the rest of the line) using shell\n"
"b, break = stop here (continue rebase later with 'git rebase --continue')\n"
"d, drop <commit> = remove commit\n"
@ -55,7 +56,7 @@ void append_todo_help(int command_count,
"m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n"
". create a merge commit using the original merge commit's\n"
". message (or the oneline, if no original merge commit was\n"
". specified). Use -c <commit> to reword the commit message.\n"
". specified); use -c <commit> to reword the commit message\n"
"\n"
"These lines can be re-ordered; they are executed from top to bottom.\n");
unsigned edit_todo = !(shortrevisions && shortonto);

View File

@ -1752,8 +1752,7 @@ static const char skip_first_commit_msg_str[] = N_("The 1st commit message will
static const char skip_nth_commit_msg_fmt[] = N_("The commit message #%d will be skipped:");
static const char combined_commit_msg_fmt[] = N_("This is a combination of %d commits.");
static int check_fixup_flag(enum todo_command command,
enum todo_item_flags flag)
static int is_fixup_flag(enum todo_command command, unsigned flag)
{
return command == TODO_FIXUP && ((flag & TODO_REPLACE_FIXUP_MSG) ||
(flag & TODO_EDIT_FIXUP_MSG));
@ -1858,7 +1857,7 @@ static void update_squash_message_for_fixup(struct strbuf *msg)
static int append_squash_message(struct strbuf *buf, const char *body,
enum todo_command command, struct replay_opts *opts,
enum todo_item_flags flag)
unsigned flag)
{
const char *fixup_msg;
size_t commented_len = 0, fixup_off;
@ -1882,7 +1881,7 @@ static int append_squash_message(struct strbuf *buf, const char *body,
strbuf_addstr(buf, body + commented_len);
/* fixup -C after squash behaves like squash */
if (check_fixup_flag(command, flag) && !seen_squash(opts)) {
if (is_fixup_flag(command, flag) && !seen_squash(opts)) {
/*
* We're replacing the commit message so we need to
* append the Signed-off-by: trailer if the user
@ -1914,7 +1913,7 @@ static int update_squash_messages(struct repository *r,
enum todo_command command,
struct commit *commit,
struct replay_opts *opts,
enum todo_item_flags flag)
unsigned flag)
{
struct strbuf buf = STRBUF_INIT;
int res = 0;
@ -1937,7 +1936,7 @@ static int update_squash_messages(struct repository *r,
opts->current_fixup_count + 2);
strbuf_splice(&buf, 0, eol - buf.buf, header.buf, header.len);
strbuf_release(&header);
if (check_fixup_flag(command, flag) && !seen_squash(opts))
if (is_fixup_flag(command, flag) && !seen_squash(opts))
update_squash_message_for_fixup(&buf);
} else {
struct object_id head;
@ -1960,11 +1959,11 @@ static int update_squash_messages(struct repository *r,
strbuf_addf(&buf, "%c ", comment_line_char);
strbuf_addf(&buf, _(combined_commit_msg_fmt), 2);
strbuf_addf(&buf, "\n%c ", comment_line_char);
strbuf_addstr(&buf, check_fixup_flag(command, flag) ?
strbuf_addstr(&buf, is_fixup_flag(command, flag) ?
_(skip_first_commit_msg_str) :
_(first_commit_msg_str));
strbuf_addstr(&buf, "\n\n");
if (check_fixup_flag(command, flag))
if (is_fixup_flag(command, flag))
strbuf_add_commented_lines(&buf, body, strlen(body));
else
strbuf_addstr(&buf, body);
@ -1977,7 +1976,7 @@ static int update_squash_messages(struct repository *r,
oid_to_hex(&commit->object.oid));
find_commit_subject(message, &body);
if (command == TODO_SQUASH || check_fixup_flag(command, flag)) {
if (command == TODO_SQUASH || is_fixup_flag(command, flag)) {
res = append_squash_message(&buf, body, command, opts, flag);
} else if (command == TODO_FIXUP) {
strbuf_addf(&buf, "\n%c ", comment_line_char);
@ -5670,7 +5669,7 @@ static int subject2item_cmp(const void *fndata,
define_commit_slab(commit_todo_item, struct todo_item *);
static inline int skip_fixup_amend_squash(const char *subject, const char **p) {
static int skip_fixupish(const char *subject, const char **p) {
return skip_prefix(subject, "fixup! ", p) ||
skip_prefix(subject, "amend! ", p) ||
skip_prefix(subject, "squash! ", p);
@ -5734,13 +5733,13 @@ int todo_list_rearrange_squash(struct todo_list *todo_list)
format_subject(&buf, subject, " ");
subject = subjects[i] = strbuf_detach(&buf, &subject_len);
unuse_commit_buffer(item->commit, commit_buffer);
if (skip_fixup_amend_squash(subject, &p)) {
if (skip_fixupish(subject, &p)) {
struct commit *commit2;
for (;;) {
while (isspace(*p))
p++;
if (!skip_fixup_amend_squash(p, &p))
if (!skip_fixupish(p, &p))
break;
}

View File

@ -15,10 +15,11 @@
# specified line.
#
# "<cmd> <lineno>" -- add a line with the specified command
# ("pick", "squash", "fixup", "edit", "reword" or "drop") and the
# SHA1 taken from the specified line.
# ("pick", "squash", "fixup"|"fixup_-C"|"fixup_-c", "edit", "reword" or "drop")
# and the SHA1 taken from the specified line.
#
# "exec_cmd_with_args" -- add an "exec cmd with args" line.
# "_" -- add a space, like "fixup_-C" implies "fixup -C" and
# "exec_cmd_with_args" add an "exec cmd with args" line.
#
# "#" -- Add a comment line.
#

View File

@ -9,7 +9,9 @@ This test checks the "fixup [-C|-c]" command of rebase interactive.
In addition to amending the contents of the commit, "fixup -C"
replaces the original commit message with the message of the fixup
commit. "fixup -c" also replaces the original message, but opens the
editor to allow the user to edit the message before committing.
editor to allow the user to edit the message before committing. Similar
to the "fixup" command that works with "fixup!", "fixup -C" works with
"amend!" upon --autosquash.
'
. ./test-lib.sh
@ -18,35 +20,35 @@ editor to allow the user to edit the message before committing.
EMPTY=""
# test_commit_message <rev> -m <msg>
# test_commit_message <rev> <path>
# Verify that the commit message of <rev> matches
# <msg> or the content of <path>.
test_commit_message () {
rev="$1" && # commit or tag we want to test
file="$2" && # test against the content of a file
git show --no-patch --pretty=format:%B "$rev" >actual-message &&
if test "$2" = -m
then
str="$3" && # test against a string
printf "%s\n" "$str" >tmp-expected-message &&
file="tmp-expected-message"
fi
test_cmp "$file" actual-message
git show --no-patch --pretty=format:%B "$1" >actual &&
case "$2" in
-m)
echo "$3" >expect &&
test_cmp expect actual ;;
*)
test_cmp "$2" actual ;;
esac
}
get_author () {
rev="$1" &&
git log -1 --pretty=format:"%an %ae" "$rev"
git log -1 --pretty=format:"%an %ae %at" "$rev"
}
test_expect_success 'setup' '
cat >message <<-EOF &&
amend! B
${EMPTY}
new subject
${EMPTY}
new
body
EOF
sed "1,2d" message >expected-message &&
amend! B
$EMPTY
new subject
$EMPTY
new
body
EOF
test_commit A A &&
test_commit B B &&
@ -68,40 +70,43 @@ test_expect_success 'setup' '
echo B1 >B &&
test_tick &&
git commit --fixup=HEAD -a &&
git tag B1 &&
test_tick &&
git commit --allow-empty -F - <<-EOF &&
amend! B
${EMPTY}
B
${EMPTY}
edited 1
EOF
amend! B
$EMPTY
B
$EMPTY
edited 1
EOF
test_tick &&
git commit --allow-empty -F - <<-EOF &&
amend! amend! B
${EMPTY}
B
${EMPTY}
edited 1
${EMPTY}
edited 2
EOF
amend! amend! B
$EMPTY
B
$EMPTY
edited 1
$EMPTY
edited 2
EOF
echo B2 >B &&
test_tick &&
FAKE_COMMIT_AMEND="edited squash" git commit --squash=HEAD -a &&
git tag B2 &&
echo B3 >B &&
test_tick &&
git commit -a -F - <<-EOF &&
amend! amend! amend! B
${EMPTY}
B
${EMPTY}
edited 1
${EMPTY}
edited 2
${EMPTY}
edited 3
EOF
amend! amend! amend! B
$EMPTY
B
$EMPTY
edited 1
$EMPTY
edited 2
$EMPTY
edited 3
EOF
git tag B3 &&
GIT_AUTHOR_NAME="Rebase Author" &&
GIT_AUTHOR_EMAIL="rebase.author@example.com" &&
@ -134,6 +139,7 @@ test_expect_success 'simple fixup -c works' '
test_expect_success 'fixup -C removes amend! from message' '
test_when_finished "test_might_fail git rebase --abort" &&
git checkout --detach A1 &&
git log -1 --pretty=format:%b >expected-message &&
FAKE_LINES="1 fixup_-C 2" git rebase -i A &&
test_cmp_rev HEAD^ A &&
test_cmp_rev HEAD^{tree} A1^{tree} &&
@ -145,13 +151,14 @@ test_expect_success 'fixup -C removes amend! from message' '
test_expect_success 'fixup -C with conflicts gives correct message' '
test_when_finished "test_might_fail git rebase --abort" &&
git checkout --detach A1 &&
git log -1 --pretty=format:%b >expected-message &&
test_write_lines "" "edited" >>expected-message &&
test_must_fail env FAKE_LINES="1 fixup_-C 2" git rebase -i conflicts &&
git checkout --theirs -- A &&
git add A &&
FAKE_COMMIT_AMEND=edited git rebase --continue &&
test_cmp_rev HEAD^ conflicts &&
test_cmp_rev HEAD^{tree} A1^{tree} &&
test_write_lines "" edited >>expected-message &&
test_commit_message HEAD expected-message &&
get_author HEAD >actual-author &&
test_cmp expected-author actual-author
@ -167,12 +174,12 @@ test_expect_success 'skipping fixup -C after fixup gives correct message' '
'
test_expect_success 'sequence of fixup, fixup -C & squash --signoff works' '
git checkout --detach branch &&
git checkout --detach B3 &&
FAKE_LINES="1 fixup 2 fixup_-C 3 fixup_-C 4 squash 5 fixup_-C 6" \
FAKE_COMMIT_AMEND=squashed \
FAKE_MESSAGE_COPY=actual-squash-message \
git -c commit.status=false rebase -ik --signoff A &&
git diff-tree --exit-code --patch HEAD branch -- &&
git diff-tree --exit-code --patch HEAD B3 -- &&
test_cmp_rev HEAD^ A &&
test_i18ncmp "$TEST_DIRECTORY/t3437/expected-squash-message" \
actual-squash-message
@ -180,7 +187,7 @@ test_expect_success 'sequence of fixup, fixup -C & squash --signoff works' '
test_expect_success 'first fixup -C commented out in sequence fixup fixup -C fixup -C' '
test_when_finished "test_might_fail git rebase --abort" &&
git checkout branch && git checkout --detach branch~2 &&
git checkout --detach B2~ &&
git log -1 --pretty=format:%b >expected-message &&
FAKE_LINES="1 fixup 2 fixup_-C 3 fixup_-C 4" git rebase -i A &&
test_cmp_rev HEAD^ A &&
@ -190,13 +197,16 @@ test_expect_success 'first fixup -C commented out in sequence fixup fixup -C fix
test_expect_success 'multiple fixup -c opens editor once' '
test_when_finished "test_might_fail git rebase --abort" &&
git checkout --detach A3 &&
base=$(git rev-parse HEAD~4) &&
FAKE_COMMIT_MESSAGE="Modified-A3" \
git log -1 --pretty=format:%B >expected-message &&
test_write_lines "" "Modified-A3" >>expected-message &&
FAKE_COMMIT_AMEND="Modified-A3" \
FAKE_LINES="1 fixup_-C 2 fixup_-c 3 fixup_-c 4" \
EXPECT_HEADER_COUNT=4 \
git rebase -i $base &&
test_cmp_rev $base HEAD^ &&
test 1 = $(git show | grep Modified-A3 | wc -l)
git rebase -i A &&
test_cmp_rev HEAD^ A &&
get_author HEAD >actual-author &&
test_cmp expected-author actual-author &&
test_commit_message HEAD expected-message
'
test_expect_success 'sequence squash, fixup & fixup -c gives combined message' '
@ -211,12 +221,12 @@ test_expect_success 'sequence squash, fixup & fixup -c gives combined message' '
'
test_expect_success 'fixup -C works upon --autosquash with amend!' '
git checkout --detach branch &&
git checkout --detach B3 &&
FAKE_COMMIT_AMEND=squashed \
FAKE_MESSAGE_COPY=actual-squash-message \
git -c commit.status=false rebase -ik --autosquash \
--signoff A &&
git diff-tree --exit-code --patch HEAD branch -- &&
git diff-tree --exit-code --patch HEAD B3 -- &&
test_cmp_rev HEAD^ A &&
test_i18ncmp "$TEST_DIRECTORY/t3437/expected-squash-message" \
actual-squash-message