]> git.ipfire.org Git - thirdparty/git.git/blobdiff - builtin/checkout.c
Merge branch 'jk/bundle-use-dash-for-stdfiles'
[thirdparty/git.git] / builtin / checkout.c
index 25d269e2f8f89e7a0ea389f8e83beb664bc34688..734d730980c18e7fd8e774ac2b720e1e823dc47e 100644 (file)
@@ -1,4 +1,4 @@
-#define USE_THE_INDEX_COMPATIBILITY_MACROS
+#define USE_THE_INDEX_VARIABLE
 #include "builtin.h"
 #include "advice.h"
 #include "blob.h"
@@ -9,6 +9,7 @@
 #include "config.h"
 #include "diff.h"
 #include "dir.h"
+#include "hex.h"
 #include "hook.h"
 #include "ll-merge.h"
 #include "lockfile.h"
@@ -29,6 +30,7 @@
 #include "xdiff-interface.h"
 #include "entry.h"
 #include "parallel-checkout.h"
+#include "add-interactive.h"
 
 static const char * const checkout_usage[] = {
        N_("git checkout [<options>] <branch>"),
@@ -74,7 +76,7 @@ struct checkout_opts {
        const char *ignore_unmerged_opt;
        int ignore_unmerged;
        int pathspec_file_nul;
-       const char *pathspec_from_file;
+       char *pathspec_from_file;
 
        const char *new_branch;
        const char *new_branch_force;
@@ -148,9 +150,9 @@ static int update_some(const struct object_id *oid, struct strbuf *base,
         * entry in place. Whether it is UPTODATE or not, checkout_entry will
         * do the right thing.
         */
-       pos = cache_name_pos(ce->name, ce->ce_namelen);
+       pos = index_name_pos(&the_index, ce->name, ce->ce_namelen);
        if (pos >= 0) {
-               struct cache_entry *old = active_cache[pos];
+               struct cache_entry *old = the_index.cache[pos];
                if (ce->ce_mode == old->ce_mode &&
                    !ce_intent_to_add(old) &&
                    oideq(&ce->oid, &old->oid)) {
@@ -160,7 +162,8 @@ static int update_some(const struct object_id *oid, struct strbuf *base,
                }
        }
 
-       add_cache_entry(ce, ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE);
+       add_index_entry(&the_index, ce,
+                       ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE);
        return 0;
 }
 
@@ -178,8 +181,8 @@ static int read_tree_some(struct tree *tree, const struct pathspec *pathspec)
 
 static int skip_same_name(const struct cache_entry *ce, int pos)
 {
-       while (++pos < active_nr &&
-              !strcmp(active_cache[pos]->name, ce->name))
+       while (++pos < the_index.cache_nr &&
+              !strcmp(the_index.cache[pos]->name, ce->name))
                ; /* skip */
        return pos;
 }
@@ -187,9 +190,9 @@ static int skip_same_name(const struct cache_entry *ce, int pos)
 static int check_stage(int stage, const struct cache_entry *ce, int pos,
                       int overlay_mode)
 {
-       while (pos < active_nr &&
-              !strcmp(active_cache[pos]->name, ce->name)) {
-               if (ce_stage(active_cache[pos]) == stage)
+       while (pos < the_index.cache_nr &&
+              !strcmp(the_index.cache[pos]->name, ce->name)) {
+               if (ce_stage(the_index.cache[pos]) == stage)
                        return 0;
                pos++;
        }
@@ -206,8 +209,8 @@ static int check_stages(unsigned stages, const struct cache_entry *ce, int pos)
        unsigned seen = 0;
        const char *name = ce->name;
 
-       while (pos < active_nr) {
-               ce = active_cache[pos];
+       while (pos < the_index.cache_nr) {
+               ce = the_index.cache[pos];
                if (strcmp(name, ce->name))
                        break;
                seen |= (1 << ce_stage(ce));
@@ -223,15 +226,15 @@ static int checkout_stage(int stage, const struct cache_entry *ce, int pos,
                          const struct checkout *state, int *nr_checkouts,
                          int overlay_mode)
 {
-       while (pos < active_nr &&
-              !strcmp(active_cache[pos]->name, ce->name)) {
-               if (ce_stage(active_cache[pos]) == stage)
-                       return checkout_entry(active_cache[pos], state,
+       while (pos < the_index.cache_nr &&
+              !strcmp(the_index.cache[pos]->name, ce->name)) {
+               if (ce_stage(the_index.cache[pos]) == stage)
+                       return checkout_entry(the_index.cache[pos], state,
                                              NULL, nr_checkouts);
                pos++;
        }
        if (!overlay_mode) {
-               unlink_entry(ce);
+               unlink_entry(ce, NULL);
                return 0;
        }
        if (stage == 2)
@@ -243,7 +246,7 @@ static int checkout_stage(int stage, const struct cache_entry *ce, int pos,
 static int checkout_merged(int pos, const struct checkout *state,
                           int *nr_checkouts, struct mem_pool *ce_mem_pool)
 {
-       struct cache_entry *ce = active_cache[pos];
+       struct cache_entry *ce = the_index.cache[pos];
        const char *path = ce->name;
        mmfile_t ancestor, ours, theirs;
        enum ll_merge_result merge_status;
@@ -256,7 +259,7 @@ static int checkout_merged(int pos, const struct checkout *state,
        int renormalize = 0;
 
        memset(threeway, 0, sizeof(threeway));
-       while (pos < active_nr) {
+       while (pos < the_index.cache_nr) {
                int stage;
                stage = ce_stage(ce);
                if (!stage || strcmp(path, ce->name))
@@ -265,7 +268,7 @@ static int checkout_merged(int pos, const struct checkout *state,
                if (stage == 2)
                        mode = create_ce_mode(ce->ce_mode);
                pos++;
-               ce = active_cache[pos];
+               ce = the_index.cache[pos];
        }
        if (is_null_oid(&threeway[1]) || is_null_oid(&threeway[2]))
                return error(_("path '%s' does not have necessary versions"), path);
@@ -391,8 +394,8 @@ static int checkout_worktree(const struct checkout_opts *opts,
        if (pc_workers > 1)
                init_parallel_checkout();
 
-       for (pos = 0; pos < active_nr; pos++) {
-               struct cache_entry *ce = active_cache[pos];
+       for (pos = 0; pos < the_index.cache_nr; pos++) {
+               struct cache_entry *ce = the_index.cache[pos];
                if (ce->ce_flags & CE_MATCHED) {
                        if (!ce_stage(ce)) {
                                errs |= checkout_entry(ce, &state,
@@ -511,7 +514,7 @@ static int checkout_paths(const struct checkout_opts *opts,
        }
 
        if (opts->patch_mode) {
-               const char *patch_mode;
+               enum add_p_mode patch_mode;
                const char *rev = new_branch_info->name;
                char rev_oid[GIT_MAX_HEXSZ + 1];
 
@@ -529,19 +532,20 @@ static int checkout_paths(const struct checkout_opts *opts,
                        rev = oid_to_hex_r(rev_oid, &new_branch_info->commit->object.oid);
 
                if (opts->checkout_index && opts->checkout_worktree)
-                       patch_mode = "--patch=checkout";
+                       patch_mode = ADD_P_CHECKOUT;
                else if (opts->checkout_index && !opts->checkout_worktree)
-                       patch_mode = "--patch=reset";
+                       patch_mode = ADD_P_RESET;
                else if (!opts->checkout_index && opts->checkout_worktree)
-                       patch_mode = "--patch=worktree";
+                       patch_mode = ADD_P_WORKTREE;
                else
                        BUG("either flag must have been set, worktree=%d, index=%d",
                            opts->checkout_worktree, opts->checkout_index);
-               return run_add_interactive(rev, patch_mode, &opts->pathspec);
+               return !!run_add_p(the_repository, patch_mode, rev,
+                                  &opts->pathspec);
        }
 
        repo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR);
-       if (read_cache_preload(&opts->pathspec) < 0)
+       if (repo_read_index_preload(the_repository, &opts->pathspec, 0) < 0)
                return error(_("index file corrupt"));
 
        if (opts->source_tree)
@@ -553,13 +557,13 @@ static int checkout_paths(const struct checkout_opts *opts,
         * Make sure all pathspecs participated in locating the paths
         * to be checked out.
         */
-       for (pos = 0; pos < active_nr; pos++)
+       for (pos = 0; pos < the_index.cache_nr; pos++)
                if (opts->overlay_mode)
-                       mark_ce_for_checkout_overlay(active_cache[pos],
+                       mark_ce_for_checkout_overlay(the_index.cache[pos],
                                                     ps_matched,
                                                     opts);
                else
-                       mark_ce_for_checkout_no_overlay(active_cache[pos],
+                       mark_ce_for_checkout_no_overlay(the_index.cache[pos],
                                                        ps_matched,
                                                        opts);
 
@@ -574,8 +578,8 @@ static int checkout_paths(const struct checkout_opts *opts,
                unmerge_marked_index(&the_index);
 
        /* Any unmerged paths? */
-       for (pos = 0; pos < active_nr; pos++) {
-               const struct cache_entry *ce = active_cache[pos];
+       for (pos = 0; pos < the_index.cache_nr; pos++) {
+               const struct cache_entry *ce = the_index.cache[pos];
                if (ce->ce_flags & CE_MATCHED) {
                        if (!ce_stage(ce))
                                continue;
@@ -735,7 +739,7 @@ static void init_topts(struct unpack_trees_options *topts, int merge,
 
        setup_unpack_trees_porcelain(topts, "checkout");
 
-       topts->initial_checkout = is_cache_unborn();
+       topts->initial_checkout = is_index_unborn(&the_index);
        topts->update = 1;
        topts->merge = 1;
        topts->quiet = merge && old_commit;
@@ -753,11 +757,11 @@ static int merge_working_tree(const struct checkout_opts *opts,
        struct lock_file lock_file = LOCK_INIT;
        struct tree *new_tree;
 
-       hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
-       if (read_cache_preload(NULL) < 0)
+       repo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR);
+       if (repo_read_index_preload(the_repository, NULL, 0) < 0)
                return error(_("index file corrupt"));
 
-       resolve_undo_clear();
+       resolve_undo_clear_index(&the_index);
        if (opts->new_orphan_branch && opts->orphan_from_empty_tree) {
                if (new_branch_info->commit)
                        BUG("'switch --orphan' should never accept a commit as starting point");
@@ -774,9 +778,9 @@ static int merge_working_tree(const struct checkout_opts *opts,
                struct unpack_trees_options topts;
                const struct object_id *old_commit_oid;
 
-               refresh_cache(REFRESH_QUIET);
+               refresh_index(&the_index, REFRESH_QUIET, NULL, NULL, NULL);
 
-               if (unmerged_cache()) {
+               if (unmerged_index(&the_index)) {
                        error(_("you need to resolve your current index first"));
                        return 1;
                }
@@ -880,7 +884,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
                }
        }
 
-       if (!cache_tree_fully_valid(active_cache_tree))
+       if (!cache_tree_fully_valid(the_index.cache_tree))
                cache_tree_update(&the_index, WRITE_TREE_SILENT | WRITE_TREE_REPAIR);
 
        if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
@@ -1282,7 +1286,7 @@ static int parse_branchname_arg(int argc, const char **argv,
         *       between A and B, A...B names that merge base.
         *
         *   (b) If <something> is _not_ a commit, either "--" is present
-        *       or <something> is not a path, no -t or -b was given, and
+        *       or <something> is not a path, no -t or -b was given,
         *       and there is a tracking branch whose name is <something>
         *       in one and only one remote (or if the branch exists on the
         *       remote named in checkout.defaultRemote), then this is a
@@ -1483,6 +1487,8 @@ static void die_if_some_operation_in_progress(void)
                      "or \"git worktree add\"."));
        if (state.bisect_in_progress)
                warning(_("you are switching branch while bisecting"));
+
+       wt_status_state_free_buffers(&state);
 }
 
 static int checkout_branch(struct checkout_opts *opts,
@@ -1884,6 +1890,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
                            options, checkout_usage, &new_branch_info);
        branch_info_release(&new_branch_info);
        clear_pathspec(&opts.pathspec);
+       free(opts.pathspec_from_file);
        FREE_AND_NULL(options);
        return ret;
 }