2006-06-26 22:40:09 +00:00
#!/bin/sh
#
# Copyright (c) 2006 Junio C Hamano
#
2009-01-12 23:18:02 +00:00
test_description = 'various format-patch tests'
2006-06-26 22:40:09 +00:00
2020-11-18 23:44:27 +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
2006-06-26 22:40:09 +00:00
. ./test-lib.sh
2010-11-23 03:16:30 +00:00
. " $TEST_DIRECTORY " /lib-terminal.sh
2006-06-26 22:40:09 +00:00
test_expect_success setup '
2021-12-09 05:11:05 +00:00
test_write_lines 1 2 3 4 5 6 7 8 9 10 >file &&
2007-09-18 22:19:47 +00:00
cat file >elif &&
git add file elif &&
2010-08-27 20:28:15 +00:00
test_tick &&
2006-06-26 22:40:09 +00:00
git commit -m Initial &&
git checkout -b side &&
2021-12-09 05:11:05 +00:00
test_write_lines 1 2 5 6 A B C 7 8 9 10 >file &&
2009-02-28 20:12:57 +00:00
test_chmod +x elif &&
2010-08-27 20:28:15 +00:00
test_tick &&
2007-05-26 07:26:20 +00:00
git commit -m "Side changes #1" &&
2006-06-26 22:40:09 +00:00
2021-12-09 05:11:05 +00:00
test_write_lines D E F >>file &&
2006-06-26 22:40:09 +00:00
git update-index file &&
2010-08-27 20:28:15 +00:00
test_tick &&
2007-05-26 07:26:20 +00:00
git commit -m "Side changes #2" &&
2006-06-29 05:48:34 +00:00
git tag C2 &&
2006-06-26 22:40:09 +00:00
2021-12-09 05:11:05 +00:00
test_write_lines 5 6 1 2 3 A 4 B C 7 8 9 10 D E F >file &&
2006-06-26 22:40:09 +00:00
git update-index file &&
2010-08-27 20:28:15 +00:00
test_tick &&
2007-05-26 07:26:20 +00:00
git commit -m "Side changes #3 with \\n backslash-n in it." &&
2006-06-26 22:40:09 +00:00
2020-11-18 23:44:27 +00:00
git checkout main &&
2019-08-27 04:05:15 +00:00
git diff-tree -p C2 >patch &&
git apply --index <patch &&
2010-08-27 20:28:15 +00:00
test_tick &&
2020-11-18 23:44:27 +00:00
git commit -m "Main accepts moral equivalent of #2" &&
2006-06-26 22:40:09 +00:00
2019-04-26 23:51:56 +00:00
git checkout side &&
git checkout -b patchid &&
2021-12-09 05:11:05 +00:00
test_write_lines 5 6 1 2 3 A 4 B C 7 8 9 10 D E F >file2 &&
test_write_lines 1 2 3 A 4 B C 7 8 9 10 D E F 5 6 >file3 &&
test_write_lines 8 9 10 >file &&
2019-04-26 23:51:56 +00:00
git add file file2 file3 &&
test_tick &&
git commit -m "patchid 1" &&
2021-12-09 05:11:05 +00:00
test_write_lines 4 A B 7 8 9 10 >file2 &&
test_write_lines 8 9 10 5 6 >file3 &&
2019-04-26 23:51:56 +00:00
git add file2 file3 &&
test_tick &&
git commit -m "patchid 2" &&
2021-12-09 05:11:05 +00:00
test_write_lines 10 5 6 >file &&
2019-04-26 23:51:56 +00:00
git add file &&
test_tick &&
git commit -m "patchid 3" &&
2023-03-03 16:03:01 +00:00
git checkout -b empty main &&
test_tick &&
git commit --allow-empty -m "empty commit" &&
2020-11-18 23:44:27 +00:00
git checkout main
2006-06-26 22:40:09 +00:00
'
2019-08-27 04:04:58 +00:00
test_expect_success 'format-patch --ignore-if-in-upstream' '
2020-11-18 23:44:27 +00:00
git format-patch --stdout main..side >patch0 &&
2019-08-27 04:05:10 +00:00
grep "^From " patch0 >from0 &&
test_line_count = 3 from0
2006-06-26 22:40:09 +00:00
'
2019-08-27 04:04:58 +00:00
test_expect_success 'format-patch --ignore-if-in-upstream' '
2006-06-26 22:40:09 +00:00
git format-patch --stdout \
2020-11-18 23:44:27 +00:00
--ignore-if-in-upstream main..side >patch1 &&
2019-08-27 04:05:10 +00:00
grep "^From " patch1 >from1 &&
test_line_count = 2 from1
2006-06-26 22:40:09 +00:00
'
2019-08-27 04:04:58 +00:00
test_expect_success 'format-patch --ignore-if-in-upstream handles tags' '
2015-06-01 17:44:21 +00:00
git tag -a v1 -m tag side &&
2020-11-18 23:44:27 +00:00
git tag -a v2 -m tag main &&
2015-06-01 17:44:21 +00:00
git format-patch --stdout --ignore-if-in-upstream v2..v1 >patch1 &&
2019-08-27 04:05:10 +00:00
grep "^From " patch1 >from1 &&
test_line_count = 2 from1
2015-06-01 17:44:21 +00:00
'
2010-08-27 20:28:16 +00:00
test_expect_success "format-patch doesn't consider merge commits" '
2020-11-18 23:44:27 +00:00
git checkout -b feature main &&
2010-08-27 20:28:16 +00:00
echo "Another line" >>file &&
test_tick &&
2020-06-19 09:32:10 +00:00
git commit -am "Feature branch change #1" &&
2010-08-27 20:28:16 +00:00
echo "Yet another line" >>file &&
test_tick &&
2020-06-19 09:32:10 +00:00
git commit -am "Feature branch change #2" &&
2020-11-18 23:44:27 +00:00
git checkout -b merger main &&
2010-08-27 20:28:16 +00:00
test_tick &&
2020-06-19 09:32:10 +00:00
git merge --no-ff feature &&
2019-08-27 04:05:10 +00:00
git format-patch -3 --stdout >patch &&
grep "^From " patch >from &&
test_line_count = 3 from
2010-08-27 20:28:16 +00:00
'
2019-08-27 04:04:58 +00:00
test_expect_success 'format-patch result applies' '
2020-11-18 23:44:27 +00:00
git checkout -b rebuild-0 main &&
2006-06-26 22:40:09 +00:00
git am -3 patch0 &&
2020-11-18 23:44:27 +00:00
git rev-list main.. >list &&
2019-08-27 04:05:10 +00:00
test_line_count = 2 list
2006-06-26 22:40:09 +00:00
'
2019-08-27 04:04:58 +00:00
test_expect_success 'format-patch --ignore-if-in-upstream result applies' '
2020-11-18 23:44:27 +00:00
git checkout -b rebuild-1 main &&
2006-06-26 22:40:09 +00:00
git am -3 patch1 &&
2020-11-18 23:44:27 +00:00
git rev-list main.. >list &&
2019-08-27 04:05:10 +00:00
test_line_count = 2 list
2006-06-26 22:40:09 +00:00
'
2007-05-26 07:26:20 +00:00
test_expect_success 'commit did not screw up the log message' '
2019-08-27 04:05:15 +00:00
git cat-file commit side >actual &&
grep "^Side .* with .* backslash-n" actual
2007-05-26 07:26:20 +00:00
'
test_expect_success 'format-patch did not screw up the log message' '
grep "^Subject: .*Side changes #3 with .* backslash-n" patch0 &&
grep "^Subject: .*Side changes #3 with .* backslash-n" patch1
'
test_expect_success 'replay did not screw up the log message' '
2019-08-27 04:05:15 +00:00
git cat-file commit rebuild-1 >actual &&
grep "^Side .* with .* backslash-n" actual
2007-05-26 07:26:20 +00:00
'
2023-03-03 16:03:01 +00:00
test_expect_success 'format-patch empty commit' '
git format-patch --stdout main..empty >empty &&
grep "^From " empty >from &&
test_line_count = 1 from
'
2008-02-19 07:40:28 +00:00
test_expect_success 'extra headers' '
2012-10-18 14:43:34 +00:00
git config format.headers " To: R E Cipient <rcipient@example.com>
2008-02-19 07:40:28 +00:00
" &&
2012-10-18 14:43:34 +00:00
git config --add format.headers " Cc: S E Cipient <scipient@example.com>
2008-02-19 07:40:28 +00:00
" &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout main..side >patch2 &&
2019-08-27 04:05:00 +00:00
sed -e "/^\$/q" patch2 >hdrs2 &&
2012-10-18 14:43:34 +00:00
grep "^To: R E Cipient <rcipient@example.com>\$" hdrs2 &&
grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs2
2008-02-19 07:40:28 +00:00
'
2008-02-19 07:40:31 +00:00
test_expect_success 'extra headers without newlines' '
2012-10-18 14:43:34 +00:00
git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
git config --add format.headers "Cc: S E Cipient <scipient@example.com>" &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout main..side >patch3 &&
2019-08-27 04:05:00 +00:00
sed -e "/^\$/q" patch3 >hdrs3 &&
2012-10-18 14:43:34 +00:00
grep "^To: R E Cipient <rcipient@example.com>\$" hdrs3 &&
grep "^Cc: S E Cipient <scipient@example.com>\$" hdrs3
2008-02-19 07:40:28 +00:00
'
2008-02-19 07:40:33 +00:00
test_expect_success 'extra headers with multiple To:s' '
2012-10-18 14:43:34 +00:00
git config --replace-all format.headers "To: R E Cipient <rcipient@example.com>" &&
git config --add format.headers "To: S E Cipient <scipient@example.com>" &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout main..side >patch4 &&
2019-08-27 04:05:00 +00:00
sed -e "/^\$/q" patch4 >hdrs4 &&
2012-10-18 14:43:34 +00:00
grep "^To: R E Cipient <rcipient@example.com>,\$" hdrs4 &&
grep "^ *S E Cipient <scipient@example.com>\$" hdrs4
2008-02-19 07:40:28 +00:00
'
2012-10-18 14:43:34 +00:00
test_expect_success 'additional command line cc (ascii)' '
git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
2020-11-18 23:44:27 +00:00
git format-patch --cc= "S E Cipient <scipient@example.com>" --stdout main..side >patch5 &&
2019-08-27 04:05:15 +00:00
sed -e "/^\$/q" patch5 >hdrs5 &&
grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs5 &&
grep "^ *S E Cipient <scipient@example.com>\$" hdrs5
2012-10-18 14:43:34 +00:00
'
test_expect_failure 'additional command line cc (rfc822)' '
git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
2020-11-18 23:44:27 +00:00
git format-patch --cc= "S. E. Cipient <scipient@example.com>" --stdout main..side >patch5 &&
2019-08-27 04:05:15 +00:00
sed -e "/^\$/q" patch5 >hdrs5 &&
grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs5 &&
grep "^ *\"S. E. Cipient\" <scipient@example.com>\$" hdrs5
2008-02-19 07:40:35 +00:00
'
2009-03-26 16:51:05 +00:00
test_expect_success 'command line headers' '
git config --unset-all format.headers &&
2020-11-18 23:44:27 +00:00
git format-patch --add-header= "Cc: R E Cipient <rcipient@example.com>" --stdout main..side >patch6 &&
2019-08-27 04:05:15 +00:00
sed -e "/^\$/q" patch6 >hdrs6 &&
grep "^Cc: R E Cipient <rcipient@example.com>\$" hdrs6
2009-03-26 16:51:05 +00:00
'
test_expect_success 'configuration headers and command line headers' '
2012-10-18 14:43:34 +00:00
git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
2020-11-18 23:44:27 +00:00
git format-patch --add-header= "Cc: S E Cipient <scipient@example.com>" --stdout main..side >patch7 &&
2019-08-27 04:05:15 +00:00
sed -e "/^\$/q" patch7 >hdrs7 &&
grep "^Cc: R E Cipient <rcipient@example.com>,\$" hdrs7 &&
grep "^ *S E Cipient <scipient@example.com>\$" hdrs7
2009-03-26 16:51:05 +00:00
'
2012-10-18 14:43:34 +00:00
test_expect_success 'command line To: header (ascii)' '
2010-02-16 23:39:34 +00:00
git config --unset-all format.headers &&
2020-11-18 23:44:27 +00:00
git format-patch --to= "R E Cipient <rcipient@example.com>" --stdout main..side >patch8 &&
2019-08-27 04:05:15 +00:00
sed -e "/^\$/q" patch8 >hdrs8 &&
grep "^To: R E Cipient <rcipient@example.com>\$" hdrs8
2012-10-18 14:43:34 +00:00
'
test_expect_failure 'command line To: header (rfc822)' '
2020-11-18 23:44:27 +00:00
git format-patch --to= "R. E. Cipient <rcipient@example.com>" --stdout main..side >patch8 &&
2019-08-27 04:05:15 +00:00
sed -e "/^\$/q" patch8 >hdrs8 &&
grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" hdrs8
2012-10-18 14:43:34 +00:00
'
test_expect_failure 'command line To: header (rfc2047)' '
2020-11-18 23:44:27 +00:00
git format-patch --to= "R Ä Cipient <rcipient@example.com>" --stdout main..side >patch8 &&
2019-08-27 04:05:15 +00:00
sed -e "/^\$/q" patch8 >hdrs8 &&
grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" hdrs8
2010-02-16 23:39:34 +00:00
'
2012-10-18 14:43:34 +00:00
test_expect_success 'configuration To: header (ascii)' '
git config format.to "R E Cipient <rcipient@example.com>" &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout main..side >patch9 &&
2019-08-27 04:05:15 +00:00
sed -e "/^\$/q" patch9 >hdrs9 &&
grep "^To: R E Cipient <rcipient@example.com>\$" hdrs9
2012-10-18 14:43:34 +00:00
'
test_expect_failure 'configuration To: header (rfc822)' '
2010-02-16 23:39:34 +00:00
git config format.to "R. E. Cipient <rcipient@example.com>" &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout main..side >patch9 &&
2019-08-27 04:05:15 +00:00
sed -e "/^\$/q" patch9 >hdrs9 &&
grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" hdrs9
2012-10-18 14:43:34 +00:00
'
test_expect_failure 'configuration To: header (rfc2047)' '
git config format.to "R Ä Cipient <rcipient@example.com>" &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout main..side >patch9 &&
2019-08-27 04:05:15 +00:00
sed -e "/^\$/q" patch9 >hdrs9 &&
grep "^To: =?UTF-8?q?R=20=C3=84=20Cipient?= <rcipient@example.com>\$" hdrs9
2010-02-16 23:39:34 +00:00
'
2011-08-29 20:10:46 +00:00
# check_patch <patch>: Verify that <patch> looks like a half-sane
# patch email to avoid a false positive with !grep
check_patch ( ) {
grep -e "^From:" " $1 " &&
grep -e "^Date:" " $1 " &&
grep -e "^Subject:" " $1 "
}
2016-07-30 09:41:56 +00:00
test_expect_success 'format.from=false' '
2020-11-18 23:44:27 +00:00
git -c format.from= false format-patch --stdout main..side >patch &&
2019-08-27 04:05:15 +00:00
sed -e "/^\$/q" patch >hdrs &&
2016-07-30 09:41:56 +00:00
check_patch patch &&
2019-08-27 04:05:15 +00:00
! grep "^From: C O Mitter <committer@example.com>\$" hdrs
2016-07-30 09:41:56 +00:00
'
test_expect_success 'format.from=true' '
2020-11-18 23:44:27 +00:00
git -c format.from= true format-patch --stdout main..side >patch &&
2019-08-27 04:05:15 +00:00
sed -e "/^\$/q" patch >hdrs &&
check_patch hdrs &&
grep "^From: C O Mitter <committer@example.com>\$" hdrs
2016-07-30 09:41:56 +00:00
'
test_expect_success 'format.from with address' '
2020-11-18 23:44:27 +00:00
git -c format.from= "F R Om <from@example.com>" format-patch --stdout main..side >patch &&
2019-08-27 04:05:15 +00:00
sed -e "/^\$/q" patch >hdrs &&
check_patch hdrs &&
grep "^From: F R Om <from@example.com>\$" hdrs
2016-07-30 09:41:56 +00:00
'
test_expect_success '--no-from overrides format.from' '
2020-11-18 23:44:27 +00:00
git -c format.from= "F R Om <from@example.com>" format-patch --no-from --stdout main..side >patch &&
2019-08-27 04:05:15 +00:00
sed -e "/^\$/q" patch >hdrs &&
check_patch hdrs &&
! grep "^From: F R Om <from@example.com>\$" hdrs
2016-07-30 09:41:56 +00:00
'
test_expect_success '--from overrides format.from' '
2020-11-18 23:44:27 +00:00
git -c format.from= "F R Om <from@example.com>" format-patch --from --stdout main..side >patch &&
2019-08-27 04:05:15 +00:00
sed -e "/^\$/q" patch >hdrs &&
check_patch hdrs &&
! grep "^From: F R Om <from@example.com>\$" hdrs
2016-07-30 09:41:56 +00:00
'
2010-03-07 22:46:47 +00:00
test_expect_success '--no-to overrides config.to' '
git config --replace-all format.to \
2012-10-18 14:43:34 +00:00
"R E Cipient <rcipient@example.com>" &&
2020-11-18 23:44:27 +00:00
git format-patch --no-to --stdout main..side >patch10 &&
2019-08-27 04:05:15 +00:00
sed -e "/^\$/q" patch10 >hdrs10 &&
check_patch hdrs10 &&
! grep "^To: R E Cipient <rcipient@example.com>\$" hdrs10
2010-03-07 22:46:47 +00:00
'
test_expect_success '--no-to and --to replaces config.to' '
git config --replace-all format.to \
"Someone <someone@out.there>" &&
git format-patch --no-to --to= "Someone Else <else@out.there>" \
2020-11-18 23:44:27 +00:00
--stdout main..side >patch11 &&
2019-08-27 04:05:15 +00:00
sed -e "/^\$/q" patch11 >hdrs11 &&
check_patch hdrs11 &&
! grep "^To: Someone <someone@out.there>\$" hdrs11 &&
grep "^To: Someone Else <else@out.there>\$" hdrs11
2010-03-07 22:46:47 +00:00
'
test_expect_success '--no-cc overrides config.cc' '
git config --replace-all format.cc \
2012-10-18 14:43:34 +00:00
"C E Cipient <rcipient@example.com>" &&
2020-11-18 23:44:27 +00:00
git format-patch --no-cc --stdout main..side >patch12 &&
2019-08-27 04:05:15 +00:00
sed -e "/^\$/q" patch12 >hdrs12 &&
check_patch hdrs12 &&
! grep "^Cc: C E Cipient <rcipient@example.com>\$" hdrs12
2010-03-07 22:46:47 +00:00
'
2011-08-29 20:10:48 +00:00
test_expect_success '--no-add-header overrides config.headers' '
2010-03-07 22:46:47 +00:00
git config --replace-all format.headers \
2012-10-18 14:43:34 +00:00
"Header1: B E Cipient <rcipient@example.com>" &&
2020-11-18 23:44:27 +00:00
git format-patch --no-add-header --stdout main..side >patch13 &&
2019-08-27 04:05:15 +00:00
sed -e "/^\$/q" patch13 >hdrs13 &&
check_patch hdrs13 &&
! grep "^Header1: B E Cipient <rcipient@example.com>\$" hdrs13
2010-03-07 22:46:47 +00:00
'
2008-02-19 03:56:02 +00:00
test_expect_success 'multiple files' '
rm -rf patches/ &&
git checkout side &&
2020-11-18 23:44:27 +00:00
git format-patch -o patches/ main &&
2008-02-19 03:56:02 +00:00
ls patches/0001-Side-changes-1.patch patches/0002-Side-changes-2.patch patches/0003-Side-changes-3-with-n-backslash-n-in-it.patch
'
format-patch: make output filename configurable
For the past 15 years, we've used the hardcoded 64 as the length
limit of the filename of the output from the "git format-patch"
command. Since the value is shorter than the 80-column terminal, it
could grow without line wrapping a bit. At the same time, since the
value is longer than half of the 80-column terminal, we could fit
two or more of them in "ls" output on such a terminal if we allowed
to lower it.
Introduce a new command line option --filename-max-length=<n> and a
new configuration variable format.filenameMaxLength to override the
hardcoded default.
While we are at it, remove a check that the name of output directory
does not exceed PATH_MAX---this check is pointless in that by the
time control reaches the function, the caller would already have
done an equivalent of "mkdir -p", so if the system does not like an
overly long directory name, the control wouldn't have reached here,
and otherwise, we know that the system allowed the output directory
to exist. In the worst case, we will get an error when we try to
open the output file and handle the error correctly anyway.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-06 21:56:24 +00:00
test_expect_success 'filename length limit' '
test_when_finished "rm -f 000*" &&
rm -rf 000[ 1-9] -*.patch &&
for len in 15 25 35
do
git format-patch --filename-max-length= $len -3 side &&
max = $(
for patch in 000[ 1-9] -*.patch
do
2021-12-09 05:11:13 +00:00
echo " $patch " | wc -c || exit 1
format-patch: make output filename configurable
For the past 15 years, we've used the hardcoded 64 as the length
limit of the filename of the output from the "git format-patch"
command. Since the value is shorter than the 80-column terminal, it
could grow without line wrapping a bit. At the same time, since the
value is longer than half of the 80-column terminal, we could fit
two or more of them in "ls" output on such a terminal if we allowed
to lower it.
Introduce a new command line option --filename-max-length=<n> and a
new configuration variable format.filenameMaxLength to override the
hardcoded default.
While we are at it, remove a check that the name of output directory
does not exceed PATH_MAX---this check is pointless in that by the
time control reaches the function, the caller would already have
done an equivalent of "mkdir -p", so if the system does not like an
overly long directory name, the control wouldn't have reached here,
and otherwise, we know that the system allowed the output directory
to exist. In the worst case, we will get an error when we try to
open the output file and handle the error correctly anyway.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-06 21:56:24 +00:00
done |
sort -nr |
head -n 1
) &&
test $max -le $len || return 1
done
'
test_expect_success 'filename length limit from config' '
test_when_finished "rm -f 000*" &&
rm -rf 000[ 1-9] -*.patch &&
for len in 15 25 35
do
git -c format.filenameMaxLength= $len format-patch -3 side &&
max = $(
for patch in 000[ 1-9] -*.patch
do
2021-12-09 05:11:13 +00:00
echo " $patch " | wc -c || exit 1
format-patch: make output filename configurable
For the past 15 years, we've used the hardcoded 64 as the length
limit of the filename of the output from the "git format-patch"
command. Since the value is shorter than the 80-column terminal, it
could grow without line wrapping a bit. At the same time, since the
value is longer than half of the 80-column terminal, we could fit
two or more of them in "ls" output on such a terminal if we allowed
to lower it.
Introduce a new command line option --filename-max-length=<n> and a
new configuration variable format.filenameMaxLength to override the
hardcoded default.
While we are at it, remove a check that the name of output directory
does not exceed PATH_MAX---this check is pointless in that by the
time control reaches the function, the caller would already have
done an equivalent of "mkdir -p", so if the system does not like an
overly long directory name, the control wouldn't have reached here,
and otherwise, we know that the system allowed the output directory
to exist. In the worst case, we will get an error when we try to
open the output file and handle the error correctly anyway.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-06 21:56:24 +00:00
done |
sort -nr |
head -n 1
) &&
test $max -le $len || return 1
done
'
test_expect_success 'filename limit applies only to basename' '
test_when_finished "rm -rf patches/" &&
rm -rf patches/ &&
for len in 15 25 35
do
git format-patch -o patches --filename-max-length= $len -3 side &&
max = $(
for patch in patches/000[ 1-9] -*.patch
do
2021-12-09 05:11:13 +00:00
echo " ${ patch #patches/ } " | wc -c || exit 1
format-patch: make output filename configurable
For the past 15 years, we've used the hardcoded 64 as the length
limit of the filename of the output from the "git format-patch"
command. Since the value is shorter than the 80-column terminal, it
could grow without line wrapping a bit. At the same time, since the
value is longer than half of the 80-column terminal, we could fit
two or more of them in "ls" output on such a terminal if we allowed
to lower it.
Introduce a new command line option --filename-max-length=<n> and a
new configuration variable format.filenameMaxLength to override the
hardcoded default.
While we are at it, remove a check that the name of output directory
does not exceed PATH_MAX---this check is pointless in that by the
time control reaches the function, the caller would already have
done an equivalent of "mkdir -p", so if the system does not like an
overly long directory name, the control wouldn't have reached here,
and otherwise, we know that the system allowed the output directory
to exist. In the worst case, we will get an error when we try to
open the output file and handle the error correctly anyway.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-06 21:56:24 +00:00
done |
sort -nr |
head -n 1
) &&
test $max -le $len || return 1
done
'
2013-01-02 22:16:07 +00:00
test_expect_success 'reroll count' '
rm -fr patches &&
2020-11-18 23:44:27 +00:00
git format-patch -o patches --cover-letter --reroll-count 4 main..side >list &&
2013-01-02 22:16:07 +00:00
! grep -v "^patches/v4-000[0-3]-" list &&
sed -n -e "/^Subject: /p" $( cat list) >subjects &&
! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
'
2013-01-02 22:19:05 +00:00
test_expect_success 'reroll count (-v)' '
rm -fr patches &&
2020-11-18 23:44:27 +00:00
git format-patch -o patches --cover-letter -v4 main..side >list &&
2013-01-02 22:19:05 +00:00
! grep -v "^patches/v4-000[0-3]-" list &&
sed -n -e "/^Subject: /p" $( cat list) >subjects &&
! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
'
2021-03-23 11:12:25 +00:00
test_expect_success 'reroll count (-v) with a fractional number' '
rm -fr patches &&
git format-patch -o patches --cover-letter -v4.4 main..side >list &&
! grep -v "^patches/v4.4-000[0-3]-" list &&
sed -n -e "/^Subject: /p" $( cat list) >subjects &&
! grep -v "^Subject: \[PATCH v4.4 [0-3]/3\] " subjects
'
test_expect_success 'reroll (-v) count with a non number' '
rm -fr patches &&
git format-patch -o patches --cover-letter -v4rev2 main..side >list &&
! grep -v "^patches/v4rev2-000[0-3]-" list &&
sed -n -e "/^Subject: /p" $( cat list) >subjects &&
! grep -v "^Subject: \[PATCH v4rev2 [0-3]/3\] " subjects
'
test_expect_success 'reroll (-v) count with a non-pathname character' '
rm -fr patches &&
git format-patch -o patches --cover-letter -v4---..././../--1/.2// main..side >list &&
! grep -v "patches/v4-\.-\.-\.-1-\.2-000[0-3]-" list &&
sed -n -e "/^Subject: /p" $( cat list) >subjects &&
! grep -v "^Subject: \[PATCH v4---\.\.\./\./\.\./--1/\.2// [0-3]/3\] " subjects
'
2009-02-19 21:26:30 +00:00
check_threading ( ) {
expect = " $1 " &&
shift &&
2019-08-27 04:05:12 +00:00
git format-patch --stdout " $@ " >patch &&
2009-02-19 21:26:30 +00:00
# Prints everything between the Message-ID and In-Reply-To,
# and replaces all Message-ID-lookalikes by a sequence number
2013-10-29 01:23:03 +00:00
perl -ne '
2009-02-19 21:26:30 +00:00
if ( /^( message-id| references| in-reply-to) /i) {
$printing = 1;
} elsif ( /^\S /) {
$printing = 0;
}
if ( $printing ) {
$h { $1 } = $i ++ if ( /<( [ ^>] +) >/ and !exists $h { $1 } ) ;
for $k ( keys %h) { s/$k /$h { $k } /} ;
print;
}
print "---\n" if /^From /i;
2019-08-27 04:05:12 +00:00
' <patch >actual &&
2009-02-19 21:26:30 +00:00
test_cmp " $expect " actual
}
2019-08-27 04:05:00 +00:00
cat >>expect.no-threading <<EOF
2009-02-19 21:26:30 +00:00
---
---
---
EOF
test_expect_success 'no threading' '
2008-02-19 03:56:02 +00:00
git checkout side &&
2020-11-18 23:44:27 +00:00
check_threading expect.no-threading main
2008-02-19 03:56:02 +00:00
'
2019-08-27 04:05:00 +00:00
cat >expect.thread <<EOF
2009-02-19 21:26:30 +00:00
---
2022-12-16 01:47:19 +00:00
Message-ID: <0>
2009-02-19 21:26:30 +00:00
---
2022-12-16 01:47:19 +00:00
Message-ID: <1>
2009-02-19 21:26:30 +00:00
In-Reply-To: <0>
References: <0>
---
2022-12-16 01:47:19 +00:00
Message-ID: <2>
2009-02-19 21:26:30 +00:00
In-Reply-To: <0>
References: <0>
EOF
2008-02-19 03:56:02 +00:00
2009-02-19 21:26:30 +00:00
test_expect_success 'thread' '
2020-11-18 23:44:27 +00:00
check_threading expect.thread --thread main
2008-02-19 03:56:02 +00:00
'
2023-04-03 04:07:24 +00:00
test_expect_success '--thread overrides format.thread=deep' '
test_config format.thread deep &&
check_threading expect.thread --thread main
'
2019-08-27 04:05:00 +00:00
cat >expect.in-reply-to <<EOF
2009-02-19 21:26:30 +00:00
---
2022-12-16 01:47:19 +00:00
Message-ID: <0>
2009-02-19 21:26:30 +00:00
In-Reply-To: <1>
References: <1>
---
2022-12-16 01:47:19 +00:00
Message-ID: <2>
2009-02-19 21:26:30 +00:00
In-Reply-To: <1>
References: <1>
---
2022-12-16 01:47:19 +00:00
Message-ID: <3>
2009-02-19 21:26:30 +00:00
In-Reply-To: <1>
References: <1>
EOF
2008-02-19 03:56:13 +00:00
2009-02-19 21:26:30 +00:00
test_expect_success 'thread in-reply-to' '
check_threading expect.in-reply-to --in-reply-to= "<test.message>" \
2020-11-18 23:44:27 +00:00
--thread main
2008-02-19 03:56:13 +00:00
'
2019-08-27 04:05:00 +00:00
cat >expect.cover-letter <<EOF
2009-02-19 21:26:30 +00:00
---
2022-12-16 01:47:19 +00:00
Message-ID: <0>
2009-02-19 21:26:30 +00:00
---
2022-12-16 01:47:19 +00:00
Message-ID: <1>
2009-02-19 21:26:30 +00:00
In-Reply-To: <0>
References: <0>
---
2022-12-16 01:47:19 +00:00
Message-ID: <2>
2009-02-19 21:26:30 +00:00
In-Reply-To: <0>
References: <0>
---
2022-12-16 01:47:19 +00:00
Message-ID: <3>
2009-02-19 21:26:30 +00:00
In-Reply-To: <0>
References: <0>
EOF
2008-02-19 03:56:13 +00:00
2009-02-19 21:26:30 +00:00
test_expect_success 'thread cover-letter' '
2020-11-18 23:44:27 +00:00
check_threading expect.cover-letter --cover-letter --thread main
2009-02-19 21:26:30 +00:00
'
2019-08-27 04:05:00 +00:00
cat >expect.cl-irt <<EOF
2009-02-19 21:26:30 +00:00
---
2022-12-16 01:47:19 +00:00
Message-ID: <0>
2009-02-19 21:26:30 +00:00
In-Reply-To: <1>
References: <1>
---
2022-12-16 01:47:19 +00:00
Message-ID: <2>
2009-02-19 21:26:32 +00:00
In-Reply-To: <0>
2009-02-19 21:26:30 +00:00
References: <1>
2009-02-19 21:26:32 +00:00
<0>
2009-02-19 21:26:30 +00:00
---
2022-12-16 01:47:19 +00:00
Message-ID: <3>
2009-02-19 21:26:32 +00:00
In-Reply-To: <0>
2009-02-19 21:26:30 +00:00
References: <1>
2009-02-19 21:26:32 +00:00
<0>
2009-02-19 21:26:30 +00:00
---
2022-12-16 01:47:19 +00:00
Message-ID: <4>
2009-02-19 21:26:32 +00:00
In-Reply-To: <0>
2009-02-19 21:26:30 +00:00
References: <1>
2009-02-19 21:26:32 +00:00
<0>
2009-02-19 21:26:30 +00:00
EOF
test_expect_success 'thread cover-letter in-reply-to' '
check_threading expect.cl-irt --cover-letter \
2020-11-18 23:44:27 +00:00
--in-reply-to= "<test.message>" --thread main
2008-02-19 03:56:13 +00:00
'
2009-02-19 21:26:33 +00:00
test_expect_success 'thread explicit shallow' '
check_threading expect.cl-irt --cover-letter \
2020-11-18 23:44:27 +00:00
--in-reply-to= "<test.message>" --thread= shallow main
2009-02-19 21:26:33 +00:00
'
2019-08-27 04:05:00 +00:00
cat >expect.deep <<EOF
2009-02-19 21:26:33 +00:00
---
2022-12-16 01:47:19 +00:00
Message-ID: <0>
2009-02-19 21:26:33 +00:00
---
2022-12-16 01:47:19 +00:00
Message-ID: <1>
2009-02-19 21:26:33 +00:00
In-Reply-To: <0>
References: <0>
---
2022-12-16 01:47:19 +00:00
Message-ID: <2>
2009-02-19 21:26:33 +00:00
In-Reply-To: <1>
References: <0>
<1>
EOF
test_expect_success 'thread deep' '
2020-11-18 23:44:27 +00:00
check_threading expect.deep --thread= deep main
2009-02-19 21:26:33 +00:00
'
2019-08-27 04:05:00 +00:00
cat >expect.deep-irt <<EOF
2009-02-19 21:26:33 +00:00
---
2022-12-16 01:47:19 +00:00
Message-ID: <0>
2009-02-19 21:26:33 +00:00
In-Reply-To: <1>
References: <1>
---
2022-12-16 01:47:19 +00:00
Message-ID: <2>
2009-02-19 21:26:33 +00:00
In-Reply-To: <0>
References: <1>
<0>
---
2022-12-16 01:47:19 +00:00
Message-ID: <3>
2009-02-19 21:26:33 +00:00
In-Reply-To: <2>
References: <1>
<0>
<2>
EOF
test_expect_success 'thread deep in-reply-to' '
check_threading expect.deep-irt --thread= deep \
2020-11-18 23:44:27 +00:00
--in-reply-to= "<test.message>" main
2009-02-19 21:26:33 +00:00
'
2019-08-27 04:05:00 +00:00
cat >expect.deep-cl <<EOF
2009-02-19 21:26:33 +00:00
---
2022-12-16 01:47:19 +00:00
Message-ID: <0>
2009-02-19 21:26:33 +00:00
---
2022-12-16 01:47:19 +00:00
Message-ID: <1>
2009-02-19 21:26:33 +00:00
In-Reply-To: <0>
References: <0>
---
2022-12-16 01:47:19 +00:00
Message-ID: <2>
2009-02-19 21:26:33 +00:00
In-Reply-To: <1>
References: <0>
<1>
---
2022-12-16 01:47:19 +00:00
Message-ID: <3>
2009-02-19 21:26:33 +00:00
In-Reply-To: <2>
References: <0>
<1>
<2>
EOF
test_expect_success 'thread deep cover-letter' '
2020-11-18 23:44:27 +00:00
check_threading expect.deep-cl --cover-letter --thread= deep main
2009-02-19 21:26:33 +00:00
'
2019-08-27 04:05:00 +00:00
cat >expect.deep-cl-irt <<EOF
2009-02-19 21:26:33 +00:00
---
2022-12-16 01:47:19 +00:00
Message-ID: <0>
2009-02-19 21:26:33 +00:00
In-Reply-To: <1>
References: <1>
---
2022-12-16 01:47:19 +00:00
Message-ID: <2>
2009-02-19 21:26:33 +00:00
In-Reply-To: <0>
References: <1>
<0>
---
2022-12-16 01:47:19 +00:00
Message-ID: <3>
2009-02-19 21:26:33 +00:00
In-Reply-To: <2>
References: <1>
<0>
<2>
---
2022-12-16 01:47:19 +00:00
Message-ID: <4>
2009-02-19 21:26:33 +00:00
In-Reply-To: <3>
References: <1>
<0>
<2>
<3>
EOF
test_expect_success 'thread deep cover-letter in-reply-to' '
check_threading expect.deep-cl-irt --cover-letter \
2020-11-18 23:44:27 +00:00
--in-reply-to= "<test.message>" --thread= deep main
2009-02-19 21:26:33 +00:00
'
test_expect_success 'thread via config' '
2011-09-19 19:15:45 +00:00
test_config format.thread true &&
2020-11-18 23:44:27 +00:00
check_threading expect.thread main
2009-02-19 21:26:33 +00:00
'
test_expect_success 'thread deep via config' '
2011-09-19 19:15:45 +00:00
test_config format.thread deep &&
2020-11-18 23:44:27 +00:00
check_threading expect.deep main
2009-02-19 21:26:33 +00:00
'
test_expect_success 'thread config + override' '
2011-09-19 19:15:45 +00:00
test_config format.thread deep &&
2020-11-18 23:44:27 +00:00
check_threading expect.thread --thread main
2009-02-19 21:26:33 +00:00
'
test_expect_success 'thread config + --no-thread' '
2011-09-19 19:15:45 +00:00
test_config format.thread deep &&
2020-11-18 23:44:27 +00:00
check_threading expect.no-threading --no-thread main
2009-02-19 21:26:33 +00:00
'
2008-02-19 03:56:02 +00:00
test_expect_success 'excessive subject' '
rm -rf patches/ &&
git checkout side &&
2018-05-21 02:01:36 +00:00
before = $( git hash-object file) &&
before = $( git rev-parse --short $before ) &&
2021-12-09 05:11:05 +00:00
test_write_lines 5 6 1 2 3 A 4 B C 7 8 9 10 D E F >>file &&
2018-05-21 02:01:36 +00:00
after = $( git hash-object file) &&
after = $( git rev-parse --short $after ) &&
2008-02-19 03:56:02 +00:00
git update-index file &&
git commit -m "This is an excessively long subject line for a message due to the habit some projects have of not having a short, one-line subject at the start of the commit message, but rather sticking a whole paragraph right at the start as the only thing in the commit message. It had better not become the filename for the patch." &&
2020-11-18 23:44:27 +00:00
git format-patch -o patches/ main..side &&
2008-02-19 03:56:02 +00:00
ls patches/0004-This-is-an-excessively-long-subject-line-for-a-messa.patch
'
2019-02-22 19:26:43 +00:00
test_expect_success 'failure to write cover-letter aborts gracefully' '
test_when_finished "rmdir 0000-cover-letter.patch" &&
mkdir 0000-cover-letter.patch &&
test_must_fail git format-patch --no-renames --cover-letter -1
'
2008-03-02 15:53:04 +00:00
test_expect_success 'cover-letter inherits diff options' '
git mv file foo &&
git commit -m foo &&
2016-02-25 08:59:21 +00:00
git format-patch --no-renames --cover-letter -1 &&
2011-08-29 20:10:46 +00:00
check_patch 0000-cover-letter.patch &&
2010-01-26 23:08:31 +00:00
! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
2008-03-02 15:53:04 +00:00
git format-patch --cover-letter -1 -M &&
2010-01-26 23:08:31 +00:00
grep "file => foo .* 0 *\$" 0000-cover-letter.patch
2008-03-02 15:53:04 +00:00
'
2008-03-02 15:53:39 +00:00
2019-08-27 04:05:00 +00:00
cat >expect <<EOF
2008-03-02 15:53:39 +00:00
This is an excessively long subject line for a message due to the
habit some projects have of not having a short, one-line subject at
the start of the commit message, but rather sticking a whole
paragraph right at the start as the only thing in the commit
message. It had better not become the filename for the patch.
foo
EOF
test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
git format-patch --cover-letter -2 &&
2019-08-27 04:05:07 +00:00
sed -e "1,/A U Thor/d" -e "/^\$/q" 0000-cover-letter.patch >output &&
2008-05-24 05:28:56 +00:00
test_cmp expect output
2008-03-02 15:53:39 +00:00
'
2019-08-27 04:05:00 +00:00
cat >expect <<EOF
2018-05-21 02:01:36 +00:00
index $before ..$after 100644
2008-08-25 02:10:29 +00:00
--- a/file
+++ b/file
@@ -13,4 +13,20 @@ C
10
D
E
F
+5
EOF
test_expect_success 'format-patch respects -U' '
git format-patch -U4 -2 &&
2012-03-13 05:05:54 +00:00
sed -e "1,/^diff/d" -e "/^+5/q" \
<0001-This-is-an-excessively-long-subject-line-for-a-messa.patch \
>output &&
2008-08-25 02:10:29 +00:00
test_cmp expect output
'
2019-08-27 04:05:00 +00:00
cat >expect <<EOF
2009-11-04 07:19:40 +00:00
diff --git a/file b/file
2018-05-21 02:01:36 +00:00
index $before ..$after 100644
2009-11-04 07:19:40 +00:00
--- a/file
+++ b/file
@@ -14,3 +14,19 @@ C
D
E
F
+5
EOF
test_expect_success 'format-patch -p suppresses stat' '
git format-patch -p -2 &&
2019-08-27 04:05:07 +00:00
sed -e "1,/^\$/d" -e "/^+5/q" 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch >output &&
2009-11-04 07:19:40 +00:00
test_cmp expect output
'
2009-01-12 23:18:02 +00:00
test_expect_success 'format-patch from a subdirectory (1)' '
filename = $(
rm -rf sub &&
mkdir -p sub/dir &&
cd sub/dir &&
git format-patch -1
) &&
case " $filename " in
0*)
; ; # ok
*)
echo " Oops? $filename "
false
; ;
esac &&
test -f " $filename "
'
test_expect_success 'format-patch from a subdirectory (2)' '
filename = $(
rm -rf sub &&
mkdir -p sub/dir &&
cd sub/dir &&
git format-patch -1 -o ..
) &&
case " $filename " in
../0*)
; ; # ok
*)
echo " Oops? $filename "
false
; ;
esac &&
basename = $( expr " $filename " : ".*/\(.*\)" ) &&
test -f " sub/ $basename "
'
test_expect_success 'format-patch from a subdirectory (3)' '
rm -f 0* &&
filename = $(
rm -rf sub &&
mkdir -p sub/dir &&
cd sub/dir &&
2009-08-09 08:38:11 +00:00
git format-patch -1 -o " $TRASH_DIRECTORY "
2009-01-12 23:18:02 +00:00
) &&
basename = $( expr " $filename " : ".*/\(.*\)" ) &&
test -f " $basename "
'
2009-05-16 09:24:45 +00:00
test_expect_success 'format-patch --in-reply-to' '
2019-08-27 04:05:00 +00:00
git format-patch -1 --stdout --in-reply-to "baz@foo.bar" >patch8 &&
2009-05-16 09:24:45 +00:00
grep "^In-Reply-To: <baz@foo.bar>" patch8 &&
grep "^References: <baz@foo.bar>" patch8
'
test_expect_success 'format-patch --signoff' '
2012-10-18 03:48:25 +00:00
git format-patch -1 --signoff --stdout >out &&
grep " ^Signed-off-by: $GIT_COMMITTER_NAME < $GIT_COMMITTER_EMAIL > " out
'
test_expect_success 'format-patch --notes --signoff' '
git notes --ref test add -m "test message" HEAD &&
git format-patch -1 --signoff --stdout --notes= test >out &&
2012-10-18 04:27:22 +00:00
# Three dashes must come after S-o-b
2012-10-18 03:48:25 +00:00
! sed "/^Signed-off-by: /q" out | grep "test message" &&
2012-10-18 04:27:22 +00:00
sed "1,/^Signed-off-by: /d" out | grep "test message" &&
# Notes message must come after three dashes
! sed " /^--- $/q " out | grep "test message" &&
sed " 1,/^--- $/d " out | grep "test message"
2009-05-16 09:24:45 +00:00
'
2019-05-16 23:14:14 +00:00
test_expect_success 'format-patch notes output control' '
git notes add -m "notes config message" HEAD &&
test_when_finished git notes remove HEAD &&
git format-patch -1 --stdout >out &&
! grep "notes config message" out &&
git format-patch -1 --stdout --notes >out &&
grep "notes config message" out &&
git format-patch -1 --stdout --no-notes >out &&
! grep "notes config message" out &&
git format-patch -1 --stdout --notes --no-notes >out &&
! grep "notes config message" out &&
git format-patch -1 --stdout --no-notes --notes >out &&
grep "notes config message" out &&
test_config format.notes true &&
git format-patch -1 --stdout >out &&
grep "notes config message" out &&
git format-patch -1 --stdout --notes >out &&
grep "notes config message" out &&
git format-patch -1 --stdout --no-notes >out &&
! grep "notes config message" out &&
git format-patch -1 --stdout --notes --no-notes >out &&
! grep "notes config message" out &&
git format-patch -1 --stdout --no-notes --notes >out &&
grep "notes config message" out
'
test_expect_success 'format-patch with multiple notes refs' '
git notes --ref note1 add -m "this is note 1" HEAD &&
test_when_finished git notes --ref note1 remove HEAD &&
git notes --ref note2 add -m "this is note 2" HEAD &&
test_when_finished git notes --ref note2 remove HEAD &&
git format-patch -1 --stdout >out &&
! grep "this is note 1" out &&
! grep "this is note 2" out &&
git format-patch -1 --stdout --notes= note1 >out &&
grep "this is note 1" out &&
! grep "this is note 2" out &&
git format-patch -1 --stdout --notes= note2 >out &&
! grep "this is note 1" out &&
grep "this is note 2" out &&
git format-patch -1 --stdout --notes= note1 --notes= note2 >out &&
grep "this is note 1" out &&
grep "this is note 2" out &&
test_config format.notes note1 &&
git format-patch -1 --stdout >out &&
grep "this is note 1" out &&
! grep "this is note 2" out &&
git format-patch -1 --stdout --no-notes >out &&
! grep "this is note 1" out &&
! grep "this is note 2" out &&
git format-patch -1 --stdout --notes= note2 >out &&
grep "this is note 1" out &&
grep "this is note 2" out &&
git format-patch -1 --stdout --no-notes --notes= note2 >out &&
! grep "this is note 1" out &&
grep "this is note 2" out &&
git config --add format.notes note2 &&
git format-patch -1 --stdout >out &&
grep "this is note 1" out &&
grep "this is note 2" out &&
git format-patch -1 --stdout --no-notes >out &&
! grep "this is note 1" out &&
! grep "this is note 2" out
'
format-patch: use --notes behavior for format.notes
When we had multiple `format.notes` config values where we had `<ref1>`,
`false`, `<ref2>` (in that order), then we would print out the notes for
both `<ref1>` and `<ref2>`. This doesn't make sense, however, since we
parse the config in a top-down manner and a `false` should be able to
override previous configurations, just like how `--no-notes` will
override previous `--notes`.
Duplicate the logic that handles the `--[no-]notes[=]` option to
`format.notes` for consistency. As a result, when parsing the config
from top to bottom, `format.notes = true` will behave like `--notes`,
`format.notes = <ref>` will behave like `--notes=<ref>` and
`format.notes = false` will behave like `--no-notes`.
This change isn't strictly backwards compatible but since it is an edge
case where a sane user would not mix notes refs with `false` and this
feature is relatively new (released only in v2.23.0), this change should
be harmless.
Signed-off-by: Denton Liu <liu.denton@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-12-09 13:10:46 +00:00
test_expect_success 'format-patch with multiple notes refs in config' '
test_when_finished "test_unconfig format.notes" &&
git notes --ref note1 add -m "this is note 1" HEAD &&
test_when_finished git notes --ref note1 remove HEAD &&
git notes --ref note2 add -m "this is note 2" HEAD &&
test_when_finished git notes --ref note2 remove HEAD &&
git config format.notes note1 &&
git format-patch -1 --stdout >out &&
grep "this is note 1" out &&
! grep "this is note 2" out &&
git config format.notes note2 &&
git format-patch -1 --stdout >out &&
! grep "this is note 1" out &&
grep "this is note 2" out &&
git config --add format.notes note1 &&
git format-patch -1 --stdout >out &&
grep "this is note 1" out &&
grep "this is note 2" out &&
git config --replace-all format.notes note1 &&
git config --add format.notes false &&
git format-patch -1 --stdout >out &&
! grep "this is note 1" out &&
! grep "this is note 2" out &&
git config --add format.notes note2 &&
git format-patch -1 --stdout >out &&
! grep "this is note 1" out &&
grep "this is note 2" out
'
2019-08-27 04:05:00 +00:00
echo "fatal: --name-only does not make sense" >expect.name-only
echo "fatal: --name-status does not make sense" >expect.name-status
echo "fatal: --check does not make sense" >expect.check
2009-11-07 09:51:56 +00:00
2011-04-12 23:27:11 +00:00
test_expect_success 'options no longer allowed for format-patch' '
2019-08-27 04:05:00 +00:00
test_must_fail git format-patch --name-only 2>output &&
2021-02-11 01:53:53 +00:00
test_cmp expect.name-only output &&
2019-08-27 04:05:00 +00:00
test_must_fail git format-patch --name-status 2>output &&
2021-02-11 01:53:53 +00:00
test_cmp expect.name-status output &&
2019-08-27 04:05:00 +00:00
test_must_fail git format-patch --check 2>output &&
2021-02-11 01:53:53 +00:00
test_cmp expect.check output
2019-08-27 04:04:55 +00:00
'
2009-11-07 09:51:56 +00:00
test_expect_success 'format-patch --numstat should produce a patch' '
2020-11-18 23:44:27 +00:00
git format-patch --numstat --stdout main..side >output &&
2019-08-27 04:05:10 +00:00
grep "^diff --git a/" output >diff &&
test_line_count = 5 diff
2019-08-27 04:04:55 +00:00
'
2009-11-07 09:51:56 +00:00
2009-11-26 19:12:00 +00:00
test_expect_success 'format-patch -- <path>' '
2022-04-30 10:32:44 +00:00
rm -f *.patch &&
git checkout -b pathspec main &&
echo file_a 1 >file_a &&
echo file_b 1 >file_b &&
git add file_a file_b &&
git commit -m pathspec_initial &&
echo file_a 2 >>file_a &&
git add file_a &&
git commit -m pathspec_a &&
echo file_b 2 >>file_b &&
git add file_b &&
git commit -m pathspec_b &&
echo file_a 3 >>file_a &&
echo file_b 3 >>file_b &&
git add file_a file_b &&
git commit -m pathspec_ab &&
cat >expect <<-\E OF &&
0001-pathspec_initial.patch
0002-pathspec_a.patch
0003-pathspec_ab.patch
EOF
git format-patch main..pathspec -- file_a >output &&
test_cmp expect output &&
! grep file_b *.patch
2009-11-26 19:12:00 +00:00
'
2010-03-30 02:46:38 +00:00
test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
2022-04-30 10:32:44 +00:00
git checkout side &&
2010-03-30 02:46:38 +00:00
git format-patch --ignore-if-in-upstream HEAD
'
2019-08-27 04:05:15 +00:00
test_expect_success 'get git version' '
git_version = $( git --version) &&
git_version = ${ git_version ##* }
'
2016-09-08 01:12:01 +00:00
signature( ) {
printf "%s\n%s\n\n" "-- " " ${ 1 :- $git_version } "
}
test_expect_success 'format-patch default signature' '
2019-08-27 04:05:15 +00:00
git format-patch --stdout -1 >patch &&
tail -n 3 patch >output &&
2016-09-08 01:12:01 +00:00
signature >expect &&
test_cmp expect output
'
2010-06-16 05:59:25 +00:00
test_expect_success 'format-patch --signature' '
2019-08-27 04:05:15 +00:00
git format-patch --stdout --signature= "my sig" -1 >patch &&
tail -n 3 patch >output &&
2016-09-08 01:12:01 +00:00
signature "my sig" >expect &&
test_cmp expect output
2010-06-16 05:59:25 +00:00
'
test_expect_success 'format-patch with format.signature config' '
git config format.signature "config sig" &&
git format-patch --stdout -1 >output &&
grep "config sig" output
'
test_expect_success 'format-patch --signature overrides format.signature' '
git config format.signature "config sig" &&
git format-patch --stdout --signature= "overrides" -1 >output &&
! grep "config sig" output &&
grep "overrides" output
'
test_expect_success 'format-patch --no-signature ignores format.signature' '
git config format.signature "config sig" &&
git format-patch --stdout --signature= "my sig" --no-signature \
-1 >output &&
2011-08-29 20:10:46 +00:00
check_patch output &&
2010-06-16 05:59:25 +00:00
! grep "config sig" output &&
! grep "my sig" output &&
! grep "^-- \$" output
'
test_expect_success 'format-patch --signature --cover-letter' '
git config --unset-all format.signature &&
git format-patch --stdout --signature= "my sig" --cover-letter \
-1 >output &&
2019-08-27 04:05:10 +00:00
grep "my sig" output >sig &&
test_line_count = 2 sig
2010-06-16 05:59:25 +00:00
'
2013-04-11 22:36:10 +00:00
test_expect_success 'format.signature="" suppresses signatures' '
2010-06-16 05:59:25 +00:00
git config format.signature "" &&
git format-patch --stdout -1 >output &&
2011-08-29 20:10:46 +00:00
check_patch output &&
2010-06-16 05:59:25 +00:00
! grep "^-- \$" output
'
2013-04-11 22:36:10 +00:00
test_expect_success 'format-patch --no-signature suppresses signatures' '
2010-06-16 05:59:25 +00:00
git config --unset-all format.signature &&
git format-patch --stdout --no-signature -1 >output &&
2011-08-29 20:10:46 +00:00
check_patch output &&
2010-06-16 05:59:25 +00:00
! grep "^-- \$" output
'
2013-04-11 22:36:10 +00:00
test_expect_success 'format-patch --signature="" suppresses signatures' '
2011-08-29 20:10:47 +00:00
git format-patch --stdout --signature= "" -1 >output &&
2011-08-29 20:10:46 +00:00
check_patch output &&
2010-06-16 05:59:25 +00:00
! grep "^-- \$" output
'
2014-05-24 04:08:14 +00:00
test_expect_success 'prepare mail-signature input' '
cat >mail-signature <<-\E OF
Test User <test.email@kernel.org>
http://git.kernel.org/cgit/git/git.git
git.kernel.org/?p= git/git.git; a = summary
EOF
'
test_expect_success '--signature-file=file works' '
git format-patch --stdout --signature-file= mail-signature -1 >output &&
check_patch output &&
2019-08-27 04:05:07 +00:00
sed -e "1,/^-- \$/d" output >actual &&
2014-05-24 04:08:14 +00:00
{
cat mail-signature && echo
} >expect &&
test_cmp expect actual
'
test_expect_success 'format.signaturefile works' '
test_config format.signaturefile mail-signature &&
git format-patch --stdout -1 >output &&
check_patch output &&
2019-08-27 04:05:07 +00:00
sed -e "1,/^-- \$/d" output >actual &&
2014-05-24 04:08:14 +00:00
{
cat mail-signature && echo
} >expect &&
test_cmp expect actual
'
test_expect_success '--no-signature suppresses format.signaturefile ' '
test_config format.signaturefile mail-signature &&
git format-patch --stdout --no-signature -1 >output &&
check_patch output &&
! grep "^-- \$" output
'
test_expect_success '--signature-file overrides format.signaturefile' '
2015-03-20 10:07:15 +00:00
cat >other-mail-signature <<-\E OF &&
2014-05-24 04:08:14 +00:00
Use this other signature instead of mail-signature.
EOF
test_config format.signaturefile mail-signature &&
git format-patch --stdout \
--signature-file= other-mail-signature -1 >output &&
check_patch output &&
2019-08-27 04:05:07 +00:00
sed -e "1,/^-- \$/d" output >actual &&
2014-05-24 04:08:14 +00:00
{
cat other-mail-signature && echo
} >expect &&
test_cmp expect actual
'
test_expect_success '--signature overrides format.signaturefile' '
test_config format.signaturefile mail-signature &&
git format-patch --stdout --signature= "my sig" -1 >output &&
check_patch output &&
grep "my sig" output
'
2010-11-23 03:16:30 +00:00
test_expect_success TTY 'format-patch --stdout paginates' '
rm -f pager_used &&
2014-03-18 18:54:05 +00:00
test_terminal env GIT_PAGER = "wc >pager_used" git format-patch --stdout --all &&
2010-11-23 03:16:30 +00:00
test_path_is_file pager_used
'
test_expect_success TTY 'format-patch --stdout pagination can be disabled' '
rm -f pager_used &&
2014-03-18 18:54:05 +00:00
test_terminal env GIT_PAGER = "wc >pager_used" git --no-pager format-patch --stdout --all &&
test_terminal env GIT_PAGER = "wc >pager_used" git -c "pager.format-patch=false" format-patch --stdout --all &&
2010-11-23 03:16:30 +00:00
test_path_is_missing pager_used &&
test_path_is_missing .git/pager_used
'
2011-02-23 09:58:41 +00:00
test_expect_success 'format-patch handles multi-line subjects' '
rm -rf patches/ &&
echo content >>file &&
2021-12-09 05:11:05 +00:00
test_write_lines one two three >msg &&
2011-02-23 09:58:41 +00:00
git add file &&
git commit -F msg &&
git format-patch -o patches -1 &&
grep ^Subject: patches/0001-one.patch >actual &&
echo "Subject: [PATCH] one two three" >expect &&
test_cmp expect actual
'
test_expect_success 'format-patch handles multi-line encoded subjects' '
rm -rf patches/ &&
echo content >>file &&
2021-12-09 05:11:05 +00:00
test_write_lines en två tre >msg &&
2011-02-23 09:58:41 +00:00
git add file &&
git commit -F msg &&
git format-patch -o patches -1 &&
grep ^Subject: patches/0001-en.patch >actual &&
echo "Subject: [PATCH] =?UTF-8?q?en=20tv=C3=A5=20tre?=" >expect &&
test_cmp expect actual
'
M8 = "foo bar "
M64 = $M8 $M8 $M8 $M8 $M8 $M8 $M8 $M8
M512 = $M64 $M64 $M64 $M64 $M64 $M64 $M64 $M64
cat >expect <<'EOF'
Subject: [ PATCH] foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
2012-10-18 14:43:29 +00:00
bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo
bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar
2011-02-23 09:58:41 +00:00
EOF
2012-10-18 14:43:29 +00:00
test_expect_success 'format-patch wraps extremely long subject (ascii)' '
2011-02-23 09:58:41 +00:00
echo content >>file &&
git add file &&
git commit -m " $M512 " &&
git format-patch --stdout -1 >patch &&
2019-08-27 04:05:07 +00:00
sed -n " /^Subject/p; /^ /p; /^ $/q " patch >subject &&
2011-02-23 09:58:41 +00:00
test_cmp expect subject
'
M8 = "föö bar "
M64 = $M8 $M8 $M8 $M8 $M8 $M8 $M8 $M8
M512 = $M64 $M64 $M64 $M64 $M64 $M64 $M64 $M64
cat >expect <<'EOF'
2012-10-18 14:43:30 +00:00
Subject: [ PATCH] = ?UTF-8?q?f= C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f?=
= ?UTF-8?q?= C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar?=
= ?UTF-8?q?= 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20?=
= ?UTF-8?q?bar= 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6?=
2013-03-07 10:55:07 +00:00
= ?UTF-8?q?= 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6?=
= ?UTF-8?q?= C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f?=
2012-10-18 14:43:30 +00:00
= ?UTF-8?q?= C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar?=
= ?UTF-8?q?= 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20?=
= ?UTF-8?q?bar= 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6?=
2013-03-07 10:55:07 +00:00
= ?UTF-8?q?= 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6?=
= ?UTF-8?q?= C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f?=
2012-10-18 14:43:30 +00:00
= ?UTF-8?q?= C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar?=
= ?UTF-8?q?= 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20?=
= ?UTF-8?q?bar= 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6?=
2013-03-07 10:55:07 +00:00
= ?UTF-8?q?= 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6?=
= ?UTF-8?q?= C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f?=
= ?UTF-8?q?= C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar?=
= ?UTF-8?q?= 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20?=
= ?UTF-8?q?bar= 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6?=
= ?UTF-8?q?= 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6?=
= ?UTF-8?q?= C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f?=
= ?UTF-8?q?= C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar?=
= ?UTF-8?q?= 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20bar = 20f = C3 = B6 = C3 = B6 = 20?=
= ?UTF-8?q?bar?=
2011-02-23 09:58:41 +00:00
EOF
2012-10-18 14:43:30 +00:00
test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
2011-02-23 09:58:41 +00:00
rm -rf patches/ &&
echo content >>file &&
git add file &&
git commit -m " $M512 " &&
git format-patch --stdout -1 >patch &&
2019-08-27 04:05:07 +00:00
sed -n " /^Subject/p; /^ /p; /^ $/q " patch >subject &&
2011-02-23 09:58:41 +00:00
test_cmp expect subject
'
2011-04-08 22:40:36 +00:00
check_author( ) {
echo content >>file &&
git add file &&
GIT_AUTHOR_NAME = $1 git commit -m author-check &&
git format-patch --stdout -1 >patch &&
2019-08-27 04:05:07 +00:00
sed -n " /^From: /p; /^ /p; /^ $/q " patch >actual &&
2011-04-08 22:40:36 +00:00
test_cmp expect actual
}
cat >expect <<'EOF'
From: "Foo B. Bar" <author@example.com>
EOF
2012-10-18 14:43:32 +00:00
test_expect_success 'format-patch quotes dot in from-headers' '
2011-04-08 22:40:36 +00:00
check_author "Foo B. Bar"
'
cat >expect <<'EOF'
From: "Foo \"The Baz\" Bar" <author@example.com>
EOF
2012-10-18 14:43:32 +00:00
test_expect_success 'format-patch quotes double-quote in from-headers' '
2011-04-08 22:40:36 +00:00
check_author "Foo \"The Baz\" Bar"
'
cat >expect <<'EOF'
2012-10-18 14:43:32 +00:00
From: = ?UTF-8?q?F= C3 = B6o = 20Bar?= <author@example.com>
2011-04-08 22:40:36 +00:00
EOF
2012-10-18 14:43:32 +00:00
test_expect_success 'format-patch uses rfc2047-encoded from-headers when necessary' '
check_author "Föo Bar"
'
cat >expect <<'EOF'
From: = ?UTF-8?q?F= C3 = B6o = 20B = 2E = 20Bar?= <author@example.com>
EOF
2012-10-18 14:43:33 +00:00
test_expect_success 'rfc2047-encoded from-headers leave no rfc822 specials' '
2011-04-08 22:40:36 +00:00
check_author "Föo B. Bar"
'
2012-10-18 14:43:29 +00:00
cat >expect <<EOF
From: foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_
<author@example.com>
EOF
test_expect_success 'format-patch wraps moderately long from-header (ascii)' '
check_author "foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_foo_bar_"
'
cat >expect <<'EOF'
From: Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
Bar Foo Bar Foo Bar Foo Bar <author@example.com>
EOF
test_expect_success 'format-patch wraps extremely long from-header (ascii)' '
check_author "Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar"
'
cat >expect <<'EOF'
From: " Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
Bar Foo Bar Foo Bar Foo Bar" <author@example.com>
EOF
test_expect_success 'format-patch wraps extremely long from-header (rfc822)' '
check_author "Foo.Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar"
'
2011-04-08 22:40:36 +00:00
cat >expect <<'EOF'
2012-10-18 14:43:30 +00:00
From: = ?UTF-8?q?Fo= C3 = B6 = 20Bar = 20Foo = 20Bar = 20Foo = 20Bar = 20Foo = 20Bar = 20Foo?=
= ?UTF-8?q?= 20Bar = 20Foo = 20Bar = 20Foo = 20Bar = 20Foo = 20Bar = 20Foo = 20Bar = 20Foo = 20?=
= ?UTF-8?q?Bar= 20Foo = 20Bar = 20Foo = 20Bar = 20Foo = 20Bar = 20Foo = 20Bar = 20Foo = 20Bar?=
= ?UTF-8?q?= 20Foo = 20Bar = 20Foo = 20Bar = 20Foo = 20Bar = 20Foo = 20Bar = 20Foo = 20Bar = 20?=
= ?UTF-8?q?Foo= 20Bar = 20Foo = 20Bar?= <author@example.com>
EOF
test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
check_author "Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar"
'
2020-04-08 04:31:38 +00:00
cat >expect <<'EOF'
From: Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
Bar Foo Bar Foo Bar Foo Bar <author@example.com>
EOF
test_expect_success 'format-patch wraps extremely long from-header (non-ASCII without Q-encoding)' '
echo content >>file &&
git add file &&
GIT_AUTHOR_NAME = "Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar" \
git commit -m author-check &&
git format-patch --no-encode-email-headers --stdout -1 >patch &&
sed -n " /^From: /p; /^ /p; /^ $/q " patch >actual &&
test_cmp expect actual
'
cat >expect <<'EOF'
Subject: [ PATCH] Foö
EOF
test_expect_success 'subject lines are unencoded with --no-encode-email-headers' '
echo content >>file &&
git add file &&
git commit -m "Foö" &&
git format-patch --no-encode-email-headers -1 --stdout >patch &&
grep ^Subject: patch >actual &&
test_cmp expect actual
'
cat >expect <<'EOF'
Subject: [ PATCH] Foö
EOF
test_expect_success 'subject lines are unencoded with format.encodeEmailHeaders=false' '
echo content >>file &&
git add file &&
git commit -m "Foö" &&
git config format.encodeEmailHeaders false &&
git format-patch -1 --stdout >patch &&
grep ^Subject: patch >actual &&
test_cmp expect actual
'
cat >expect <<'EOF'
Subject: [ PATCH] = ?UTF-8?q?Fo= C3 = B6?=
EOF
test_expect_success '--encode-email-headers overrides format.encodeEmailHeaders' '
echo content >>file &&
git add file &&
git commit -m "Foö" &&
git config format.encodeEmailHeaders false &&
git format-patch --encode-email-headers -1 --stdout >patch &&
grep ^Subject: patch >actual &&
test_cmp expect actual
'
2012-10-18 14:43:30 +00:00
cat >expect <<'EOF'
2011-04-08 22:40:36 +00:00
Subject: header with . in it
EOF
test_expect_success 'subject lines do not have 822 atom-quoting' '
echo content >>file &&
git add file &&
git commit -m "header with . in it" &&
git format-patch -k -1 --stdout >patch &&
grep ^Subject: patch >actual &&
test_cmp expect actual
'
2011-05-30 14:19:05 +00:00
cat >expect <<'EOF'
Subject: [ PREFIX 1/1] header with . in it
EOF
test_expect_success 'subject prefixes have space prepended' '
git format-patch -n -1 --stdout --subject-prefix= PREFIX >patch &&
grep ^Subject: patch >actual &&
test_cmp expect actual
'
cat >expect <<'EOF'
Subject: [ 1/1] header with . in it
EOF
test_expect_success 'empty subject prefix does not have extra space' '
git format-patch -n -1 --stdout --subject-prefix= >patch &&
grep ^Subject: patch >actual &&
test_cmp expect actual
'
format-patch: allow --rfc to optionally take a value, like --rfc=WIP
With the "--rfc" option, we can tweak the "[PATCH]" (or whatever
string specified with the "--subject-prefix" option, instead of
"PATCH") that we prefix the title of the commit with into "[RFC
PATCH]", but some projects may want "[rfc PATCH]". Adding a new
option, e.g., "--rfc-lowercase", to support such need every time
somebody wants to use different strings would lead to insanity of
accumulating unbounded number of such options.
Allow an optional value specified for the option, so that users can
use "--rfc=rfc" (think of "--rfc" without value as a short-hand for
"--rfc=RFC") if they wanted to.
This can of course be (ab)used to make the prefix "[WIP PATCH]" by
passing "--rfc=WIP". Passing an empty string, i.e., "--rfc=", is
the same as "--no-rfc" to override an option given earlier on the
same command line.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-04-23 17:52:33 +00:00
test_expect_success '--rfc and --no-rfc' '
2016-09-20 04:23:25 +00:00
cat >expect <<-\E OF &&
Subject: [ RFC PATCH 1/1] header with . in it
EOF
git format-patch -n -1 --stdout --rfc >patch &&
2023-08-30 06:43:33 +00:00
grep "^Subject:" patch >actual &&
format-patch: allow --rfc to optionally take a value, like --rfc=WIP
With the "--rfc" option, we can tweak the "[PATCH]" (or whatever
string specified with the "--subject-prefix" option, instead of
"PATCH") that we prefix the title of the commit with into "[RFC
PATCH]", but some projects may want "[rfc PATCH]". Adding a new
option, e.g., "--rfc-lowercase", to support such need every time
somebody wants to use different strings would lead to insanity of
accumulating unbounded number of such options.
Allow an optional value specified for the option, so that users can
use "--rfc=rfc" (think of "--rfc" without value as a short-hand for
"--rfc=RFC") if they wanted to.
This can of course be (ab)used to make the prefix "[WIP PATCH]" by
passing "--rfc=WIP". Passing an empty string, i.e., "--rfc=", is
the same as "--no-rfc" to override an option given earlier on the
same command line.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-04-23 17:52:33 +00:00
test_cmp expect actual &&
git format-patch -n -1 --stdout --rfc --no-rfc >patch &&
sed -e "s/RFC //" expect >expect-raw &&
grep "^Subject:" patch >actual &&
test_cmp expect-raw actual
'
test_expect_success '--rfc=WIP and --rfc=' '
cat >expect <<-\E OF &&
Subject: [ WIP PATCH 1/1] header with . in it
EOF
git format-patch -n -1 --stdout --rfc= WIP >patch &&
grep "^Subject:" patch >actual &&
test_cmp expect actual &&
git format-patch -n -1 --stdout --rfc --rfc= >patch &&
sed -e "s/WIP //" expect >expect-raw &&
grep "^Subject:" patch >actual &&
test_cmp expect-raw actual
2023-08-30 06:43:33 +00:00
'
2024-04-23 17:52:34 +00:00
test_expect_success '--rfc=-(WIP) appends' '
cat >expect <<-\E OF &&
Subject: [ PATCH ( WIP) 1/1] header with . in it
EOF
git format-patch -n -1 --stdout --rfc= "-(WIP)" >patch &&
grep "^Subject:" patch >actual &&
2023-08-30 06:43:33 +00:00
test_cmp expect actual
'
test_expect_success '--rfc does not overwrite prefix' '
cat >expect <<-\E OF &&
Subject: [ RFC PATCH foobar 1/1] header with . in it
EOF
git -c format.subjectPrefix= "PATCH foobar" \
format-patch -n -1 --stdout --rfc >patch &&
grep "^Subject:" patch >actual &&
test_cmp expect actual
'
test_expect_success '--rfc is argument order independent' '
cat >expect <<-\E OF &&
Subject: [ RFC PATCH foobar 1/1] header with . in it
EOF
git format-patch -n -1 --stdout --rfc \
--subject-prefix= "PATCH foobar" >patch &&
grep "^Subject:" patch >actual &&
2016-09-20 04:23:25 +00:00
test_cmp expect actual
'
2024-04-19 01:05:30 +00:00
test_expect_success '--subject-prefix="<non-empty>" and -k cannot be used together' '
echo "fatal: options '\''--subject-prefix/--rfc'\'' and '\''-k'\'' cannot be used together" >expect.err &&
test_must_fail git format-patch -1 --stdout --subject-prefix= "MYPREFIX" -k >actual.out 2>actual.err &&
test_must_be_empty actual.out &&
test_cmp expect.err actual.err
'
test_expect_success '--subject-prefix="" and -k cannot be used together' '
echo "fatal: options '\''--subject-prefix/--rfc'\'' and '\''-k'\'' cannot be used together" >expect.err &&
test_must_fail git format-patch -1 --stdout --subject-prefix= "" -k >actual.out 2>actual.err &&
test_must_be_empty actual.out &&
test_cmp expect.err actual.err
'
test_expect_success '--rfc and -k cannot be used together' '
echo "fatal: options '\''--subject-prefix/--rfc'\'' and '\''-k'\'' cannot be used together" >expect.err &&
test_must_fail git format-patch -1 --stdout --rfc -k >actual.out 2>actual.err &&
test_must_be_empty actual.out &&
test_cmp expect.err actual.err
'
teach format-patch to place other authors into in-body "From"
Format-patch generates emails with the "From" address set to the
author of each patch. If you are going to send the emails, however,
you would want to replace the author identity with yours (if they
are not the same), and bump the author identity to an in-body
header.
Normally this is handled by git-send-email, which does the
transformation before sending out the emails. However, some
workflows may not use send-email (e.g., imap-send, or a custom
script which feeds the mbox to a non-git MUA). They could each
implement this feature themselves, but getting it right is
non-trivial (one must canonicalize the identities by reversing any
RFC2047 encoding or RFC822 quoting of the headers, which has caused
many bugs in send-email over the years).
This patch takes a different approach: it teaches format-patch a
"--from" option which handles the ident check and in-body header
while it is writing out the email. It's much simpler to do at this
level (because we haven't done any quoting yet), and any workflow
based on format-patch can easily turn it on.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-03 07:08:22 +00:00
test_expect_success '--from=ident notices bogus ident' '
test_must_fail git format-patch -1 --stdout --from= foo >patch
'
test_expect_success '--from=ident replaces author' '
git format-patch -1 --stdout --from= "Me <me@example.com>" >patch &&
cat >expect <<-\E OF &&
From: Me <me@example.com>
From: A U Thor <author@example.com>
EOF
2019-08-27 04:05:07 +00:00
sed -ne " /^From:/p; /^ $/p; /^--- $/q " patch >patch.head &&
teach format-patch to place other authors into in-body "From"
Format-patch generates emails with the "From" address set to the
author of each patch. If you are going to send the emails, however,
you would want to replace the author identity with yours (if they
are not the same), and bump the author identity to an in-body
header.
Normally this is handled by git-send-email, which does the
transformation before sending out the emails. However, some
workflows may not use send-email (e.g., imap-send, or a custom
script which feeds the mbox to a non-git MUA). They could each
implement this feature themselves, but getting it right is
non-trivial (one must canonicalize the identities by reversing any
RFC2047 encoding or RFC822 quoting of the headers, which has caused
many bugs in send-email over the years).
This patch takes a different approach: it teaches format-patch a
"--from" option which handles the ident check and in-body header
while it is writing out the email. It's much simpler to do at this
level (because we haven't done any quoting yet), and any workflow
based on format-patch can easily turn it on.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-03 07:08:22 +00:00
test_cmp expect patch.head
'
test_expect_success '--from uses committer ident' '
git format-patch -1 --stdout --from >patch &&
cat >expect <<-\E OF &&
From: C O Mitter <committer@example.com>
From: A U Thor <author@example.com>
EOF
2019-08-27 04:05:07 +00:00
sed -ne " /^From:/p; /^ $/p; /^--- $/q " patch >patch.head &&
teach format-patch to place other authors into in-body "From"
Format-patch generates emails with the "From" address set to the
author of each patch. If you are going to send the emails, however,
you would want to replace the author identity with yours (if they
are not the same), and bump the author identity to an in-body
header.
Normally this is handled by git-send-email, which does the
transformation before sending out the emails. However, some
workflows may not use send-email (e.g., imap-send, or a custom
script which feeds the mbox to a non-git MUA). They could each
implement this feature themselves, but getting it right is
non-trivial (one must canonicalize the identities by reversing any
RFC2047 encoding or RFC822 quoting of the headers, which has caused
many bugs in send-email over the years).
This patch takes a different approach: it teaches format-patch a
"--from" option which handles the ident check and in-body header
while it is writing out the email. It's much simpler to do at this
level (because we haven't done any quoting yet), and any workflow
based on format-patch can easily turn it on.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-03 07:08:22 +00:00
test_cmp expect patch.head
'
2013-09-20 10:16:28 +00:00
test_expect_success '--from omits redundant in-body header' '
git format-patch -1 --stdout --from= "A U Thor <author@example.com>" >patch &&
cat >expect <<-\E OF &&
From: A U Thor <author@example.com>
EOF
2019-08-27 04:05:07 +00:00
sed -ne " /^From:/p; /^ $/p; /^--- $/q " patch >patch.head &&
2013-09-20 10:16:28 +00:00
test_cmp expect patch.head
'
2022-08-29 21:38:36 +00:00
test_expect_success 'with --force-in-body-from, redundant in-body from is kept' '
git format-patch --force-in-body-from \
-1 --stdout --from= "A U Thor <author@example.com>" >patch &&
cat >expect <<-\E OF &&
From: A U Thor <author@example.com>
From: A U Thor <author@example.com>
EOF
sed -ne " /^From:/p; /^ $/p; /^--- $/q " patch >patch.head &&
test_cmp expect patch.head
'
2022-08-29 21:38:37 +00:00
test_expect_success 'format.forceInBodyFrom, equivalent to --force-in-body-from' '
git -c format.forceInBodyFrom= yes format-patch \
-1 --stdout --from= "A U Thor <author@example.com>" >patch &&
cat >expect <<-\E OF &&
From: A U Thor <author@example.com>
From: A U Thor <author@example.com>
EOF
sed -ne " /^From:/p; /^ $/p; /^--- $/q " patch >patch.head &&
test_cmp expect patch.head
'
test_expect_success 'format.forceInBodyFrom, equivalent to --force-in-body-from' '
git -c format.forceInBodyFrom= yes format-patch --no-force-in-body-from \
-1 --stdout --from= "A U Thor <author@example.com>" >patch &&
cat >expect <<-\E OF &&
From: A U Thor <author@example.com>
EOF
sed -ne " /^From:/p; /^ $/p; /^--- $/q " patch >patch.head &&
test_cmp expect patch.head
'
teach format-patch to place other authors into in-body "From"
Format-patch generates emails with the "From" address set to the
author of each patch. If you are going to send the emails, however,
you would want to replace the author identity with yours (if they
are not the same), and bump the author identity to an in-body
header.
Normally this is handled by git-send-email, which does the
transformation before sending out the emails. However, some
workflows may not use send-email (e.g., imap-send, or a custom
script which feeds the mbox to a non-git MUA). They could each
implement this feature themselves, but getting it right is
non-trivial (one must canonicalize the identities by reversing any
RFC2047 encoding or RFC822 quoting of the headers, which has caused
many bugs in send-email over the years).
This patch takes a different approach: it teaches format-patch a
"--from" option which handles the ident check and in-body header
while it is writing out the email. It's much simpler to do at this
level (because we haven't done any quoting yet), and any workflow
based on format-patch can easily turn it on.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-03 07:08:22 +00:00
test_expect_success 'in-body headers trigger content encoding' '
2016-06-01 07:04:26 +00:00
test_env GIT_AUTHOR_NAME = "éxötìc" test_commit exotic &&
teach format-patch to place other authors into in-body "From"
Format-patch generates emails with the "From" address set to the
author of each patch. If you are going to send the emails, however,
you would want to replace the author identity with yours (if they
are not the same), and bump the author identity to an in-body
header.
Normally this is handled by git-send-email, which does the
transformation before sending out the emails. However, some
workflows may not use send-email (e.g., imap-send, or a custom
script which feeds the mbox to a non-git MUA). They could each
implement this feature themselves, but getting it right is
non-trivial (one must canonicalize the identities by reversing any
RFC2047 encoding or RFC822 quoting of the headers, which has caused
many bugs in send-email over the years).
This patch takes a different approach: it teaches format-patch a
"--from" option which handles the ident check and in-body header
while it is writing out the email. It's much simpler to do at this
level (because we haven't done any quoting yet), and any workflow
based on format-patch can easily turn it on.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-03 07:08:22 +00:00
test_when_finished "git reset --hard HEAD^" &&
git format-patch -1 --stdout --from >patch &&
cat >expect <<-\E OF &&
From: C O Mitter <committer@example.com>
Content-Type: text/plain; charset = UTF-8
From: éxötìc <author@example.com>
EOF
2019-08-27 04:05:07 +00:00
sed -ne " /^From:/p; /^ $/p; /^Content-Type/p; /^--- $/q " patch >patch.head &&
teach format-patch to place other authors into in-body "From"
Format-patch generates emails with the "From" address set to the
author of each patch. If you are going to send the emails, however,
you would want to replace the author identity with yours (if they
are not the same), and bump the author identity to an in-body
header.
Normally this is handled by git-send-email, which does the
transformation before sending out the emails. However, some
workflows may not use send-email (e.g., imap-send, or a custom
script which feeds the mbox to a non-git MUA). They could each
implement this feature themselves, but getting it right is
non-trivial (one must canonicalize the identities by reversing any
RFC2047 encoding or RFC822 quoting of the headers, which has caused
many bugs in send-email over the years).
This patch takes a different approach: it teaches format-patch a
"--from" option which handles the ident check and in-body header
while it is writing out the email. It's much simpler to do at this
level (because we haven't done any quoting yet), and any workflow
based on format-patch can easily turn it on.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-07-03 07:08:22 +00:00
test_cmp expect patch.head
'
2013-02-12 10:17:37 +00:00
append_signoff( )
{
C = $( git commit-tree HEAD^^{ tree} -p HEAD) &&
git format-patch --stdout --signoff $C ^..$C >append_signoff.patch &&
sed -n -e " 1,/^--- $/p " append_signoff.patch |
2022-09-21 13:02:31 +00:00
grep -E -n " ^Subject|Sign|^ $"
2013-02-12 10:17:37 +00:00
}
test_expect_success 'signoff: commit with no body' '
append_signoff </dev/null >actual &&
2019-08-27 04:05:03 +00:00
cat <<-\EOF | sed "s/EO L$//" >expect &&
4:Subject: [ PATCH] EOL
8:
9:Signed-off-by: C O Mitter <committer@example.com>
EOF
2019-08-27 04:04:52 +00:00
test_cmp expect actual
2013-02-12 10:17:37 +00:00
'
test_expect_success 'signoff: commit with only subject' '
echo subject | append_signoff >actual &&
2019-08-27 04:05:03 +00:00
cat >expect <<-\E OF &&
4:Subject: [ PATCH] subject
8:
9:Signed-off-by: C O Mitter <committer@example.com>
EOF
2019-08-27 04:04:52 +00:00
test_cmp expect actual
2013-02-12 10:17:37 +00:00
'
test_expect_success 'signoff: commit with only subject that does not end with NL' '
printf subject | append_signoff >actual &&
2019-08-27 04:05:03 +00:00
cat >expect <<-\E OF &&
4:Subject: [ PATCH] subject
8:
9:Signed-off-by: C O Mitter <committer@example.com>
EOF
2019-08-27 04:04:52 +00:00
test_cmp expect actual
2013-02-12 10:17:37 +00:00
'
test_expect_success 'signoff: no existing signoffs' '
2019-08-27 04:05:03 +00:00
append_signoff <<-\E OF >actual &&
subject
2013-02-12 10:17:37 +00:00
2019-08-27 04:05:03 +00:00
body
EOF
cat >expect <<-\E OF &&
4:Subject: [ PATCH] subject
8:
10:
11:Signed-off-by: C O Mitter <committer@example.com>
EOF
2019-08-27 04:04:52 +00:00
test_cmp expect actual
2013-02-12 10:17:37 +00:00
'
test_expect_success 'signoff: no existing signoffs and no trailing NL' '
printf "subject\n\nbody" | append_signoff >actual &&
2019-08-27 04:05:03 +00:00
cat >expect <<-\E OF &&
4:Subject: [ PATCH] subject
8:
10:
11:Signed-off-by: C O Mitter <committer@example.com>
EOF
2019-08-27 04:04:52 +00:00
test_cmp expect actual
2013-02-12 10:17:37 +00:00
'
test_expect_success 'signoff: some random signoff' '
2019-08-27 04:05:03 +00:00
append_signoff <<-\E OF >actual &&
subject
2013-02-12 10:17:37 +00:00
2019-08-27 04:05:03 +00:00
body
2013-02-12 10:17:37 +00:00
2019-08-27 04:05:03 +00:00
Signed-off-by: my@house
EOF
cat >expect <<-\E OF &&
4:Subject: [ PATCH] subject
8:
10:
11:Signed-off-by: my@house
12:Signed-off-by: C O Mitter <committer@example.com>
EOF
2019-08-27 04:04:52 +00:00
test_cmp expect actual
2013-02-12 10:17:37 +00:00
'
2013-02-12 10:17:39 +00:00
test_expect_success 'signoff: misc conforming footer elements' '
2019-08-27 04:05:03 +00:00
append_signoff <<-\E OF >actual &&
subject
2013-02-12 10:17:39 +00:00
2019-08-27 04:05:03 +00:00
body
2013-02-12 10:17:39 +00:00
2019-08-27 04:05:03 +00:00
Signed-off-by: my@house
( cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
Tested-by: Some One <someone@example.com>
Bug: 1234
EOF
cat >expect <<-\E OF &&
4:Subject: [ PATCH] subject
8:
10:
11:Signed-off-by: my@house
15:Signed-off-by: C O Mitter <committer@example.com>
EOF
2019-08-27 04:04:52 +00:00
test_cmp expect actual
2013-02-12 10:17:39 +00:00
'
test_expect_success 'signoff: some random signoff-alike' '
2019-08-27 04:05:03 +00:00
append_signoff <<-\E OF >actual &&
subject
2013-02-12 10:17:37 +00:00
2019-08-27 04:05:03 +00:00
body
Fooled-by-me: my@house
EOF
cat >expect <<-\E OF &&
4:Subject: [ PATCH] subject
8:
11:
12:Signed-off-by: C O Mitter <committer@example.com>
EOF
2019-08-27 04:04:52 +00:00
test_cmp expect actual
2013-02-12 10:17:37 +00:00
'
2013-02-12 10:17:39 +00:00
test_expect_success 'signoff: not really a signoff' '
2019-08-27 04:05:03 +00:00
append_signoff <<-\E OF >actual &&
subject
2013-02-12 10:17:37 +00:00
2019-08-27 04:05:03 +00:00
I want to mention about Signed-off-by: here.
EOF
cat >expect <<-\E OF &&
4:Subject: [ PATCH] subject
8:
9:I want to mention about Signed-off-by: here.
10:
11:Signed-off-by: C O Mitter <committer@example.com>
EOF
2019-08-27 04:04:52 +00:00
test_cmp expect actual
2013-02-12 10:17:37 +00:00
'
2013-02-12 10:17:39 +00:00
test_expect_success 'signoff: not really a signoff (2)' '
2019-08-27 04:05:03 +00:00
append_signoff <<-\E OF >actual &&
subject
2013-02-12 10:17:37 +00:00
2019-08-27 04:05:03 +00:00
My unfortunate
Signed-off-by: example happens to be wrapped here.
EOF
cat >expect <<-\E OF &&
4:Subject: [ PATCH] subject
8:
10:Signed-off-by: example happens to be wrapped here.
11:Signed-off-by: C O Mitter <committer@example.com>
EOF
2019-08-27 04:04:52 +00:00
test_cmp expect actual
2013-02-12 10:17:37 +00:00
'
2013-02-12 10:17:39 +00:00
test_expect_success 'signoff: valid S-o-b paragraph in the middle' '
2019-08-27 04:05:03 +00:00
append_signoff <<-\E OF >actual &&
subject
2013-02-12 10:17:37 +00:00
2019-08-27 04:05:03 +00:00
Signed-off-by: my@house
Signed-off-by: your@house
2013-02-12 10:17:37 +00:00
2019-08-27 04:05:03 +00:00
A lot of houses.
EOF
cat >expect <<-\E OF &&
4:Subject: [ PATCH] subject
8:
9:Signed-off-by: my@house
10:Signed-off-by: your@house
11:
13:
14:Signed-off-by: C O Mitter <committer@example.com>
EOF
2019-08-27 04:04:52 +00:00
test_cmp expect actual
2013-02-12 10:17:37 +00:00
'
test_expect_success 'signoff: the same signoff at the end' '
2019-08-27 04:05:03 +00:00
append_signoff <<-\E OF >actual &&
subject
2013-02-12 10:17:37 +00:00
2019-08-27 04:05:03 +00:00
body
2013-02-12 10:17:37 +00:00
2019-08-27 04:05:03 +00:00
Signed-off-by: C O Mitter <committer@example.com>
EOF
cat >expect <<-\E OF &&
4:Subject: [ PATCH] subject
8:
10:
11:Signed-off-by: C O Mitter <committer@example.com>
EOF
2019-08-27 04:04:52 +00:00
test_cmp expect actual
2013-02-12 10:17:37 +00:00
'
test_expect_success 'signoff: the same signoff at the end, no trailing NL' '
printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" |
append_signoff >actual &&
2019-08-27 04:05:03 +00:00
cat >expect <<-\E OF &&
4:Subject: [ PATCH] subject
8:
9:Signed-off-by: C O Mitter <committer@example.com>
EOF
2019-08-27 04:04:52 +00:00
test_cmp expect actual
2013-02-12 10:17:37 +00:00
'
test_expect_success 'signoff: the same signoff NOT at the end' '
2019-08-27 04:05:03 +00:00
append_signoff <<-\E OF >actual &&
subject
2013-02-12 10:17:37 +00:00
2019-08-27 04:05:03 +00:00
body
2013-02-12 10:17:37 +00:00
2019-08-27 04:05:03 +00:00
Signed-off-by: C O Mitter <committer@example.com>
Signed-off-by: my@house
EOF
cat >expect <<-\E OF &&
4:Subject: [ PATCH] subject
8:
10:
11:Signed-off-by: C O Mitter <committer@example.com>
12:Signed-off-by: my@house
EOF
2019-08-27 04:04:52 +00:00
test_cmp expect actual
2013-02-12 10:17:37 +00:00
'
2016-11-02 17:29:20 +00:00
test_expect_success 'signoff: tolerate garbage in conforming footer' '
2019-08-27 04:05:03 +00:00
append_signoff <<-\E OF >actual &&
subject
2013-02-12 10:17:37 +00:00
2019-08-27 04:05:03 +00:00
body
2013-02-12 10:17:37 +00:00
2019-08-27 04:05:03 +00:00
Tested-by: my@house
Some Trash
Signed-off-by: C O Mitter <committer@example.com>
EOF
cat >expect <<-\E OF &&
4:Subject: [ PATCH] subject
8:
10:
13:Signed-off-by: C O Mitter <committer@example.com>
EOF
2019-08-27 04:04:52 +00:00
test_cmp expect actual
2016-11-02 17:29:20 +00:00
'
test_expect_success 'signoff: respect trailer config' '
2019-08-27 04:05:03 +00:00
append_signoff <<-\E OF >actual &&
subject
2016-11-02 17:29:20 +00:00
2019-08-27 04:05:03 +00:00
Myfooter: x
Some Trash
EOF
cat >expect <<-\E OF &&
4:Subject: [ PATCH] subject
8:
11:
12:Signed-off-by: C O Mitter <committer@example.com>
EOF
2019-08-27 04:04:52 +00:00
test_cmp expect actual &&
2016-11-02 17:29:20 +00:00
test_config trailer.Myfooter.ifexists add &&
2019-08-27 04:05:03 +00:00
append_signoff <<-\E OF >actual &&
subject
2016-11-02 17:29:20 +00:00
2019-08-27 04:05:03 +00:00
Myfooter: x
Some Trash
EOF
cat >expect <<-\E OF &&
4:Subject: [ PATCH] subject
8:
11:Signed-off-by: C O Mitter <committer@example.com>
EOF
2019-08-27 04:04:52 +00:00
test_cmp expect actual
2013-02-12 10:17:37 +00:00
'
test_expect_success 'signoff: footer begins with non-signoff without @ sign' '
2019-08-27 04:05:03 +00:00
append_signoff <<-\E OF >actual &&
subject
2013-02-12 10:17:37 +00:00
2019-08-27 04:05:03 +00:00
body
2013-02-12 10:17:37 +00:00
2019-08-27 04:05:03 +00:00
Reviewed-id: Noone
Tested-by: my@house
Change-id: Ideadbeef
Signed-off-by: C O Mitter <committer@example.com>
Bug: 1234
EOF
cat >expect <<-\E OF &&
4:Subject: [ PATCH] subject
8:
10:
14:Signed-off-by: C O Mitter <committer@example.com>
EOF
2019-08-27 04:04:52 +00:00
test_cmp expect actual
2013-02-12 10:17:37 +00:00
'
2011-09-12 17:46:41 +00:00
test_expect_success 'format patch ignores color.ui' '
test_unconfig color.ui &&
git format-patch --stdout -1 >expect &&
test_config color.ui always &&
git format-patch --stdout -1 >actual &&
test_cmp expect actual
'
2020-05-22 10:46:18 +00:00
test_expect_success 'format patch respects diff.relative' '
rm -rf subdir &&
mkdir subdir &&
echo other content >subdir/file2 &&
git add subdir/file2 &&
git commit -F msg &&
test_unconfig diff.relative &&
git format-patch --relative= subdir --stdout -1 >expect &&
test_config diff.relative true &&
git -C subdir format-patch --stdout -1 >actual &&
test_cmp expect actual
'
2019-10-15 09:06:40 +00:00
test_expect_success 'cover letter with invalid --cover-from-description and config' '
test_config branch.rebuild-1.description " config subject
body" &&
2020-11-18 23:44:27 +00:00
test_must_fail git format-patch --cover-letter --cover-from-description garbage main &&
2019-10-15 09:06:40 +00:00
test_config format.coverFromDescription garbage &&
2020-11-18 23:44:27 +00:00
test_must_fail git format-patch --cover-letter main
2019-10-15 09:06:40 +00:00
'
test_expect_success 'cover letter with format.coverFromDescription = default' '
test_config branch.rebuild-1.description " config subject
body" &&
test_config format.coverFromDescription default &&
git checkout rebuild-1 &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout --cover-letter main >actual &&
2019-10-15 09:06:40 +00:00
grep " ^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\* $" actual &&
! grep " ^\*\*\* BLURB HERE \*\*\* $" actual &&
grep " ^config subject $" actual &&
grep " ^body $" actual
'
test_expect_success 'cover letter with --cover-from-description default' '
test_config branch.rebuild-1.description " config subject
body" &&
git checkout rebuild-1 &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout --cover-letter --cover-from-description default main >actual &&
2019-10-15 09:06:40 +00:00
grep " ^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\* $" actual &&
! grep " ^\*\*\* BLURB HERE \*\*\* $" actual &&
grep " ^config subject $" actual &&
grep " ^body $" actual
'
test_expect_success 'cover letter with format.coverFromDescription = none' '
test_config branch.rebuild-1.description " config subject
body" &&
test_config format.coverFromDescription none &&
git checkout rebuild-1 &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout --cover-letter main >actual &&
2019-10-15 09:06:40 +00:00
grep " ^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\* $" actual &&
grep " ^\*\*\* BLURB HERE \*\*\* $" actual &&
! grep " ^config subject $" actual &&
! grep " ^body $" actual
'
test_expect_success 'cover letter with --cover-from-description none' '
test_config branch.rebuild-1.description " config subject
body" &&
git checkout rebuild-1 &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout --cover-letter --cover-from-description none main >actual &&
2019-10-15 09:06:40 +00:00
grep " ^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\* $" actual &&
grep " ^\*\*\* BLURB HERE \*\*\* $" actual &&
! grep " ^config subject $" actual &&
! grep " ^body $" actual
'
test_expect_success 'cover letter with format.coverFromDescription = message' '
test_config branch.rebuild-1.description " config subject
body" &&
test_config format.coverFromDescription message &&
git checkout rebuild-1 &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout --cover-letter main >actual &&
2019-10-15 09:06:40 +00:00
grep " ^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\* $" actual &&
! grep " ^\*\*\* BLURB HERE \*\*\* $" actual &&
grep " ^config subject $" actual &&
grep " ^body $" actual
'
test_expect_success 'cover letter with --cover-from-description message' '
test_config branch.rebuild-1.description " config subject
body" &&
git checkout rebuild-1 &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout --cover-letter --cover-from-description message main >actual &&
2019-10-15 09:06:40 +00:00
grep " ^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\* $" actual &&
! grep " ^\*\*\* BLURB HERE \*\*\* $" actual &&
grep " ^config subject $" actual &&
grep " ^body $" actual
'
test_expect_success 'cover letter with format.coverFromDescription = subject' '
test_config branch.rebuild-1.description " config subject
body" &&
test_config format.coverFromDescription subject &&
git checkout rebuild-1 &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout --cover-letter main >actual &&
2019-10-15 09:06:40 +00:00
grep " ^Subject: \[PATCH 0/2\] config subject $" actual &&
! grep " ^\*\*\* BLURB HERE \*\*\* $" actual &&
! grep " ^config subject $" actual &&
grep " ^body $" actual
'
test_expect_success 'cover letter with --cover-from-description subject' '
test_config branch.rebuild-1.description " config subject
body" &&
git checkout rebuild-1 &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout --cover-letter --cover-from-description subject main >actual &&
2019-10-15 09:06:40 +00:00
grep " ^Subject: \[PATCH 0/2\] config subject $" actual &&
! grep " ^\*\*\* BLURB HERE \*\*\* $" actual &&
! grep " ^config subject $" actual &&
grep " ^body $" actual
'
2023-11-09 11:19:56 +00:00
test_expect_success 'cover letter with --cover-from-description subject (UTF-8 subject line)' '
test_config branch.rebuild-1.description " Café?
body" &&
git checkout rebuild-1 &&
git format-patch --stdout --cover-letter --cover-from-description subject --encode-email-headers main >actual &&
grep " ^Subject: \[PATCH 0/2\] =?UTF-8?q?Caf=C3=A9=3F?= $" actual &&
! grep "Café" actual
'
2019-10-15 09:06:40 +00:00
test_expect_success 'cover letter with format.coverFromDescription = auto (short subject line)' '
test_config branch.rebuild-1.description " config subject
body" &&
test_config format.coverFromDescription auto &&
git checkout rebuild-1 &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout --cover-letter main >actual &&
2019-10-15 09:06:40 +00:00
grep " ^Subject: \[PATCH 0/2\] config subject $" actual &&
! grep " ^\*\*\* BLURB HERE \*\*\* $" actual &&
! grep " ^config subject $" actual &&
grep " ^body $" actual
'
test_expect_success 'cover letter with --cover-from-description auto (short subject line)' '
test_config branch.rebuild-1.description " config subject
body" &&
git checkout rebuild-1 &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout --cover-letter --cover-from-description auto main >actual &&
2019-10-15 09:06:40 +00:00
grep " ^Subject: \[PATCH 0/2\] config subject $" actual &&
! grep " ^\*\*\* BLURB HERE \*\*\* $" actual &&
! grep " ^config subject $" actual &&
grep " ^body $" actual
'
test_expect_success 'cover letter with format.coverFromDescription = auto (long subject line)' '
test_config branch.rebuild-1.description " this is a really long first line and it is over 100 characters long which is the threshold for long subjects
body" &&
test_config format.coverFromDescription auto &&
git checkout rebuild-1 &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout --cover-letter main >actual &&
2019-10-15 09:06:40 +00:00
grep " ^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\* $" actual &&
! grep " ^\*\*\* BLURB HERE \*\*\* $" actual &&
grep " ^this is a really long first line and it is over 100 characters long which is the threshold for long subjects $" actual &&
grep " ^body $" actual
'
test_expect_success 'cover letter with --cover-from-description auto (long subject line)' '
test_config branch.rebuild-1.description " this is a really long first line and it is over 100 characters long which is the threshold for long subjects
body" &&
git checkout rebuild-1 &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout --cover-letter --cover-from-description auto main >actual &&
2019-10-15 09:06:40 +00:00
grep " ^Subject: \[PATCH 0/2\] \*\*\* SUBJECT HERE \*\*\* $" actual &&
! grep " ^\*\*\* BLURB HERE \*\*\* $" actual &&
grep " ^this is a really long first line and it is over 100 characters long which is the threshold for long subjects $" actual &&
grep " ^body $" actual
'
test_expect_success 'cover letter with command-line --cover-from-description overrides config' '
test_config branch.rebuild-1.description " config subject
body" &&
test_config format.coverFromDescription none &&
git checkout rebuild-1 &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout --cover-letter --cover-from-description subject main >actual &&
2019-10-15 09:06:40 +00:00
grep " ^Subject: \[PATCH 0/2\] config subject $" actual &&
! grep " ^\*\*\* BLURB HERE \*\*\* $" actual &&
! grep " ^config subject $" actual &&
grep " ^body $" actual
'
2013-01-03 14:03:09 +00:00
test_expect_success 'cover letter using branch description (1)' '
git checkout rebuild-1 &&
test_config branch.rebuild-1.description hello &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout --cover-letter main >actual &&
2019-08-27 04:05:05 +00:00
grep hello actual
2013-01-03 14:03:09 +00:00
'
test_expect_success 'cover letter using branch description (2)' '
git checkout rebuild-1 &&
test_config branch.rebuild-1.description hello &&
git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
2019-08-27 04:05:05 +00:00
grep hello actual
2013-01-03 14:03:09 +00:00
'
test_expect_success 'cover letter using branch description (3)' '
git checkout rebuild-1 &&
test_config branch.rebuild-1.description hello &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout --cover-letter ^main rebuild-1 >actual &&
2019-08-27 04:05:05 +00:00
grep hello actual
2013-01-03 14:03:09 +00:00
'
2013-01-03 14:03:10 +00:00
test_expect_success 'cover letter using branch description (4)' '
git checkout rebuild-1 &&
test_config branch.rebuild-1.description hello &&
2020-11-18 23:44:27 +00:00
git format-patch --stdout --cover-letter main.. >actual &&
2019-08-27 04:05:05 +00:00
grep hello actual
2013-01-03 14:03:10 +00:00
'
test_expect_success 'cover letter using branch description (5)' '
git checkout rebuild-1 &&
test_config branch.rebuild-1.description hello &&
git format-patch --stdout --cover-letter -2 HEAD >actual &&
2019-08-27 04:05:05 +00:00
grep hello actual
2013-01-03 14:03:10 +00:00
'
2013-01-03 16:16:37 +00:00
test_expect_success 'cover letter using branch description (6)' '
git checkout rebuild-1 &&
test_config branch.rebuild-1.description hello &&
git format-patch --stdout --cover-letter -2 >actual &&
2019-08-27 04:05:05 +00:00
grep hello actual
2013-01-03 16:16:37 +00:00
'
2023-08-21 17:07:20 +00:00
test_expect_success 'cover letter with --description-file' '
test_when_finished "rm -f description.txt" &&
cat >description.txt <<-\E OF &&
subject from file
body from file
EOF
git checkout rebuild-1 &&
git format-patch --stdout --cover-letter --cover-from-description auto \
--description-file description.txt main >actual &&
grep " ^Subject: \[PATCH 0/2\] subject from file $" actual &&
grep " ^body from file $" actual
'
2013-04-07 17:46:20 +00:00
test_expect_success 'cover letter with nothing' '
git format-patch --stdout --cover-letter >actual &&
test_line_count = 0 actual
'
2013-04-07 17:46:23 +00:00
test_expect_success 'cover letter auto' '
mkdir -p tmp &&
test_when_finished " rm -rf tmp;
git config --unset format.coverletter" &&
git config format.coverletter auto &&
git format-patch -o tmp -1 >list &&
test_line_count = 1 list &&
git format-patch -o tmp -2 >list &&
test_line_count = 3 list
'
test_expect_success 'cover letter auto user override' '
mkdir -p tmp &&
test_when_finished " rm -rf tmp;
git config --unset format.coverletter" &&
git config format.coverletter auto &&
git format-patch -o tmp --cover-letter -1 >list &&
test_line_count = 2 list &&
git format-patch -o tmp --cover-letter -2 >list &&
test_line_count = 3 list &&
git format-patch -o tmp --no-cover-letter -1 >list &&
test_line_count = 1 list &&
git format-patch -o tmp --no-cover-letter -2 >list &&
test_line_count = 2 list
'
2015-12-15 01:52:04 +00:00
test_expect_success 'format-patch --zero-commit' '
git format-patch --zero-commit --stdout v2..v1 >patch2 &&
grep "^From " patch2 | sort | uniq >actual &&
2018-05-13 02:24:13 +00:00
echo " From $ZERO_OID Mon Sep 17 00:00:00 2001 " >expect &&
2015-12-15 01:52:04 +00:00
test_cmp expect actual
'
2015-12-15 01:52:05 +00:00
test_expect_success 'From line has expected format' '
git format-patch --stdout v2..v1 >patch2 &&
grep "^From " patch2 >from &&
2018-05-13 02:24:15 +00:00
grep " ^From $OID_REGEX Mon Sep 17 00:00:00 2001 $" patch2 >filtered &&
2015-12-15 01:52:05 +00:00
test_cmp from filtered
'
2019-10-11 08:36:41 +00:00
test_expect_success 'format-patch -o with no leading directories' '
rm -fr patches &&
2020-11-18 23:44:27 +00:00
git format-patch -o patches main..side &&
count = $( git rev-list --count main..side) &&
2019-10-11 08:36:41 +00:00
ls patches >list &&
test_line_count = $count list
'
test_expect_success 'format-patch -o with leading existing directories' '
2019-10-21 13:23:42 +00:00
rm -rf existing-dir &&
mkdir existing-dir &&
2020-11-18 23:44:27 +00:00
git format-patch -o existing-dir/patches main..side &&
count = $( git rev-list --count main..side) &&
2019-10-21 13:23:42 +00:00
ls existing-dir/patches >list &&
2019-10-11 08:36:41 +00:00
test_line_count = $count list
'
test_expect_success 'format-patch -o with leading non-existing directories' '
2019-10-21 13:23:42 +00:00
rm -rf non-existing-dir &&
2020-11-18 23:44:27 +00:00
git format-patch -o non-existing-dir/patches main..side &&
count = $( git rev-list --count main..side) &&
2019-10-21 13:23:42 +00:00
test_path_is_dir non-existing-dir &&
ls non-existing-dir/patches >list &&
2019-10-11 08:36:41 +00:00
test_line_count = $count list
'
2016-01-13 13:20:11 +00:00
test_expect_success 'format-patch format.outputDirectory option' '
test_config format.outputDirectory patches &&
rm -fr patches &&
2020-11-18 23:44:27 +00:00
git format-patch main..side &&
count = $( git rev-list --count main..side) &&
2019-10-08 09:14:11 +00:00
ls patches >list &&
test_line_count = $count list
2016-01-13 13:20:11 +00:00
'
test_expect_success 'format-patch -o overrides format.outputDirectory' '
test_config format.outputDirectory patches &&
rm -fr patches patchset &&
2020-11-18 23:44:27 +00:00
git format-patch main..side -o patchset &&
2016-01-13 13:20:11 +00:00
test_path_is_missing patches &&
test_path_is_dir patchset
'
2020-11-04 19:28:31 +00:00
test_expect_success 'format-patch forbids multiple outputs' '
format-patch: support --output option
We've never intended to support diff's --output option in format-patch.
And until baa4adc66a (parse-options: disable option abbreviation with
PARSE_OPT_KEEP_UNKNOWN, 2019-01-27), it was impossible to trigger. We
first parse the format-patch options before handing the remainder off to
setup_revisions(). Before that commit, we'd accept "--output=foo" as an
abbreviation for "--output-directory=foo". But afterwards, we don't
check abbreviations, and --output gets passed to the diff code.
This results in nonsense behavior and bugs. The diff code will have
opened a filehandle at rev.diffopt.file, but we'll overwrite that with
our own handles that we open for each individual patch file. So the
--output file will always just be empty. But worse, the diff code also
sets rev.diffopt.close_file, so log_tree_commit() will close the
filehandle itself. And then the main loop in cmd_format_patch() will try
to close it again, resulting in a double-free.
The simplest solution would be to just disallow --output with
format-patch, as nobody ever intended it to work. However, we have
accidentally documented it (because format-patch includes diff-options).
And it does work with "git log", which writes the whole output to the
specified file. It's easy enough to make that work for format-patch,
too: it's really the same as --stdout, but pointed at a specific file.
We can detect the use of the --output option by the "close_file" flag
(note that we can't use rev.diffopt.file, since the diff setup will
otherwise set it to stdout). So we just need to unset that flag, but
don't have to do anything else. Our situation is otherwise exactly like
--stdout (note that we don't fclose() the file, but nor does the stdout
case; exiting the program takes care of that for us).
Reported-by: Johannes Postler <johannes.postler@txture.io>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-04 19:28:36 +00:00
rm -fr outfile outdir &&
2020-11-04 19:28:31 +00:00
test_must_fail \
format-patch: support --output option
We've never intended to support diff's --output option in format-patch.
And until baa4adc66a (parse-options: disable option abbreviation with
PARSE_OPT_KEEP_UNKNOWN, 2019-01-27), it was impossible to trigger. We
first parse the format-patch options before handing the remainder off to
setup_revisions(). Before that commit, we'd accept "--output=foo" as an
abbreviation for "--output-directory=foo". But afterwards, we don't
check abbreviations, and --output gets passed to the diff code.
This results in nonsense behavior and bugs. The diff code will have
opened a filehandle at rev.diffopt.file, but we'll overwrite that with
our own handles that we open for each individual patch file. So the
--output file will always just be empty. But worse, the diff code also
sets rev.diffopt.close_file, so log_tree_commit() will close the
filehandle itself. And then the main loop in cmd_format_patch() will try
to close it again, resulting in a double-free.
The simplest solution would be to just disallow --output with
format-patch, as nobody ever intended it to work. However, we have
accidentally documented it (because format-patch includes diff-options).
And it does work with "git log", which writes the whole output to the
specified file. It's easy enough to make that work for format-patch,
too: it's really the same as --stdout, but pointed at a specific file.
We can detect the use of the --output option by the "close_file" flag
(note that we can't use rev.diffopt.file, since the diff setup will
otherwise set it to stdout). So we just need to unset that flag, but
don't have to do anything else. Our situation is otherwise exactly like
--stdout (note that we don't fclose() the file, but nor does the stdout
case; exiting the program takes care of that for us).
Reported-by: Johannes Postler <johannes.postler@txture.io>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-04 19:28:36 +00:00
git format-patch --stdout --output-directory= outdir &&
test_must_fail \
git format-patch --stdout --output= outfile &&
test_must_fail \
git format-patch --output= outfile --output-directory= outdir
2020-11-04 19:28:31 +00:00
'
test_expect_success 'configured outdir does not conflict with output options' '
format-patch: support --output option
We've never intended to support diff's --output option in format-patch.
And until baa4adc66a (parse-options: disable option abbreviation with
PARSE_OPT_KEEP_UNKNOWN, 2019-01-27), it was impossible to trigger. We
first parse the format-patch options before handing the remainder off to
setup_revisions(). Before that commit, we'd accept "--output=foo" as an
abbreviation for "--output-directory=foo". But afterwards, we don't
check abbreviations, and --output gets passed to the diff code.
This results in nonsense behavior and bugs. The diff code will have
opened a filehandle at rev.diffopt.file, but we'll overwrite that with
our own handles that we open for each individual patch file. So the
--output file will always just be empty. But worse, the diff code also
sets rev.diffopt.close_file, so log_tree_commit() will close the
filehandle itself. And then the main loop in cmd_format_patch() will try
to close it again, resulting in a double-free.
The simplest solution would be to just disallow --output with
format-patch, as nobody ever intended it to work. However, we have
accidentally documented it (because format-patch includes diff-options).
And it does work with "git log", which writes the whole output to the
specified file. It's easy enough to make that work for format-patch,
too: it's really the same as --stdout, but pointed at a specific file.
We can detect the use of the --output option by the "close_file" flag
(note that we can't use rev.diffopt.file, since the diff setup will
otherwise set it to stdout). So we just need to unset that flag, but
don't have to do anything else. Our situation is otherwise exactly like
--stdout (note that we don't fclose() the file, but nor does the stdout
case; exiting the program takes care of that for us).
Reported-by: Johannes Postler <johannes.postler@txture.io>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-04 19:28:36 +00:00
rm -fr outfile outdir &&
2020-11-04 19:28:31 +00:00
test_config format.outputDirectory outdir &&
git format-patch --stdout &&
format-patch: support --output option
We've never intended to support diff's --output option in format-patch.
And until baa4adc66a (parse-options: disable option abbreviation with
PARSE_OPT_KEEP_UNKNOWN, 2019-01-27), it was impossible to trigger. We
first parse the format-patch options before handing the remainder off to
setup_revisions(). Before that commit, we'd accept "--output=foo" as an
abbreviation for "--output-directory=foo". But afterwards, we don't
check abbreviations, and --output gets passed to the diff code.
This results in nonsense behavior and bugs. The diff code will have
opened a filehandle at rev.diffopt.file, but we'll overwrite that with
our own handles that we open for each individual patch file. So the
--output file will always just be empty. But worse, the diff code also
sets rev.diffopt.close_file, so log_tree_commit() will close the
filehandle itself. And then the main loop in cmd_format_patch() will try
to close it again, resulting in a double-free.
The simplest solution would be to just disallow --output with
format-patch, as nobody ever intended it to work. However, we have
accidentally documented it (because format-patch includes diff-options).
And it does work with "git log", which writes the whole output to the
specified file. It's easy enough to make that work for format-patch,
too: it's really the same as --stdout, but pointed at a specific file.
We can detect the use of the --output option by the "close_file" flag
(note that we can't use rev.diffopt.file, since the diff setup will
otherwise set it to stdout). So we just need to unset that flag, but
don't have to do anything else. Our situation is otherwise exactly like
--stdout (note that we don't fclose() the file, but nor does the stdout
case; exiting the program takes care of that for us).
Reported-by: Johannes Postler <johannes.postler@txture.io>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-04 19:28:36 +00:00
test_path_is_missing outdir &&
git format-patch --output= outfile &&
2020-11-04 19:28:31 +00:00
test_path_is_missing outdir
'
format-patch: support --output option
We've never intended to support diff's --output option in format-patch.
And until baa4adc66a (parse-options: disable option abbreviation with
PARSE_OPT_KEEP_UNKNOWN, 2019-01-27), it was impossible to trigger. We
first parse the format-patch options before handing the remainder off to
setup_revisions(). Before that commit, we'd accept "--output=foo" as an
abbreviation for "--output-directory=foo". But afterwards, we don't
check abbreviations, and --output gets passed to the diff code.
This results in nonsense behavior and bugs. The diff code will have
opened a filehandle at rev.diffopt.file, but we'll overwrite that with
our own handles that we open for each individual patch file. So the
--output file will always just be empty. But worse, the diff code also
sets rev.diffopt.close_file, so log_tree_commit() will close the
filehandle itself. And then the main loop in cmd_format_patch() will try
to close it again, resulting in a double-free.
The simplest solution would be to just disallow --output with
format-patch, as nobody ever intended it to work. However, we have
accidentally documented it (because format-patch includes diff-options).
And it does work with "git log", which writes the whole output to the
specified file. It's easy enough to make that work for format-patch,
too: it's really the same as --stdout, but pointed at a specific file.
We can detect the use of the --output option by the "close_file" flag
(note that we can't use rev.diffopt.file, since the diff setup will
otherwise set it to stdout). So we just need to unset that flag, but
don't have to do anything else. Our situation is otherwise exactly like
--stdout (note that we don't fclose() the file, but nor does the stdout
case; exiting the program takes care of that for us).
Reported-by: Johannes Postler <johannes.postler@txture.io>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-04 19:28:36 +00:00
test_expect_success 'format-patch --output' '
rm -fr outfile &&
git format-patch -3 --stdout HEAD >expect &&
git format-patch -3 --output= outfile HEAD &&
test_cmp expect outfile
'
test_expect_success 'format-patch --cover-letter --output' '
rm -fr outfile &&
git format-patch --cover-letter -3 --stdout HEAD >expect &&
git format-patch --cover-letter -3 --output= outfile HEAD &&
test_cmp expect outfile
'
format-patch: add '--base' option to record base tree info
Maintainers or third party testers may want to know the exact base tree
the patch series applies to. Teach git format-patch a '--base' option
to record the base tree info and append it at the end of the first
message (either the cover letter or the first patch in the series).
The base tree info consists of the "base commit", which is a well-known
commit that is part of the stable part of the project history everybody
else works off of, and zero or more "prerequisite patches", which are
well-known patches in flight that is not yet part of the "base commit"
that need to be applied on top of "base commit" in topological order
before the patches can be applied.
The "base commit" is shown as "base-commit: " followed by the 40-hex of
the commit object name. A "prerequisite patch" is shown as
"prerequisite-patch-id: " followed by the 40-hex "patch id", which can
be obtained by passing the patch through the "git patch-id --stable"
command.
Imagine that on top of the public commit P, you applied well-known
patches X, Y and Z from somebody else, and then built your three-patch
series A, B, C, the history would be like:
---P---X---Y---Z---A---B---C
With "git format-patch --base=P -3 C" (or variants thereof, e.g. with
"--cover-letter" of using "Z..C" instead of "-3 C" to specify the
range), the base tree information block is shown at the end of the
first message the command outputs (either the first patch, or the
cover letter), like this:
base-commit: P
prerequisite-patch-id: X
prerequisite-patch-id: Y
prerequisite-patch-id: Z
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Wu Fengguang <fengguang.wu@intel.com>
Signed-off-by: Xiaolong Ye <xiaolong.ye@intel.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-04-26 07:51:22 +00:00
test_expect_success 'format-patch --base' '
2019-04-26 23:51:56 +00:00
git checkout patchid &&
2019-08-27 04:05:15 +00:00
git format-patch --stdout --base= HEAD~3 -1 >patch &&
tail -n 7 patch >actual1 &&
git format-patch --stdout --base= HEAD~3 HEAD~.. >patch &&
tail -n 7 patch >actual2 &&
2019-08-27 04:04:52 +00:00
echo >expect &&
2019-08-27 04:05:15 +00:00
git rev-parse HEAD~3 >commit-id-base &&
echo " base-commit: $( cat commit-id-base) " >>expect &&
git show --patch HEAD~2 >patch &&
git patch-id --stable <patch >patch.id.raw &&
awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>expect &&
git show --patch HEAD~1 >patch &&
git patch-id --stable <patch >patch.id.raw &&
awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>expect &&
2019-08-27 04:05:00 +00:00
signature >>expect &&
2019-08-27 04:04:52 +00:00
test_cmp expect actual1 &&
test_cmp expect actual2 &&
2019-08-27 04:05:15 +00:00
2019-04-26 23:51:56 +00:00
echo >fail &&
2019-08-27 04:05:15 +00:00
echo " base-commit: $( cat commit-id-base) " >>fail &&
git show --patch HEAD~2 >patch &&
git patch-id --unstable <patch >patch.id.raw &&
awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>fail &&
git show --patch HEAD~1 >patch &&
git patch-id --unstable <patch >patch.id.raw &&
awk "{print \"prerequisite-patch-id:\", \$1}" <patch.id.raw >>fail &&
2019-08-27 04:05:00 +00:00
signature >>fail &&
2019-04-26 23:51:56 +00:00
! test_cmp fail actual1 &&
! test_cmp fail actual2
format-patch: add '--base' option to record base tree info
Maintainers or third party testers may want to know the exact base tree
the patch series applies to. Teach git format-patch a '--base' option
to record the base tree info and append it at the end of the first
message (either the cover letter or the first patch in the series).
The base tree info consists of the "base commit", which is a well-known
commit that is part of the stable part of the project history everybody
else works off of, and zero or more "prerequisite patches", which are
well-known patches in flight that is not yet part of the "base commit"
that need to be applied on top of "base commit" in topological order
before the patches can be applied.
The "base commit" is shown as "base-commit: " followed by the 40-hex of
the commit object name. A "prerequisite patch" is shown as
"prerequisite-patch-id: " followed by the 40-hex "patch id", which can
be obtained by passing the patch through the "git patch-id --stable"
command.
Imagine that on top of the public commit P, you applied well-known
patches X, Y and Z from somebody else, and then built your three-patch
series A, B, C, the history would be like:
---P---X---Y---Z---A---B---C
With "git format-patch --base=P -3 C" (or variants thereof, e.g. with
"--cover-letter" of using "Z..C" instead of "-3 C" to specify the
range), the base tree information block is shown at the end of the
first message the command outputs (either the first patch, or the
cover letter), like this:
base-commit: P
prerequisite-patch-id: X
prerequisite-patch-id: Y
prerequisite-patch-id: Z
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Wu Fengguang <fengguang.wu@intel.com>
Signed-off-by: Xiaolong Ye <xiaolong.ye@intel.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-04-26 07:51:22 +00:00
'
test_expect_success 'format-patch --base errors out when base commit is in revision list' '
test_must_fail git format-patch --base= HEAD -2 &&
test_must_fail git format-patch --base= HEAD~1 -2 &&
git format-patch --stdout --base= HEAD~2 -2 >patch &&
grep "^base-commit:" patch >actual &&
2019-08-27 04:05:15 +00:00
git rev-parse HEAD~2 >commit-id-base &&
echo " base-commit: $( cat commit-id-base) " >expect &&
2019-08-27 04:04:52 +00:00
test_cmp expect actual
format-patch: add '--base' option to record base tree info
Maintainers or third party testers may want to know the exact base tree
the patch series applies to. Teach git format-patch a '--base' option
to record the base tree info and append it at the end of the first
message (either the cover letter or the first patch in the series).
The base tree info consists of the "base commit", which is a well-known
commit that is part of the stable part of the project history everybody
else works off of, and zero or more "prerequisite patches", which are
well-known patches in flight that is not yet part of the "base commit"
that need to be applied on top of "base commit" in topological order
before the patches can be applied.
The "base commit" is shown as "base-commit: " followed by the 40-hex of
the commit object name. A "prerequisite patch" is shown as
"prerequisite-patch-id: " followed by the 40-hex "patch id", which can
be obtained by passing the patch through the "git patch-id --stable"
command.
Imagine that on top of the public commit P, you applied well-known
patches X, Y and Z from somebody else, and then built your three-patch
series A, B, C, the history would be like:
---P---X---Y---Z---A---B---C
With "git format-patch --base=P -3 C" (or variants thereof, e.g. with
"--cover-letter" of using "Z..C" instead of "-3 C" to specify the
range), the base tree information block is shown at the end of the
first message the command outputs (either the first patch, or the
cover letter), like this:
base-commit: P
prerequisite-patch-id: X
prerequisite-patch-id: Y
prerequisite-patch-id: Z
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Wu Fengguang <fengguang.wu@intel.com>
Signed-off-by: Xiaolong Ye <xiaolong.ye@intel.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-04-26 07:51:22 +00:00
'
test_expect_success 'format-patch --base errors out when base commit is not ancestor of revision list' '
# For history as below:
#
# ---Q---P---Z---Y---*---X
# \ /
# ------------W
#
# If "format-patch Z..X" is given, P and Z can not be specified as the base commit
2020-11-18 23:44:27 +00:00
git checkout -b topic1 main &&
format-patch: add '--base' option to record base tree info
Maintainers or third party testers may want to know the exact base tree
the patch series applies to. Teach git format-patch a '--base' option
to record the base tree info and append it at the end of the first
message (either the cover letter or the first patch in the series).
The base tree info consists of the "base commit", which is a well-known
commit that is part of the stable part of the project history everybody
else works off of, and zero or more "prerequisite patches", which are
well-known patches in flight that is not yet part of the "base commit"
that need to be applied on top of "base commit" in topological order
before the patches can be applied.
The "base commit" is shown as "base-commit: " followed by the 40-hex of
the commit object name. A "prerequisite patch" is shown as
"prerequisite-patch-id: " followed by the 40-hex "patch id", which can
be obtained by passing the patch through the "git patch-id --stable"
command.
Imagine that on top of the public commit P, you applied well-known
patches X, Y and Z from somebody else, and then built your three-patch
series A, B, C, the history would be like:
---P---X---Y---Z---A---B---C
With "git format-patch --base=P -3 C" (or variants thereof, e.g. with
"--cover-letter" of using "Z..C" instead of "-3 C" to specify the
range), the base tree information block is shown at the end of the
first message the command outputs (either the first patch, or the
cover letter), like this:
base-commit: P
prerequisite-patch-id: X
prerequisite-patch-id: Y
prerequisite-patch-id: Z
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Wu Fengguang <fengguang.wu@intel.com>
Signed-off-by: Xiaolong Ye <xiaolong.ye@intel.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-04-26 07:51:22 +00:00
git rev-parse HEAD >commit-id-base &&
test_commit P &&
git rev-parse HEAD >commit-id-P &&
test_commit Z &&
git rev-parse HEAD >commit-id-Z &&
test_commit Y &&
2020-11-18 23:44:27 +00:00
git checkout -b topic2 main &&
format-patch: add '--base' option to record base tree info
Maintainers or third party testers may want to know the exact base tree
the patch series applies to. Teach git format-patch a '--base' option
to record the base tree info and append it at the end of the first
message (either the cover letter or the first patch in the series).
The base tree info consists of the "base commit", which is a well-known
commit that is part of the stable part of the project history everybody
else works off of, and zero or more "prerequisite patches", which are
well-known patches in flight that is not yet part of the "base commit"
that need to be applied on top of "base commit" in topological order
before the patches can be applied.
The "base commit" is shown as "base-commit: " followed by the 40-hex of
the commit object name. A "prerequisite patch" is shown as
"prerequisite-patch-id: " followed by the 40-hex "patch id", which can
be obtained by passing the patch through the "git patch-id --stable"
command.
Imagine that on top of the public commit P, you applied well-known
patches X, Y and Z from somebody else, and then built your three-patch
series A, B, C, the history would be like:
---P---X---Y---Z---A---B---C
With "git format-patch --base=P -3 C" (or variants thereof, e.g. with
"--cover-letter" of using "Z..C" instead of "-3 C" to specify the
range), the base tree information block is shown at the end of the
first message the command outputs (either the first patch, or the
cover letter), like this:
base-commit: P
prerequisite-patch-id: X
prerequisite-patch-id: Y
prerequisite-patch-id: Z
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Wu Fengguang <fengguang.wu@intel.com>
Signed-off-by: Xiaolong Ye <xiaolong.ye@intel.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-04-26 07:51:22 +00:00
test_commit W &&
git merge topic1 &&
test_commit X &&
test_must_fail git format-patch --base= $( cat commit-id-P) -3 &&
test_must_fail git format-patch --base= $( cat commit-id-Z) -3 &&
git format-patch --stdout --base= $( cat commit-id-base) -3 >patch &&
grep "^base-commit:" patch >actual &&
2019-08-27 04:04:52 +00:00
echo " base-commit: $( cat commit-id-base) " >expect &&
test_cmp expect actual
format-patch: add '--base' option to record base tree info
Maintainers or third party testers may want to know the exact base tree
the patch series applies to. Teach git format-patch a '--base' option
to record the base tree info and append it at the end of the first
message (either the cover letter or the first patch in the series).
The base tree info consists of the "base commit", which is a well-known
commit that is part of the stable part of the project history everybody
else works off of, and zero or more "prerequisite patches", which are
well-known patches in flight that is not yet part of the "base commit"
that need to be applied on top of "base commit" in topological order
before the patches can be applied.
The "base commit" is shown as "base-commit: " followed by the 40-hex of
the commit object name. A "prerequisite patch" is shown as
"prerequisite-patch-id: " followed by the 40-hex "patch id", which can
be obtained by passing the patch through the "git patch-id --stable"
command.
Imagine that on top of the public commit P, you applied well-known
patches X, Y and Z from somebody else, and then built your three-patch
series A, B, C, the history would be like:
---P---X---Y---Z---A---B---C
With "git format-patch --base=P -3 C" (or variants thereof, e.g. with
"--cover-letter" of using "Z..C" instead of "-3 C" to specify the
range), the base tree information block is shown at the end of the
first message the command outputs (either the first patch, or the
cover letter), like this:
base-commit: P
prerequisite-patch-id: X
prerequisite-patch-id: Y
prerequisite-patch-id: Z
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Wu Fengguang <fengguang.wu@intel.com>
Signed-off-by: Xiaolong Ye <xiaolong.ye@intel.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-04-26 07:51:22 +00:00
'
2016-04-26 07:51:23 +00:00
test_expect_success 'format-patch --base=auto' '
2020-11-18 23:44:27 +00:00
git checkout -b upstream main &&
2016-04-26 07:51:23 +00:00
git checkout -b local upstream &&
git branch --set-upstream-to= upstream &&
test_commit N1 &&
test_commit N2 &&
git format-patch --stdout --base= auto -2 >patch &&
grep "^base-commit:" patch >actual &&
2019-08-27 04:05:15 +00:00
git rev-parse upstream >commit-id-base &&
echo " base-commit: $( cat commit-id-base) " >expect &&
2019-08-27 04:04:52 +00:00
test_cmp expect actual
2016-04-26 07:51:23 +00:00
'
test_expect_success 'format-patch errors out when history involves criss-cross' '
# setup criss-cross history
#
# B---M1---D
# / \ /
# A X
# \ / \
# C---M2---E
#
2020-11-18 23:44:27 +00:00
git checkout main &&
2016-04-26 07:51:23 +00:00
test_commit A &&
2020-11-18 23:44:27 +00:00
git checkout -b xb main &&
2016-04-26 07:51:23 +00:00
test_commit B &&
2020-11-18 23:44:27 +00:00
git checkout -b xc main &&
2016-04-26 07:51:23 +00:00
test_commit C &&
git checkout -b xbc xb -- &&
git merge xc &&
git checkout -b xcb xc -- &&
git branch --set-upstream-to= xbc &&
git merge xb &&
git checkout xbc &&
test_commit D &&
git checkout xcb &&
test_commit E &&
test_must_fail git format-patch --base= auto -1
'
format-patch: teach format.useAutoBase "whenAble" option
The format.useAutoBase configuration option exists to allow users to
enable '--base=auto' for format-patch by default.
This can sometimes lead to poor workflow, due to unexpected failures
when attempting to format an ancient patch:
$ git format-patch -1 <an old commit>
fatal: base commit shouldn't be in revision list
This can be very confusing, as it is not necessarily immediately obvious
that the user requested a --base (since this was in the configuration,
not on the command line).
We do want --base=auto to fail when it cannot provide a suitable base,
as it would be equally confusing if a formatted patch did not include
the base information when it was requested.
Teach format.useAutoBase a new mode, "whenAble". This mode will cause
format-patch to attempt to include a base commit when it can. However,
if no valid base commit can be found, then format-patch will continue
formatting the patch without a base commit.
In order to avoid making yet another branch name unusable with --base,
do not teach --base=whenAble or --base=whenable.
Instead, refactor the base_commit option to use a callback, and rely on
the global configuration variable auto_base.
This does mean that a user cannot request this optional base commit
generation from the command line. However, this is likely not too
valuable. If the user requests base information manually, they will be
immediately informed of the failure to acquire a suitable base commit.
This allows the user to make an informed choice about whether to
continue the format.
Add tests to cover the new mode of operation for --base.
Signed-off-by: Jacob Keller <jacob.keller@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-10-01 21:46:53 +00:00
test_expect_success 'format-patch format.useAutoBase whenAble history involves criss-cross' '
test_config format.useAutoBase whenAble &&
git format-patch -1 >patch &&
! grep "^base-commit:" patch
'
2019-12-04 21:25:00 +00:00
test_expect_success 'format-patch format.useAutoBase option' '
2016-04-26 07:51:24 +00:00
git checkout local &&
2019-12-04 21:25:00 +00:00
test_config format.useAutoBase true &&
2016-04-26 07:51:24 +00:00
git format-patch --stdout -1 >patch &&
grep "^base-commit:" patch >actual &&
2019-08-27 04:05:15 +00:00
git rev-parse upstream >commit-id-base &&
echo " base-commit: $( cat commit-id-base) " >expect &&
2019-08-27 04:04:52 +00:00
test_cmp expect actual
2016-04-26 07:51:24 +00:00
'
format-patch: teach format.useAutoBase "whenAble" option
The format.useAutoBase configuration option exists to allow users to
enable '--base=auto' for format-patch by default.
This can sometimes lead to poor workflow, due to unexpected failures
when attempting to format an ancient patch:
$ git format-patch -1 <an old commit>
fatal: base commit shouldn't be in revision list
This can be very confusing, as it is not necessarily immediately obvious
that the user requested a --base (since this was in the configuration,
not on the command line).
We do want --base=auto to fail when it cannot provide a suitable base,
as it would be equally confusing if a formatted patch did not include
the base information when it was requested.
Teach format.useAutoBase a new mode, "whenAble". This mode will cause
format-patch to attempt to include a base commit when it can. However,
if no valid base commit can be found, then format-patch will continue
formatting the patch without a base commit.
In order to avoid making yet another branch name unusable with --base,
do not teach --base=whenAble or --base=whenable.
Instead, refactor the base_commit option to use a callback, and rely on
the global configuration variable auto_base.
This does mean that a user cannot request this optional base commit
generation from the command line. However, this is likely not too
valuable. If the user requests base information manually, they will be
immediately informed of the failure to acquire a suitable base commit.
This allows the user to make an informed choice about whether to
continue the format.
Add tests to cover the new mode of operation for --base.
Signed-off-by: Jacob Keller <jacob.keller@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-10-01 21:46:53 +00:00
test_expect_success 'format-patch format.useAutoBase option with whenAble' '
git checkout local &&
test_config format.useAutoBase whenAble &&
git format-patch --stdout -1 >patch &&
grep "^base-commit:" patch >actual &&
git rev-parse upstream >commit-id-base &&
echo " base-commit: $( cat commit-id-base) " >expect &&
test_cmp expect actual
'
2016-04-26 07:51:24 +00:00
test_expect_success 'format-patch --base overrides format.useAutoBase' '
2019-12-04 21:25:00 +00:00
test_config format.useAutoBase true &&
2016-04-26 07:51:24 +00:00
git format-patch --stdout --base= HEAD~1 -1 >patch &&
grep "^base-commit:" patch >actual &&
2019-08-27 04:05:15 +00:00
git rev-parse HEAD~1 >commit-id-base &&
echo " base-commit: $( cat commit-id-base) " >expect &&
2019-08-27 04:04:52 +00:00
test_cmp expect actual
2016-04-26 07:51:24 +00:00
'
2019-12-04 21:25:06 +00:00
test_expect_success 'format-patch --no-base overrides format.useAutoBase' '
test_config format.useAutoBase true &&
git format-patch --stdout --no-base -1 >patch &&
! grep "^base-commit:" patch
'
format-patch: teach format.useAutoBase "whenAble" option
The format.useAutoBase configuration option exists to allow users to
enable '--base=auto' for format-patch by default.
This can sometimes lead to poor workflow, due to unexpected failures
when attempting to format an ancient patch:
$ git format-patch -1 <an old commit>
fatal: base commit shouldn't be in revision list
This can be very confusing, as it is not necessarily immediately obvious
that the user requested a --base (since this was in the configuration,
not on the command line).
We do want --base=auto to fail when it cannot provide a suitable base,
as it would be equally confusing if a formatted patch did not include
the base information when it was requested.
Teach format.useAutoBase a new mode, "whenAble". This mode will cause
format-patch to attempt to include a base commit when it can. However,
if no valid base commit can be found, then format-patch will continue
formatting the patch without a base commit.
In order to avoid making yet another branch name unusable with --base,
do not teach --base=whenAble or --base=whenable.
Instead, refactor the base_commit option to use a callback, and rely on
the global configuration variable auto_base.
This does mean that a user cannot request this optional base commit
generation from the command line. However, this is likely not too
valuable. If the user requests base information manually, they will be
immediately informed of the failure to acquire a suitable base commit.
This allows the user to make an informed choice about whether to
continue the format.
Add tests to cover the new mode of operation for --base.
Signed-off-by: Jacob Keller <jacob.keller@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-10-01 21:46:53 +00:00
test_expect_success 'format-patch --no-base overrides format.useAutoBase whenAble' '
test_config format.useAutoBase whenAble &&
git format-patch --stdout --no-base -1 >patch &&
! grep "^base-commit:" patch
'
2016-09-08 01:12:01 +00:00
test_expect_success 'format-patch --base with --attach' '
git format-patch --attach= mimemime --stdout --base= HEAD~ -1 >patch &&
sed -n -e "/^base-commit:/s/.*/1/p" -e " /^---*mimemime-- $/s/.*/2/p " \
patch >actual &&
test_write_lines 1 2 >expect &&
test_cmp expect actual
'
2018-05-02 02:20:52 +00:00
test_expect_success 'format-patch --attach cover-letter only is non-multipart' '
test_when_finished "rm -fr patches" &&
git format-patch -o patches --cover-letter --attach= mimemime --base= HEAD~ -1 &&
2022-09-21 13:02:31 +00:00
! grep -E "^--+mimemime" patches/0000*.patch &&
grep -E " ^--+mimemime $" patches/0001*.patch >output &&
2018-05-02 02:20:52 +00:00
test_line_count = 2 output &&
2022-09-21 13:02:31 +00:00
grep -E " ^--+mimemime-- $" patches/0001*.patch >output &&
2018-05-02 02:20:52 +00:00
test_line_count = 1 output
'
2016-09-08 01:12:01 +00:00
2023-02-17 23:33:37 +00:00
test_expect_success 'format-patch with format.attach' '
test_when_finished "rm -fr patches" &&
separator = attachment-separator &&
test_config format.attach " $separator " &&
filename = $( git format-patch -o patches -1) &&
grep " ^Content-Type: multipart/.* $separator " " $filename "
'
test_expect_success 'format-patch with format.attach=disabled' '
test_when_finished "rm -fr patches" &&
separator = attachment-separator &&
test_config_global format.attach " $separator " &&
test_config format.attach "" &&
filename = $( git format-patch -o patches -1) &&
# The output should not even declare content type for text/plain.
! grep "^Content-Type: multipart/" " $filename "
'
2022-12-22 20:16:19 +00:00
test_expect_success '-c format.mboxrd format-patch' '
2016-06-05 04:46:39 +00:00
sp = " " &&
cat >msg <<-INPUT_END &&
mboxrd should escape the body
From could trip up a loose mbox parser
>From extra escape for reversibility
>>From extra escape for reversibility 2
from lower case not escaped
Fromm bad speling not escaped
From with leading space not escaped
F
From
From$sp
From $sp
From $sp
INPUT_END
cat >expect <<-INPUT_END &&
>From could trip up a loose mbox parser
>>From extra escape for reversibility
>>>From extra escape for reversibility 2
from lower case not escaped
Fromm bad speling not escaped
From with leading space not escaped
F
From
From
From
From
INPUT_END
C = $( git commit-tree HEAD^^{ tree} -p HEAD <msg) &&
2022-12-22 20:16:19 +00:00
git -c format.mboxrd format-patch --stdout -1 $C ~1..$C >patch &&
git format-patch --pretty= mboxrd --stdout -1 $C ~1..$C >compat &&
test_cmp patch compat &&
2016-06-05 04:46:39 +00:00
git grep -h --no-index -A11 \
"^>From could trip up a loose mbox parser" patch >actual &&
test_cmp expect actual
'
2018-07-22 09:57:05 +00:00
test_expect_success 'interdiff: setup' '
2020-11-18 23:44:27 +00:00
git checkout -b boop main &&
2018-07-22 09:57:05 +00:00
test_commit fnorp blorp &&
test_commit fleep blorp
'
test_expect_success 'interdiff: cover-letter' '
sed "y/q/ /" >expect <<-\E OF &&
+fleep
--q
EOF
git format-patch --cover-letter --interdiff= boop~2 -1 boop &&
2023-10-31 05:23:30 +00:00
test_grep " ^Interdiff: $" 0000-cover-letter.patch &&
test_grep ! " ^Interdiff: $" 0001-fleep.patch &&
2019-08-27 04:05:07 +00:00
sed " 1,/^@@ /d; /^-- $/q " 0000-cover-letter.patch >actual &&
2018-07-22 09:57:05 +00:00
test_cmp expect actual
'
2018-07-22 09:57:06 +00:00
test_expect_success 'interdiff: reroll-count' '
git format-patch --cover-letter --interdiff= boop~2 -v2 -1 boop &&
2023-10-31 05:23:30 +00:00
test_grep " ^Interdiff ..* v1: $" v2-0000-cover-letter.patch
2018-07-22 09:57:06 +00:00
'
2021-03-23 11:12:25 +00:00
test_expect_success 'interdiff: reroll-count with a non-integer' '
git format-patch --cover-letter --interdiff= boop~2 -v2.2 -1 boop &&
2023-10-31 05:23:30 +00:00
test_grep " ^Interdiff: $" v2.2-0000-cover-letter.patch
2021-03-23 11:12:25 +00:00
'
test_expect_success 'interdiff: reroll-count with a integer' '
git format-patch --cover-letter --interdiff= boop~2 -v2 -1 boop &&
2023-10-31 05:23:30 +00:00
test_grep " ^Interdiff ..* v1: $" v2-0000-cover-letter.patch
2021-03-23 11:12:25 +00:00
'
2018-07-22 09:57:09 +00:00
test_expect_success 'interdiff: solo-patch' '
cat >expect <<-\E OF &&
+fleep
EOF
git format-patch --interdiff= boop~2 -1 boop &&
2023-10-31 05:23:30 +00:00
test_grep " ^Interdiff: $" 0001-fleep.patch &&
2019-08-27 04:05:07 +00:00
sed " 1,/^ @@ /d; /^ $/q " 0001-fleep.patch >actual &&
2018-07-22 09:57:09 +00:00
test_cmp expect actual
'
format-patch: do not respect diff.noprefix
The output of format-patch respects diff.noprefix, but this usually ends
up being a hassle for people receiving the patch, as they have to
manually specify "-p0" in order to apply it.
I don't think there was any specific intention for it to behave this
way. The noprefix option is handled by git_diff_ui_config(), and
format-patch exists in a gray area between plumbing and porcelain.
People do look at the output, and we'd expect it to colorize things,
respect their choice of algorithm, and so on. But this particular option
creates problems for the receiver (in theory so does diff.mnemonicprefix,
but since we are always formatting commits, the mnemonic prefixes will
always be "a/" and "b/").
So let's disable it. The slight downsides are:
- people who have set diff.noprefix presumably like to see their
patches without prefixes. If they use format-patch to review their
series, they'll see prefixes. On the other hand, it is probably a
good idea for them to look at what will actually get sent out.
We could try to play games here with "is stdout a tty", as we do for
color. But that's not a completely reliable signal, and it's
probably not worth the trouble. If you want to see the patch with
the usual bells and whistles, then you are better off using "git
log" or "git show".
- if a project really does have a workflow that likes prefix-less
patches, and the receiver is prepared to use "-p0", then the sender
now has to manually say "--no-prefix" for each format-patch
invocation. That doesn't seem _too_ terrible given that the receiver
has to manually say "-p0" for each git-am invocation.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-09 06:11:49 +00:00
test_expect_success 'format-patch does not respect diff.noprefix' '
git -c diff.noprefix format-patch -1 --stdout >actual &&
grep "^--- a/blorp" actual
'
2023-03-09 06:12:37 +00:00
test_expect_success 'format-patch respects format.noprefix' '
git -c format.noprefix format-patch -1 --stdout >actual &&
grep "^--- blorp" actual
'
test_expect_success 'format-patch --default-prefix overrides format.noprefix' '
git -c format.noprefix \
format-patch -1 --default-prefix --stdout >actual &&
grep "^--- a/blorp" actual
'
2006-06-26 22:40:09 +00:00
test_done