2010-07-28 08:20:16 +00:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='git rebase --continue tests'
|
|
|
|
|
2020-11-18 23:44:25 +00:00
|
|
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
tests: mark tests relying on the current default for `init.defaultBranch`
In addition to the manual adjustment to let the `linux-gcc` CI job run
the test suite with `master` and then with `main`, this patch makes sure
that GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME is set in all test scripts
that currently rely on the initial branch name being `master by default.
To determine which test scripts to mark up, the first step was to
force-set the default branch name to `master` in
- all test scripts that contain the keyword `master`,
- t4211, which expects `t/t4211/history.export` with a hard-coded ref to
initialize the default branch,
- t5560 because it sources `t/t556x_common` which uses `master`,
- t8002 and t8012 because both source `t/annotate-tests.sh` which also
uses `master`)
This trick was performed by this command:
$ sed -i '/^ *\. \.\/\(test-lib\|lib-\(bash\|cvs\|git-svn\)\|gitweb-lib\)\.sh$/i\
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master\
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\
' $(git grep -l master t/t[0-9]*.sh) \
t/t4211*.sh t/t5560*.sh t/t8002*.sh t/t8012*.sh
After that, careful, manual inspection revealed that some of the test
scripts containing the needle `master` do not actually rely on a
specific default branch name: either they mention `master` only in a
comment, or they initialize that branch specificially, or they do not
actually refer to the current default branch. Therefore, the
aforementioned modification was undone in those test scripts thusly:
$ git checkout HEAD -- \
t/t0027-auto-crlf.sh t/t0060-path-utils.sh \
t/t1011-read-tree-sparse-checkout.sh \
t/t1305-config-include.sh t/t1309-early-config.sh \
t/t1402-check-ref-format.sh t/t1450-fsck.sh \
t/t2024-checkout-dwim.sh \
t/t2106-update-index-assume-unchanged.sh \
t/t3040-subprojects-basic.sh t/t3301-notes.sh \
t/t3308-notes-merge.sh t/t3423-rebase-reword.sh \
t/t3436-rebase-more-options.sh \
t/t4015-diff-whitespace.sh t/t4257-am-interactive.sh \
t/t5323-pack-redundant.sh t/t5401-update-hooks.sh \
t/t5511-refspec.sh t/t5526-fetch-submodules.sh \
t/t5529-push-errors.sh t/t5530-upload-pack-error.sh \
t/t5548-push-porcelain.sh \
t/t5552-skipping-fetch-negotiator.sh \
t/t5572-pull-submodule.sh t/t5608-clone-2gb.sh \
t/t5614-clone-submodules-shallow.sh \
t/t7508-status.sh t/t7606-merge-custom.sh \
t/t9302-fast-import-unpack-limit.sh
We excluded one set of test scripts in these commands, though: the range
of `git p4` tests. The reason? `git p4` stores the (foreign) remote
branch in the branch called `p4/master`, which is obviously not the
default branch. Manual analysis revealed that only five of these tests
actually require a specific default branch name to pass; They were
modified thusly:
$ sed -i '/^ *\. \.\/lib-git-p4\.sh$/i\
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master\
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\
' t/t980[0167]*.sh t/t9811*.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-18 23:44:19 +00:00
|
|
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
|
|
|
|
2010-07-28 08:20:16 +00:00
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
. "$TEST_DIRECTORY"/lib-rebase.sh
|
|
|
|
|
|
|
|
set_fake_editor
|
|
|
|
|
|
|
|
test_expect_success 'setup' '
|
|
|
|
test_commit "commit-new-file-F1" F1 1 &&
|
|
|
|
test_commit "commit-new-file-F2" F2 2 &&
|
|
|
|
|
|
|
|
git checkout -b topic HEAD^ &&
|
|
|
|
test_commit "commit-new-file-F2-on-topic-branch" F2 22 &&
|
|
|
|
|
2020-11-18 23:44:25 +00:00
|
|
|
git checkout main
|
2010-07-28 08:20:16 +00:00
|
|
|
'
|
|
|
|
|
2021-08-12 13:42:08 +00:00
|
|
|
test_expect_success 'merge based rebase --continue with works with touched file' '
|
2010-07-28 08:20:16 +00:00
|
|
|
rm -fr .git/rebase-* &&
|
|
|
|
git reset --hard &&
|
2020-11-18 23:44:25 +00:00
|
|
|
git checkout main &&
|
2010-07-28 08:20:16 +00:00
|
|
|
|
|
|
|
FAKE_LINES="edit 1" git rebase -i HEAD^ &&
|
2018-03-24 07:44:31 +00:00
|
|
|
test-tool chmtime =-60 F1 &&
|
2010-07-28 08:20:16 +00:00
|
|
|
git rebase --continue
|
|
|
|
'
|
|
|
|
|
2021-08-12 13:42:09 +00:00
|
|
|
test_expect_success 'merge based rebase --continue removes .git/MERGE_MSG' '
|
|
|
|
git checkout -f --detach topic &&
|
|
|
|
|
|
|
|
test_must_fail git rebase --onto main HEAD^ &&
|
|
|
|
git read-tree --reset -u HEAD &&
|
|
|
|
test_path_is_file .git/MERGE_MSG &&
|
|
|
|
git rebase --continue &&
|
|
|
|
test_path_is_missing .git/MERGE_MSG
|
|
|
|
'
|
|
|
|
|
2021-08-12 13:42:08 +00:00
|
|
|
test_expect_success 'apply based rebase --continue works with touched file' '
|
2010-07-28 08:20:16 +00:00
|
|
|
rm -fr .git/rebase-* &&
|
|
|
|
git reset --hard &&
|
2020-11-18 23:44:25 +00:00
|
|
|
git checkout main &&
|
2010-07-28 08:20:16 +00:00
|
|
|
|
2021-08-12 13:42:08 +00:00
|
|
|
test_must_fail git rebase --apply --onto main main topic &&
|
2010-07-28 08:20:16 +00:00
|
|
|
echo "Resolved" >F2 &&
|
|
|
|
git add F2 &&
|
2018-03-24 07:44:31 +00:00
|
|
|
test-tool chmtime =-60 F1 &&
|
2010-07-28 08:20:16 +00:00
|
|
|
git rebase --continue
|
|
|
|
'
|
|
|
|
|
2011-02-06 18:43:36 +00:00
|
|
|
test_expect_success 'rebase --continue can not be used with other options' '
|
|
|
|
test_must_fail git rebase -v --continue &&
|
|
|
|
test_must_fail git rebase --continue -v
|
|
|
|
'
|
|
|
|
|
2011-02-06 18:43:55 +00:00
|
|
|
test_expect_success 'rebase --continue remembers merge strategy and options' '
|
|
|
|
rm -fr .git/rebase-* &&
|
|
|
|
git reset --hard commit-new-file-F2-on-topic-branch &&
|
|
|
|
test_commit "commit-new-file-F3-on-topic-branch" F3 32 &&
|
2023-04-10 09:08:30 +00:00
|
|
|
test_when_finished "rm -fr test-bin" &&
|
2011-02-06 18:43:55 +00:00
|
|
|
mkdir test-bin &&
|
2023-04-10 09:08:30 +00:00
|
|
|
|
|
|
|
write_script test-bin/git-merge-funny <<-\EOF &&
|
|
|
|
printf "[%s]\n" $# "$1" "$2" "$3" "$5" >actual
|
|
|
|
shift 3 &&
|
|
|
|
exec git merge-recursive "$@"
|
2011-02-06 18:43:55 +00:00
|
|
|
EOF
|
2023-04-10 09:08:30 +00:00
|
|
|
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
[7]
|
|
|
|
[--option=arg with space]
|
|
|
|
[--op"tion\]
|
|
|
|
[--new
|
|
|
|
line ]
|
|
|
|
[--]
|
|
|
|
EOF
|
|
|
|
|
|
|
|
rm -f actual &&
|
2011-02-06 18:43:55 +00:00
|
|
|
(
|
2018-07-02 00:23:58 +00:00
|
|
|
PATH=./test-bin:$PATH &&
|
2023-04-10 09:08:30 +00:00
|
|
|
test_must_fail git rebase -s funny -X"option=arg with space" \
|
|
|
|
-Xop\"tion\\ -X"new${LF}line " main topic
|
2011-02-06 18:43:55 +00:00
|
|
|
) &&
|
2023-04-10 09:08:30 +00:00
|
|
|
test_cmp expect actual &&
|
|
|
|
rm actual &&
|
2011-02-06 18:43:55 +00:00
|
|
|
echo "Resolved" >F2 &&
|
|
|
|
git add F2 &&
|
|
|
|
(
|
2018-07-02 00:23:58 +00:00
|
|
|
PATH=./test-bin:$PATH &&
|
2011-02-06 18:43:55 +00:00
|
|
|
git rebase --continue
|
|
|
|
) &&
|
2023-04-10 09:08:30 +00:00
|
|
|
test_cmp expect actual
|
2011-02-06 18:43:55 +00:00
|
|
|
'
|
2018-01-04 21:31:52 +00:00
|
|
|
|
2019-07-31 15:18:49 +00:00
|
|
|
test_expect_success 'rebase -r passes merge strategy options correctly' '
|
|
|
|
rm -fr .git/rebase-* &&
|
|
|
|
git reset --hard commit-new-file-F3-on-topic-branch &&
|
|
|
|
test_commit merge-theirs &&
|
|
|
|
git reset --hard HEAD^ &&
|
|
|
|
test_commit some-other-commit &&
|
|
|
|
test_tick &&
|
|
|
|
git merge --no-ff merge-theirs &&
|
|
|
|
FAKE_LINES="1 3 edit 4 5 7 8 9" git rebase -i -f -r -m \
|
|
|
|
-s recursive --strategy-option=theirs HEAD~2 &&
|
|
|
|
test_commit force-change-ours &&
|
|
|
|
git rebase --continue
|
2018-01-04 21:31:52 +00:00
|
|
|
'
|
2018-04-27 20:48:16 +00:00
|
|
|
|
rebase --skip: clean up commit message after a failed fixup/squash
During a series of fixup/squash commands, the interactive rebase builds
up a commit message with comments. This will be presented to the user in
the editor if at least one of those commands was a `squash`.
In any case, the commit message will be cleaned up eventually, removing
all those intermediate comments, in the final step of such a
fixup/squash chain.
However, if the last fixup/squash command in such a chain fails with
merge conflicts, and if the user then decides to skip it (or resolve it
to a clean worktree and then continue the rebase), the current code
fails to clean up the commit message.
This commit fixes that behavior.
The fix is quite a bit more involved than meets the eye because it is
not only about the question whether we are `git rebase --skip`ing a
fixup or squash. It is also about removing the skipped fixup/squash's
commit message from the accumulated commit message. And it is also about
the question whether we should let the user edit the final commit
message or not ("Was there a squash in the chain *that was not
skipped*?").
For example, in this case we will want to fix the commit message, but
not open it in an editor:
pick <- succeeds
fixup <- succeeds
squash <- fails, will be skipped
This is where the newly-introduced `current-fixups` file comes in real
handy. A quick look and we can determine whether there was a non-skipped
squash. We only need to make sure to keep it up to date with respect to
skipped fixup/squash commands. As a bonus, we can even avoid committing
unnecessarily, e.g. when there was only one fixup, and it failed, and
was skipped.
To fix only the bug where the final commit message was not cleaned up
properly, but without fixing the rest, would have been more complicated
than fixing it all in one go, hence this commit lumps together more than
a single concern.
For the same reason, this commit also adds a bit more to the existing
test case for the regression we just fixed.
The diff is best viewed with --color-moved.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-27 20:48:30 +00:00
|
|
|
test_expect_success '--skip after failed fixup cleans commit message' '
|
2018-04-27 20:48:16 +00:00
|
|
|
test_when_finished "test_might_fail git rebase --abort" &&
|
|
|
|
git checkout -b with-conflicting-fixup &&
|
|
|
|
test_commit wants-fixup &&
|
2023-08-03 13:09:35 +00:00
|
|
|
test_commit "fixup 1" wants-fixup.t 1 wants-fixup-1 &&
|
|
|
|
test_commit "fixup 2" wants-fixup.t 2 wants-fixup-2 &&
|
|
|
|
test_commit "fixup 3" wants-fixup.t 3 wants-fixup-3 &&
|
rebase --skip: clean up commit message after a failed fixup/squash
During a series of fixup/squash commands, the interactive rebase builds
up a commit message with comments. This will be presented to the user in
the editor if at least one of those commands was a `squash`.
In any case, the commit message will be cleaned up eventually, removing
all those intermediate comments, in the final step of such a
fixup/squash chain.
However, if the last fixup/squash command in such a chain fails with
merge conflicts, and if the user then decides to skip it (or resolve it
to a clean worktree and then continue the rebase), the current code
fails to clean up the commit message.
This commit fixes that behavior.
The fix is quite a bit more involved than meets the eye because it is
not only about the question whether we are `git rebase --skip`ing a
fixup or squash. It is also about removing the skipped fixup/squash's
commit message from the accumulated commit message. And it is also about
the question whether we should let the user edit the final commit
message or not ("Was there a squash in the chain *that was not
skipped*?").
For example, in this case we will want to fix the commit message, but
not open it in an editor:
pick <- succeeds
fixup <- succeeds
squash <- fails, will be skipped
This is where the newly-introduced `current-fixups` file comes in real
handy. A quick look and we can determine whether there was a non-skipped
squash. We only need to make sure to keep it up to date with respect to
skipped fixup/squash commands. As a bonus, we can even avoid committing
unnecessarily, e.g. when there was only one fixup, and it failed, and
was skipped.
To fix only the bug where the final commit message was not cleaned up
properly, but without fixing the rest, would have been more complicated
than fixing it all in one go, hence this commit lumps together more than
a single concern.
For the same reason, this commit also adds a bit more to the existing
test case for the regression we just fixed.
The diff is best viewed with --color-moved.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-27 20:48:30 +00:00
|
|
|
test_must_fail env FAKE_LINES="1 fixup 2 squash 4" \
|
2018-04-27 20:48:16 +00:00
|
|
|
git rebase -i HEAD~4 &&
|
|
|
|
|
|
|
|
: now there is a conflict, and comments in the commit message &&
|
2023-08-03 13:09:35 +00:00
|
|
|
test_commit_message HEAD <<-\EOF &&
|
|
|
|
# This is a combination of 2 commits.
|
|
|
|
# This is the 1st commit message:
|
|
|
|
|
|
|
|
wants-fixup
|
|
|
|
|
|
|
|
# The commit message #2 will be skipped:
|
|
|
|
|
|
|
|
# fixup 1
|
|
|
|
EOF
|
2018-04-27 20:48:16 +00:00
|
|
|
|
|
|
|
: skip and continue &&
|
rebase --skip: clean up commit message after a failed fixup/squash
During a series of fixup/squash commands, the interactive rebase builds
up a commit message with comments. This will be presented to the user in
the editor if at least one of those commands was a `squash`.
In any case, the commit message will be cleaned up eventually, removing
all those intermediate comments, in the final step of such a
fixup/squash chain.
However, if the last fixup/squash command in such a chain fails with
merge conflicts, and if the user then decides to skip it (or resolve it
to a clean worktree and then continue the rebase), the current code
fails to clean up the commit message.
This commit fixes that behavior.
The fix is quite a bit more involved than meets the eye because it is
not only about the question whether we are `git rebase --skip`ing a
fixup or squash. It is also about removing the skipped fixup/squash's
commit message from the accumulated commit message. And it is also about
the question whether we should let the user edit the final commit
message or not ("Was there a squash in the chain *that was not
skipped*?").
For example, in this case we will want to fix the commit message, but
not open it in an editor:
pick <- succeeds
fixup <- succeeds
squash <- fails, will be skipped
This is where the newly-introduced `current-fixups` file comes in real
handy. A quick look and we can determine whether there was a non-skipped
squash. We only need to make sure to keep it up to date with respect to
skipped fixup/squash commands. As a bonus, we can even avoid committing
unnecessarily, e.g. when there was only one fixup, and it failed, and
was skipped.
To fix only the bug where the final commit message was not cleaned up
properly, but without fixing the rest, would have been more complicated
than fixing it all in one go, hence this commit lumps together more than
a single concern.
For the same reason, this commit also adds a bit more to the existing
test case for the regression we just fixed.
The diff is best viewed with --color-moved.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-27 20:48:30 +00:00
|
|
|
echo "cp \"\$1\" .git/copy.txt" | write_script copy-editor.sh &&
|
|
|
|
(test_set_editor "$PWD/copy-editor.sh" && git rebase --skip) &&
|
|
|
|
|
|
|
|
: the user should not have had to edit the commit message &&
|
|
|
|
test_path_is_missing .git/copy.txt &&
|
2018-04-27 20:48:16 +00:00
|
|
|
|
|
|
|
: now the comments in the commit message should have been cleaned up &&
|
2023-08-03 13:09:35 +00:00
|
|
|
test_commit_message HEAD -m wants-fixup &&
|
rebase --skip: clean up commit message after a failed fixup/squash
During a series of fixup/squash commands, the interactive rebase builds
up a commit message with comments. This will be presented to the user in
the editor if at least one of those commands was a `squash`.
In any case, the commit message will be cleaned up eventually, removing
all those intermediate comments, in the final step of such a
fixup/squash chain.
However, if the last fixup/squash command in such a chain fails with
merge conflicts, and if the user then decides to skip it (or resolve it
to a clean worktree and then continue the rebase), the current code
fails to clean up the commit message.
This commit fixes that behavior.
The fix is quite a bit more involved than meets the eye because it is
not only about the question whether we are `git rebase --skip`ing a
fixup or squash. It is also about removing the skipped fixup/squash's
commit message from the accumulated commit message. And it is also about
the question whether we should let the user edit the final commit
message or not ("Was there a squash in the chain *that was not
skipped*?").
For example, in this case we will want to fix the commit message, but
not open it in an editor:
pick <- succeeds
fixup <- succeeds
squash <- fails, will be skipped
This is where the newly-introduced `current-fixups` file comes in real
handy. A quick look and we can determine whether there was a non-skipped
squash. We only need to make sure to keep it up to date with respect to
skipped fixup/squash commands. As a bonus, we can even avoid committing
unnecessarily, e.g. when there was only one fixup, and it failed, and
was skipped.
To fix only the bug where the final commit message was not cleaned up
properly, but without fixing the rest, would have been more complicated
than fixing it all in one go, hence this commit lumps together more than
a single concern.
For the same reason, this commit also adds a bit more to the existing
test case for the regression we just fixed.
The diff is best viewed with --color-moved.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-27 20:48:30 +00:00
|
|
|
|
|
|
|
: now, let us ensure that "squash" is handled correctly &&
|
|
|
|
git reset --hard wants-fixup-3 &&
|
2023-08-03 13:09:35 +00:00
|
|
|
test_must_fail env FAKE_LINES="1 squash 2 squash 1 squash 3 squash 1" \
|
rebase --skip: clean up commit message after a failed fixup/squash
During a series of fixup/squash commands, the interactive rebase builds
up a commit message with comments. This will be presented to the user in
the editor if at least one of those commands was a `squash`.
In any case, the commit message will be cleaned up eventually, removing
all those intermediate comments, in the final step of such a
fixup/squash chain.
However, if the last fixup/squash command in such a chain fails with
merge conflicts, and if the user then decides to skip it (or resolve it
to a clean worktree and then continue the rebase), the current code
fails to clean up the commit message.
This commit fixes that behavior.
The fix is quite a bit more involved than meets the eye because it is
not only about the question whether we are `git rebase --skip`ing a
fixup or squash. It is also about removing the skipped fixup/squash's
commit message from the accumulated commit message. And it is also about
the question whether we should let the user edit the final commit
message or not ("Was there a squash in the chain *that was not
skipped*?").
For example, in this case we will want to fix the commit message, but
not open it in an editor:
pick <- succeeds
fixup <- succeeds
squash <- fails, will be skipped
This is where the newly-introduced `current-fixups` file comes in real
handy. A quick look and we can determine whether there was a non-skipped
squash. We only need to make sure to keep it up to date with respect to
skipped fixup/squash commands. As a bonus, we can even avoid committing
unnecessarily, e.g. when there was only one fixup, and it failed, and
was skipped.
To fix only the bug where the final commit message was not cleaned up
properly, but without fixing the rest, would have been more complicated
than fixing it all in one go, hence this commit lumps together more than
a single concern.
For the same reason, this commit also adds a bit more to the existing
test case for the regression we just fixed.
The diff is best viewed with --color-moved.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-27 20:48:30 +00:00
|
|
|
git rebase -i HEAD~4 &&
|
|
|
|
|
2023-08-03 13:09:35 +00:00
|
|
|
: the second squash failed, but there are two more in the chain &&
|
rebase --skip: clean up commit message after a failed fixup/squash
During a series of fixup/squash commands, the interactive rebase builds
up a commit message with comments. This will be presented to the user in
the editor if at least one of those commands was a `squash`.
In any case, the commit message will be cleaned up eventually, removing
all those intermediate comments, in the final step of such a
fixup/squash chain.
However, if the last fixup/squash command in such a chain fails with
merge conflicts, and if the user then decides to skip it (or resolve it
to a clean worktree and then continue the rebase), the current code
fails to clean up the commit message.
This commit fixes that behavior.
The fix is quite a bit more involved than meets the eye because it is
not only about the question whether we are `git rebase --skip`ing a
fixup or squash. It is also about removing the skipped fixup/squash's
commit message from the accumulated commit message. And it is also about
the question whether we should let the user edit the final commit
message or not ("Was there a squash in the chain *that was not
skipped*?").
For example, in this case we will want to fix the commit message, but
not open it in an editor:
pick <- succeeds
fixup <- succeeds
squash <- fails, will be skipped
This is where the newly-introduced `current-fixups` file comes in real
handy. A quick look and we can determine whether there was a non-skipped
squash. We only need to make sure to keep it up to date with respect to
skipped fixup/squash commands. As a bonus, we can even avoid committing
unnecessarily, e.g. when there was only one fixup, and it failed, and
was skipped.
To fix only the bug where the final commit message was not cleaned up
properly, but without fixing the rest, would have been more complicated
than fixing it all in one go, hence this commit lumps together more than
a single concern.
For the same reason, this commit also adds a bit more to the existing
test case for the regression we just fixed.
The diff is best viewed with --color-moved.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-27 20:48:30 +00:00
|
|
|
(test_set_editor "$PWD/copy-editor.sh" &&
|
|
|
|
test_must_fail git rebase --skip) &&
|
|
|
|
|
|
|
|
: not the final squash, no need to edit the commit message &&
|
|
|
|
test_path_is_missing .git/copy.txt &&
|
|
|
|
|
2023-08-03 13:09:35 +00:00
|
|
|
: The first and third squashes succeeded, therefore: &&
|
|
|
|
test_commit_message HEAD <<-\EOF &&
|
|
|
|
# This is a combination of 3 commits.
|
|
|
|
# This is the 1st commit message:
|
|
|
|
|
|
|
|
wants-fixup
|
|
|
|
|
|
|
|
# This is the commit message #2:
|
|
|
|
|
|
|
|
fixup 1
|
|
|
|
|
|
|
|
# This is the commit message #3:
|
|
|
|
|
|
|
|
fixup 2
|
|
|
|
EOF
|
rebase --skip: clean up commit message after a failed fixup/squash
During a series of fixup/squash commands, the interactive rebase builds
up a commit message with comments. This will be presented to the user in
the editor if at least one of those commands was a `squash`.
In any case, the commit message will be cleaned up eventually, removing
all those intermediate comments, in the final step of such a
fixup/squash chain.
However, if the last fixup/squash command in such a chain fails with
merge conflicts, and if the user then decides to skip it (or resolve it
to a clean worktree and then continue the rebase), the current code
fails to clean up the commit message.
This commit fixes that behavior.
The fix is quite a bit more involved than meets the eye because it is
not only about the question whether we are `git rebase --skip`ing a
fixup or squash. It is also about removing the skipped fixup/squash's
commit message from the accumulated commit message. And it is also about
the question whether we should let the user edit the final commit
message or not ("Was there a squash in the chain *that was not
skipped*?").
For example, in this case we will want to fix the commit message, but
not open it in an editor:
pick <- succeeds
fixup <- succeeds
squash <- fails, will be skipped
This is where the newly-introduced `current-fixups` file comes in real
handy. A quick look and we can determine whether there was a non-skipped
squash. We only need to make sure to keep it up to date with respect to
skipped fixup/squash commands. As a bonus, we can even avoid committing
unnecessarily, e.g. when there was only one fixup, and it failed, and
was skipped.
To fix only the bug where the final commit message was not cleaned up
properly, but without fixing the rest, would have been more complicated
than fixing it all in one go, hence this commit lumps together more than
a single concern.
For the same reason, this commit also adds a bit more to the existing
test case for the regression we just fixed.
The diff is best viewed with --color-moved.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-27 20:48:30 +00:00
|
|
|
|
|
|
|
(test_set_editor "$PWD/copy-editor.sh" && git rebase --skip) &&
|
2023-08-03 13:09:35 +00:00
|
|
|
test_commit_message HEAD <<-\EOF &&
|
|
|
|
wants-fixup
|
|
|
|
|
|
|
|
fixup 1
|
|
|
|
|
|
|
|
fixup 2
|
|
|
|
EOF
|
rebase --skip: clean up commit message after a failed fixup/squash
During a series of fixup/squash commands, the interactive rebase builds
up a commit message with comments. This will be presented to the user in
the editor if at least one of those commands was a `squash`.
In any case, the commit message will be cleaned up eventually, removing
all those intermediate comments, in the final step of such a
fixup/squash chain.
However, if the last fixup/squash command in such a chain fails with
merge conflicts, and if the user then decides to skip it (or resolve it
to a clean worktree and then continue the rebase), the current code
fails to clean up the commit message.
This commit fixes that behavior.
The fix is quite a bit more involved than meets the eye because it is
not only about the question whether we are `git rebase --skip`ing a
fixup or squash. It is also about removing the skipped fixup/squash's
commit message from the accumulated commit message. And it is also about
the question whether we should let the user edit the final commit
message or not ("Was there a squash in the chain *that was not
skipped*?").
For example, in this case we will want to fix the commit message, but
not open it in an editor:
pick <- succeeds
fixup <- succeeds
squash <- fails, will be skipped
This is where the newly-introduced `current-fixups` file comes in real
handy. A quick look and we can determine whether there was a non-skipped
squash. We only need to make sure to keep it up to date with respect to
skipped fixup/squash commands. As a bonus, we can even avoid committing
unnecessarily, e.g. when there was only one fixup, and it failed, and
was skipped.
To fix only the bug where the final commit message was not cleaned up
properly, but without fixing the rest, would have been more complicated
than fixing it all in one go, hence this commit lumps together more than
a single concern.
For the same reason, this commit also adds a bit more to the existing
test case for the regression we just fixed.
The diff is best viewed with --color-moved.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-27 20:48:30 +00:00
|
|
|
|
|
|
|
: Final squash failed, but there was still a squash &&
|
2023-08-03 13:09:35 +00:00
|
|
|
head -n1 .git/copy.txt >first-line &&
|
2023-10-31 05:23:30 +00:00
|
|
|
test_grep "# This is a combination of 3 commits" first-line &&
|
|
|
|
test_grep "# This is the commit message #3:" .git/copy.txt
|
2018-04-27 20:48:16 +00:00
|
|
|
'
|
2011-02-06 18:43:55 +00:00
|
|
|
|
2017-08-02 10:44:16 +00:00
|
|
|
test_expect_success 'setup rerere database' '
|
2011-02-06 18:43:56 +00:00
|
|
|
rm -fr .git/rebase-* &&
|
|
|
|
git reset --hard commit-new-file-F3-on-topic-branch &&
|
2020-11-18 23:44:25 +00:00
|
|
|
git checkout main &&
|
2011-02-06 18:43:56 +00:00
|
|
|
test_commit "commit-new-file-F3" F3 3 &&
|
2017-08-02 10:44:16 +00:00
|
|
|
test_config rerere.enabled true &&
|
2018-10-31 20:02:00 +00:00
|
|
|
git update-ref refs/heads/topic commit-new-file-F3-on-topic-branch &&
|
2020-11-18 23:44:25 +00:00
|
|
|
test_must_fail git rebase -m main topic &&
|
2011-02-06 18:43:56 +00:00
|
|
|
echo "Resolved" >F2 &&
|
2017-08-02 10:44:16 +00:00
|
|
|
cp F2 expected-F2 &&
|
2011-02-06 18:43:56 +00:00
|
|
|
git add F2 &&
|
|
|
|
test_must_fail git rebase --continue &&
|
|
|
|
echo "Resolved" >F3 &&
|
2017-08-02 10:44:16 +00:00
|
|
|
cp F3 expected-F3 &&
|
2011-02-06 18:43:56 +00:00
|
|
|
git add F3 &&
|
|
|
|
git rebase --continue &&
|
2017-08-02 10:44:16 +00:00
|
|
|
git reset --hard topic@{1}
|
2011-02-06 18:43:56 +00:00
|
|
|
'
|
|
|
|
|
2017-08-02 10:44:16 +00:00
|
|
|
prepare () {
|
|
|
|
rm -fr .git/rebase-* &&
|
|
|
|
git reset --hard commit-new-file-F3-on-topic-branch &&
|
2020-11-18 23:44:25 +00:00
|
|
|
git checkout main &&
|
2017-08-02 10:44:16 +00:00
|
|
|
test_config rerere.enabled true
|
|
|
|
}
|
|
|
|
|
|
|
|
test_rerere_autoupdate () {
|
|
|
|
action=$1 &&
|
|
|
|
test_expect_success "rebase $action --continue remembers --rerere-autoupdate" '
|
|
|
|
prepare &&
|
2020-11-18 23:44:25 +00:00
|
|
|
test_must_fail git rebase $action --rerere-autoupdate main topic &&
|
2017-08-02 10:44:16 +00:00
|
|
|
test_cmp expected-F2 F2 &&
|
|
|
|
git diff-files --quiet &&
|
|
|
|
test_must_fail git rebase --continue &&
|
|
|
|
test_cmp expected-F3 F3 &&
|
|
|
|
git diff-files --quiet &&
|
|
|
|
git rebase --continue
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "rebase $action --continue honors rerere.autoUpdate" '
|
|
|
|
prepare &&
|
|
|
|
test_config rerere.autoupdate true &&
|
2020-11-18 23:44:25 +00:00
|
|
|
test_must_fail git rebase $action main topic &&
|
2017-08-02 10:44:16 +00:00
|
|
|
test_cmp expected-F2 F2 &&
|
|
|
|
git diff-files --quiet &&
|
|
|
|
test_must_fail git rebase --continue &&
|
|
|
|
test_cmp expected-F3 F3 &&
|
|
|
|
git diff-files --quiet &&
|
|
|
|
git rebase --continue
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "rebase $action --continue remembers --no-rerere-autoupdate" '
|
|
|
|
prepare &&
|
|
|
|
test_config rerere.autoupdate true &&
|
2020-11-18 23:44:25 +00:00
|
|
|
test_must_fail git rebase $action --no-rerere-autoupdate main topic &&
|
2017-08-02 10:44:16 +00:00
|
|
|
test_cmp expected-F2 F2 &&
|
|
|
|
test_must_fail git diff-files --quiet &&
|
|
|
|
git add F2 &&
|
|
|
|
test_must_fail git rebase --continue &&
|
|
|
|
test_cmp expected-F3 F3 &&
|
|
|
|
test_must_fail git diff-files --quiet &&
|
|
|
|
git add F3 &&
|
|
|
|
git rebase --continue
|
|
|
|
'
|
|
|
|
}
|
|
|
|
|
2021-08-12 13:42:08 +00:00
|
|
|
test_rerere_autoupdate --apply
|
2017-08-02 10:44:16 +00:00
|
|
|
test_rerere_autoupdate -m
|
2017-08-02 10:44:17 +00:00
|
|
|
GIT_SEQUENCE_EDITOR=: && export GIT_SEQUENCE_EDITOR
|
|
|
|
test_rerere_autoupdate -i
|
2018-10-12 13:14:26 +00:00
|
|
|
unset GIT_SEQUENCE_EDITOR
|
|
|
|
|
|
|
|
test_expect_success 'the todo command "break" works' '
|
|
|
|
rm -f execed &&
|
2018-10-25 20:47:45 +00:00
|
|
|
FAKE_LINES="break b exec_>execed" git rebase -i HEAD &&
|
|
|
|
test_path_is_missing execed &&
|
|
|
|
git rebase --continue &&
|
2018-10-12 13:14:26 +00:00
|
|
|
test_path_is_missing execed &&
|
|
|
|
git rebase --continue &&
|
|
|
|
test_path_is_file execed
|
|
|
|
'
|
2017-08-02 10:44:16 +00:00
|
|
|
|
2023-09-06 15:22:46 +00:00
|
|
|
test_expect_success 'patch file is removed before break command' '
|
|
|
|
test_when_finished "git rebase --abort" &&
|
|
|
|
cat >todo <<-\EOF &&
|
|
|
|
pick commit-new-file-F2-on-topic-branch
|
|
|
|
break
|
|
|
|
EOF
|
|
|
|
|
|
|
|
(
|
|
|
|
set_replace_editor todo &&
|
|
|
|
test_must_fail git rebase -i --onto commit-new-file-F2 HEAD
|
|
|
|
) &&
|
|
|
|
test_path_is_file .git/rebase-merge/patch &&
|
|
|
|
echo 22>F2 &&
|
|
|
|
git add F2 &&
|
|
|
|
git rebase --continue &&
|
|
|
|
test_path_is_missing .git/rebase-merge/patch
|
|
|
|
'
|
|
|
|
|
2018-12-10 19:04:58 +00:00
|
|
|
test_expect_success '--reschedule-failed-exec' '
|
|
|
|
test_when_finished "git rebase --abort" &&
|
|
|
|
test_must_fail git rebase -x false --reschedule-failed-exec HEAD^ &&
|
2018-12-10 19:04:59 +00:00
|
|
|
grep "^exec false" .git/rebase-merge/git-rebase-todo &&
|
|
|
|
git rebase --abort &&
|
|
|
|
test_must_fail git -c rebase.rescheduleFailedExec=true \
|
|
|
|
rebase -x false HEAD^ 2>err &&
|
|
|
|
grep "^exec false" .git/rebase-merge/git-rebase-todo &&
|
2023-10-31 05:23:30 +00:00
|
|
|
test_grep "has been rescheduled" err
|
2018-12-10 19:04:58 +00:00
|
|
|
'
|
|
|
|
|
2021-04-09 08:01:37 +00:00
|
|
|
test_expect_success 'rebase.rescheduleFailedExec only affects `rebase -i`' '
|
|
|
|
test_config rebase.rescheduleFailedExec true &&
|
2019-07-01 11:58:15 +00:00
|
|
|
test_must_fail git rebase -x false HEAD^ &&
|
|
|
|
grep "^exec false" .git/rebase-merge/git-rebase-todo &&
|
|
|
|
git rebase --abort &&
|
|
|
|
git rebase HEAD^
|
|
|
|
'
|
|
|
|
|
2021-04-09 08:01:38 +00:00
|
|
|
test_expect_success 'rebase.rescheduleFailedExec=true & --no-reschedule-failed-exec' '
|
|
|
|
test_when_finished "git rebase --abort" &&
|
|
|
|
test_config rebase.rescheduleFailedExec true &&
|
|
|
|
test_must_fail git rebase -x false --no-reschedule-failed-exec HEAD~2 &&
|
|
|
|
test_must_fail git rebase --continue 2>err &&
|
|
|
|
! grep "has been rescheduled" err
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'new rebase.rescheduleFailedExec=true setting in an ongoing rebase is ignored' '
|
|
|
|
test_when_finished "git rebase --abort" &&
|
|
|
|
test_must_fail git rebase -x false HEAD~2 &&
|
|
|
|
test_config rebase.rescheduleFailedExec true &&
|
|
|
|
test_must_fail git rebase --continue 2>err &&
|
|
|
|
! grep "has been rescheduled" err
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'there is no --no-reschedule-failed-exec in an ongoing rebase' '
|
|
|
|
test_when_finished "git rebase --abort" &&
|
|
|
|
test_must_fail git rebase -x false HEAD~2 &&
|
|
|
|
test_expect_code 129 git rebase --continue --no-reschedule-failed-exec &&
|
|
|
|
test_expect_code 129 git rebase --edit-todo --no-reschedule-failed-exec
|
|
|
|
'
|
|
|
|
|
2022-01-26 13:05:48 +00:00
|
|
|
test_orig_head_helper () {
|
|
|
|
test_when_finished 'git rebase --abort &&
|
|
|
|
git checkout topic &&
|
|
|
|
git reset --hard commit-new-file-F2-on-topic-branch' &&
|
|
|
|
git update-ref -d ORIG_HEAD &&
|
|
|
|
test_must_fail git rebase "$@" &&
|
|
|
|
test_cmp_rev ORIG_HEAD commit-new-file-F2-on-topic-branch
|
|
|
|
}
|
|
|
|
|
|
|
|
test_orig_head () {
|
|
|
|
type=$1
|
|
|
|
test_expect_success "rebase $type sets ORIG_HEAD correctly" '
|
|
|
|
git checkout topic &&
|
|
|
|
git reset --hard commit-new-file-F2-on-topic-branch &&
|
|
|
|
test_orig_head_helper $type main
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success "rebase $type <upstream> <branch> sets ORIG_HEAD correctly" '
|
|
|
|
git checkout main &&
|
|
|
|
test_orig_head_helper $type main topic
|
|
|
|
'
|
|
|
|
}
|
|
|
|
|
|
|
|
test_orig_head --apply
|
|
|
|
test_orig_head --merge
|
|
|
|
|
2010-07-28 08:20:16 +00:00
|
|
|
test_done
|