git mv file foo &&
git commit -m foo &&
- git format-patch --cover-letter -1 &&
+ git format-patch --no-renames --cover-letter -1 &&
check_patch 0000-cover-letter.patch &&
! grep "file => foo .* 0 *\$" 0000-cover-letter.patch &&
git format-patch --cover-letter -1 -M &&
test_expect_success 'format-patch --numstat should produce a patch' '
git format-patch --numstat --stdout master..side > output &&
- test 6 = $(grep "^diff --git a/" output | wc -l)'
+ test 5 = $(grep "^diff --git a/" output | wc -l)'
test_expect_success 'format-patch -- <path>' '
git format-patch master..side -- file 2>error &&
'
test_expect_success 'in-body headers trigger content encoding' '
- GIT_AUTHOR_NAME="éxötìc" test_commit exotic &&
+ test_env GIT_AUTHOR_NAME="éxötìc" test_commit exotic &&
test_when_finished "git reset --hard HEAD^" &&
git format-patch -1 --stdout --from >patch &&
cat >expect <<-\EOF &&
test_cmp from filtered
'
+test_expect_success 'format-patch format.outputDirectory option' '
+ test_config format.outputDirectory patches &&
+ rm -fr patches &&
+ git format-patch master..side &&
+ test $(git rev-list master..side | wc -l) -eq $(ls patches | wc -l)
+'
+
+test_expect_success 'format-patch -o overrides format.outputDirectory' '
+ test_config format.outputDirectory patches &&
+ rm -fr patches patchset &&
+ git format-patch master..side -o patchset &&
+ test_path_is_missing patches &&
+ test_path_is_dir patchset
+'
+
+test_expect_success 'format-patch --base' '
+ git checkout side &&
+ git format-patch --stdout --base=HEAD~3 -1 >patch &&
+ grep "^base-commit:" patch >actual &&
+ grep "^prerequisite-patch-id:" patch >>actual &&
+ echo "base-commit: $(git rev-parse HEAD~3)" >expected &&
+ echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --stable | awk "{print \$1}")" >>expected &&
+ echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --stable | awk "{print \$1}")" >>expected &&
+ test_cmp expected actual
+'
+
+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 &&
+ echo "base-commit: $(git rev-parse HEAD~2)" >expected &&
+ test_cmp expected actual
+'
+
+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
+ git checkout -b topic1 master &&
+ 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 &&
+ git checkout -b topic2 master &&
+ 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 &&
+ echo "base-commit: $(cat commit-id-base)" >expected &&
+ test_cmp expected actual
+'
+
+test_expect_success 'format-patch --base=auto' '
+ git checkout -b upstream master &&
+ 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 &&
+ echo "base-commit: $(git rev-parse upstream)" >expected &&
+ test_cmp expected actual
+'
+
+test_expect_success 'format-patch errors out when history involves criss-cross' '
+ # setup criss-cross history
+ #
+ # B---M1---D
+ # / \ /
+ # A X
+ # \ / \
+ # C---M2---E
+ #
+ git checkout master &&
+ test_commit A &&
+ git checkout -b xb master &&
+ test_commit B &&
+ git checkout -b xc master &&
+ 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
+'
+
+test_expect_success 'format-patch format.useAutoBaseoption' '
+ test_when_finished "git config --unset format.useAutoBase" &&
+ git checkout local &&
+ git config format.useAutoBase true &&
+ git format-patch --stdout -1 >patch &&
+ grep "^base-commit:" patch >actual &&
+ echo "base-commit: $(git rev-parse upstream)" >expected &&
+ test_cmp expected actual
+'
+
+test_expect_success 'format-patch --base overrides format.useAutoBase' '
+ test_when_finished "git config --unset format.useAutoBase" &&
+ git config format.useAutoBase true &&
+ git format-patch --stdout --base=HEAD~1 -1 >patch &&
+ grep "^base-commit:" patch >actual &&
+ echo "base-commit: $(git rev-parse HEAD~1)" >expected &&
+ test_cmp expected actual
+'
+
test_done