summaryrefslogtreecommitdiff
path: root/t/t4014-format-patch.sh
diff options
context:
space:
mode:
authorXiaolong Ye <xiaolong.ye@intel.com>2016-04-26 07:51:22 (GMT)
committerJunio C Hamano <gitster@pobox.com>2016-04-26 17:50:13 (GMT)
commitfa2ab86d18f16ab5e6d2f2cd6e8cc00460bada17 (patch)
treed5bc46205824dd87c8bf1ce959119a004d54d7ab /t/t4014-format-patch.sh
parentded2c097bae67e00f8b4f3f777a516254207ca15 (diff)
downloadgit-fa2ab86d18f16ab5e6d2f2cd6e8cc00460bada17.zip
git-fa2ab86d18f16ab5e6d2f2cd6e8cc00460bada17.tar.gz
git-fa2ab86d18f16ab5e6d2f2cd6e8cc00460bada17.tar.bz2
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>
Diffstat (limited to 't/t4014-format-patch.sh')
-rwxr-xr-xt/t4014-format-patch.sh47
1 files changed, 47 insertions, 0 deletions
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index 3b99434..edf07ee 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -1460,4 +1460,51 @@ test_expect_success 'format-patch -o overrides format.outputDirectory' '
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_done