@matheusbsbs / matheus-bagliano / commits / 30984ed2e9
Fork 0

format-patch: support deep threading

For deep threading mode, i.e., the mode that gives a thread structured like + [PATCH 0/n] Cover letter `-+ [PATCH 1/n] First patch `-+ [PATCH 2/n] Second patch `-+ ... we currently have to use 'git send-email --thread' (the default). On the other hand, format-patch also has a --thread option which gives shallow mode, i.e., + [PATCH 0/n] Cover letter |-+ [PATCH 1/n] First patch |-+ [PATCH 2/n] Second patch ... To reduce the confusion resulting from having two indentically named features in different tools giving different results, let format-patch take an optional argument '--thread=deep' that gives the same output as 'send-mail --thread'. With no argument, or 'shallow', behave as before. Also add a configuration variable format.thread with the same semantics. Signed-off-by: Thomas Rast <trast@student.ethz.ch> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Thomas Rast committed Feb 19, 2009 at 22:26 UTC 30984ed2e92651962c6b8bdacf1f84da75d1da95
4 files changed +170 -5
Documentation/config.txt
+10
@@ -677,6 +677,16 @@ format.pretty::
677 See linkgit:git-log[1], linkgit:git-show[1],
678 linkgit:git-whatchanged[1].
679
680 +format.thread::
681 + The default threading style for 'git-format-patch'. Can be
682 + either a boolean value, `shallow` or `deep`. 'Shallow'
683 + threading makes every mail a reply to the head of the series,
684 + where the head is chosen from the cover letter, the
685 + `\--in-reply-to`, and the first patch mail, in this order.
686 + 'Deep' threading makes every mail a reply to the previous one.
687 + A true boolean value is the same as `shallow`, and a false
688 + value disables threading.
689 +
690 gc.aggressiveWindow::
691 The window size parameter used in the delta compression
692 algorithm used by 'git-gc --aggressive'. This defaults
Documentation/git-format-patch.txt
+9 -1
@@ -122,10 +122,18 @@ include::diff-options.txt[]
122 which is the commit message and the patch itself in the
123 second part, with "Content-Disposition: inline".
124
125 ---thread::
125 +--thread[=<style>]::
126 Add In-Reply-To and References headers to make the second and
127 subsequent mails appear as replies to the first. Also generates
128 the Message-Id header to reference.
129 ++
130 +The optional <style> argument can be either `shallow` or `deep`.
131 +'Shallow' threading makes every mail a reply to the head of the
132 +series, where the head is chosen from the cover letter, the
133 +`\--in-reply-to`, and the first patch mail, in this order. 'Deep'
134 +threading makes every mail a reply to the previous one. If not
135 +specified, defaults to the 'format.thread' configuration, or `shallow`
136 +if that is not set.
137
138 --in-reply-to=Message-Id::
139 Make the first mail (or all the mails with --no-thread) appear as a
builtin-log.c
+31 -4
@@ -460,6 +460,10 @@ static void add_header(const char *value)
460 extra_hdr[extra_hdr_nr++] = xstrndup(value, len);
461 }
462
463 +#define THREAD_SHALLOW 1
464 +#define THREAD_DEEP 2
465 +static int thread = 0;
466 +
467 static int git_format_config(const char *var, const char *value, void *cb)
468 {
469 if (!strcmp(var, "format.headers")) {
@@ -489,6 +493,18 @@ static int git_format_config(const char *var, const char *value, void *cb)
493 auto_number = auto_number && numbered;
494 return 0;
495 }
496 + if (!strcmp(var, "format.thread")) {
497 + if (value && !strcasecmp(value, "deep")) {
498 + thread = THREAD_DEEP;
499 + return 0;
500 + }
501 + if (value && !strcasecmp(value, "shallow")) {
502 + thread = THREAD_SHALLOW;
503 + return 0;
504 + }
505 + thread = git_config_bool(var, value) && THREAD_SHALLOW;
506 + return 0;
507 + }
508
509 return git_log_config(var, value, cb);
510 }
@@ -767,7 +783,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
783 int numbered_files = 0; /* _just_ numbers */
784 int subject_prefix = 0;
785 int ignore_if_in_upstream = 0;
770 - int thread = 0;
786 int cover_letter = 0;
787 int boundary_count = 0;
788 int no_binary_diff = 0;
@@ -860,8 +875,13 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
875 }
876 else if (!strcmp(argv[i], "--ignore-if-in-upstream"))
877 ignore_if_in_upstream = 1;
863 - else if (!strcmp(argv[i], "--thread"))
864 - thread = 1;
878 + else if (!strcmp(argv[i], "--thread")
879 + || !strcmp(argv[i], "--thread=shallow"))
880 + thread = THREAD_SHALLOW;
881 + else if (!strcmp(argv[i], "--thread=deep"))
882 + thread = THREAD_DEEP;
883 + else if (!strcmp(argv[i], "--no-thread"))
884 + thread = 0;
885 else if (!prefixcmp(argv[i], "--in-reply-to="))
886 in_reply_to = argv[i] + 14;
887 else if (!strcmp(argv[i], "--in-reply-to")) {
@@ -1036,6 +1056,12 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1056 /* Have we already had a message ID? */
1057 if (rev.message_id) {
1058 /*
1059 + * For deep threading: make every mail
1060 + * a reply to the previous one, no
1061 + * matter what other options are set.
1062 + *
1063 + * For shallow threading:
1064 + *
1065 * Without --cover-letter and
1066 * --in-reply-to, make every mail a
1067 * reply to the one before.
@@ -1050,7 +1076,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1076 * letter is a reply to the
1077 * --in-reply-to, if specified.
1078 */
1053 - if (rev.ref_message_ids->nr > 0
1079 + if (thread == THREAD_SHALLOW
1080 + && rev.ref_message_ids->nr > 0
1081 && (!cover_letter || rev.nr > 1))
1082 free(rev.message_id);
1083 else
t/t4014-format-patch.sh
+120
@@ -257,6 +257,126 @@ test_expect_success 'thread cover-letter in-reply-to' '
257 --in-reply-to="<test.message>" --thread master
258 '
259
260 +test_expect_success 'thread explicit shallow' '
261 + check_threading expect.cl-irt --cover-letter \
262 + --in-reply-to="<test.message>" --thread=shallow master
263 +'
264 +
265 +cat > expect.deep <<EOF
266 +---
267 +Message-Id: <0>
268 +---
269 +Message-Id: <1>
270 +In-Reply-To: <0>
271 +References: <0>
272 +---
273 +Message-Id: <2>
274 +In-Reply-To: <1>
275 +References: <0>
276 + <1>
277 +EOF
278 +
279 +test_expect_success 'thread deep' '
280 + check_threading expect.deep --thread=deep master
281 +'
282 +
283 +cat > expect.deep-irt <<EOF
284 +---
285 +Message-Id: <0>
286 +In-Reply-To: <1>
287 +References: <1>
288 +---
289 +Message-Id: <2>
290 +In-Reply-To: <0>
291 +References: <1>
292 + <0>
293 +---
294 +Message-Id: <3>
295 +In-Reply-To: <2>
296 +References: <1>
297 + <0>
298 + <2>
299 +EOF
300 +
301 +test_expect_success 'thread deep in-reply-to' '
302 + check_threading expect.deep-irt --thread=deep \
303 + --in-reply-to="<test.message>" master
304 +'
305 +
306 +cat > expect.deep-cl <<EOF
307 +---
308 +Message-Id: <0>
309 +---
310 +Message-Id: <1>
311 +In-Reply-To: <0>
312 +References: <0>
313 +---
314 +Message-Id: <2>
315 +In-Reply-To: <1>
316 +References: <0>
317 + <1>
318 +---
319 +Message-Id: <3>
320 +In-Reply-To: <2>
321 +References: <0>
322 + <1>
323 + <2>
324 +EOF
325 +
326 +test_expect_success 'thread deep cover-letter' '
327 + check_threading expect.deep-cl --cover-letter --thread=deep master
328 +'
329 +
330 +cat > expect.deep-cl-irt <<EOF
331 +---
332 +Message-Id: <0>
333 +In-Reply-To: <1>
334 +References: <1>
335 +---
336 +Message-Id: <2>
337 +In-Reply-To: <0>
338 +References: <1>
339 + <0>
340 +---
341 +Message-Id: <3>
342 +In-Reply-To: <2>
343 +References: <1>
344 + <0>
345 + <2>
346 +---
347 +Message-Id: <4>
348 +In-Reply-To: <3>
349 +References: <1>
350 + <0>
351 + <2>
352 + <3>
353 +EOF
354 +
355 +test_expect_success 'thread deep cover-letter in-reply-to' '
356 + check_threading expect.deep-cl-irt --cover-letter \
357 + --in-reply-to="<test.message>" --thread=deep master
358 +'
359 +
360 +test_expect_success 'thread via config' '
361 + git config format.thread true &&
362 + check_threading expect.thread master
363 +'
364 +
365 +test_expect_success 'thread deep via config' '
366 + git config format.thread deep &&
367 + check_threading expect.deep master
368 +'
369 +
370 +test_expect_success 'thread config + override' '
371 + git config format.thread deep &&
372 + check_threading expect.thread --thread master
373 +'
374 +
375 +test_expect_success 'thread config + --no-thread' '
376 + git config format.thread deep &&
377 + check_threading expect.no-threading --no-thread master
378 +'
379 +
380 test_expect_success 'excessive subject' '
381
382 rm -rf patches/ &&