Skip to content

Commit 9be1980

Browse files
jlehmanngitster
authored andcommitted
clone: support atomic operation with --separate-git-dir
Since b57fb80 (init, clone: support --separate-git-dir for .git file) git clone supports the --separate-git-dir option to create the git dir outside the work tree. But when that option is used, the git dir won't be deleted in case the clone fails like it would be without this option. This makes clone lose its atomicity as in case of a failure a partly set up git dir is left behind. A real world example where this leads to problems is when "git submodule update" fails to clone a submodule and later calls to "git submodule update" stumble over the partially set up git dir and try to revive the submodule from there, which then fails with a not very user friendly error message. Fix that by updating the junk_git_dir variable (used to remember if and what git dir should be removed in case of failure) to the new value given with the --seperate-git-dir option. Also add a test for this to t5600 (and while at it fix the former last test to not cd into a directory to test for its existence but use "test -d" instead). Reported-by: Manlio Perillo <[email protected]> Signed-off-by: Jens Lehmann <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b57fb80 commit 9be1980

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

builtin/clone.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,8 +471,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
471471
die("could not create leading directories of '%s'", git_dir);
472472

473473
set_git_dir_init(git_dir, real_git_dir, 0);
474-
if (real_git_dir)
474+
if (real_git_dir) {
475475
git_dir = real_git_dir;
476+
junk_git_dir = real_git_dir;
477+
}
476478

477479
if (0 <= option_verbosity)
478480
printf("Cloning into %s%s...\n",

t/t5600-clone-fail-cleanup.sh

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@ test_expect_success \
3737

3838
test_expect_success \
3939
'successful clone must leave the directory' \
40-
'cd bar'
40+
'test -d bar'
41+
42+
test_expect_success 'failed clone --separate-git-dir should not leave any directories' '
43+
mkdir foo/.git/objects.bak/ &&
44+
mv foo/.git/objects/* foo/.git/objects.bak/ &&
45+
test_must_fail git clone --separate-git-dir gitdir foo worktree &&
46+
test_must_fail test -e gitdir &&
47+
test_must_fail test -e worktree &&
48+
mv foo/.git/objects.bak/* foo/.git/objects/ &&
49+
rmdir foo/.git/objects.bak
50+
'
4151

4252
test_done

0 commit comments

Comments
 (0)