
The `--exec <cmd>` is documented as Append "exec <cmd>" after each line creating a commit in the final history. ... If --autosquash is used, "exec" lines will not be appended for the intermediate commits, and will only appear at the end of each squash/fixup series. Unfortunately, it would also add exec commands after non-pick operations, such as 'no-op', which could be seen for example with git rebase -i --exec true HEAD todo_list_add_exec_commands() intent was to insert exec commands after each logical pick, while trying to consider a chains of fixup and squash commits to be part of the pick before it. So it would keep an 'insert' boolean tracking if it had seen a pick or merge, but not write the exec command until it saw the next non-fixup/squash command. Since that would make it miss the final exec command, it had some code that would check whether it still needed to insert one at the end, but instead of a simple if (insert) it had a if (insert || <condition that is always true>) That's buggy; as per the docs, we should only add exec commands for lines that create commits, i.e. only if insert is true. Fix the conditional. There was one testcase in the testsuite that we tweak for this change; it was introduced in 54fd3243da ("rebase -i: reread the todo list if `exec` touched it", 2017-04-26), and was merely testing that after an exec had fired that the todo list would be re-read. The test at the time would have worked given any revision at all, though it would only work with 'HEAD' as a side-effect of this bug. Since we're fixing this bug, choose something other than 'HEAD' for that test. Finally, add a testcase that verifies when we have no commits to pick, that we get no exec lines in the generated todo list. Reported-by: Nikita Bobko <nikitabobko@gmail.com> Signed-off-by: Elijah Newren <newren@gmail.com> Acked-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
91 lines
2.2 KiB
Bash
Executable File
91 lines
2.2 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
test_description='rebase should reread the todo file if an exec modifies it'
|
|
|
|
. ./test-lib.sh
|
|
. "$TEST_DIRECTORY"/lib-rebase.sh
|
|
|
|
test_expect_success 'setup' '
|
|
test_commit first file &&
|
|
test_commit second file &&
|
|
test_commit third file
|
|
'
|
|
|
|
test_expect_success 'rebase exec modifies rebase-todo' '
|
|
todo=.git/rebase-merge/git-rebase-todo &&
|
|
git rebase HEAD~1 -x "echo exec touch F >>$todo" &&
|
|
test -e F
|
|
'
|
|
|
|
test_expect_success 'rebase exec with an empty list does not exec anything' '
|
|
git rebase HEAD -x "true" 2>output &&
|
|
! grep "Executing: true" output
|
|
'
|
|
|
|
test_expect_success 'loose object cache vs re-reading todo list' '
|
|
GIT_REBASE_TODO=.git/rebase-merge/git-rebase-todo &&
|
|
export GIT_REBASE_TODO &&
|
|
write_script append-todo.sh <<-\EOS &&
|
|
# For values 5 and 6, this yields SHA-1s with the same first two digits
|
|
echo "pick $(git rev-parse --short \
|
|
$(printf "%s\\n" \
|
|
"tree $EMPTY_TREE" \
|
|
"author A U Thor <author@example.org> $1 +0000" \
|
|
"committer A U Thor <author@example.org> $1 +0000" \
|
|
"" \
|
|
"$1" |
|
|
git hash-object -t commit -w --stdin))" >>$GIT_REBASE_TODO
|
|
|
|
shift
|
|
test -z "$*" ||
|
|
echo "exec $0 $*" >>$GIT_REBASE_TODO
|
|
EOS
|
|
|
|
git rebase HEAD -x "./append-todo.sh 5 6"
|
|
'
|
|
|
|
test_expect_success 'todo is re-read after reword and squash' '
|
|
write_script reword-editor.sh <<-\EOS &&
|
|
GIT_SEQUENCE_EDITOR="echo \"exec echo $(cat file) >>actual\" >>" \
|
|
git rebase --edit-todo
|
|
EOS
|
|
|
|
test_write_lines first third >expected &&
|
|
set_fake_editor &&
|
|
GIT_SEQUENCE_EDITOR="$EDITOR" FAKE_LINES="reword 1 squash 2 fixup 3" \
|
|
GIT_EDITOR=./reword-editor.sh git rebase -i --root third &&
|
|
test_cmp expected actual
|
|
'
|
|
|
|
test_expect_success 're-reading todo doesnt interfere with revert --edit' '
|
|
git reset --hard third &&
|
|
|
|
git revert --edit third second &&
|
|
|
|
cat >expect <<-\EOF &&
|
|
Revert "second"
|
|
Revert "third"
|
|
third
|
|
second
|
|
first
|
|
EOF
|
|
git log --format="%s" >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 're-reading todo doesnt interfere with cherry-pick --edit' '
|
|
git reset --hard first &&
|
|
|
|
git cherry-pick --edit second third &&
|
|
|
|
cat >expect <<-\EOF &&
|
|
third
|
|
second
|
|
first
|
|
EOF
|
|
git log --format="%s" >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_done
|