From 28ca0ea51e3d73fca03e8d36b218fe8f0e65ef3d Mon Sep 17 00:00:00 2001 From: Ben Wijen Date: Thu, 26 May 2016 08:57:26 +0200 Subject: [PATCH 1/2] Add index.lock test to t/t6026-merge-attr.sh This test was added to verify the behaviour of merge when a merge server is spawned. Because file handles are inherited by child processes, the index.lock is also inherited and - on win32 - can't be released until the child has stopped. Signed-off-by: Ben Wijen --- t/t6026-merge-attr.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/t/t6026-merge-attr.sh b/t/t6026-merge-attr.sh index ef0cbceafe..9be8119008 100755 --- a/t/t6026-merge-attr.sh +++ b/t/t6026-merge-attr.sh @@ -181,4 +181,19 @@ test_expect_success 'up-to-date merge without common ancestor' ' ) ' +test_expect_success 'custom merge does not lock index' ' + git reset --hard anchor && + + write_script sleep-one-second.sh <<-\EOF && + sleep 1 & + EOF + + printf "* merge=ours\ntext merge=sleep-one-second\n" >.gitattributes && + + git config merge.ours.driver "true" && + git config merge.sleep-one-second.driver "./sleep-one-second.sh" && + + git merge master +' + test_done From b11ff4921efd5d3c7c8f71da22eb979085db0a74 Mon Sep 17 00:00:00 2001 From: Ben Wijen Date: Thu, 19 May 2016 07:27:54 +0200 Subject: [PATCH 2/2] Make sure temporary file handles are not inherited by child processes When testing a merge driver which spawns a merge server (for future merges) I got the following error: Rename from 'xxx/.git/index.lock' to 'xxx/.git/index' failed. Should I try again? (y/n) Only after I stop the merge server the lock is released. This is caused by windows handle inheritance. Starting childs with bInheritHandles==FALSE does not work, because no file handles would be inherited, not even the hStdXxx handles in STARTUPINFO. Opening every file with O_NOINHERIT does not work, Since it is used by git-upload-pack for example, which expects inherited handles. This leaves us with only creating temp files with the O_NOINHERIT flag. Which (currently) only used by lock_file which is exactly what we want. Signed-off-by: Ben Wijen --- compat/mingw.h | 4 ++++ tempfile.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/compat/mingw.h b/compat/mingw.h index ef22cbb05d..6090e83947 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -67,6 +67,10 @@ typedef int pid_t; #define F_SETFD 2 #define FD_CLOEXEC 0x1 +#if !defined O_CLOEXEC && defined O_NOINHERIT +#define O_CLOEXEC O_NOINHERIT +#endif + #ifndef EAFNOSUPPORT #define EAFNOSUPPORT WSAEAFNOSUPPORT #endif diff --git a/tempfile.c b/tempfile.c index 0af7ebf016..db3981deab 100644 --- a/tempfile.c +++ b/tempfile.c @@ -120,7 +120,7 @@ int create_tempfile(struct tempfile *tempfile, const char *path) prepare_tempfile_object(tempfile); strbuf_add_absolute_path(&tempfile->filename, path); - tempfile->fd = open(tempfile->filename.buf, O_RDWR | O_CREAT | O_EXCL, 0666); + tempfile->fd = open(tempfile->filename.buf, O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC, 0666); if (tempfile->fd < 0) { strbuf_reset(&tempfile->filename); return -1;