git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 1/5] merge-tree --stdin: flush stdout to avoid deadlock

From
PGPhillip Wood via GitGitGadget <gitgitgadget@gmail.com>
Date
Feb 18, 2025, 16:24 UTC
Message-ID
<3b3179785098580f3336bb24bdbaf0aa1366bfcd.1739895879.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.1862.v2.git.1739895879.gitgitgadget@gmail.com>
From: Phillip Wood <phillip.wood@dunelm.org.uk>

If a process tries to read the output from "git merge-tree --stdin" before it closes merge-tree's stdin then it deadlocks. This happens because merge-tree does not flush its output before trying to read another line of input and means that it is not possible to cherry-pick a sequence of commits using "git merge-tree --stdin". Fix this by calling maybe_flush_or_die() before trying to read the next line of input. Flushing the output after each merge does not seem to affect the performance, any difference is lost in the noise even after increasing the number of runs.

$ git rev-list --merges --parents -n100 origin/master |
	sed 's/^[^ ]* //' >/tmp/merges
$ hyperfine -L flush 0,1 --warmup 1 --runs 30 \
	'GIT_FLUSH={flush} ./git merge-tree --stdin </tmp/merges'
Benchmark 1: GIT_FLUSH=0 ./git merge-tree --stdin </tmp/merges
  Time (mean ± σ):     546.6 ms ±  11.7 ms    [User: 503.2 ms, System: 40.9 ms]
  Range (min … max):   535.9 ms … 567.7 ms    30 runs
Benchmark 2: GIT_FLUSH=1 ./git merge-tree --stdin </tmp/merges
  Time (mean ± σ):     546.9 ms ±  12.0 ms    [User: 505.9 ms, System: 38.9 ms]
  Range (min … max):   529.8 ms … 570.0 ms    30 runs
Summary
  'GIT_FLUSH=0 ./git merge-tree --stdin </tmp/merges' ran
    1.00 ± 0.03 times faster than 'GIT_FLUSH=1 ./git merge-tree --stdin </tmp/merges'
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
---
 builtin/merge-tree.c | 2 ++
 1 file changed, 2 insertions(+)
diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c
index 9a6c8b4e4cf..57f4340faba 100644
--- a/builtin/merge-tree.c
+++ b/builtin/merge-tree.c
@@ -18,6 +18,7 @@
 #include "tree.h"
 #include "config.h"
 #include "strvec.h"
+#include "write-or-die.h"
 
 static int line_termination = '\n';
 
@@ -623,6 +624,7 @@ int cmd_merge_tree(int argc,
 			} else {
 				die(_("malformed input line: '%s'."), buf.buf);
 			}
+			maybe_flush_or_die(stdout, "stdout");
 
 			if (result < 0)
 				die(_("merging cannot continue; got unclean result of %d"), result);
-- 
gitgitgadget
Previous: Phillip Wood via GitGitGadgetNext: Patrick Steinhardt
Message 15 of 25 in “merge-tree --stdin: flush stdout”
  1. 0/5 merge-tree --stdin: flush stdoutPhillip Wood via GitGitGadget, Feb 16, 2025
  2. 2/5 merge-tree: remove redundant codePhillip Wood via GitGitGadget, Feb 16, 2025
  3. Elijah NewrenFeb 17, 2025
  4. Phillip WoodFeb 18, 2025
  5. 1/5 merge-tree --stdin: flush stdout to avoid deadlockPhillip Wood via GitGitGadget, Feb 16, 2025
  6. Elijah NewrenFeb 17, 2025
  7. 3/5 merge-tree: only use basic merge configPhillip Wood via GitGitGadget, Feb 16, 2025
  8. 4/5 merge-tree: improve docs for --stdinPhillip Wood via GitGitGadget, Feb 16, 2025
  9. Elijah NewrenFeb 17, 2025
  10. Phillip WoodFeb 18, 2025
  11. Elijah NewrenFeb 18, 2025
  12. 5/5 merge-tree: fix link formatting in html docsPhillip Wood via GitGitGadget, Feb 16, 2025
  13. Elijah NewrenFeb 17, 2025
  14. 0/5 merge-tree --stdin: flush stdoutPhillip Wood via GitGitGadget, Feb 18, 2025
  15. 1/5 merge-tree --stdin: flush stdout to avoid deadlockPhillip Wood via GitGitGadget, Feb 18, 2025
  16. Patrick SteinhardtFeb 19, 2025
  17. Phillip WoodFeb 19, 2025
  18. Junio C HamanoFeb 19, 2025
  19. 2/5 merge-tree: remove redundant codePhillip Wood via GitGitGadget, Feb 18, 2025
  20. 3/5 merge-tree: only use basic merge configPhillip Wood via GitGitGadget, Feb 18, 2025
  21. 4/5 merge-tree: improve docs for --stdinPhillip Wood via GitGitGadget, Feb 18, 2025
  22. 5/5 merge-tree: fix link formatting in html docsPhillip Wood via GitGitGadget, Feb 18, 2025
  23. Elijah NewrenFeb 18, 2025
  24. Phillip WoodFeb 18, 2025
  25. Junio C HamanoFeb 18, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.