]> git.proxmox.com Git - libgit2.git/commitdiff
git_checkout_index: checkout other indexes
authorEdward Thomson <ethomson@microsoft.com>
Fri, 23 May 2014 21:50:51 +0000 (14:50 -0700)
committerEdward Thomson <ethomson@edwardthomson.com>
Tue, 1 Jul 2014 21:32:15 +0000 (17:32 -0400)
git_checkout_index can now check out other git_index's (that are not
necessarily the repository index).  This allows checkout_index to use
the repository's index for stat cache information instead of the index
data being checked out.  git_merge and friends now check out their
indexes directly instead of trying to blend it into the running index.

src/checkout.c
src/cherrypick.c
src/merge.c
src/merge.h
src/revert.c
tests/merge/workdir/dirty.c

index 20763fd35b08fe22291681540d746076135e8188..adb3c81e078605c1f6a393210fad1bfd7af754f2 100644 (file)
@@ -46,6 +46,7 @@ enum {
 
 typedef struct {
        git_repository *repo;
+       git_iterator *target;
        git_diff *diff;
        git_checkout_options opts;
        bool opts_free_baseline;
@@ -54,6 +55,8 @@ typedef struct {
        git_pool pool;
        git_vector removes;
        git_vector conflicts;
+       git_vector *reuc;
+       git_vector *names;
        git_buf path;
        size_t workdir_len;
        git_buf tmp;
@@ -138,6 +141,7 @@ static int checkout_notify(
 static bool checkout_is_workdir_modified(
        checkout_data *data,
        const git_diff_file *baseitem,
+       const git_diff_file *newitem,
        const git_index_entry *wditem)
 {
        git_oid oid;
@@ -169,13 +173,16 @@ static bool checkout_is_workdir_modified(
 
        /* Look at the cache to decide if the workdir is modified.  If not,
         * we can simply compare the oid in the cache to the baseitem instead
-        * of hashing the file.
+        * of hashing the file.  If so, we allow the checkout to proceed if the
+        * oid is identical (ie, the staged item is what we're trying to check
+        * out.)
         */
        if ((ie = git_index_get_bypath(data->index, wditem->path, 0)) != NULL) {
                if (wditem->mtime.seconds == ie->mtime.seconds &&
                        wditem->mtime.nanoseconds == ie->mtime.nanoseconds &&
                        wditem->file_size == ie->file_size)
-                       return (git_oid__cmp(&baseitem->id, &ie->id) != 0);
+                       return (git_oid__cmp(&baseitem->id, &ie->id) != 0 &&
+                               git_oid_cmp(&newitem->id, &ie->id) != 0);
        }
 
        /* depending on where base is coming from, we may or may not know
@@ -401,7 +408,7 @@ static int checkout_action_with_wd(
 
        switch (delta->status) {
        case GIT_DELTA_UNMODIFIED: /* case 14/15 or 33 */
-               if (checkout_is_workdir_modified(data, &delta->old_file, wd)) {
+               if (checkout_is_workdir_modified(data, &delta->old_file, &delta->new_file, wd)) {
                        GITERR_CHECK_ERROR(
                                checkout_notify(data, GIT_CHECKOUT_NOTIFY_DIRTY, delta, wd) );
                        *action = CHECKOUT_ACTION_IF(FORCE, UPDATE_BLOB, NONE);
@@ -414,13 +421,13 @@ static int checkout_action_with_wd(
                        *action = CHECKOUT_ACTION_IF(FORCE, UPDATE_BLOB, CONFLICT);
                break;
        case GIT_DELTA_DELETED: /* case 9 or 10 (or 26 but not really) */
-               if (checkout_is_workdir_modified(data, &delta->old_file, wd))
+               if (checkout_is_workdir_modified(data, &delta->old_file, &delta->new_file, wd))
                        *action = CHECKOUT_ACTION_IF(FORCE, REMOVE, CONFLICT);
                else
                        *action = CHECKOUT_ACTION_IF(SAFE, REMOVE, NONE);
                break;
        case GIT_DELTA_MODIFIED: /* case 16, 17, 18 (or 36 but not really) */
-               if (checkout_is_workdir_modified(data, &delta->old_file, wd))
+               if (checkout_is_workdir_modified(data, &delta->old_file, &delta->new_file, wd))
                        *action = CHECKOUT_ACTION_IF(FORCE, UPDATE_BLOB, CONFLICT);
                else
                        *action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE);
@@ -443,7 +450,7 @@ static int checkout_action_with_wd(
                        } else
                                *action = CHECKOUT_ACTION_IF(FORCE, REMOVE, CONFLICT);
                }
-               else if (checkout_is_workdir_modified(data, &delta->old_file, wd))
+               else if (checkout_is_workdir_modified(data, &delta->old_file, &delta->new_file, wd))
                        *action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT);
                else
                        *action = CHECKOUT_ACTION_IF(SAFE, REMOVE_AND_UPDATE, NONE);
@@ -788,11 +795,16 @@ done:
 static int checkout_conflicts_load(checkout_data *data, git_iterator *workdir, git_vector *pathspec)
 {
        git_index_conflict_iterator *iterator = NULL;
+       git_index *index;
        const git_index_entry *ancestor, *ours, *theirs;
        checkout_conflictdata *conflict;
        int error = 0;
 
-       if ((error = git_index_conflict_iterator_new(&iterator, data->index)) < 0)
+       /* Only write conficts from sources that have them: indexes. */
+       if ((index = git_iterator_get_index(data->target)) == NULL)
+               return 0;
+
+       if ((error = git_index_conflict_iterator_new(&iterator, index)) < 0)
                goto done;
 
        data->conflicts._cmp = checkout_conflictdata_cmp;
@@ -819,6 +831,10 @@ static int checkout_conflicts_load(checkout_data *data, git_iterator *workdir, g
                git_vector_insert(&data->conflicts, conflict);
        }
 
+       /* Collect the REUC and NAME entries */
+       data->reuc = &index->reuc;
+       data->names = &index->names;
+
        if (error == GIT_ITEROVER)
                error = 0;
 
@@ -957,16 +973,20 @@ done:
 static int checkout_conflicts_coalesce_renames(
        checkout_data *data)
 {
+       git_index *index;
        const git_index_name_entry *name_entry;
        checkout_conflictdata *ancestor_conflict, *our_conflict, *their_conflict;
        size_t i, names;
        int error = 0;
 
+       if ((index = git_iterator_get_index(data->target)) == NULL)
+               return 0;
+
        /* Juggle entries based on renames */
-       names = git_index_name_entrycount(data->index);
+       names = git_index_name_entrycount(index);
 
        for (i = 0; i < names; i++) {
-               name_entry = git_index_name_get_byindex(data->index, i);
+               name_entry = git_index_name_get_byindex(index, i);
 
                if ((error = checkout_conflicts_load_byname_entry(
                        &ancestor_conflict, &our_conflict, &their_conflict,
@@ -1010,13 +1030,17 @@ done:
 static int checkout_conflicts_mark_directoryfile(
        checkout_data *data)
 {
+       git_index *index;
        checkout_conflictdata *conflict;
        const git_index_entry *entry;
        size_t i, j, len;
        const char *path;
        int prefixed, error = 0;
 
-       len = git_index_entrycount(data->index);
+       if ((index = git_iterator_get_index(data->target)) == NULL)
+               return 0;
+
+       len = git_index_entrycount(index);
 
        /* Find d/f conflicts */
        git_vector_foreach(&data->conflicts, i, conflict) {
@@ -1027,7 +1051,7 @@ static int checkout_conflicts_mark_directoryfile(
                path = conflict->ours ?
                        conflict->ours->path : conflict->theirs->path;
 
-               if ((error = git_index_find(&j, data->index, path)) < 0) {
+               if ((error = git_index_find(&j, index, path)) < 0) {
                        if (error == GIT_ENOTFOUND)
                                giterr_set(GITERR_INDEX,
                                        "Index inconsistency, could not find entry for expected conflict '%s'", path);
@@ -1036,7 +1060,7 @@ static int checkout_conflicts_mark_directoryfile(
                }
 
                for (; j < len; j++) {
-                       if ((entry = git_index_get_byindex(data->index, j)) == NULL) {
+                       if ((entry = git_index_get_byindex(index, j)) == NULL) {
                                giterr_set(GITERR_INDEX,
                                        "Index inconsistency, truncated index while loading expected conflict '%s'", path);
                                error = -1;
@@ -1802,6 +1826,24 @@ done:
        return error;
 }
 
+static int checkout_conflict_update_index(
+       checkout_data *data,
+       checkout_conflictdata *conflict)
+{
+       int error = 0;
+
+       if (conflict->ancestor)
+               error = git_index_add(data->index, conflict->ancestor);
+
+       if (!error && conflict->ours)
+               error = git_index_add(data->index, conflict->ours);
+
+       if (!error && conflict->theirs)
+               error = git_index_add(data->index, conflict->theirs);
+
+       return error;
+}
+
 static int checkout_create_conflicts(checkout_data *data)
 {
        checkout_conflictdata *conflict;
@@ -1864,6 +1906,12 @@ static int checkout_create_conflicts(checkout_data *data)
                else if (!error)
                        error = checkout_write_merge(data, conflict);
 
+               /* Update the index extensions (REUC and NAME) if we're checking
+                * out a different index. (Otherwise just leave them there.)
+                */
+               if (!error && (data->strategy & GIT_CHECKOUT_DONT_UPDATE_INDEX) == 0)
+                       error = checkout_conflict_update_index(data, conflict);
+
                if (error)
                        break;
 
@@ -1876,6 +1924,37 @@ static int checkout_create_conflicts(checkout_data *data)
        return error;
 }
 
+static int checkout_extensions_update_index(checkout_data *data)
+{
+       const git_index_reuc_entry *reuc_entry;
+       const git_index_name_entry *name_entry;
+       size_t i;
+       int error = 0;
+
+       if ((data->strategy & GIT_CHECKOUT_UPDATE_ONLY) != 0)
+               return 0;
+
+       if (data->reuc) {
+               git_vector_foreach(data->reuc, i, reuc_entry) {
+                       if ((error = git_index_reuc_add(data->index, reuc_entry->path,
+                               reuc_entry->mode[0], &reuc_entry->oid[0],
+                               reuc_entry->mode[1], &reuc_entry->oid[1],
+                               reuc_entry->mode[2], &reuc_entry->oid[2])) < 0)
+                               goto done;
+               }
+       }
+
+       if (data->names) {
+               git_vector_foreach(data->names, i, name_entry) {
+                       if ((error = git_index_name_add(data->index, name_entry->ancestor,
+                               name_entry->ours, name_entry->theirs)) < 0)
+                               goto done;
+               }
+       }
+
+done:
+       return error;
+}
 
 static void checkout_data_clear(checkout_data *data)
 {
@@ -1919,6 +1998,7 @@ static int checkout_data_init(
                return error;
 
        data->repo = repo;
+       data->target = target;
 
        GITERR_CHECK_VERSION(
                proposed, GIT_CHECKOUT_OPTIONS_VERSION, "git_checkout_options");
@@ -1943,15 +2023,15 @@ static int checkout_data_init(
                        (error = git_config_refresh(cfg)) < 0)
                        goto cleanup;
 
-               /* if we are checking out the index, don't reload,
-                * otherwise get index and force reload
+               /* Get the repository index and reload it (unless we're checking
+                * out the index; then it has the changes we're trying to check
+                * out and those should not be overwritten.)
                 */
-               if ((data->index = git_iterator_get_index(target)) != NULL) {
-                       GIT_REFCOUNT_INC(data->index);
-               } else {
-                       /* otherwise, grab and reload the index */
-                       if ((error = git_repository_index(&data->index, data->repo)) < 0 ||
-                               (error = git_index_read(data->index, true)) < 0)
+               if ((error = git_repository_index(&data->index, data->repo)) < 0)
+                       goto cleanup;
+
+               if (data->index != git_iterator_get_index(target)) {
+                       if ((error = git_index_read(data->index, true)) < 0)
                                goto cleanup;
 
                        /* cannot checkout if unresolved conflicts exist */
@@ -1963,7 +2043,7 @@ static int checkout_data_init(
                                goto cleanup;
                        }
 
-                       /* clean conflict data when doing a tree or commit checkout */
+                       /* clean conflict data in the current index */
                        git_index_name_clear(data->index);
                        git_index_reuc_clear(data->index);
                }
@@ -2132,6 +2212,10 @@ int git_checkout_iterator(
                (error = checkout_create_conflicts(&data)) < 0)
                goto cleanup;
 
+       if (data.index != git_iterator_get_index(target) &&
+               (error = checkout_extensions_update_index(&data)) < 0)
+               goto cleanup;
+
        assert(data.completed_steps == data.total_steps);
 
 cleanup:
@@ -2154,7 +2238,7 @@ int git_checkout_index(
        git_index *index,
        const git_checkout_options *opts)
 {
-       int error;
+       int error, owned = 0;
        git_iterator *index_i;
 
        if (!index && !repo) {
@@ -2162,10 +2246,16 @@ int git_checkout_index(
                        "Must provide either repository or index to checkout");
                return -1;
        }
-       if (index && repo && git_index_owner(index) != repo) {
+
+       if (index && repo &&
+               git_index_owner(index) &&
+               git_index_owner(index) != repo) {
                giterr_set(GITERR_CHECKOUT,
                        "Index to checkout does not match repository");
                return -1;
+       } else if(index && repo && !git_index_owner(index)) {
+               GIT_REFCOUNT_OWN(index, repo);
+               owned = 1;
        }
 
        if (!repo)
@@ -2178,6 +2268,9 @@ int git_checkout_index(
        if (!(error = git_iterator_for_index(&index_i, index, 0, NULL, NULL)))
                error = git_checkout_iterator(index_i, opts);
 
+       if (owned)
+               GIT_REFCOUNT_OWN(index, NULL);
+
        git_iterator_free(index_i);
        git_index_free(index);
 
index e02348a03fde70aacb7341afad48e86fc2e62670..cdc0eaac271a9c2505a274f1fc99b1243bbd85bf 100644 (file)
@@ -171,7 +171,7 @@ int git_cherry_pick(
        char commit_oidstr[GIT_OID_HEXSZ + 1];
        const char *commit_msg, *commit_summary;
        git_buf their_label = GIT_BUF_INIT;
-       git_index *index_new = NULL, *index_repo = NULL;
+       git_index *index_new = NULL;
        int error = 0;
 
        assert(repo && commit);
@@ -196,12 +196,10 @@ int git_cherry_pick(
                (error = git_repository_head(&our_ref, repo)) < 0 ||
                (error = git_reference_peel((git_object **)&our_commit, our_ref, GIT_OBJ_COMMIT)) < 0 ||
                (error = git_cherry_pick_commit(&index_new, repo, commit, our_commit, opts.mainline, &opts.merge_opts)) < 0 ||
-               (error = git_merge__indexes(repo, index_new)) < 0 ||
-               (error = git_repository_index(&index_repo, repo)) < 0 ||
-               (error = git_merge__append_conflicts_to_merge_msg(repo, index_repo)) < 0 ||
-               (error = git_checkout_index(repo, index_repo, &opts.checkout_opts)) < 0)
+               (error = git_merge__check_result(repo, index_new)) < 0 ||
+               (error = git_merge__append_conflicts_to_merge_msg(repo, index_new)) < 0 ||
+               (error = git_checkout_index(repo, index_new, &opts.checkout_opts)) < 0)
                goto on_error;
-
        goto done;
 
 on_error:
@@ -209,7 +207,6 @@ on_error:
 
 done:
        git_index_free(index_new);
-       git_index_free(index_repo);
        git_commit_free(our_commit);
        git_reference_free(our_ref);
        git_buf_free(&their_label);
index a279d31d4e63e6bb7414ddacef2c953da86f7c9b..68c9f66e2b7e20ef562a6a59de0d34364549d736 100644 (file)
@@ -2226,64 +2226,6 @@ static int merge_normalize_checkout_opts(
        return error;
 }
 
-static int merge_affected_paths(git_vector *paths, git_repository *repo, git_index *index_new)
-{
-       git_tree *head_tree = NULL;
-       git_iterator *iter_head = NULL, *iter_new = NULL;
-       git_diff *merged_list = NULL;
-       git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
-       git_diff_delta *delta;
-       size_t i;
-       const git_index_entry *e;
-       char *path;
-       int error = 0;
-
-       if ((error = git_repository_head_tree(&head_tree, repo)) < 0 ||
-               (error = git_iterator_for_tree(&iter_head, head_tree, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
-               (error = git_iterator_for_index(&iter_new, index_new, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
-               (error = git_diff__from_iterators(&merged_list, repo, iter_head, iter_new, &opts)) < 0)
-               goto done;
-
-       git_vector_foreach(&merged_list->deltas, i, delta) {
-               path = git__strdup(delta->new_file.path);
-               GITERR_CHECK_ALLOC(path);
-
-               if ((error = git_vector_insert(paths, path)) < 0)
-                       goto on_error;
-       }
-
-       for (i = 0; i < git_index_entrycount(index_new); i++) {
-               e = git_index_get_byindex(index_new, i);
-
-               if (git_index_entry_stage(e) != 0 &&
-                       (git_vector_last(paths) == NULL ||
-                       strcmp(git_vector_last(paths), e->path) != 0)) {
-
-                       path = git__strdup(e->path);
-                       GITERR_CHECK_ALLOC(path);
-
-                       if ((error = git_vector_insert(paths, path)) < 0)
-                               goto on_error;
-               }
-       }
-
-       goto done;
-
-on_error:
-       git_vector_foreach(paths, i, path)
-               git__free(path);
-
-       git_vector_clear(paths);
-
-done:
-       git_tree_free(head_tree);
-       git_iterator_free(iter_head);
-       git_iterator_free(iter_new);
-       git_diff_free(merged_list);
-
-       return error;
-}
-
 static int merge_check_index(size_t *conflicts, git_repository *repo, git_index *index_new, git_vector *merged_paths)
 {
        git_tree *head_tree = NULL;
@@ -2372,99 +2314,58 @@ done:
        return error;
 }
 
-int git_merge__indexes(git_repository *repo, git_index *index_new)
+int git_merge__check_result(git_repository *repo, git_index *index_new)
 {
-       git_index *index_repo = NULL;
-       int index_repo_caps = 0;
+       git_tree *head_tree = NULL;
+       git_iterator *iter_head = NULL, *iter_new = NULL;
+       git_diff *merged_list = NULL;
+       git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+       git_diff_delta *delta;
        git_vector paths = GIT_VECTOR_INIT;
-       size_t index_conflicts = 0, wd_conflicts = 0, conflicts, i;
-       char *path;
+       size_t i, index_conflicts = 0, wd_conflicts = 0, conflicts;
        const git_index_entry *e;
-       const git_index_name_entry *name;
-       const git_index_reuc_entry *reuc;
        int error = 0;
 
-       if ((error = git_repository_index(&index_repo, repo)) < 0)
-               goto done;
-
-       /* Set the index to case sensitive to handle the merge */
-       index_repo_caps = git_index_caps(index_repo);
-
-       if ((error = git_index_set_caps(index_repo, (index_repo_caps & ~GIT_INDEXCAP_IGNORE_CASE))) < 0)
-               goto done;
-
-       /* Make sure the index and workdir state do not prevent merging */
-       if ((error = merge_affected_paths(&paths, repo, index_new)) < 0 ||
-               (error = merge_check_index(&index_conflicts, repo, index_new, &paths)) < 0 ||
-               (error = merge_check_workdir(&wd_conflicts, repo, index_new, &paths)) < 0)
-               goto done;
-
-       if ((conflicts = index_conflicts + wd_conflicts) > 0) {
-               giterr_set(GITERR_MERGE, "%d uncommitted change%s would be overwritten by merge",
-                       conflicts, (conflicts != 1) ? "s" : "");
-               error = GIT_EMERGECONFLICT;
-
+       if ((error = git_repository_head_tree(&head_tree, repo)) < 0 ||
+               (error = git_iterator_for_tree(&iter_head, head_tree, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
+               (error = git_iterator_for_index(&iter_new, index_new, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
+               (error = git_diff__from_iterators(&merged_list, repo, iter_head, iter_new, &opts)) < 0)
                goto done;
-       }
 
-       /* Remove removed items from the index */
-       git_vector_foreach(&paths, i, path) {
-               if (git_index_get_bypath(index_new, path, 0) == NULL) {
-                       if ((error = git_index_remove(index_repo, path, 0)) < 0 &&
-                               error != GIT_ENOTFOUND)
-                               goto done;
-               }
-       }
-
-       /* Add updated items to the index */
-       git_vector_foreach(&paths, i, path) {
-               if ((e = git_index_get_bypath(index_new, path, 0)) != NULL) {
-                       if ((error = git_index_add(index_repo, e)) < 0)
-                               goto done;
-               }
+       git_vector_foreach(&merged_list->deltas, i, delta) {
+               if ((error = git_vector_insert(&paths, (char *)delta->new_file.path)) < 0)
+                       goto done;
        }
 
-       /* Add conflicts */
-       git_index_conflict_cleanup(index_repo);
-
        for (i = 0; i < git_index_entrycount(index_new); i++) {
                e = git_index_get_byindex(index_new, i);
 
                if (git_index_entry_stage(e) != 0 &&
-                       (error = git_index_add(index_repo, e)) < 0)
-                       goto done;
-       }
+                       (git_vector_last(&paths) == NULL ||
+                       strcmp(git_vector_last(&paths), e->path) != 0)) {
 
-       /* Add name entries */
-       git_index_name_clear(index_repo);
-
-       for (i = 0; i < git_index_name_entrycount(index_new); i++) {
-               name = git_index_name_get_byindex(index_new, i);
-
-               if ((error = git_index_name_add(index_repo,
-                       name->ancestor, name->ours, name->theirs)) < 0)
-                       goto done;
+                       if ((error = git_vector_insert(&paths, (char *)e->path)) < 0)
+                               goto done;
+               }
        }
 
-       /* Add the reuc */
-       git_index_reuc_clear(index_repo);
-
-       for (i = 0; i < git_index_reuc_entrycount(index_new); i++) {
-               reuc = (git_index_reuc_entry *)git_index_reuc_get_byindex(index_new, i);
+       /* Make sure the index and workdir state do not prevent merging */
+       if ((error = merge_check_index(&index_conflicts, repo, index_new, &paths)) < 0 ||
+               (error = merge_check_workdir(&wd_conflicts, repo, index_new, &paths)) < 0)
+               goto done;
 
-               if ((error = git_index_reuc_add(index_repo, reuc->path,
-                       reuc->mode[0], &reuc->oid[0],
-                       reuc->mode[1], &reuc->oid[1],
-                       reuc->mode[2], &reuc->oid[2])) < 0)
-                       goto done;
+       if ((conflicts = index_conflicts + wd_conflicts) > 0) {
+               giterr_set(GITERR_MERGE, "%d uncommitted change%s would be overwritten by merge",
+                       conflicts, (conflicts != 1) ? "s" : "");
+               error = GIT_EMERGECONFLICT;
        }
 
 done:
-       if (index_repo != NULL)
-        git_index_set_caps(index_repo, index_repo_caps);
-
-       git_index_free(index_repo);
-       git_vector_free_deep(&paths);
+       git_vector_free(&paths);
+       git_tree_free(head_tree);
+       git_iterator_free(iter_head);
+       git_iterator_free(iter_new);
+       git_diff_free(merged_list);
 
        return error;
 }
@@ -2657,7 +2558,7 @@ int git_merge(
        git_checkout_options checkout_opts;
        git_merge_head *ancestor_head = NULL, *our_head = NULL;
        git_tree *ancestor_tree = NULL, *our_tree = NULL, **their_trees = NULL;
-       git_index *index_new = NULL, *index_repo = NULL;
+       git_index *index_new = NULL;
        size_t i;
        int error = 0;
 
@@ -2697,10 +2598,9 @@ int git_merge(
        /* TODO: recursive, octopus, etc... */
 
        if ((error = git_merge_trees(&index_new, repo, ancestor_tree, our_tree, their_trees[0], merge_opts)) < 0 ||
-               (error = git_merge__indexes(repo, index_new)) < 0 ||
-               (error = git_repository_index(&index_repo, repo)) < 0 ||
-               (error = git_merge__append_conflicts_to_merge_msg(repo, index_repo)) < 0 ||
-               (error = git_checkout_index(repo, index_repo, &checkout_opts)) < 0)
+               (error = git_merge__check_result(repo, index_new)) < 0 ||
+               (error = git_merge__append_conflicts_to_merge_msg(repo, index_new)) < 0 ||
+               (error = git_checkout_index(repo, index_new, &checkout_opts)) < 0)
                goto on_error;
 
        goto done;
@@ -2710,7 +2610,6 @@ on_error:
 
 done:
        git_index_free(index_new);
-       git_index_free(index_repo);
 
        git_tree_free(ancestor_tree);
        git_tree_free(our_tree);
index 00f6197bfce4e56ec7d9c532d841bf9a8851d0b5..cc17389ab78d54c5bb7c2833c1d3ecc9f1844fa3 100644 (file)
@@ -149,7 +149,7 @@ int git_merge__setup(
        const git_merge_head *heads[],
        size_t heads_len);
 
-int git_merge__indexes(git_repository *repo, git_index *index_new);
+int git_merge__check_result(git_repository *repo, git_index *index_new);
 
 int git_merge__append_conflicts_to_merge_msg(git_repository *repo, git_index *index);
 
index 9c587724b1a3c633f9454a61a2bb91f848728057..36560a77c822ee358618af541b7b5620dc7357a7 100644 (file)
@@ -174,7 +174,7 @@ int git_revert(
        char commit_oidstr[GIT_OID_HEXSZ + 1];
        const char *commit_msg;
        git_buf their_label = GIT_BUF_INIT;
-       git_index *index_new = NULL, *index_repo = NULL;
+       git_index *index_new = NULL;
        int error;
 
        assert(repo && commit);
@@ -199,10 +199,9 @@ int git_revert(
                (error = git_repository_head(&our_ref, repo)) < 0 ||
                (error = git_reference_peel((git_object **)&our_commit, our_ref, GIT_OBJ_COMMIT)) < 0 ||
                (error = git_revert_commit(&index_new, repo, commit, our_commit, opts.mainline, &opts.merge_opts)) < 0 ||
-               (error = git_merge__indexes(repo, index_new)) < 0 ||
-               (error = git_repository_index(&index_repo, repo)) < 0 ||
-               (error = git_merge__append_conflicts_to_merge_msg(repo, index_repo)) < 0 ||
-               (error = git_checkout_index(repo, index_repo, &opts.checkout_opts)) < 0)
+               (error = git_merge__check_result(repo, index_new)) < 0 ||
+               (error = git_merge__append_conflicts_to_merge_msg(repo, index_new)) < 0 ||
+               (error = git_checkout_index(repo, index_new, &opts.checkout_opts)) < 0)
                goto on_error;
 
        goto done;
@@ -212,7 +211,6 @@ on_error:
 
 done:
        git_index_free(index_new);
-       git_index_free(index_repo);
        git_commit_free(our_commit);
        git_reference_free(our_ref);
        git_buf_free(&their_label);
index 776e4ea692c8706041a312f992945abca9024d46..2f776853e896da7523d551f4cc6ff7c401f10a61 100644 (file)
@@ -97,7 +97,7 @@ static int merge_branch(void)
        cl_git_pass(git_oid_fromstr(&their_oids[0], MERGE_BRANCH_OID));
        cl_git_pass(git_merge_head_from_id(&their_heads[0], repo, &their_oids[0]));
 
-       checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_ALLOW_CONFLICTS;
+       checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
        error = git_merge(repo, (const git_merge_head **)their_heads, 1, &merge_opts, &checkout_opts);
 
        git_merge_head_free(their_heads[0]);