git-remote-testgit: fix race when spawning fast-import
Test "pushing to local repo" in t5800-remote-helpers can hang due to a race condition in git-remote-testgit. Fix it by setting stdin to unbuffered. 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. Signed-off-by: Pete Wyckoff <pw@padd.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									fdec2eb8eb
								
							
						
					
					
						commit
						7fb8e163bd
					
				|  | @ -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) | ||||
|  | ||||
|  |  | |||
|  | @ -72,6 +72,19 @@ test_expect_success 'pushing to local repo' ' | |||
| 	compare_refs localclone HEAD server HEAD | ||||
| ' | ||||
|  | ||||
| # Generally, skip this test.  It demonstrates a now-fixed race in | ||||
| # git-remote-testgit, but is too slow to leave in for general use. | ||||
| : test_expect_success 'racily pushing to local repo' ' | ||||
| 	test_when_finished "rm -rf server2 localclone2" && | ||||
| 	cp -a server server2 && | ||||
| 	git clone "testgit::${PWD}/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) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Pete Wyckoff
						Pete Wyckoff