Skip to content

Commit 344a107

Browse files
phillipwoodgitster
authored andcommitted
merge-tree --stdin: flush stdout to avoid deadlock
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 <[email protected]> Acked-by: Elijah Newren <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f93ff17 commit 344a107

File tree

1 file changed

+2
-0
lines changed

1 file changed

+2
-0
lines changed

builtin/merge-tree.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "tree.h"
1919
#include "config.h"
2020
#include "strvec.h"
21+
#include "write-or-die.h"
2122

2223
static int line_termination = '\n';
2324

@@ -623,6 +624,7 @@ int cmd_merge_tree(int argc,
623624
} else {
624625
die(_("malformed input line: '%s'."), buf.buf);
625626
}
627+
maybe_flush_or_die(stdout, "stdout");
626628

627629
if (result < 0)
628630
die(_("merging cannot continue; got unclean result of %d"), result);

0 commit comments

Comments
 (0)