{"thread":{"id":"66331","subject":"[PATCH] git-contacts: allow inputting patch via stdin","startedAt":"2026-09-15T02:43:53Z","lastAt":"2026-10-02T14:50:05Z","messageCount":19,"participants":["Brigham Campbell","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"552733","messageId":"20260914-git-contacts-stdin-v1-1-9ac628e6fd20@brighamcampbell.com","threadId":"66331","inReplyTo":null,"subject":"[PATCH] git-contacts: allow inputting patch via stdin","fromName":"Brigham Campbell","fromEmail":"me@brighamcampbell.com","sentAt":"2026-09-15T02:43:13Z","receivedAt":"2026-09-15T02:43:53Z","isPatch":true,"body":"Make git-contacts accept patch contents via stdin for better\ninteroperability with other utilities. Read from stdin under the\nfollowing circumstances:\n\n* stdin is not a terminal\n* argv is empty\n\nCc: Junio C Hamano <gitster@pobox.com>\nCc: Patrick Steinhardt <ps@pks.im>\nSigned-off-by: Brigham Campbell <me@brighamcampbell.com>\n---\nI authored this patch as the first of a two-patch series to enable b4 to\nautomatically determine patch recipients. The second patch modifies\n.b4-config to wire everything up. I discovered, however, that b4 doesn't\nyet pass the mbox \"Fixes \" header as it should. I sent a fix to b4.\n\nThe second patch of this series will therefore have to wait until the b4\nfix lands in the latest version, so I'm splitting up this series of\npatches to git. This patch is useful and warranted even by itself.\n\nLink: https://lore.kernel.org/tools/20260914-mbox-from-auto-to-cc-v1-1-fbf0c3fbd460@brighamcampbell.com\n---\n contrib/contacts/git-contacts | 5 ++++-\n 1 file changed, 4 insertions(+), 1 deletion(-)\n\ndiff --git a/contrib/contacts/git-contacts b/contrib/contacts/git-contacts\nindex 85ad732fc0..52f6fbd044 100755\n--- a/contrib/contacts/git-contacts\n+++ b/contrib/contacts/git-contacts\n@@ -158,7 +158,7 @@ sub mailmap_contacts {\n \treturn \\%mapped;\n }\n \n-if (!@ARGV) {\n+if (!@ARGV && -t STDIN) {\n \tdie \"No input revisions or patch files\\n\";\n }\n \n@@ -178,6 +178,9 @@ for (@files) {\n if (@rev_args) {\n \tscan_rev_args(\\%sources, \\@rev_args)\n }\n+if (!@ARGV) {\n+\tscan_patches(\\%sources, undef, \\*STDIN);\n+}\n \n my $toplevel = `git rev-parse --show-toplevel`;\n chomp $toplevel;\n\n---\nbase-commit: 47ce80527c56f462cb97db4ca8125342204d3783\nchange-id: 20260914-git-contacts-stdin-1e829930e19b\n\nThanks!\n-- \nBrigham Campbell\nhttps://brighamcampbell.com\n\n"},{"id":"552734","messageId":"xmqqbj9z2l3y.fsf@gitster.g","threadId":"66331","inReplyTo":"20260914-git-contacts-stdin-v1-1-9ac628e6fd20@brighamcampbell.com","subject":"Re: [PATCH] git-contacts: allow inputting patch via stdin","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-09-15T04:29:21Z","receivedAt":"2026-09-15T04:29:24Z","isPatch":true,"body":"Brigham Campbell <me@brighamcampbell.com> writes:\n\n> Make git-contacts accept patch contents via stdin for better\n> interoperability with other utilities. Read from stdin under the\n> following circumstances:\n>\n> * stdin is not a terminal\n> * argv is empty\n>\n> Cc: Junio C Hamano <gitster@pobox.com>\n> Cc: Patrick Steinhardt <ps@pks.im>\n\nIt is unusual for these trailers to be here for this project.\n\n> Signed-off-by: Brigham Campbell <me@brighamcampbell.com>\n> ---\n\n> diff --git a/contrib/contacts/git-contacts b/contrib/contacts/git-contacts\n> index 85ad732fc0..52f6fbd044 100755\n> --- a/contrib/contacts/git-contacts\n> +++ b/contrib/contacts/git-contacts\n> @@ -158,7 +158,7 @@ sub mailmap_contacts {\n>  \treturn \\%mapped;\n>  }\n>  \n> -if (!@ARGV) {\n> +if (!@ARGV && -t STDIN) {\n>  \tdie \"No input revisions or patch files\\n\";\n>  }\n>  \n> @@ -178,6 +178,9 @@ for (@files) {\n>  if (@rev_args) {\n>  \tscan_rev_args(\\%sources, \\@rev_args)\n>  }\n> +if (!@ARGV) {\n> +\tscan_patches(\\%sources, undef, \\*STDIN);\n> +}\n\nImmediately before this hunk, there is\n\nfor (@files) {\n\tscan_patch_file(\\%sources, $_);\n}\n\nwhere both @rev_args and @files are derived from @ARGV.  In fact,\nonce @ARGV is sifted into @rev_args and @files, nobody uses @ARGV\nafterwards.  @ARGV is used only to decide which things to work on\nand how, and the decision is recorded in variables with more\nmeaningful names than @ARGV.  After we are done with @ARGV, the\nactions are carried out using variables with more meaningful names.\n\nIt would be nicer if you followed the pattern by doing something\nlike the attached patch instead.\n\nBy the way, there is a comment at the beginning of the file that\nsays:\n\n    # List people who might be interested in a patch.  Useful as the argument to\n    # git-send-email --cc-cmd option, and in other situations.\n    #\n    # Usage: git contacts <file | rev-list option> ...\n\nWe'd probably need to update that part of the file as well.\n\n contrib/contacts/git-contacts | 13 ++++++++++---\n 1 file changed, 10 insertions(+), 3 deletions(-)\n\ndiff --git c/contrib/contacts/git-contacts w/contrib/contacts/git-contacts\nindex 85ad732fc0..f9e225b8b2 100755\n--- c/contrib/contacts/git-contacts\n+++ w/contrib/contacts/git-contacts\n@@ -158,11 +158,15 @@ sub mailmap_contacts {\n \treturn \\%mapped;\n }\n \n-if (!@ARGV) {\n-\tdie \"No input revisions or patch files\\n\";\n+my (@files, @rev_args, $read_from_stdin);\n+\n+if (!@ARGV)\n+\tif (-t STDIN) {\n+\t\tdie \"No input revisions or patch files\\n\";\n+\t}\n+\t$read_from_stdin = 1;\n }\n \n-my (@files, @rev_args);\n for (@ARGV) {\n \tif (-e) {\n \t\tpush @files, $_;\n@@ -178,6 +182,9 @@ for (@files) {\n if (@rev_args) {\n \tscan_rev_args(\\%sources, \\@rev_args)\n }\n+if ($read_from_stdin) {\n+\tscan_patches(\\%sources, undef, \\*STDIN);\n+}\n \n my $toplevel = `git rev-parse --show-toplevel`;\n chomp $toplevel;\n"},{"id":"552779","messageId":"20260915-git-contacts-stdin-v2-1-2005061d907a@brighamcampbell.com","threadId":"66331","inReplyTo":"20260914-git-contacts-stdin-v1-1-9ac628e6fd20@brighamcampbell.com","subject":"[PATCH v2] git-contacts: allow inputting patch via stdin","fromName":"Brigham Campbell","fromEmail":"me@brighamcampbell.com","sentAt":"2026-09-16T04:52:23Z","receivedAt":"2026-09-16T04:52:39Z","isPatch":true,"body":"Make git-contacts accept patch contents via stdin for better\ninteroperability with other utilities. Read from stdin under the\nfollowing circumstances:\n\n* stdin is not a terminal\n* argv is empty\n\nSigned-off-by: Brigham Campbell <me@brighamcampbell.com>\n---\nI authored this patch as the first of a two-patch series to enable b4 to\nautomatically determine patch recipients. The second patch modifies\n.b4-config to wire everything up. I discovered, however, that the latest\nversion of b4 doesn't pass the mbox \"Fixes \" header as it should. A fix\nis queued for the next release of b4.\n\nThe second patch of this series will therefore have to wait until the b4\nfix lands in the latest version, so I'm splitting up this series of\npatches to git. This patch is useful and warranted even by itself.\n\nLink: https://lore.kernel.org/tools/20260914-mbox-from-auto-to-cc-v1-1-fbf0c3fbd460@brighamcampbell.com\n---\nChanges in v2 (Thanks for your careful review, Junio):\n- Minor variable cleanup / un-spaghettification\n- Include update to usage comment\n- Remove Cc trailers from commit message\n- Link to v1: https://patch.msgid.link/20260914-git-contacts-stdin-v1-1-9ac628e6fd20@brighamcampbell.com\n---\n contrib/contacts/git-contacts | 12 ++++++++++--\n 1 file changed, 10 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/contacts/git-contacts b/contrib/contacts/git-contacts\nindex 85ad732fc0..03d03135d6 100755\n--- a/contrib/contacts/git-contacts\n+++ b/contrib/contacts/git-contacts\n@@ -4,6 +4,7 @@\n # git-send-email --cc-cmd option, and in other situations.\n #\n # Usage: git contacts <file | rev-list option> ...\n+#        git contacts < <patch>\n \n use strict;\n use warnings;\n@@ -158,11 +159,15 @@ sub mailmap_contacts {\n \treturn \\%mapped;\n }\n \n+my (@files, @rev_args, $read_from_stdin);\n+\n if (!@ARGV) {\n-\tdie \"No input revisions or patch files\\n\";\n+\tif (-t STDIN) {\n+\t\tdie \"No input revisions or patch files\\n\";\n+\t}\n+\t$read_from_stdin = 1;\n }\n \n-my (@files, @rev_args);\n for (@ARGV) {\n \tif (-e) {\n \t\tpush @files, $_;\n@@ -178,6 +183,9 @@ for (@files) {\n if (@rev_args) {\n \tscan_rev_args(\\%sources, \\@rev_args)\n }\n+if ($read_from_stdin) {\n+\tscan_patches(\\%sources, undef, \\*STDIN);\n+}\n \n my $toplevel = `git rev-parse --show-toplevel`;\n chomp $toplevel;\n\n---\nbase-commit: f0ef1b96a076d08dc972a8d2cb0d1cfd60931eb6\nchange-id: 20260914-git-contacts-stdin-1e829930e19b\n\nThanks!\n-- \nBrigham Campbell\nhttps://brighamcampbell.com\n\n"},{"id":"552787","messageId":"xmqqa4phxogc.fsf@gitster.g","threadId":"66331","inReplyTo":"20260915-git-contacts-stdin-v2-1-2005061d907a@brighamcampbell.com","subject":"Re: [PATCH v2] git-contacts: allow inputting patch via stdin","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-09-16T14:25:55Z","receivedAt":"2026-09-16T14:25:58Z","isPatch":true,"body":"Brigham Campbell <me@brighamcampbell.com> writes:\n\n>  # git-send-email --cc-cmd option, and in other situations.\n>  #\n>  # Usage: git contacts <file | rev-list option> ...\n> +#        git contacts < <patch>\n\nNot necessarily a suggestion to change what you already added, but a\nmere food for thought.\n\nAn obvious (and UNIX-y) alternative design would have been to follow\nthe popular convention to tell the command to read from the standard\ninput stream when \"-\" is used instead of a filename.  Then this line\ndid not have to change, and the command would have allowed arguments\nlike:\n\n\t$ git contacts patch1 patch2 - <patch3\n\t$ git contacts patch1 - patch3 <patch2\n\n"},{"id":"552806","messageId":"DLHE97Z5RDVA.168ZY5Q3TG8YJ@brighamcampbell.com","threadId":"66331","inReplyTo":"xmqqa4phxogc.fsf@gitster.g","subject":"Re: [PATCH v2] git-contacts: allow inputting patch via stdin","fromName":"Brigham Campbell","fromEmail":"me@brighamcampbell.com","sentAt":"2026-09-17T06:56:54Z","receivedAt":"2026-09-17T06:56:57Z","isPatch":true,"body":"On Wed Sep 16, 2026 at 8:25 AM MDT, Junio C Hamano wrote:\n> Not necessarily a suggestion to change what you already added, but a\n> mere food for thought.\n>\n> An obvious (and UNIX-y) alternative design would have been to follow\n> the popular convention to tell the command to read from the standard\n> input stream when \"-\" is used instead of a filename.  Then this line\n> did not have to change, and the command would have allowed arguments\n> like:\n>\n> \t$ git contacts patch1 patch2 - <patch3\n> \t$ git contacts patch1 - patch3 <patch2\n\nI considered this approach as well. I may as well have flipped a coin.\nMy approach to choosing hyphen or no wasn't very scientific.\n\nNaturally, if you'd prefer that I change the approach to instead allow\nthe user to pass \"-\" to indicate that a patch should be read via stdin,\nI'm happy to send out another revision. I understand why we would rather\nget the interface right on the first try, even for something small like\nthis.\n\nUntil you ask me to work a revision that uses \"-\", I'll await further\nreview on this v2.\n\nThanks again for your time!\n-- \nBrigham Campbell\nhttps://brighamcampbell.com\n\n"},{"id":"553133","messageId":"20260923-git-contacts-stdin-v3-1-56dd43c64d56@brighamcampbell.com","threadId":"66331","inReplyTo":"20260914-git-contacts-stdin-v1-1-9ac628e6fd20@brighamcampbell.com","subject":"[PATCH v3] git-contacts: allow inputting patch via stdin","fromName":"Brigham Campbell","fromEmail":"me@brighamcampbell.com","sentAt":"2026-09-24T01:25:30Z","receivedAt":"2026-09-24T01:26:18Z","isPatch":true,"body":"Make git-contacts accept patch contents via stdin for better\ninteroperability with other utilities. Read from stdin when the user\npasses `-` at least once:\n\n$ git contacts - <patch\n$ git contacts patch1 - patch3 <patch2\n\nSigned-off-by: Brigham Campbell <me@brighamcampbell.com>\n---\nThis patch is motivated by an ongoing personal effort to allow b4 to\ninvoke git-contacts automatically.\n\nThis latest revision requires the user to pass '-' instead of implicitly\nreading from stdin when stdin is not a tty and argv is empty. This\nsimplifies the change slightly and allows for input via files,\nrevisions, and stdin in a single invocation of git-contacts.\n---\nChanges in v3:\n- Make user pass '-' instead of an empty argv and non-TTY stdin\n- Link to v2: https://patch.msgid.link/20260915-git-contacts-stdin-v2-1-2005061d907a@brighamcampbell.com\n\nChanges in v2:\n- Minor variable cleanup / un-spaghettification\n- Include update to usage comment\n- Remove Cc trailers from commit message\n- Link to v1: https://patch.msgid.link/20260914-git-contacts-stdin-v1-1-9ac628e6fd20@brighamcampbell.com\n---\n contrib/contacts/git-contacts | 9 +++++++--\n 1 file changed, 7 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/contacts/git-contacts b/contrib/contacts/git-contacts\nindex 85ad732fc0..74910496f4 100755\n--- a/contrib/contacts/git-contacts\n+++ b/contrib/contacts/git-contacts\n@@ -162,9 +162,11 @@ if (!@ARGV) {\n \tdie \"No input revisions or patch files\\n\";\n }\n \n-my (@files, @rev_args);\n+my (@files, @rev_args, $read_from_stdin);\n for (@ARGV) {\n-\tif (-e) {\n+\tif ($_ eq '-') {\n+\t\t$read_from_stdin = 1;\n+\t} elsif (-e) {\n \t\tpush @files, $_;\n \t} else {\n \t\tpush @rev_args, $_;\n@@ -178,6 +180,9 @@ for (@files) {\n if (@rev_args) {\n \tscan_rev_args(\\%sources, \\@rev_args)\n }\n+if ($read_from_stdin) {\n+\tscan_patches(\\%sources, undef, \\*STDIN);\n+}\n \n my $toplevel = `git rev-parse --show-toplevel`;\n chomp $toplevel;\n\n---\nbase-commit: f0ef1b96a076d08dc972a8d2cb0d1cfd60931eb6\nchange-id: 20260914-git-contacts-stdin-1e829930e19b\n\nThanks!\n-- \nBrigham Campbell\nhttps://brighamcampbell.com\n\n"},{"id":"553135","messageId":"xmqqtsnf477e.fsf@gitster.g","threadId":"66331","inReplyTo":"20260923-git-contacts-stdin-v3-1-56dd43c64d56@brighamcampbell.com","subject":"Re: [PATCH v3] git-contacts: allow inputting patch via stdin","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-09-24T04:13:57Z","receivedAt":"2026-09-24T04:14:00Z","isPatch":true,"body":"Brigham Campbell <me@brighamcampbell.com> writes:\n\n> $ git contacts - <patch\n> $ git contacts patch1 - patch3 <patch2\n\nThe second one is an example that we could tell the command to read\nthese three files in patch1 and then patch2 and then patch3.\n\n> -my (@files, @rev_args);\n> +my (@files, @rev_args, $read_from_stdin);\n>  for (@ARGV) {\n> -\tif (-e) {\n> +\tif ($_ eq '-') {\n> +\t\t$read_from_stdin = 1;\n> +\t} elsif (-e) {\n>  \t\tpush @files, $_;\n>  \t} else {\n>  \t\tpush @rev_args, $_;\n\nBut this does not match what I would expect here, which would be\nto have something like this ...\n\n        if (-e || $_ eq '-') {\n\t        push @files, $_;\n        } else {\n\t\tpush @rev_args, $_;\n\t}\n\n... around here, and then tell scan_patch_file that \"-\" shouldn't be\nopened and instead read from the standard input stream, perhaps like\n\n        sub scan_patch_file {\n                my ($commits, $file) = @_;\n                if ($file eq '-') {\n                        $f = \\*STDIN;\n                } else {\n                        open my $f, '<', $file or die \"read failure: $file: $!\\n\";\n                }\n                scan_patches($commits, undef, $f);\n                close $f;\n        }\n\nor something.\n"},{"id":"553258","messageId":"DLO0S0UUB0EM.1NLQFJUPOMGY0@brighamcampbell.com","threadId":"66331","inReplyTo":"xmqqtsnf477e.fsf@gitster.g","subject":"Re: [PATCH v3] git-contacts: allow inputting patch via stdin","fromName":"Brigham Campbell","fromEmail":"me@brighamcampbell.com","sentAt":"2026-09-25T01:51:52Z","receivedAt":"2026-09-25T01:51:53Z","isPatch":true,"body":"On Wed Sep 23, 2026 at 10:13 PM MDT, Junio C Hamano wrote:\n> Brigham Campbell <me@brighamcampbell.com> writes:\n>\n>> $ git contacts - <patch\n>> $ git contacts patch1 - patch3 <patch2\n>\n> The second one is an example that we could tell the command to read\n> these three files in patch1 and then patch2 and then patch3.\n\nDoes the order in which arguments are processed matter? If it's a matter\nof producing predictable output, I just checked out `master` and I see\nthat running git-contacts twice produces the same email addresses, but\nin different orders for the same two input patches:\n\n\t$ git format-patch HEAD~2\n\t0001-Git-2.56-rc2.patch\n\t0002-Revert-Merge-branch-en-no-amend-during-conflicts.patch\n\t$ ./contrib/contacts/git-contacts *.patch\n\tÆvar Arnfjörð Bjarmason <avarab@gmail.com>\n\tElijah Newren <newren@gmail.com>\n\tJunio C Hamano <gitster@pobox.com>\n\t$ ./contrib/contacts/git-contacts *.patch\n\tElijah Newren <newren@gmail.com>\n\tÆvar Arnfjörð Bjarmason <avarab@gmail.com>\n\tJunio C Hamano <gitster@pobox.com>\n\nWhat's more, git-contacts already disregards the order of argv. It will\nalways scan file contents first and then git rev-lists second, even if\nthe user passes the rev-list first like follows:\n\n\tgit contacts HEAD~2.. foo.patch\n\nI would argue that this is not by mistake. The user should have no\nexpectation as to the order in which arguments are processed. If the\ncommit message implies that the arguments are processed one after\nanother, regardless of whether it's a file, a rev-list, or stdin, then\nthe commit message should be changed.\n\nDo I misunderstand?\n\n-- \nBrigham Campbell\nhttps://brighamcampbell.com\n\n"},{"id":"553261","messageId":"xmqqfqyyx7vw.fsf@gitster.g","threadId":"66331","inReplyTo":"DLO0S0UUB0EM.1NLQFJUPOMGY0@brighamcampbell.com","subject":"Re: [PATCH v3] git-contacts: allow inputting patch via stdin","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-09-25T04:38:43Z","receivedAt":"2026-09-25T04:38:50Z","isPatch":true,"body":"\"Brigham Campbell\" <me@brighamcampbell.com> writes:\n\n> On Wed Sep 23, 2026 at 10:13 PM MDT, Junio C Hamano wrote:\n>> Brigham Campbell <me@brighamcampbell.com> writes:\n>>\n>>> $ git contacts - <patch\n>>> $ git contacts patch1 - patch3 <patch2\n>>\n>> The second one is an example that we could tell the command to read\n>> these three files in patch1 and then patch2 and then patch3.\n>\n> Does the order in which arguments are processed matter?\n\nIt does not matter if the order makes difference in the end result,\nbecause my comment was made out of principle.  I would not at all\nsurprised if the command gathers information from all sources, sorts\nand then emits---in which case the end result won't be obviously\naffected.\n\n"},{"id":"553264","messageId":"20260925-git-contacts-stdin-v4-1-9b4e4bcbb91c@brighamcampbell.com","threadId":"66331","inReplyTo":"20260914-git-contacts-stdin-v1-1-9ac628e6fd20@brighamcampbell.com","subject":"[PATCH v4] git-contacts: allow inputting patch via stdin","fromName":"Brigham Campbell","fromEmail":"me@brighamcampbell.com","sentAt":"2026-09-25T06:42:39Z","receivedAt":"2026-09-25T06:44:08Z","isPatch":true,"body":"Make git-contacts accept patch contents via stdin for better\ninteroperability with other utilities. Read from stdin when the user\npasses `-` at least once:\n\n$ git contacts - <patch\n\nSigned-off-by: Brigham Campbell <me@brighamcampbell.com>\n---\nJunio, you suggested that I make git-contacts process files and stdin\nwith respect to the order in which they appear in argv. I instead\nremoved the implication that git-contacts processes input in any\nparticular order.\n\nEven before this patch, git-contacts parses files first, then git\nrev-lists second, regardless of their order in argv. If we instead want\ngit-contacts to parse arguments in the same order that they're passed,\nthat's a change which should occur in a separate patch.\n\nI'm happy to write that patch if you'd like.\n---\nChanges in v4:\n- Don't imply that git-contacts processes input in any particular order\n- Link to v3: https://patch.msgid.link/20260923-git-contacts-stdin-v3-1-56dd43c64d56@brighamcampbell.com\n\nChanges in v3:\n- Make user pass '-' instead of an empty argv and non-TTY stdin\n- Link to v2: https://patch.msgid.link/20260915-git-contacts-stdin-v2-1-2005061d907a@brighamcampbell.com\n\nChanges in v2:\n- Minor variable cleanup / un-spaghettification\n- Include update to usage comment\n- Remove Cc trailers from commit message\n- Link to v1: https://patch.msgid.link/20260914-git-contacts-stdin-v1-1-9ac628e6fd20@brighamcampbell.com\n\nTo: git@vger.kernel.org\nCc: Junio C Hamano <gitster@pobox.com>\nCc: Patrick Steinhardt <ps@pks.im>\n---\n contrib/contacts/git-contacts | 9 +++++++--\n 1 file changed, 7 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/contacts/git-contacts b/contrib/contacts/git-contacts\nindex 85ad732fc0..df7b920d9e 100755\n--- a/contrib/contacts/git-contacts\n+++ b/contrib/contacts/git-contacts\n@@ -162,9 +162,11 @@ if (!@ARGV) {\n \tdie \"No input revisions or patch files\\n\";\n }\n \n-my (@files, @rev_args);\n+my ($read_from_stdin, @files, @rev_args);\n for (@ARGV) {\n-\tif (-e) {\n+\tif ($_ eq '-') {\n+\t\t$read_from_stdin = 1;\n+\t} elsif (-e) {\n \t\tpush @files, $_;\n \t} else {\n \t\tpush @rev_args, $_;\n@@ -172,6 +174,9 @@ for (@ARGV) {\n }\n \n my %sources;\n+if ($read_from_stdin) {\n+\tscan_patches(\\%sources, undef, \\*STDIN);\n+}\n for (@files) {\n \tscan_patch_file(\\%sources, $_);\n }\n\n---\nbase-commit: 0f8e75abebff0877cae681a3d5ff31ac47f54220\nchange-id: 20260914-git-contacts-stdin-1e829930e19b\n\nThanks!\n-- \nBrigham Campbell\nhttps://brighamcampbell.com\n\n"},{"id":"553290","messageId":"xmqqy0cpwbw5.fsf@gitster.g","threadId":"66331","inReplyTo":"20260925-git-contacts-stdin-v4-1-9b4e4bcbb91c@brighamcampbell.com","subject":"Re: [PATCH v4] git-contacts: allow inputting patch via stdin","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-09-25T16:09:46Z","receivedAt":"2026-09-25T16:09:52Z","isPatch":true,"body":"Brigham Campbell <me@brighamcampbell.com> writes:\n\n> Make git-contacts accept patch contents via stdin for better\n> interoperability with other utilities. Read from stdin when the user\n> passes `-` at least once:\n>\n> $ git contacts - <patch\n\nOK.\n\n> Even before this patch, git-contacts parses files first, then git\n> rev-lists second, regardless of their order in argv. If we instead want\n> git-contacts to parse arguments in the same order that they're passed,\n> that's a change which should occur in a separate patch.\n\nFair enough.\n\nWe would want an update to contrib/contacts/git-contacts.adoc as\nwell.  Here is my attempt.  I realize that the new text implies that\nwe read only one patch from the standard input, but I do not know\noffhand whether scan_patches() successfully reads multiple patches\nconcatenated together into a single stream.  If it does, we may want\nto say \"read patch file(s) from\" instead.\n\nThe original uses <rev> in <angle brackets> to clarify that it is a\nplaceholder, so the added text does the same for <patch>.  The\noriginal text does not say what the command expects of the \"patch\nfiles\" it mentions, which may be worth improving and when it happens\nwe would say <patch> in the description to refer to one argument on\nthe command line.  But I left it outside the scope of this message.\n\n\n\n contrib/contacts/git-contacts.adoc | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git c/contrib/contacts/git-contacts.adoc w/contrib/contacts/git-contacts.adoc\nindex dd914d1261..6473e878e0 100644\n--- c/contrib/contacts/git-contacts.adoc\n+++ w/contrib/contacts/git-contacts.adoc\n@@ -24,7 +24,8 @@ Input consists of one or more patch files or revision arguments.  A revision\n argument can be a range or a single `<rev>` which is interpreted as\n `<rev>..HEAD`, thus the same revision arguments are accepted as for\n linkgit:git-format-patch[1]. Patch files and revision arguments can be combined\n-in the same invocation.\n+in the same invocation.  A single dash `'-'` character in place of a <patch>\n+tells the command to read a patch from the standard input.  \n \n This command can be useful for determining the list of people with whom to\n discuss proposed changes, or for finding the list of recipients to Cc: when\n"},{"id":"553543","messageId":"20260928-git-contacts-stdin-v5-0-e9becaebc47e@brighamcampbell.com","threadId":"66331","inReplyTo":"20260914-git-contacts-stdin-v1-1-9ac628e6fd20@brighamcampbell.com","subject":"[PATCH v5 0/2] git-contacts: allow inputting patch via stdin","fromName":"Brigham Campbell","fromEmail":"me@brighamcampbell.com","sentAt":"2026-09-29T05:47:11Z","receivedAt":"2026-09-29T05:47:32Z","isPatch":true,"body":"Make git-contacts accept patches via stdin. Multiple patches may be\nconcatenated together before being passed into git-contacts;\ngit-contacts recognizes the mbox `From ` header inserted by\ngit-format-patch to separate concatenated patches.\n\nUpdate git-contacts and its corresponding documentation.\n\n---\nChanges in v5:\n- Add a patch documenting stdin support\n- Link to v4: https://patch.msgid.link/20260925-git-contacts-stdin-v4-1-9b4e4bcbb91c@brighamcampbell.com\n\nChanges in v4:\n- Don't imply that git-contacts processes input in any particular order\n- Link to v3: https://patch.msgid.link/20260923-git-contacts-stdin-v3-1-56dd43c64d56@brighamcampbell.com\n\nChanges in v3:\n- Make user pass '-' instead of an empty argv and non-TTY stdin\n- Link to v2: https://patch.msgid.link/20260915-git-contacts-stdin-v2-1-2005061d907a@brighamcampbell.com\n\nChanges in v2:\n- Minor variable cleanup / un-spaghettification\n- Include update to usage comment\n- Remove Cc trailers from commit message\n- Link to v1: https://patch.msgid.link/20260914-git-contacts-stdin-v1-1-9ac628e6fd20@brighamcampbell.com\n\nTo: git@vger.kernel.org\nCc: Junio C Hamano <gitster@pobox.com>\nCc: Patrick Steinhardt <ps@pks.im>\n---\nBrigham Campbell (2):\n      git-contacts: allow inputting patch via stdin\n      git-contacts: add stdin functionality to docs\n\n contrib/contacts/git-contacts      | 9 +++++++--\n contrib/contacts/git-contacts.adoc | 3 ++-\n 2 files changed, 9 insertions(+), 3 deletions(-)\n---\nbase-commit: 0f8e75abebff0877cae681a3d5ff31ac47f54220\nchange-id: 20260914-git-contacts-stdin-1e829930e19b\n\nThanks!\n-- \nBrigham Campbell\nhttps://brighamcampbell.com\n\n"},{"id":"553544","messageId":"20260928-git-contacts-stdin-v5-1-e9becaebc47e@brighamcampbell.com","threadId":"66331","inReplyTo":"20260928-git-contacts-stdin-v5-0-e9becaebc47e@brighamcampbell.com","subject":"[PATCH v5 1/2] git-contacts: allow inputting patch via stdin","fromName":"Brigham Campbell","fromEmail":"me@brighamcampbell.com","sentAt":"2026-09-29T05:47:12Z","receivedAt":"2026-09-29T05:47:36Z","isPatch":true,"body":"Make git-contacts accept patch contents via stdin for better\ninteroperability with other utilities. Read from stdin when the user\npasses `-` at least once:\n\n$ git contacts - <patch\n\nSigned-off-by: Brigham Campbell <me@brighamcampbell.com>\n---\n contrib/contacts/git-contacts | 9 +++++++--\n 1 file changed, 7 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/contacts/git-contacts b/contrib/contacts/git-contacts\nindex 85ad732fc0..df7b920d9e 100755\n--- a/contrib/contacts/git-contacts\n+++ b/contrib/contacts/git-contacts\n@@ -162,9 +162,11 @@ if (!@ARGV) {\n \tdie \"No input revisions or patch files\\n\";\n }\n \n-my (@files, @rev_args);\n+my ($read_from_stdin, @files, @rev_args);\n for (@ARGV) {\n-\tif (-e) {\n+\tif ($_ eq '-') {\n+\t\t$read_from_stdin = 1;\n+\t} elsif (-e) {\n \t\tpush @files, $_;\n \t} else {\n \t\tpush @rev_args, $_;\n@@ -172,6 +174,9 @@ for (@ARGV) {\n }\n \n my %sources;\n+if ($read_from_stdin) {\n+\tscan_patches(\\%sources, undef, \\*STDIN);\n+}\n for (@files) {\n \tscan_patch_file(\\%sources, $_);\n }\n\n-- \n2.55.0\n\n"},{"id":"553545","messageId":"20260928-git-contacts-stdin-v5-2-e9becaebc47e@brighamcampbell.com","threadId":"66331","inReplyTo":"20260928-git-contacts-stdin-v5-0-e9becaebc47e@brighamcampbell.com","subject":"[PATCH v5 2/2] git-contacts: add stdin functionality to docs","fromName":"Brigham Campbell","fromEmail":"me@brighamcampbell.com","sentAt":"2026-09-29T05:47:13Z","receivedAt":"2026-09-29T05:47:39Z","isPatch":true,"body":"git-contacts now accepts patches via stdin. Optionally, multiple patches\nmay be concatenated before piping the result into git-contacts.\nDocument this feature.\n\nSigned-off-by: Brigham Campbell <me@brighamcampbell.com>\n---\n contrib/contacts/git-contacts.adoc | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/contrib/contacts/git-contacts.adoc b/contrib/contacts/git-contacts.adoc\nindex dd914d1261..4e0b518aae 100644\n--- a/contrib/contacts/git-contacts.adoc\n+++ b/contrib/contacts/git-contacts.adoc\n@@ -24,7 +24,8 @@ Input consists of one or more patch files or revision arguments.  A revision\n argument can be a range or a single `<rev>` which is interpreted as\n `<rev>..HEAD`, thus the same revision arguments are accepted as for\n linkgit:git-format-patch[1]. Patch files and revision arguments can be combined\n-in the same invocation.\n+in the same invocation.  A single dash `'-'` character in place of a `<patch>`\n+tells the command to read patch file(s) from the standard input.\n \n This command can be useful for determining the list of people with whom to\n discuss proposed changes, or for finding the list of recipients to Cc: when\n\n-- \n2.55.0\n\n"},{"id":"553615","messageId":"xmqqh5j8hvfq.fsf@gitster.g","threadId":"66331","inReplyTo":"20260928-git-contacts-stdin-v5-0-e9becaebc47e@brighamcampbell.com","subject":"Re: [PATCH v5 0/2] git-contacts: allow inputting patch via stdin","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-09-29T16:30:17Z","receivedAt":"2026-09-29T16:30:19Z","isPatch":true,"body":"Brigham Campbell <me@brighamcampbell.com> writes:\n\n> Make git-contacts accept patches via stdin. Multiple patches may be\n> concatenated together before being passed into git-contacts;\n> git-contacts recognizes the mbox `From ` header inserted by\n> git-format-patch to separate concatenated patches.\n>\n> Update git-contacts and its corresponding documentation.\n>\n> ---\n> Changes in v5:\n> - Add a patch documenting stdin support\n> - Link to v4: https://patch.msgid.link/20260925-git-contacts-stdin-v4-1-9b4e4bcbb91c@brighamcampbell.com\n\nThe end result may be the same, but I somehow expected that a new\nfeature plus the documentation update to describe the new feature to\ncome in a single patch.\n\nThanks.\n"},{"id":"553633","messageId":"xmqqv77ng8kk.fsf@gitster.g","threadId":"66331","inReplyTo":"20260928-git-contacts-stdin-v5-1-e9becaebc47e@brighamcampbell.com","subject":"Re: [PATCH v5 1/2] git-contacts: allow inputting patch via stdin","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-09-29T19:29:31Z","receivedAt":"2026-09-29T19:29:33Z","isPatch":true,"body":"Brigham Campbell <me@brighamcampbell.com> writes:\n\n> Make git-contacts accept patch contents via stdin for better\n> interoperability with other utilities. Read from stdin when the user\n> passes `-` at least once:\n>\n> $ git contacts - <patch\n>\n> Signed-off-by: Brigham Campbell <me@brighamcampbell.com>\n> ---\n>  contrib/contacts/git-contacts | 9 +++++++--\n>  1 file changed, 7 insertions(+), 2 deletions(-)\n>\n> diff --git a/contrib/contacts/git-contacts b/contrib/contacts/git-contacts\n> index 85ad732fc0..df7b920d9e 100755\n> --- a/contrib/contacts/git-contacts\n> +++ b/contrib/contacts/git-contacts\n> @@ -162,9 +162,11 @@ if (!@ARGV) {\n>  \tdie \"No input revisions or patch files\\n\";\n>  }\n>  \n> -my (@files, @rev_args);\n> +my ($read_from_stdin, @files, @rev_args);\n>  for (@ARGV) {\n> -\tif (-e) {\n> +\tif ($_ eq '-') {\n> +\t\t$read_from_stdin = 1;\n> +\t} elsif (-e) {\n>  \t\tpush @files, $_;\n>  \t} else {\n>  \t\tpush @rev_args, $_;\n> @@ -172,6 +174,9 @@ for (@ARGV) {\n>  }\n>  \n>  my %sources;\n> +if ($read_from_stdin) {\n> +\tscan_patches(\\%sources, undef, \\*STDIN);\n> +}\n>  for (@files) {\n>  \tscan_patch_file(\\%sources, $_);\n>  }\n\nDoesn't the Usage comment at the beginning also want to be updated?\n\nThanks.\n\n\ndiff --git i/contrib/contacts/git-contacts w/contrib/contacts/git-contacts\nindex 85ad732fc0..1eb91c4ab1 100755\n--- i/contrib/contacts/git-contacts\n+++ w/contrib/contacts/git-contacts\n@@ -3,7 +3,7 @@\n # List people who might be interested in a patch.  Useful as the argument to\n # git-send-email --cc-cmd option, and in other situations.\n #\n-# Usage: git contacts <file | rev-list option> ...\n+# Usage: git contacts <file | '-' | rev-list option> ...\n \n use strict;\n use warnings;\n"},{"id":"553887","messageId":"DLU2TTDQB6OQ.5FQZGHG1AGZP@brighamcampbell.com","threadId":"66331","inReplyTo":"xmqqv77ng8kk.fsf@gitster.g","subject":"Re: [PATCH v5 1/2] git-contacts: allow inputting patch via stdin","fromName":"Brigham Campbell","fromEmail":"me@brighamcampbell.com","sentAt":"2026-10-02T04:44:14Z","receivedAt":"2026-10-02T04:44:24Z","isPatch":true,"body":"On Tue Sep 29, 2026 at 1:29 PM MDT, Junio C Hamano wrote:\n> Doesn't the Usage comment at the beginning also want to be updated?\n\nI'm inclined to agree with you. I would have updated it had you not\ncommented the following on v2, referring to the Usage comment:\n\nOn Wed Sep 16, 2026 at 8:25 AM MDT, Junio C Hamano wrote:\n>                                                       Then this line\n> did not have to change\n\nI took that to mean that v5 did not have to change the Usage comment. I\nwill update it in v6.\n\nThanks for your patience,\n-- \nBrigham Campbell\nhttps://brighamcampbell.com\n\n"},{"id":"553889","messageId":"20261002-git-contacts-stdin-v6-1-49878e872d3d@brighamcampbell.com","threadId":"66331","inReplyTo":"20260914-git-contacts-stdin-v1-1-9ac628e6fd20@brighamcampbell.com","subject":"[PATCH v6] git-contacts: allow inputting patch via stdin","fromName":"Brigham Campbell","fromEmail":"me@brighamcampbell.com","sentAt":"2026-10-02T06:50:20Z","receivedAt":"2026-10-02T06:50:35Z","isPatch":true,"body":"Make git-contacts accept patch contents via stdin for better\ninteroperability with other utilities. Read from stdin when the user\npasses `-` at least once:\n\n$ git contacts - <patch\n\nSigned-off-by: Brigham Campbell <me@brighamcampbell.com>\n---\nI verified the documentation changes by rendering html and inspecting\nthe output in a web browser.\n---\nChanges in v6:\n- Squash documentation and code into a single commit\n- Make documentation changes more complete\n- Link to v5: https://patch.msgid.link/20260928-git-contacts-stdin-v5-0-e9becaebc47e@brighamcampbell.com\n\nChanges in v5:\n- Add a patch documenting stdin support\n- Link to v4: https://patch.msgid.link/20260925-git-contacts-stdin-v4-1-9b4e4bcbb91c@brighamcampbell.com\n\nChanges in v4:\n- Don't imply that git-contacts processes input in any particular order\n- Link to v3: https://patch.msgid.link/20260923-git-contacts-stdin-v3-1-56dd43c64d56@brighamcampbell.com\n\nChanges in v3:\n- Make user pass '-' instead of an empty argv and non-TTY stdin\n- Link to v2: https://patch.msgid.link/20260915-git-contacts-stdin-v2-1-2005061d907a@brighamcampbell.com\n\nChanges in v2:\n- Minor variable cleanup / un-spaghettification\n- Include update to usage comment\n- Remove Cc trailers from commit message\n- Link to v1: https://patch.msgid.link/20260914-git-contacts-stdin-v1-1-9ac628e6fd20@brighamcampbell.com\n\nTo: git@vger.kernel.org\nCc: Junio C Hamano <gitster@pobox.com>\nCc: Patrick Steinhardt <ps@pks.im>\n---\n contrib/contacts/git-contacts      | 11 ++++++++---\n contrib/contacts/git-contacts.adoc | 14 +++++++++++---\n 2 files changed, 19 insertions(+), 6 deletions(-)\n\ndiff --git a/contrib/contacts/git-contacts b/contrib/contacts/git-contacts\nindex 85ad732fc0..e4656affb5 100755\n--- a/contrib/contacts/git-contacts\n+++ b/contrib/contacts/git-contacts\n@@ -3,7 +3,7 @@\n # List people who might be interested in a patch.  Useful as the argument to\n # git-send-email --cc-cmd option, and in other situations.\n #\n-# Usage: git contacts <file | rev-list option> ...\n+# Usage: git contacts <file | '-' | rev-list option> ...\n \n use strict;\n use warnings;\n@@ -162,9 +162,11 @@ if (!@ARGV) {\n \tdie \"No input revisions or patch files\\n\";\n }\n \n-my (@files, @rev_args);\n+my ($read_from_stdin, @files, @rev_args);\n for (@ARGV) {\n-\tif (-e) {\n+\tif ($_ eq '-') {\n+\t\t$read_from_stdin = 1;\n+\t} elsif (-e) {\n \t\tpush @files, $_;\n \t} else {\n \t\tpush @rev_args, $_;\n@@ -172,6 +174,9 @@ for (@ARGV) {\n }\n \n my %sources;\n+if ($read_from_stdin) {\n+\tscan_patches(\\%sources, undef, \\*STDIN);\n+}\n for (@files) {\n \tscan_patch_file(\\%sources, $_);\n }\ndiff --git a/contrib/contacts/git-contacts.adoc b/contrib/contacts/git-contacts.adoc\nindex dd914d1261..ea5dd58826 100644\n--- a/contrib/contacts/git-contacts.adoc\n+++ b/contrib/contacts/git-contacts.adoc\n@@ -9,7 +9,7 @@ git-contacts - List people who might be interested in a set of changes\n SYNOPSIS\n --------\n [verse]\n-'git contacts' (<patch>|<range>|<rev>)...\n+'git contacts' (<patch>|'-'|<range>|<rev>)...\n \n \n DESCRIPTION\n@@ -23,8 +23,10 @@ which touched the lines of files under consideration.\n Input consists of one or more patch files or revision arguments.  A revision\n argument can be a range or a single `<rev>` which is interpreted as\n `<rev>..HEAD`, thus the same revision arguments are accepted as for\n-linkgit:git-format-patch[1]. Patch files and revision arguments can be combined\n-in the same invocation.\n+linkgit:git-format-patch[1].  A single dash `'-'` character in place of a\n+`<patch>` tells the command to read patch file(s) from the standard input.\n+Patch files, standard input, and revision arguments can be combined in the same\n+invocation.\n \n This command can be useful for determining the list of people with whom to\n discuss proposed changes, or for finding the list of recipients to Cc: when\n@@ -73,6 +75,12 @@ $ git contacts R1..R2\n $ git contacts origin\n ------------\n \n+* Input a patch via stdin:\n++\n+------------\n+$ git contacts - <feature.patch\n+------------\n+\n * Helper for `git send-email`:\n +\n ------------\n\n---\nbase-commit: c46c1e37724f0478939de636ab8ea5a89086d532\nchange-id: 20260914-git-contacts-stdin-1e829930e19b\n\nThanks!\n-- \nBrigham Campbell\nhttps://brighamcampbell.com\n\n"},{"id":"553973","messageId":"xmqqo6dc17jb.fsf@gitster.g","threadId":"66331","inReplyTo":"20261002-git-contacts-stdin-v6-1-49878e872d3d@brighamcampbell.com","subject":"Re: [PATCH v6] git-contacts: allow inputting patch via stdin","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-10-02T14:50:00Z","receivedAt":"2026-10-02T14:50:05Z","isPatch":true,"body":"Brigham Campbell <me@brighamcampbell.com> writes:\n\n> Make git-contacts accept patch contents via stdin for better\n> interoperability with other utilities. Read from stdin when the user\n> passes `-` at least once:\n>\n> $ git contacts - <patch\n>\n> Signed-off-by: Brigham Campbell <me@brighamcampbell.com>\n> ---\n> I verified the documentation changes by rendering html and inspecting\n> the output in a web browser.\n\nVery much appreciated.  Will replace.\n\nLet me mark the topic for 'next'.\n\nThanks.\n"}]}