]> git.proxmox.com Git - libgit2.git/commitdiff
checkout: upgrade to `SAFE_CREATE` when no index file
authorEdward Thomson <ethomson@edwardthomson.com>
Sat, 14 Feb 2015 15:33:06 +0000 (10:33 -0500)
committerEdward Thomson <ethomson@microsoft.com>
Fri, 27 Feb 2015 18:50:32 +0000 (13:50 -0500)
When the repository does not contain an index, emulate git's behavior
and upgrade to `SAFE_CREATE`.  This allows us to check out repositories
created with `git clone --no-checkout`.

src/checkout.c
tests/checkout/tree.c

index f71be26f966a6c1f7ac8fff80eaf1e8bc2d4e6dd..6e1abce4acddbef4d0dfc44d1ec589b8064805c2 100644 (file)
@@ -2346,6 +2346,13 @@ static int checkout_data_init(
                }
        }
 
+       /* if the repository does not actually have an index file, then this
+        * is an initial checkout (perhaps from clone), so we allow safe updates
+        */
+       if (!data->index->on_disk &&
+               (data->opts.checkout_strategy & GIT_CHECKOUT_SAFE) != 0)
+               data->opts.checkout_strategy |= GIT_CHECKOUT_SAFE_CREATE;
+
        /* if you are forcing, definitely allow safe updates */
        if ((data->opts.checkout_strategy & GIT_CHECKOUT_FORCE) != 0)
                data->opts.checkout_strategy |= GIT_CHECKOUT_SAFE_CREATE;
index 0fabadc8d8e6901870f35ed5038df14be4d27a2c..1b4a3327341b68a84888a6d0411c9feeb61528c5 100644 (file)
@@ -1264,3 +1264,39 @@ void test_checkout_tree__can_update_but_not_write_index(void)
        git_object_free(head);
        git_index_free(index);
 }
+
+/* Emulate checking out in a repo created by clone --no-checkout,
+ * which would not have written an index. */
+void test_checkout_tree__safe_proceeds_if_no_index(void)
+{
+       git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+       git_oid oid;
+       git_object *obj = NULL;
+
+       assert_on_branch(g_repo, "master");
+       cl_must_pass(p_unlink("testrepo/.git/index"));
+
+       /* do second checkout safe because we should be clean after first */
+       opts.checkout_strategy = GIT_CHECKOUT_SAFE;
+
+       cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/subtrees"));
+       cl_git_pass(git_object_lookup(&obj, g_repo, &oid, GIT_OBJ_ANY));
+
+       cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
+       cl_git_pass(git_repository_set_head(g_repo, "refs/heads/subtrees", NULL, NULL));
+
+       cl_assert(git_path_isfile("testrepo/README"));
+       cl_assert(git_path_isfile("testrepo/branch_file.txt"));
+       cl_assert(git_path_isfile("testrepo/new.txt"));
+       cl_assert(git_path_isfile("testrepo/ab/4.txt"));
+       cl_assert(git_path_isfile("testrepo/ab/c/3.txt"));
+       cl_assert(git_path_isfile("testrepo/ab/de/2.txt"));
+       cl_assert(git_path_isfile("testrepo/ab/de/fgh/1.txt"));
+
+       cl_assert(!git_path_isdir("testrepo/a"));
+
+       assert_on_branch(g_repo, "subtrees");
+
+       git_object_free(obj);
+}
+