1#!/bin/sh
2
3test_description='git patch-id'
4
5GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
7
8. ./test-lib.sh
9
10test_expect_success 'setup' '
11	as="a a a a a a a a" && # eight a
12	test_write_lines $as >foo &&
13	test_write_lines $as >bar &&
14	git add foo bar &&
15	git commit -a -m initial &&
16	test_write_lines $as b >foo &&
17	test_write_lines $as b >bar &&
18	git commit -a -m first &&
19	git checkout -b same main &&
20	git commit --amend -m same-msg &&
21	git checkout -b notsame main &&
22	echo c >foo &&
23	echo c >bar &&
24	git commit --amend -a -m notsame-msg &&
25	test_write_lines bar foo >bar-then-foo &&
26	test_write_lines foo bar >foo-then-bar
27'
28
29test_expect_success 'patch-id output is well-formed' '
30	git log -p -1 | git patch-id >output &&
31	grep "^$OID_REGEX $(git rev-parse HEAD)$" output
32'
33
34#calculate patch id. Make sure output is not empty.
35calc_patch_id () {
36	patch_name="$1"
37	shift
38	git patch-id "$@" |
39	sed "s/ .*//" >patch-id_"$patch_name" &&
40	test_line_count -gt 0 patch-id_"$patch_name"
41}
42
43get_top_diff () {
44	git log -p -1 "$@" -O bar-then-foo --
45}
46
47get_patch_id () {
48	get_top_diff "$1" | calc_patch_id "$@"
49}
50
51test_expect_success 'patch-id detects equality' '
52	get_patch_id main &&
53	get_patch_id same &&
54	test_cmp patch-id_main patch-id_same
55'
56
57test_expect_success 'patch-id detects inequality' '
58	get_patch_id main &&
59	get_patch_id notsame &&
60	! test_cmp patch-id_main patch-id_notsame
61'
62
63test_expect_success 'patch-id supports git-format-patch output' '
64	get_patch_id main &&
65	git checkout same &&
66	git format-patch -1 --stdout | calc_patch_id same &&
67	test_cmp patch-id_main patch-id_same &&
68	set $(git format-patch -1 --stdout | git patch-id) &&
69	test "$2" = $(git rev-parse HEAD)
70'
71
72test_expect_success 'whitespace is irrelevant in footer' '
73	get_patch_id main &&
74	git checkout same &&
75	git format-patch -1 --stdout | sed "s/ \$//" | calc_patch_id same &&
76	test_cmp patch-id_main patch-id_same
77'
78
79cmp_patch_id () {
80	if
81		test "$1" = "relevant"
82	then
83		! test_cmp patch-id_"$2" patch-id_"$3"
84	else
85		test_cmp patch-id_"$2" patch-id_"$3"
86	fi
87}
88
89test_patch_id_file_order () {
90	relevant="$1"
91	shift
92	name="order-${1}-$relevant"
93	shift
94	get_top_diff "main" | calc_patch_id "$name" "$@" &&
95	git checkout same &&
96	git format-patch -1 --stdout -O foo-then-bar |
97		calc_patch_id "ordered-$name" "$@" &&
98	cmp_patch_id $relevant "$name" "ordered-$name"
99
100}
101
102# combined test for options: add more tests here to make them
103# run with all options
104test_patch_id () {
105	test_patch_id_file_order "$@"
106}
107
108# small tests with detailed diagnostic for basic options.
109test_expect_success 'file order is irrelevant with --stable' '
110	test_patch_id_file_order irrelevant --stable --stable
111'
112
113test_expect_success 'file order is relevant with --unstable' '
114	test_patch_id_file_order relevant --unstable --unstable
115'
116
117#Now test various option combinations.
118test_expect_success 'default is unstable' '
119	test_patch_id relevant default
120'
121
122test_expect_success 'patchid.stable = true is stable' '
123	test_config patchid.stable true &&
124	test_patch_id irrelevant patchid.stable=true
125'
126
127test_expect_success 'patchid.stable = false is unstable' '
128	test_config patchid.stable false &&
129	test_patch_id relevant patchid.stable=false
130'
131
132test_expect_success '--unstable overrides patchid.stable = true' '
133	test_config patchid.stable true &&
134	test_patch_id relevant patchid.stable=true--unstable --unstable
135'
136
137test_expect_success '--stable overrides patchid.stable = false' '
138	test_config patchid.stable false &&
139	test_patch_id irrelevant patchid.stable=false--stable --stable
140'
141
142test_expect_success 'patch-id supports git-format-patch MIME output' '
143	get_patch_id main &&
144	git checkout same &&
145	git format-patch -1 --attach --stdout | calc_patch_id same &&
146	test_cmp patch-id_main patch-id_same
147'
148
149test_expect_success 'patch-id respects config from subdir' '
150	test_config patchid.stable true &&
151	mkdir subdir &&
152
153	# copy these because test_patch_id() looks for them in
154	# the current directory
155	cp bar-then-foo foo-then-bar subdir &&
156
157	(
158		cd subdir &&
159		test_patch_id irrelevant patchid.stable=true
160	)
161'
162
163cat >nonl <<\EOF
164diff --git i/a w/a
165index e69de29..2e65efe 100644
166--- i/a
167+++ w/a
168@@ -0,0 +1 @@
169+a
170\ No newline at end of file
171diff --git i/b w/b
172index e69de29..6178079 100644
173--- i/b
174+++ w/b
175@@ -0,0 +1 @@
176+b
177EOF
178
179cat >withnl <<\EOF
180diff --git i/a w/a
181index e69de29..7898192 100644
182--- i/a
183+++ w/a
184@@ -0,0 +1 @@
185+a
186diff --git i/b w/b
187index e69de29..6178079 100644
188--- i/b
189+++ w/b
190@@ -0,0 +1 @@
191+b
192EOF
193
194test_expect_success 'patch-id handles no-nl-at-eof markers' '
195	cat nonl | calc_patch_id nonl &&
196	cat withnl | calc_patch_id withnl &&
197	test_cmp patch-id_nonl patch-id_withnl
198'
199test_done
200