summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <carlosmn@github.com>2016-06-17 15:45:55 +0200
committerGitHub <noreply@github.com>2016-06-17 15:45:55 +0200
commit69c71f2917fede843789e783ab6fe0fcda68753a (patch)
tree0a098b7356b880033239ab82b4fc9924e1216212
parent3e9830d7bc29f214ec2420eed2bf7de4c02720da (diff)
parentbb0bd71ab4f404509aefa3be923916e886c9d25d (diff)
downloadlibgit2-69c71f2917fede843789e783ab6fe0fcda68753a.tar.gz
Merge pull request #3823 from libgit2/ethomson/checkout_no_index
checkout: use empty baseline when no index file exists
-rw-r--r--src/checkout.c7
-rw-r--r--tests/checkout/tree.c63
2 files changed, 69 insertions, 1 deletions
diff --git a/src/checkout.c b/src/checkout.c
index b3e95dff8..f39c341d4 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -2430,8 +2430,13 @@ static int checkout_data_init(
if (!data->opts.baseline && !data->opts.baseline_index) {
data->opts_free_baseline = true;
+ error = 0;
- error = checkout_lookup_head_tree(&data->opts.baseline, repo);
+ /* if we don't have an index, this is an initial checkout and
+ * should be against an empty baseline
+ */
+ if (data->index->on_disk)
+ error = checkout_lookup_head_tree(&data->opts.baseline, repo);
if (error == GIT_EUNBORNBRANCH) {
error = 0;
diff --git a/tests/checkout/tree.c b/tests/checkout/tree.c
index 5680b86df..7df4d7ef0 100644
--- a/tests/checkout/tree.c
+++ b/tests/checkout/tree.c
@@ -1416,3 +1416,66 @@ void test_checkout_tree__safe_proceeds_if_no_index(void)
git_object_free(obj);
}
+static int checkout_conflict_count_cb(
+ git_checkout_notify_t why,
+ const char *path,
+ const git_diff_file *b,
+ const git_diff_file *t,
+ const git_diff_file *w,
+ void *payload)
+{
+ size_t *n = payload;
+
+ GIT_UNUSED(why);
+ GIT_UNUSED(path);
+ GIT_UNUSED(b);
+ GIT_UNUSED(t);
+ GIT_UNUSED(w);
+
+ (*n)++;
+
+ return 0;
+}
+
+/* A repo that has a HEAD (even a properly born HEAD that peels to
+ * a commit) but no index should be treated as if it's an empty baseline
+ */
+void test_checkout_tree__baseline_is_empty_when_no_index(void)
+{
+ git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
+ git_reference *head;
+ git_object *obj;
+ git_status_list *status;
+ size_t conflicts = 0;
+
+ assert_on_branch(g_repo, "master");
+ cl_git_pass(git_repository_head(&head, g_repo));
+ cl_git_pass(git_reference_peel(&obj, head, GIT_OBJ_COMMIT));
+
+ cl_git_pass(git_reset(g_repo, obj, GIT_RESET_HARD, NULL));
+
+ cl_must_pass(p_unlink("testrepo/.git/index"));
+
+ /* for a safe checkout, we should have checkout conflicts with
+ * the existing untracked files.
+ */
+ opts.checkout_strategy &= ~GIT_CHECKOUT_FORCE;
+ opts.notify_flags = GIT_CHECKOUT_NOTIFY_CONFLICT;
+ opts.notify_cb = checkout_conflict_count_cb;
+ opts.notify_payload = &conflicts;
+
+ cl_git_fail_with(GIT_ECONFLICT, git_checkout_tree(g_repo, obj, &opts));
+ cl_assert_equal_i(4, conflicts);
+
+ /* but force should succeed and update the index */
+ opts.checkout_strategy |= GIT_CHECKOUT_FORCE;
+ cl_git_pass(git_checkout_tree(g_repo, obj, &opts));
+
+ cl_git_pass(git_status_list_new(&status, g_repo, NULL));
+ cl_assert_equal_i(0, git_status_list_entrycount(status));
+ git_status_list_free(status);
+
+ git_object_free(obj);
+ git_reference_free(head);
+}
+