fix 'got checkout' into existing directory; add test cases for this
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
diff --git a/got/got.c b/got/got.c
index 6016098..87f59f1 100644
--- a/got/got.c
+++ b/got/got.c
@@ -916,7 +916,8 @@ cmd_checkout(int argc, char *argv[])
/* Pre-create work tree path for unveil(2) */
error = got_path_mkdir(worktree_path);
if (error) {
- if (!(error->code == GOT_ERR_ERRNO && errno == EISDIR))
+ if (!(error->code == GOT_ERR_ERRNO && errno == EISDIR) &&
+ !(error->code == GOT_ERR_ERRNO && errno == EEXIST))
goto done;
if (!got_path_dir_is_empty(worktree_path)) {
error = got_error_path(worktree_path,
diff --git a/regress/cmdline/checkout.sh b/regress/cmdline/checkout.sh
index 31e8151..691d705 100755
--- a/regress/cmdline/checkout.sh
+++ b/regress/cmdline/checkout.sh
@@ -55,6 +55,123 @@ function test_checkout_basic {
test_done "$testroot" "$ret"
}
+function test_checkout_dir_exists {
+ local testroot=`test_init checkout_dir_exists`
+
+ echo "A $testroot/wt/alpha" > $testroot/stdout.expected
+ echo "A $testroot/wt/beta" >> $testroot/stdout.expected
+ echo "A $testroot/wt/epsilon/zeta" >> $testroot/stdout.expected
+ echo "A $testroot/wt/gamma/delta" >> $testroot/stdout.expected
+ echo "Now shut up and hack" >> $testroot/stdout.expected
+
+ mkdir $testroot/wt
+
+ got checkout $testroot/repo $testroot/wt > $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo "alpha" > $testroot/content.expected
+ echo "beta" >> $testroot/content.expected
+ echo "zeta" >> $testroot/content.expected
+ echo "delta" >> $testroot/content.expected
+ cat $testroot/wt/alpha $testroot/wt/beta $testroot/wt/epsilon/zeta \
+ $testroot/wt/gamma/delta > $testroot/content
+
+ cmp -s $testroot/content.expected $testroot/content
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/content.expected $testroot/content
+ fi
+ test_done "$testroot" "$ret"
+}
+
+function test_checkout_dir_not_empty {
+ local testroot=`test_init checkout_dir_not_empty`
+
+ echo "A $testroot/wt/alpha" > $testroot/stdout.expected
+ echo "A $testroot/wt/beta" >> $testroot/stdout.expected
+ echo "A $testroot/wt/epsilon/zeta" >> $testroot/stdout.expected
+ echo "A $testroot/wt/gamma/delta" >> $testroot/stdout.expected
+ echo "Now shut up and hack" >> $testroot/stdout.expected
+
+ mkdir $testroot/wt
+ touch $testroot/wt/foo
+
+ got checkout $testroot/repo $testroot/wt > $testroot/stdout \
+ 2> $testroot/stderr
+ ret="$?"
+ if [ "$ret" == "0" ]; then
+ echo "checkout succeeded unexpectedly" >&2
+ test_done "$testroot" "1"
+ return 1
+ fi
+
+ echo "got: $testroot/wt: directory exists and is not empty" \
+ > $testroot/stderr.expected
+ cmp -s $testroot/stderr.expected $testroot/stderr
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stderr.expected $testroot/stderr
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo -n > $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ fi
+ test_done "$testroot" "$ret"
+
+}
+
+function test_checkout_sets_xbit {
+ local testroot=`test_init checkout_sets_xbit 1`
+
+ touch $testroot/repo/xfile
+ chmod +x $testroot/repo/xfile
+ (cd $testroot/repo && git add .)
+ git_commit $testroot/repo -m "adding executable file"
+
+ echo "A $testroot/wt/xfile" > $testroot/stdout.expected
+ echo "Now shut up and hack" >> $testroot/stdout.expected
+
+ got checkout $testroot/repo $testroot/wt > $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ ls -l $testroot/wt/xfile | grep -q '^-rwx'
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ echo "file is not executable" >&2
+ ls -l $testroot/wt/xfile >&2
+ fi
+ test_done "$testroot" "$ret"
+}
+
function test_checkout_sets_xbit {
local testroot=`test_init checkout_sets_xbit 1`
@@ -129,5 +246,7 @@ function test_checkout_commit_from_wrong_branch {
}
run_test test_checkout_basic
+run_test test_checkout_dir_exists
+run_test test_checkout_dir_not_empty
run_test test_checkout_sets_xbit
run_test test_checkout_commit_from_wrong_branch