test_cmp expect actual
'
-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
-'
-
+ 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 |
+ egrep -n "^Subject|Sign|^$"
+ }
+
+ test_expect_success 'signoff: commit with no body' '
+ append_signoff </dev/null >actual &&
+ cat <<\EOF | sed "s/EOL$//" >expected &&
+ 4:Subject: [PATCH] EOL
+ 8:
+ 9:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expected actual
+ '
+
+ test_expect_success 'signoff: commit with only subject' '
+ echo subject | append_signoff >actual &&
+ cat >expected <<\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 9:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expected actual
+ '
+
+ test_expect_success 'signoff: commit with only subject that does not end with NL' '
+ printf subject | append_signoff >actual &&
+ cat >expected <<\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 9:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expected actual
+ '
+
+ test_expect_success 'signoff: no existing signoffs' '
+ append_signoff <<\EOF >actual &&
+ subject
+
+ body
+ EOF
+ cat >expected <<\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 11:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expected actual
+ '
+
+ test_expect_success 'signoff: no existing signoffs and no trailing NL' '
+ printf "subject\n\nbody" | append_signoff >actual &&
+ cat >expected <<\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 11:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expected actual
+ '
+
+ test_expect_success 'signoff: some random signoff' '
+ append_signoff <<\EOF >actual &&
+ subject
+
+ body
+
+ Signed-off-by: my@house
+ EOF
+ cat >expected <<\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 11:Signed-off-by: my@house
+ 12:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expected actual
+ '
+
+ test_expect_success 'signoff: misc conforming footer elements' '
+ append_signoff <<\EOF >actual &&
+ subject
+
+ body
+
+ Signed-off-by: my@house
+ (cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
+ Tested-by: Some One <someone@example.com>
+ Bug: 1234
+ EOF
+ cat >expected <<\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 11:Signed-off-by: my@house
+ 15:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expected actual
+ '
+
+ test_expect_success 'signoff: some random signoff-alike' '
+ append_signoff <<\EOF >actual &&
+ subject
+
+ body
+ Fooled-by-me: my@house
+ EOF
+ cat >expected <<\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 11:
+ 12:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expected actual
+ '
+
+ test_expect_success 'signoff: not really a signoff' '
+ append_signoff <<\EOF >actual &&
+ subject
+
+ I want to mention about Signed-off-by: here.
+ EOF
+ cat >expected <<\EOF &&
+ 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
+ test_cmp expected actual
+ '
+
+ test_expect_success 'signoff: not really a signoff (2)' '
+ append_signoff <<\EOF >actual &&
+ subject
+
+ My unfortunate
+ Signed-off-by: example happens to be wrapped here.
+ EOF
+ cat >expected <<\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:Signed-off-by: example happens to be wrapped here.
+ 11:
+ 12:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expected actual
+ '
+
+ test_expect_success 'signoff: valid S-o-b paragraph in the middle' '
+ append_signoff <<\EOF >actual &&
+ subject
+
+ Signed-off-by: my@house
+ Signed-off-by: your@house
+
+ A lot of houses.
+ EOF
+ cat >expected <<\EOF &&
+ 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
+ test_cmp expected actual
+ '
+
+ test_expect_success 'signoff: the same signoff at the end' '
+ append_signoff <<\EOF >actual &&
+ subject
+
+ body
+
+ Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ cat >expected <<\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 11:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expected actual
+ '
+
+ 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 &&
+ cat >expected <<\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 9:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expected actual
+ '
+
+ test_expect_success 'signoff: the same signoff NOT at the end' '
+ append_signoff <<\EOF >actual &&
+ subject
+
+ body
+
+ Signed-off-by: C O Mitter <committer@example.com>
+ Signed-off-by: my@house
+ EOF
+ cat >expected <<\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 11:Signed-off-by: C O Mitter <committer@example.com>
+ 12:Signed-off-by: my@house
+ EOF
+ test_cmp expected actual
+ '
+
+ test_expect_success 'signoff: detect garbage in non-conforming footer' '
+ append_signoff <<\EOF >actual &&
+ subject
+
+ body
+
+ Tested-by: my@house
+ Some Trash
+ Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ cat >expected <<\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 13:Signed-off-by: C O Mitter <committer@example.com>
+ 14:
+ 15:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expected actual
+ '
+
+ test_expect_success 'signoff: footer begins with non-signoff without @ sign' '
+ append_signoff <<\EOF >actual &&
+ subject
+
+ body
+
+ Reviewed-id: Noone
+ Tested-by: my@house
+ Change-id: Ideadbeef
+ Signed-off-by: C O Mitter <committer@example.com>
+ Bug: 1234
+ EOF
+ cat >expected <<\EOF &&
+ 4:Subject: [PATCH] subject
+ 8:
+ 10:
+ 14:Signed-off-by: C O Mitter <committer@example.com>
+ EOF
+ test_cmp expected actual
+ '
+
+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
+'
+
+test_expect_success 'cover letter using branch description (1)' '
+ git checkout rebuild-1 &&
+ test_config branch.rebuild-1.description hello &&
+ git format-patch --stdout --cover-letter master >actual &&
+ grep hello actual >/dev/null
+'
+
+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 &&
+ grep hello actual >/dev/null
+'
+
+test_expect_success 'cover letter using branch description (3)' '
+ git checkout rebuild-1 &&
+ test_config branch.rebuild-1.description hello &&
+ git format-patch --stdout --cover-letter ^master rebuild-1 >actual &&
+ grep hello actual >/dev/null
+'
+
+test_expect_success 'cover letter using branch description (4)' '
+ git checkout rebuild-1 &&
+ test_config branch.rebuild-1.description hello &&
+ git format-patch --stdout --cover-letter master.. >actual &&
+ grep hello actual >/dev/null
+'
+
+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 &&
+ grep hello actual >/dev/null
+'
+
+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 &&
+ grep hello actual >/dev/null
+'
+
test_done