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

[PATCH] git-remote-testgit: fix race when spawning fast-import

From
PWPete Wyckoff <pw@padd.com>
Date
Apr 21, 2012, 23:45 UTC
Message-ID
<20120421234555.GA11808@padd.com>
In-Reply-To
<20120421201524.GA18419@padd.com>

Test "pushing to local repo" in t5800-remote-helpers can hang in a race condition between git push and git-remote-testgit.

On the writer side, "git push" invokes push_refs_with_export(), which sends to stdout the command "export\n" and immediately starts up "git fast-export". The latter writes its output stream to the same stdout.

On the reader side, remote helper "git-remote-testgit" reads from stdin to get its next command. It uses getc() to read characters from libc up until \n. Libc has buffered a potentially much larger chunk of stdin. When it sees the "export\n" command, it forks "git fast-import" to read the stream.

If fast-export finishes before git fast-import starts, the fast-export output can end up in libc's buffer in git-remote-testgit, rather than in git fast-import. The latter hangs indefinitely on a now-empty stdin.

Fix this by setting stdin to unbuffered.
Signed-off-by: Pete Wyckoff <pw@padd.com>
---

This is the one that might be suitable for upstream. It fixes the problem with this particular remote helper.

 git-remote-testgit.py     |    7 +++++++
 t/t5800-remote-helpers.sh |   11 +++++++++++
 2 files changed, 18 insertions(+)
diff --git a/git-remote-testgit.py b/git-remote-testgit.py
index 3dc4851..5f3ebd2 100644
--- a/git-remote-testgit.py
+++ b/git-remote-testgit.py
@@ -22,6 +22,7 @@ except ImportError:
     _digest = sha.new
 import sys
 import os
+import time
 sys.path.insert(0, os.getenv("GITPYTHONLIB","."))
 
 from git_remote_helpers.util import die, debug, warn
@@ -204,6 +205,11 @@ def read_one_line(repo):
     """Reads and processes one command.
     """
 
+    sleepy = os.environ.get("GIT_REMOTE_TESTGIT_SLEEPY")
+    if sleepy:
+        debug("Sleeping %d sec before readline" % int(sleepy))
+        time.sleep(int(sleepy))
+
     line = sys.stdin.readline()
 
     cmdline = line
@@ -258,6 +264,7 @@ def main(args):
 
     more = True
 
+    sys.stdin = os.fdopen(sys.stdin.fileno(), 'r', 0)
     while (more):
         more = read_one_line(repo)
 
diff --git a/t/t5800-remote-helpers.sh b/t/t5800-remote-helpers.sh
index 1c62001..cdcee83 100755
--- a/t/t5800-remote-helpers.sh
+++ b/t/t5800-remote-helpers.sh
@@ -72,6 +72,17 @@ test_expect_success 'pushing to local repo' '
 	compare_refs localclone HEAD server HEAD
 '
 
+test_expect_success 'racily pushing to local repo' '
+	cp -a server server2 &&
+	git clone "testgit::${PWD}/server2" localclone2 &&
+	test_when_finished "rm -rf server2 localclone2" &&
+	(cd localclone2 &&
+	echo content >>file &&
+	git commit -a -m three &&
+	GIT_REMOTE_TESTGIT_SLEEPY=2 git push) &&
+	compare_refs localclone2 HEAD server2 HEAD
+'
+
 test_expect_success 'synch with changes from localclone' '
 	(cd clone &&
 	 git pull)
-- 
1.7.10.57.g22c0b.dirty
Previous: Pete WyckoffNext: Clemens Buchacher
Message 19 of 26 in “master: t5800-remote-helpers.sh hangs on test "pulling from remote remote"”
  1. Stefano LattariniApr 14, 2012
  2. Clemens BuchacherApr 14, 2012
  3. Stefano LattariniApr 15, 2012
  4. Clemens BuchacherApr 15, 2012
  5. Stefano LattariniApr 15, 2012
  6. Clemens BuchacherApr 15, 2012
  7. Stefano LattariniApr 15, 2012
  8. Clemens BuchacherApr 15, 2012
  9. Stefano LattariniApr 15, 2012
  10. Clemens BuchacherApr 15, 2012
  11. Stefano LattariniApr 15, 2012
  12. Clemens BuchacherApr 15, 2012
  13. Sverre RabbelierApr 17, 2012
  14. Pete WyckoffApr 19, 2012
  15. Stefano LattariniApr 15, 2012
  16. Pete WyckoffApr 21, 2012
  17. Clemens BuchacherApr 21, 2012
  18. Pete WyckoffApr 22, 2012
  19. git-remote-testgit: fix race when spawning fast-importPete Wyckoff, Apr 21, 2012
  20. Clemens BuchacherApr 21, 2012
  21. Pete WyckoffApr 22, 2012
  22. Clemens BuchacherApr 22, 2012
  23. Junio C HamanoApr 22, 2012
  24. [PATCHv2] git-remote-testgit: fix race when spawning fast-importPete Wyckoff, Apr 22, 2012
  25. Junio C HamanoApr 23, 2012
  26. Pete WyckoffApr 23, 2012

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.