2007-07-29 08:57:25 +08:00
|
|
|
#!/bin/sh
|
|
|
|
|
2012-06-26 22:51:56 +08:00
|
|
|
test_description='rebase should handle arbitrary git message'
|
2007-07-29 08:57:25 +08:00
|
|
|
|
2020-11-19 07:44:25 +08: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-19 07:44:19 +08:00
|
|
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
|
|
|
|
2007-07-29 08:57:25 +08:00
|
|
|
. ./test-lib.sh
|
2018-02-05 04:08:13 +08:00
|
|
|
. "$TEST_DIRECTORY"/lib-rebase.sh
|
2007-07-29 08:57:25 +08:00
|
|
|
|
|
|
|
cat >F <<\EOF
|
|
|
|
This is an example of a commit log message
|
|
|
|
that does not conform to git commit convention.
|
|
|
|
|
|
|
|
It has two paragraphs, but its first paragraph is not friendly
|
|
|
|
to oneline summary format.
|
|
|
|
EOF
|
|
|
|
|
2012-06-26 22:51:56 +08:00
|
|
|
cat >G <<\EOF
|
|
|
|
commit log message containing a diff
|
|
|
|
EOF
|
|
|
|
|
|
|
|
|
2007-07-29 08:57:25 +08:00
|
|
|
test_expect_success setup '
|
|
|
|
|
|
|
|
>file1 &&
|
|
|
|
>file2 &&
|
|
|
|
git add file1 file2 &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m "Initial commit" &&
|
2015-03-20 18:07:15 +08:00
|
|
|
git branch diff-in-message &&
|
2018-02-05 04:08:13 +08:00
|
|
|
git branch empty-message-merge &&
|
2007-07-29 08:57:25 +08:00
|
|
|
|
2012-06-26 22:51:56 +08:00
|
|
|
git checkout -b multi-line-subject &&
|
2007-07-29 08:57:25 +08:00
|
|
|
cat F >file2 &&
|
|
|
|
git add file2 &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -F F &&
|
|
|
|
|
|
|
|
git cat-file commit HEAD | sed -e "1,/^\$/d" >F0 &&
|
|
|
|
|
2012-06-26 22:51:56 +08:00
|
|
|
git checkout diff-in-message &&
|
|
|
|
echo "commit log message containing a diff" >G &&
|
2015-03-20 18:07:15 +08:00
|
|
|
echo "" >>G &&
|
2012-06-26 22:51:56 +08:00
|
|
|
cat G >file2 &&
|
|
|
|
git add file2 &&
|
|
|
|
git diff --cached >>G &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -F G &&
|
|
|
|
|
|
|
|
git cat-file commit HEAD | sed -e "1,/^\$/d" >G0 &&
|
|
|
|
|
2018-02-05 04:08:13 +08:00
|
|
|
git checkout empty-message-merge &&
|
|
|
|
echo file3 >file3 &&
|
|
|
|
git add file3 &&
|
|
|
|
git commit --allow-empty-message -m "" &&
|
|
|
|
|
2020-11-19 07:44:25 +08:00
|
|
|
git checkout main &&
|
2007-07-29 08:57:25 +08:00
|
|
|
|
|
|
|
echo One >file1 &&
|
|
|
|
test_tick &&
|
|
|
|
git add file1 &&
|
|
|
|
git commit -m "Second commit"
|
|
|
|
'
|
|
|
|
|
2012-06-26 22:51:56 +08:00
|
|
|
test_expect_success 'rebase commit with multi-line subject' '
|
2007-07-29 08:57:25 +08:00
|
|
|
|
2020-11-19 07:44:25 +08:00
|
|
|
git rebase main multi-line-subject &&
|
2007-07-29 08:57:25 +08:00
|
|
|
git cat-file commit HEAD | sed -e "1,/^\$/d" >F1 &&
|
|
|
|
|
2008-03-13 05:36:36 +08:00
|
|
|
test_cmp F0 F1 &&
|
|
|
|
test_cmp F F0
|
2007-07-29 08:57:25 +08:00
|
|
|
'
|
|
|
|
|
2012-06-26 22:51:56 +08:00
|
|
|
test_expect_success 'rebase commit with diff in message' '
|
2020-11-19 07:44:25 +08:00
|
|
|
git rebase main diff-in-message &&
|
2012-06-26 22:51:56 +08:00
|
|
|
git cat-file commit HEAD | sed -e "1,/^$/d" >G1 &&
|
|
|
|
test_cmp G0 G1 &&
|
|
|
|
test_cmp G G0
|
|
|
|
'
|
|
|
|
|
2018-02-05 04:08:13 +08:00
|
|
|
test_expect_success 'rebase -m commit with empty message' '
|
2020-11-19 07:44:25 +08:00
|
|
|
git rebase -m main empty-message-merge
|
2018-02-05 04:08:13 +08:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'rebase -i commit with empty message' '
|
|
|
|
git checkout diff-in-message &&
|
|
|
|
set_fake_editor &&
|
sequencer: fix --allow-empty-message behavior, make it smarter
In commit b00bf1c9a8dd ("git-rebase: make --allow-empty-message the
default", 2018-06-27), several arguments were given for transplanting
empty commits without halting and asking the user for confirmation on
each commit. These arguments were incomplete because the logic clearly
assumed the only cases under consideration were transplanting of commits
with empty messages (see the comment about "There are two sources for
commits with empty messages). It didn't discuss or even consider
rewords, squashes, etc. where the user is explicitly asked for a new
commit message and provides an empty one. (My bad, I totally should
have thought about that at the time, but just didn't.)
Rewords and squashes are significantly different, though, as described
by SZEDER:
Let's suppose you start an interactive rebase, choose a commit to
squash, save the instruction sheet, rebase fires up your editor, and
then you notice that you mistakenly chose the wrong commit to
squash. What do you do, how do you abort?
Before [that commit] you could clear the commit message, exit the
editor, and then rebase would say "Aborting commit due to empty
commit message.", and you get to run 'git rebase --abort', and start
over.
But [since that commit, ...] saving the commit message as is would
let rebase continue and create a bunch of unnecessary objects, and
then you would have to use the reflog to return to the pre-rebase
state.
Also, he states:
The instructions in the commit message template, which is shown for
'reword' and 'squash', too, still say...
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
These are sound arguments that when editing commit messages during a
sequencer operation, that if the commit message is empty then the
operation should halt and ask the user to correct. The arguments in
commit b00bf1c9a8dd (referenced above) still apply when transplanting
previously created commits with empty commit messages, so the sequencer
should not halt for those.
Furthermore, all rationale so far applies equally for cherry-pick as for
rebase. Therefore, make the code default to --allow-empty-message when
transplanting an existing commit, and to default to halting when the
user is asked to edit a commit message and provides an empty one -- for
both rebase and cherry-pick.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-13 05:18:48 +08:00
|
|
|
test_must_fail env FAKE_COMMIT_MESSAGE=" " FAKE_LINES="reword 1" \
|
git-rebase: make --allow-empty-message the default
rebase backends currently behave differently with empty commit messages,
largely as a side-effect of the different underlying commands on which
they are based. am-based rebases apply commits with an empty commit
message without stopping or requiring the user to specify an extra flag.
(It is interesting to note that am-based rebases are the default rebase
type, and no one has ever requested a --no-allow-empty-message flag to
change this behavior.) merge-based and interactive-based rebases (which
are ultimately based on git-commit), will currently halt on any such
commits and require the user to manually specify what to do with the
commit and continue.
One possible rationale for the difference in behavior is that the purpose
of an "am" based rebase is solely to transplant an existing history, while
an "interactive" rebase is one whose purpose is to polish a series before
making it publishable. Thus, stopping and asking for confirmation for a
possible problem is more appropriate in the latter case. However, there
are two problems with this rationale:
1) merge-based rebases are also non-interactive and there are multiple
types of rebases that use the interactive machinery but are not
explicitly interactive (e.g. when either --rebase-merges or
--keep-empty are specified without --interactive). These rebases are
also used solely to transplant an existing history, and thus also
should default to --allow-empty-message.
2) this rationale only says that the user is more accepting of stopping
in the case of an explicitly interactive rebase, not that stopping
for this particular reason actually makes sense. Exploring whether
it makes sense, requires backing up and analyzing the underlying
commands...
If git-commit did not error out on empty commits by default, accidental
creation of commits with empty messages would be a very common occurrence
(this check has caught me many times). Further, nearly all such empty
commit messages would be considered an accidental error (as evidenced by a
huge amount of documentation across version control systems and in various
blog posts explaining how important commit messages are). A simple check
for what would otherwise be a common error thus made a lot of sense, and
git-commit gained an --allow-empty-message flag for special case
overrides. This has made commits with empty messages very rare.
There are two sources for commits with empty messages for rebase (and
cherry-pick): (a) commits created in git where the user previously
specified --allow-empty-message to git-commit, and (b) commits imported
into git from other version control systems. In case (a), the user has
already explicitly specified that there is something special about this
commit that makes them not want to specify a commit message; forcing them
to re-specify with every cherry-pick or rebase seems more likely to be
infuriating than helpful. In case (b), the commit is highly unlikely to
have been authored by the person who has imported the history and is doing
the rebase or cherry-pick, and thus the user is unlikely to be the
appropriate person to write a commit message for it. Stopping and
expecting the user to modify the commit before proceeding thus seems
counter-productive.
Further, note that while empty commit messages was a common error case for
git-commit to deal with, it is a rare case for rebase (or cherry-pick).
The fact that it is rare raises the question of why it would be worth
checking and stopping on this particular condition and not others. For
example, why doesn't an interactive rebase automatically stop if the
commit message's first line is 2000 columns long, or is missing a blank
line after the first line, or has every line indented with five spaces, or
any number of other myriad problems?
Finally, note that if a user doing an interactive rebase does have the
necessary knowledge to add a message for any such commit and wants to do
so, it is rather simple for them to change the appropriate line from
'pick' to 'reword'. The fact that the subject is empty in the todo list
that the user edits should even serve as a way to notify them.
As far as I can tell, the fact that merge-based and interactive-based
rebases stop on commits with empty commit messages is solely a by-product
of having been based on git-commit. It went without notice for a long
time precisely because such cases are rare. The rareness of this
situation made it difficult to reason about, so when folks did eventually
notice this behavior, they assumed it was there for a good reason and just
added an --allow-empty-message flag. In my opinion, stopping on such
messages not desirable in any of these cases, even the (explicitly)
interactive case.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-06-27 15:23:19 +08:00
|
|
|
git rebase -i HEAD^
|
2018-02-05 04:08:13 +08:00
|
|
|
'
|
|
|
|
|
2007-07-29 08:57:25 +08:00
|
|
|
test_done
|