Merge branch 'nd/no-the-index'
authorJunio C Hamano <gitster@pobox.com>
Mon, 20 Aug 2018 18:33:53 +0000 (11:33 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 20 Aug 2018 18:33:53 +0000 (11:33 -0700)
The more library-ish parts of the codebase learned to work on the
in-core index-state instance that is passed in by their callers,
instead of always working on the singleton "the_index" instance.

* nd/no-the-index: (24 commits)
  blame.c: remove implicit dependency on the_index
  apply.c: remove implicit dependency on the_index
  apply.c: make init_apply_state() take a struct repository
  apply.c: pass struct apply_state to more functions
  resolve-undo.c: use the right index instead of the_index
  archive-*.c: use the right repository
  archive.c: avoid access to the_index
  grep: use the right index instead of the_index
  attr: remove index from git_attr_set_direction()
  entry.c: use the right index instead of the_index
  submodule.c: use the right index instead of the_index
  pathspec.c: use the right index instead of the_index
  unpack-trees: avoid the_index in verify_absent()
  unpack-trees: convert clear_ce_flags* to avoid the_index
  unpack-trees: don't shadow global var the_index
  unpack-trees: add a note about path invalidation
  unpack-trees: remove 'extern' on function declaration
  ls-files: correct index argument to get_convert_attr_ascii()
  preload-index.c: use the right index instead of the_index
  dir.c: remove an implicit dependency on the_index in pathspec code
  ...

55 files changed:
apply.c
apply.h
archive-tar.c
archive-zip.c
archive.c
archive.h
attr.c
attr.h
blame.c
blame.h
builtin/add.c
builtin/am.c
builtin/apply.c
builtin/archive.c
builtin/blame.c
builtin/cat-file.c
builtin/check-attr.c
builtin/checkout-index.c
builtin/checkout.c
builtin/clean.c
builtin/commit.c
builtin/diff-tree.c
builtin/grep.c
builtin/ls-files.c
builtin/pack-objects.c
builtin/rm.c
builtin/submodule--helper.c
builtin/update-index.c
builtin/upload-archive.c
cache-tree.c
cache-tree.h
convert.c
convert.h
diff-lib.c
diff.c
diff.h
dir.c
dir.h
entry.c
ll-merge.c
merge-recursive.c
pathspec.c
preload-index.c
read-cache.c
rerere.c
resolve-undo.c
revision.c
sequencer.c
sha1-file.c
submodule.c
unpack-trees.c
unpack-trees.h
userdiff.c
ws.c
wt-status.c

diff --git a/apply.c b/apply.c
index 2594927..e485fbc 100644 (file)
--- a/apply.c
+++ b/apply.c
@@ -76,10 +76,12 @@ static int parse_ignorewhitespace_option(struct apply_state *state,
 }
 
 int init_apply_state(struct apply_state *state,
+                    struct repository *repo,
                     const char *prefix)
 {
        memset(state, 0, sizeof(*state));
        state->prefix = prefix;
+       state->repo = repo;
        state->apply = 1;
        state->line_termination = '\n';
        state->p_value = 1;
@@ -3374,14 +3376,17 @@ static struct patch *previous_patch(struct apply_state *state,
        return previous;
 }
 
-static int verify_index_match(const struct cache_entry *ce, struct stat *st)
+static int verify_index_match(struct apply_state *state,
+                             const struct cache_entry *ce,
+                             struct stat *st)
 {
        if (S_ISGITLINK(ce->ce_mode)) {
                if (!S_ISDIR(st->st_mode))
                        return -1;
                return 0;
        }
-       return ce_match_stat(ce, st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE);
+       return ie_match_stat(state->repo->index, ce, st,
+                            CE_MATCH_IGNORE_VALID | CE_MATCH_IGNORE_SKIP_WORKTREE);
 }
 
 #define SUBMODULE_PATCH_WITHOUT_INDEX 1
@@ -3514,17 +3519,17 @@ static int load_current(struct apply_state *state,
        if (!patch->is_new)
                BUG("patch to %s is not a creation", patch->old_name);
 
-       pos = cache_name_pos(name, strlen(name));
+       pos = index_name_pos(state->repo->index, name, strlen(name));
        if (pos < 0)
                return error(_("%s: does not exist in index"), name);
-       ce = active_cache[pos];
+       ce = state->repo->index->cache[pos];
        if (lstat(name, &st)) {
                if (errno != ENOENT)
                        return error_errno("%s", name);
-               if (checkout_target(&the_index, ce, &st))
+               if (checkout_target(state->repo->index, ce, &st))
                        return -1;
        }
-       if (verify_index_match(ce, &st))
+       if (verify_index_match(state, ce, &st))
                return error(_("%s: does not match index"), name);
 
        status = load_patch_target(state, &buf, ce, &st, patch, name, mode);
@@ -3683,18 +3688,19 @@ static int check_preimage(struct apply_state *state,
        }
 
        if (state->check_index && !previous) {
-               int pos = cache_name_pos(old_name, strlen(old_name));
+               int pos = index_name_pos(state->repo->index, old_name,
+                                        strlen(old_name));
                if (pos < 0) {
                        if (patch->is_new < 0)
                                goto is_new;
                        return error(_("%s: does not exist in index"), old_name);
                }
-               *ce = active_cache[pos];
+               *ce = state->repo->index->cache[pos];
                if (stat_ret < 0) {
-                       if (checkout_target(&the_index, *ce, st))
+                       if (checkout_target(state->repo->index, *ce, st))
                                return -1;
                }
-               if (!state->cached && verify_index_match(*ce, st))
+               if (!state->cached && verify_index_match(state, *ce, st))
                        return error(_("%s: does not match index"), old_name);
                if (state->cached)
                        st_mode = (*ce)->ce_mode;
@@ -3738,7 +3744,7 @@ static int check_to_create(struct apply_state *state,
        struct stat nst;
 
        if (state->check_index &&
-           cache_name_pos(new_name, strlen(new_name)) >= 0 &&
+           index_name_pos(state->repo->index, new_name, strlen(new_name)) >= 0 &&
            !ok_if_exists)
                return EXISTS_IN_INDEX;
        if (state->cached)
@@ -3827,7 +3833,8 @@ static int path_is_beyond_symlink_1(struct apply_state *state, struct strbuf *na
                if (state->check_index) {
                        struct cache_entry *ce;
 
-                       ce = cache_file_exists(name->buf, name->len, ignore_case);
+                       ce = index_file_exists(state->repo->index, name->buf,
+                                              name->len, ignore_case);
                        if (ce && S_ISLNK(ce->ce_mode))
                                return 1;
                } else {
@@ -4002,9 +4009,10 @@ static int check_patch_list(struct apply_state *state, struct patch *patch)
 static int read_apply_cache(struct apply_state *state)
 {
        if (state->index_file)
-               return read_cache_from(state->index_file);
+               return read_index_from(state->repo->index, state->index_file,
+                                      get_git_dir());
        else
-               return read_cache();
+               return read_index(state->repo->index);
 }
 
 /* This function tries to read the object name from the current index */
@@ -4015,10 +4023,10 @@ static int get_current_oid(struct apply_state *state, const char *path,
 
        if (read_apply_cache(state) < 0)
                return -1;
-       pos = cache_name_pos(path, strlen(path));
+       pos = index_name_pos(state->repo->index, path, strlen(path));
        if (pos < 0)
                return -1;
-       oidcpy(oid, &active_cache[pos]->oid);
+       oidcpy(oid, &state->repo->index->cache[pos]->oid);
        return 0;
 }
 
@@ -4246,7 +4254,7 @@ static void patch_stats(struct apply_state *state, struct patch *patch)
 static int remove_file(struct apply_state *state, struct patch *patch, int rmdir_empty)
 {
        if (state->update_index && !state->ita_only) {
-               if (remove_file_from_cache(patch->old_name) < 0)
+               if (remove_file_from_index(state->repo->index, patch->old_name) < 0)
                        return error(_("unable to remove %s from index"), patch->old_name);
        }
        if (!state->cached) {
@@ -4267,7 +4275,7 @@ static int add_index_file(struct apply_state *state,
        struct cache_entry *ce;
        int namelen = strlen(path);
 
-       ce = make_empty_cache_entry(&the_index, namelen);
+       ce = make_empty_cache_entry(state->repo->index, namelen);
        memcpy(ce->name, path, namelen);
        ce->ce_mode = create_ce_mode(mode);
        ce->ce_flags = create_ce_flags(0);
@@ -4299,7 +4307,7 @@ static int add_index_file(struct apply_state *state,
                                       "for newly created file %s"), path);
                }
        }
-       if (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD) < 0) {
+       if (add_index_entry(state->repo->index, ce, ADD_CACHE_OK_TO_ADD) < 0) {
                discard_cache_entry(ce);
                return error(_("unable to add cache entry for %s"), path);
        }
@@ -4313,7 +4321,9 @@ static int add_index_file(struct apply_state *state,
  *   0 if everything went well
  *   1 if a recoverable error happened
  */
-static int try_create_file(const char *path, unsigned int mode, const char *buf, unsigned long size)
+static int try_create_file(struct apply_state *state, const char *path,
+                          unsigned int mode, const char *buf,
+                          unsigned long size)
 {
        int fd, res;
        struct strbuf nbuf = STRBUF_INIT;
@@ -4335,7 +4345,7 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,
        if (fd < 0)
                return 1;
 
-       if (convert_to_working_tree(path, buf, size, &nbuf)) {
+       if (convert_to_working_tree(state->repo->index, path, buf, size, &nbuf)) {
                size = nbuf.len;
                buf  = nbuf.buf;
        }
@@ -4371,7 +4381,7 @@ static int create_one_file(struct apply_state *state,
        if (state->cached)
                return 0;
 
-       res = try_create_file(path, mode, buf, size);
+       res = try_create_file(state, path, mode, buf, size);
        if (res < 0)
                return -1;
        if (!res)
@@ -4380,7 +4390,7 @@ static int create_one_file(struct apply_state *state,
        if (errno == ENOENT) {
                if (safe_create_leading_directories(path))
                        return 0;
-               res = try_create_file(path, mode, buf, size);
+               res = try_create_file(state, path, mode, buf, size);
                if (res < 0)
                        return -1;
                if (!res)
@@ -4402,7 +4412,7 @@ static int create_one_file(struct apply_state *state,
                for (;;) {
                        char newpath[PATH_MAX];
                        mksnpath(newpath, sizeof(newpath), "%s~%u", path, nr);
-                       res = try_create_file(newpath, mode, buf, size);
+                       res = try_create_file(state, newpath, mode, buf, size);
                        if (res < 0)
                                return -1;
                        if (!res) {
@@ -4432,17 +4442,17 @@ static int add_conflicted_stages_file(struct apply_state *state,
        namelen = strlen(patch->new_name);
        mode = patch->new_mode ? patch->new_mode : (S_IFREG | 0644);
 
-       remove_file_from_cache(patch->new_name);
+       remove_file_from_index(state->repo->index, patch->new_name);
        for (stage = 1; stage < 4; stage++) {
                if (is_null_oid(&patch->threeway_stage[stage - 1]))
                        continue;
-               ce = make_empty_cache_entry(&the_index, namelen);
+               ce = make_empty_cache_entry(state->repo->index, namelen);
                memcpy(ce->name, patch->new_name, namelen);
                ce->ce_mode = create_ce_mode(mode);
                ce->ce_flags = create_ce_flags(stage);
                ce->ce_namelen = namelen;
                oidcpy(&ce->oid, &patch->threeway_stage[stage - 1]);
-               if (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD) < 0) {
+               if (add_index_entry(state->repo->index, ce, ADD_CACHE_OK_TO_ADD) < 0) {
                        discard_cache_entry(ce);
                        return error(_("unable to add cache entry for %s"),
                                     patch->new_name);
@@ -4891,7 +4901,7 @@ int apply_all_patches(struct apply_state *state,
        }
 
        if (state->update_index) {
-               res = write_locked_index(&the_index, &state->lock_file, COMMIT_LOCK);
+               res = write_locked_index(state->repo->index, &state->lock_file, COMMIT_LOCK);
                if (res) {
                        error(_("Unable to write new index file"));
                        res = -128;
diff --git a/apply.h b/apply.h
index 01963b5..78c8bcf 100644 (file)
--- a/apply.h
+++ b/apply.h
@@ -1,6 +1,8 @@
 #ifndef APPLY_H
 #define APPLY_H
 
+struct repository;
+
 enum apply_ws_error_action {
        nowarn_ws_error,
        warn_on_ws_error,
@@ -62,6 +64,7 @@ struct apply_state {
        int unsafe_paths;
 
        /* Other non boolean parameters */
+       struct repository *repo;
        const char *index_file;
        enum apply_verbosity apply_verbosity;
        const char *fake_ancestor;
@@ -116,6 +119,7 @@ int apply_parse_options(int argc, const char **argv,
                        int *force_apply, int *options,
                        const char * const *apply_usage);
 int init_apply_state(struct apply_state *state,
+                    struct repository *repo,
                     const char *prefix);
 void clear_apply_state(struct apply_state *state);
 int check_apply_state(struct apply_state *state, int force_apply);
index 0bc50f6..7a535cb 100644 (file)
@@ -277,7 +277,7 @@ static int write_tar_entry(struct archiver_args *args,
                memcpy(header.name, path, pathlen);
 
        if (S_ISREG(mode) && !args->convert &&
-           oid_object_info(the_repository, oid, &size) == OBJ_BLOB &&
+           oid_object_info(args->repo, oid, &size) == OBJ_BLOB &&
            size > big_file_threshold)
                buffer = NULL;
        else if (S_ISLNK(mode) || S_ISREG(mode)) {
index 024267f..5a62351 100644 (file)
@@ -326,7 +326,7 @@ static int write_zip_entry(struct archiver_args *args,
                compressed_size = 0;
                buffer = NULL;
        } else if (S_ISREG(mode) || S_ISLNK(mode)) {
-               enum object_type type = oid_object_info(the_repository, oid,
+               enum object_type type = oid_object_info(args->repo, oid,
                                                        &size);
 
                method = 0;
index 78b0a39..0a07b14 100644 (file)
--- a/archive.c
+++ b/archive.c
@@ -79,7 +79,7 @@ void *object_file_to_archive(const struct archiver_args *args,
                size_t size = 0;
 
                strbuf_attach(&buf, buffer, *sizep, *sizep + 1);
-               convert_to_working_tree(path, buf.buf, buf.len, &buf);
+               convert_to_working_tree(args->repo->index, path, buf.buf, buf.len, &buf);
                if (commit)
                        format_subst(commit, buf.buf, buf.len, &buf);
                buffer = strbuf_detach(&buf, &size);
@@ -104,12 +104,13 @@ struct archiver_context {
        struct directory *bottom;
 };
 
-static const struct attr_check *get_archive_attrs(const char *path)
+static const struct attr_check *get_archive_attrs(struct index_state *istate,
+                                                 const char *path)
 {
        static struct attr_check *check;
        if (!check)
                check = attr_check_initl("export-ignore", "export-subst", NULL);
-       return git_check_attr(path, check) ? NULL : check;
+       return git_check_attr(istate, path, check) ? NULL : check;
 }
 
 static int check_attr_export_ignore(const struct attr_check *check)
@@ -145,7 +146,7 @@ static int write_archive_entry(const struct object_id *oid, const char *base,
 
        if (!S_ISDIR(mode)) {
                const struct attr_check *check;
-               check = get_archive_attrs(path_without_prefix);
+               check = get_archive_attrs(args->repo->index, path_without_prefix);
                if (check_attr_export_ignore(check))
                        return 0;
                args->convert = check_attr_export_subst(check);
@@ -220,7 +221,7 @@ static int queue_or_write_archive_entry(const struct object_id *oid,
                /* Borrow base, but restore its original value when done. */
                strbuf_addstr(base, filename);
                strbuf_addch(base, '/');
-               check = get_archive_attrs(base->buf);
+               check = get_archive_attrs(c->args->repo->index, base->buf);
                strbuf_setlen(base, baselen);
 
                if (check_attr_export_ignore(check))
@@ -268,13 +269,13 @@ int write_archive_entries(struct archiver_args *args,
                memset(&opts, 0, sizeof(opts));
                opts.index_only = 1;
                opts.head_idx = -1;
-               opts.src_index = &the_index;
-               opts.dst_index = &the_index;
+               opts.src_index = args->repo->index;
+               opts.dst_index = args->repo->index;
                opts.fn = oneway_merge;
                init_tree_desc(&t, args->tree->buffer, args->tree->size);
                if (unpack_trees(1, &t, &opts))
                        return -1;
-               git_attr_set_direction(GIT_ATTR_INDEX, &the_index);
+               git_attr_set_direction(GIT_ATTR_INDEX);
        }
 
        err = read_tree_recursive(args->tree, "", 0, 0, &args->pathspec,
@@ -304,33 +305,43 @@ static const struct archiver *lookup_archiver(const char *name)
        return NULL;
 }
 
+struct path_exists_context {
+       struct pathspec pathspec;
+       struct archiver_args *args;
+};
+
 static int reject_entry(const struct object_id *oid, struct strbuf *base,
                        const char *filename, unsigned mode,
                        int stage, void *context)
 {
        int ret = -1;
+       struct path_exists_context *ctx = context;
+
        if (S_ISDIR(mode)) {
                struct strbuf sb = STRBUF_INIT;
                strbuf_addbuf(&sb, base);
                strbuf_addstr(&sb, filename);
-               if (!match_pathspec(context, sb.buf, sb.len, 0, NULL, 1))
+               if (!match_pathspec(ctx->args->repo->index,
+                                   &ctx->pathspec,
+                                   sb.buf, sb.len, 0, NULL, 1))
                        ret = READ_TREE_RECURSIVE;
                strbuf_release(&sb);
        }
        return ret;
 }
 
-static int path_exists(struct tree *tree, const char *path)
+static int path_exists(struct archiver_args *args, const char *path)
 {
        const char *paths[] = { path, NULL };
-       struct pathspec pathspec;
+       struct path_exists_context ctx;
        int ret;
 
-       parse_pathspec(&pathspec, 0, 0, "", paths);
-       pathspec.recursive = 1;
-       ret = read_tree_recursive(tree, "", 0, 0, &pathspec,
-                                 reject_entry, &pathspec);
-       clear_pathspec(&pathspec);
+       ctx.args = args;
+       parse_pathspec(&ctx.pathspec, 0, 0, "", paths);
+       ctx.pathspec.recursive = 1;
+       ret = read_tree_recursive(args->tree, "", 0, 0, &ctx.pathspec,
+                                 reject_entry, &ctx);
+       clear_pathspec(&ctx.pathspec);
        return ret != 0;
 }
 
@@ -348,7 +359,7 @@ static void parse_pathspec_arg(const char **pathspec,
        ar_args->pathspec.recursive = 1;
        if (pathspec) {
                while (*pathspec) {
-                       if (**pathspec && !path_exists(ar_args->tree, *pathspec))
+                       if (**pathspec && !path_exists(ar_args, *pathspec))
                                die(_("pathspec '%s' did not match any files"), *pathspec);
                        pathspec++;
                }
@@ -510,6 +521,7 @@ static int parse_archive_args(int argc, const char **argv,
 }
 
 int write_archive(int argc, const char **argv, const char *prefix,
+                 struct repository *repo,
                  const char *name_hint, int remote)
 {
        const struct archiver *ar = NULL;
@@ -521,6 +533,7 @@ int write_archive(int argc, const char **argv, const char *prefix,
        init_tar_archiver();
        init_zip_archiver();
 
+       args.repo = repo;
        argc = parse_archive_args(argc, argv, &ar, &args, name_hint, remote);
        if (!startup_info->have_repository) {
                /*
index 1f9954f..75b9a86 100644 (file)
--- a/archive.h
+++ b/archive.h
@@ -3,7 +3,10 @@
 
 #include "pathspec.h"
 
+struct repository;
+
 struct archiver_args {
+       struct repository *repo;
        const char *base;
        size_t baselen;
        struct tree *tree;
@@ -17,6 +20,16 @@ struct archiver_args {
        int compression_level;
 };
 
+/* main api */
+
+extern int write_archive(int argc, const char **argv, const char *prefix,
+                        struct repository *repo,
+                        const char *name_hint, int remote);
+
+const char *archive_format_from_filename(const char *filename);
+
+/* archive backend stuff */
+
 #define ARCHIVER_WANT_COMPRESSION_LEVELS 1
 #define ARCHIVER_REMOTE 2
 struct archiver {
@@ -36,9 +49,6 @@ typedef int (*write_archive_entry_fn_t)(struct archiver_args *args,
                                        unsigned int mode);
 
 extern int write_archive_entries(struct archiver_args *args, write_archive_entry_fn_t write_entry);
-extern int write_archive(int argc, const char **argv, const char *prefix, const char *name_hint, int remote);
-
-const char *archive_format_from_filename(const char *filename);
 extern void *object_file_to_archive(const struct archiver_args *args,
                                    const char *path, const struct object_id *oid,
                                    unsigned int mode, enum object_type *type,
diff --git a/attr.c b/attr.c
index 067fb9e..98e4953 100644 (file)
--- a/attr.c
+++ b/attr.c
@@ -708,10 +708,8 @@ static struct attr_stack *read_attr_from_array(const char **list)
  * another thread could potentially be calling into the attribute system.
  */
 static enum git_attr_direction direction;
-static struct index_state *use_index;
 
-void git_attr_set_direction(enum git_attr_direction new_direction,
-                           struct index_state *istate)
+void git_attr_set_direction(enum git_attr_direction new_direction)
 {
        if (is_bare_repository() && new_direction != GIT_ATTR_INDEX)
                BUG("non-INDEX attr direction in a bare repo");
@@ -720,7 +718,6 @@ void git_attr_set_direction(enum git_attr_direction new_direction,
                drop_all_attr_stacks();
 
        direction = new_direction;
-       use_index = istate;
 }
 
 static struct attr_stack *read_attr_from_file(const char *path, int macro_ok)
@@ -743,13 +740,18 @@ static struct attr_stack *read_attr_from_file(const char *path, int macro_ok)
        return res;
 }
 
-static struct attr_stack *read_attr_from_index(const char *path, int macro_ok)
+static struct attr_stack *read_attr_from_index(const struct index_state *istate,
+                                              const char *path,
+                                              int macro_ok)
 {
        struct attr_stack *res;
        char *buf, *sp;
        int lineno = 0;
 
-       buf = read_blob_data_from_index(use_index ? use_index : &the_index, path, NULL);
+       if (!istate)
+               return NULL;
+
+       buf = read_blob_data_from_index(istate, path, NULL);
        if (!buf)
                return NULL;
 
@@ -768,15 +770,16 @@ static struct attr_stack *read_attr_from_index(const char *path, int macro_ok)
        return res;
 }
 
-static struct attr_stack *read_attr(const char *path, int macro_ok)
+static struct attr_stack *read_attr(const struct index_state *istate,
+                                   const char *path, int macro_ok)
 {
        struct attr_stack *res = NULL;
 
        if (direction == GIT_ATTR_INDEX) {
-               res = read_attr_from_index(path, macro_ok);
+               res = read_attr_from_index(istate, path, macro_ok);
        } else if (!is_bare_repository()) {
                if (direction == GIT_ATTR_CHECKOUT) {
-                       res = read_attr_from_index(path, macro_ok);
+                       res = read_attr_from_index(istate, path, macro_ok);
                        if (!res)
                                res = read_attr_from_file(path, macro_ok);
                } else if (direction == GIT_ATTR_CHECKIN) {
@@ -788,7 +791,7 @@ static struct attr_stack *read_attr(const char *path, int macro_ok)
                                 * We allow operation in a sparsely checked out
                                 * work tree, so read from it.
                                 */
-                               res = read_attr_from_index(path, macro_ok);
+                               res = read_attr_from_index(istate, path, macro_ok);
                }
        }
 
@@ -859,7 +862,8 @@ static void push_stack(struct attr_stack **attr_stack_p,
        }
 }
 
-static void bootstrap_attr_stack(struct attr_stack **stack)
+static void bootstrap_attr_stack(const struct index_state *istate,
+                                struct attr_stack **stack)
 {
        struct attr_stack *e;
 
@@ -883,7 +887,7 @@ static void bootstrap_attr_stack(struct attr_stack **stack)
        }
 
        /* root directory */
-       e = read_attr(GITATTRIBUTES_FILE, 1);
+       e = read_attr(istate, GITATTRIBUTES_FILE, 1);
        push_stack(stack, e, xstrdup(""), 0);
 
        /* info frame */
@@ -896,7 +900,8 @@ static void bootstrap_attr_stack(struct attr_stack **stack)
        push_stack(stack, e, NULL, 0);
 }
 
-static void prepare_attr_stack(const char *path, int dirlen,
+static void prepare_attr_stack(const struct index_state *istate,
+                              const char *path, int dirlen,
                               struct attr_stack **stack)
 {
        struct attr_stack *info;
@@ -917,7 +922,7 @@ static void prepare_attr_stack(const char *path, int dirlen,
         * .gitattributes in deeper directories to shallower ones,
         * and finally use the built-in set as the default.
         */
-       bootstrap_attr_stack(stack);
+       bootstrap_attr_stack(istate, stack);
 
        /*
         * Pop the "info" one that is always at the top of the stack.
@@ -973,7 +978,7 @@ static void prepare_attr_stack(const char *path, int dirlen,
                strbuf_add(&pathbuf, path + pathbuf.len, (len - pathbuf.len));
                strbuf_addf(&pathbuf, "/%s", GITATTRIBUTES_FILE);
 
-               next = read_attr(pathbuf.buf, 0);
+               next = read_attr(istate, pathbuf.buf, 0);
 
                /* reset the pathbuf to not include "/.gitattributes" */
                strbuf_setlen(&pathbuf, len);
@@ -1095,7 +1100,9 @@ static void determine_macros(struct all_attrs_item *all_attrs,
  * If check->check_nr is non-zero, only attributes in check[] are collected.
  * Otherwise all attributes are collected.
  */
-static void collect_some_attrs(const char *path, struct attr_check *check)
+static void collect_some_attrs(const struct index_state *istate,
+                              const char *path,
+                              struct attr_check *check)
 {
        int i, pathlen, rem, dirlen;
        const char *cp, *last_slash = NULL;
@@ -1114,7 +1121,7 @@ static void collect_some_attrs(const char *path, struct attr_check *check)
                dirlen = 0;
        }
 
-       prepare_attr_stack(path, dirlen, &check->stack);
+       prepare_attr_stack(istate, path, dirlen, &check->stack);
        all_attrs_init(&g_attr_hashmap, check);
        determine_macros(check->all_attrs, check->stack);
 
@@ -1136,11 +1143,13 @@ static void collect_some_attrs(const char *path, struct attr_check *check)
        fill(path, pathlen, basename_offset, check->stack, check->all_attrs, rem);
 }
 
-int git_check_attr(const char *path, struct attr_check *check)
+int git_check_attr(const struct index_state *istate,
+                  const char *path,
+                  struct attr_check *check)
 {
        int i;
 
-       collect_some_attrs(path, check);
+       collect_some_attrs(istate, path, check);
 
        for (i = 0; i < check->nr; i++) {
                size_t n = check->items[i].attr->attr_nr;
@@ -1153,12 +1162,13 @@ int git_check_attr(const char *path, struct attr_check *check)
        return 0;
 }
 
-void git_all_attrs(const char *path, struct attr_check *check)
+void git_all_attrs(const struct index_state *istate,
+                  const char *path, struct attr_check *check)
 {
        int i;
 
        attr_check_reset(check);
-       collect_some_attrs(path, check);
+       collect_some_attrs(istate, path, check);
 
        for (i = 0; i < check->all_attrs_nr; i++) {
                const char *name = check->all_attrs[i].attr->name;
diff --git a/attr.h b/attr.h
index 4634001..01dab4a 100644 (file)
--- a/attr.h
+++ b/attr.h
@@ -1,6 +1,8 @@
 #ifndef ATTR_H
 #define ATTR_H
 
+struct index_state;
+
 /* An attribute is a pointer to this opaque structure */
 struct git_attr;
 
@@ -60,21 +62,22 @@ void attr_check_free(struct attr_check *check);
  */
 const char *git_attr_name(const struct git_attr *);
 
-int git_check_attr(const char *path, struct attr_check *check);
+int git_check_attr(const struct index_state *istate,
+                  const char *path, struct attr_check *check);
 
 /*
  * Retrieve all attributes that apply to the specified path.
  * check holds the attributes and their values.
  */
-void git_all_attrs(const char *path, struct attr_check *check);
+void git_all_attrs(const struct index_state *istate,
+                  const char *path, struct attr_check *check);
 
 enum git_attr_direction {
        GIT_ATTR_CHECKIN,
        GIT_ATTR_CHECKOUT,
        GIT_ATTR_INDEX
 };
-void git_attr_set_direction(enum git_attr_direction new_direction,
-                           struct index_state *istate);
+void git_attr_set_direction(enum git_attr_direction new_direction);
 
 void attr_start(void);
 
diff --git a/blame.c b/blame.c
index 58a7036..08c0c6c 100644 (file)
--- a/blame.c
+++ b/blame.c
@@ -90,7 +90,8 @@ static struct blame_origin *get_origin(struct commit *commit, const char *path)
 
 
 
-static void verify_working_tree_path(struct commit *work_tree, const char *path)
+static void verify_working_tree_path(struct repository *repo,
+                                    struct commit *work_tree, const char *path)
 {
        struct commit_list *parents;
        int pos;
@@ -101,15 +102,15 @@ static void verify_working_tree_path(struct commit *work_tree, const char *path)
                unsigned mode;
 
                if (!get_tree_entry(commit_oid, path, &blob_oid, &mode) &&
-                   oid_object_info(the_repository, &blob_oid, NULL) == OBJ_BLOB)
+                   oid_object_info(repo, &blob_oid, NULL) == OBJ_BLOB)
                        return;
        }
 
-       pos = cache_name_pos(path, strlen(path));
+       pos = index_name_pos(repo->index, path, strlen(path));
        if (pos >= 0)
                ; /* path is in the index */
-       else if (-1 - pos < active_nr &&
-                !strcmp(active_cache[-1 - pos]->name, path))
+       else if (-1 - pos < repo->index->cache_nr &&
+                !strcmp(repo->index->cache[-1 - pos]->name, path))
                ; /* path is in the index, unmerged */
        else
                die("no such path '%s' in HEAD", path);
@@ -165,7 +166,8 @@ static void set_commit_buffer_from_strbuf(struct commit *c, struct strbuf *sb)
  * Prepare a dummy commit that represents the work tree (or staged) item.
  * Note that annotating work tree item never works in the reverse.
  */
-static struct commit *fake_working_tree_commit(struct diff_options *opt,
+static struct commit *fake_working_tree_commit(struct repository *repo,
+                                              struct diff_options *opt,
                                               const char *path,
                                               const char *contents_from)
 {
@@ -181,7 +183,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
        unsigned mode;
        struct strbuf msg = STRBUF_INIT;
 
-       read_cache();
+       read_index(repo->index);
        time(&now);
        commit = alloc_commit_node(the_repository);
        commit->object.parsed = 1;
@@ -193,7 +195,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
 
        parent_tail = append_parent(parent_tail, &head_oid);
        append_merge_parents(parent_tail);
-       verify_working_tree_path(commit, path);
+       verify_working_tree_path(repo, commit, path);
 
        origin = make_origin(commit, path);
 
@@ -251,7 +253,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
                if (strbuf_read(&buf, 0, 0) < 0)
                        die_errno("failed to read from stdin");
        }
-       convert_to_git(&the_index, path, buf.buf, buf.len, &buf, 0);
+       convert_to_git(repo->index, path, buf.buf, buf.len, &buf, 0);
        origin->file.ptr = buf.buf;
        origin->file.size = buf.len;
        pretend_object_file(buf.buf, buf.len, OBJ_BLOB, &origin->blob_oid);
@@ -262,27 +264,28 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
         * bits; we are not going to write this index out -- we just
         * want to run "diff-index --cached".
         */
-       discard_cache();
-       read_cache();
+       discard_index(repo->index);
+       read_index(repo->index);
 
        len = strlen(path);
        if (!mode) {
-               int pos = cache_name_pos(path, len);
+               int pos = index_name_pos(repo->index, path, len);
                if (0 <= pos)
-                       mode = active_cache[pos]->ce_mode;
+                       mode = repo->index->cache[pos]->ce_mode;
                else
                        /* Let's not bother reading from HEAD tree */
                        mode = S_IFREG | 0644;
        }
-       ce = make_empty_cache_entry(&the_index, len);
+       ce = make_empty_cache_entry(repo->index, len);
        oidcpy(&ce->oid, &origin->blob_oid);
        memcpy(ce->name, path, len);
        ce->ce_flags = create_ce_flags(0);
        ce->ce_namelen = len;
        ce->ce_mode = create_ce_mode(mode);
-       add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);
+       add_index_entry(repo->index, ce,
+                       ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE);
 
-       cache_tree_invalidate_path(&the_index, path);
+       cache_tree_invalidate_path(repo->index, path);
 
        return commit;
 }
@@ -519,13 +522,14 @@ static void queue_blames(struct blame_scoreboard *sb, struct blame_origin *porig
  *
  * This also fills origin->mode for corresponding tree path.
  */
-static int fill_blob_sha1_and_mode(struct blame_origin *origin)
+static int fill_blob_sha1_and_mode(struct repository *repo,
+                                  struct blame_origin *origin)
 {
        if (!is_null_oid(&origin->blob_oid))
                return 0;
        if (get_tree_entry(&origin->commit->object.oid, origin->path, &origin->blob_oid, &origin->mode))
                goto error_out;
-       if (oid_object_info(the_repository, &origin->blob_oid, NULL) != OBJ_BLOB)
+       if (oid_object_info(repo, &origin->blob_oid, NULL) != OBJ_BLOB)
                goto error_out;
        return 0;
  error_out:
@@ -1767,7 +1771,9 @@ void init_scoreboard(struct blame_scoreboard *sb)
        sb->copy_score = BLAME_DEFAULT_COPY_SCORE;
 }
 
-void setup_scoreboard(struct blame_scoreboard *sb, const char *path, struct blame_origin **orig)
+void setup_scoreboard(struct blame_scoreboard *sb,
+                     const char *path,
+                     struct blame_origin **orig)
 {
        const char *final_commit_name = NULL;
        struct blame_origin *o;
@@ -1779,6 +1785,9 @@ void setup_scoreboard(struct blame_scoreboard *sb, const char *path, struct blam
        if (sb->reverse && sb->contents_from)
                die(_("--contents and --reverse do not blend well."));
 
+       if (!sb->repo)
+               BUG("repo is NULL");
+
        if (!sb->reverse) {
                sb->final = find_single_final(sb->revs, &final_commit_name);
                sb->commits.compare = compare_commits_by_commit_date;
@@ -1800,7 +1809,8 @@ void setup_scoreboard(struct blame_scoreboard *sb, const char *path, struct blam
                 * or "--contents".
                 */
                setup_work_tree();
-               sb->final = fake_working_tree_commit(&sb->revs->diffopt,
+               sb->final = fake_working_tree_commit(sb->repo,
+                                                    &sb->revs->diffopt,
                                                     path, sb->contents_from);
                add_pending_object(sb->revs, &(sb->final->object), ":");
        }
@@ -1845,7 +1855,7 @@ void setup_scoreboard(struct blame_scoreboard *sb, const char *path, struct blam
        }
        else {
                o = get_origin(sb->final, path);
-               if (fill_blob_sha1_and_mode(o))
+               if (fill_blob_sha1_and_mode(sb->repo, o))
                        die(_("no such path %s in %s"), path, final_commit_name);
 
                if (sb->revs->diffopt.flags.allow_textconv &&
diff --git a/blame.h b/blame.h
index 9b5240f..be3a895 100644 (file)
--- a/blame.h
+++ b/blame.h
@@ -102,6 +102,7 @@ struct blame_scoreboard {
        struct commit *final;
        /* Priority queue for commits with unassigned blame records */
        struct prio_queue commits;
+       struct repository *repo;
        struct rev_info *revs;
        const char *path;
 
index ba1ff56..9916498 100644 (file)
@@ -40,7 +40,7 @@ static void chmod_pathspec(struct pathspec *pathspec, char flip)
        for (i = 0; i < active_nr; i++) {
                struct cache_entry *ce = active_cache[i];
 
-               if (pathspec && !ce_path_match(ce, pathspec, NULL))
+               if (pathspec && !ce_path_match(&the_index, ce, pathspec, NULL))
                        continue;
 
                if (chmod_cache_entry(ce, flip) < 0)
@@ -135,7 +135,7 @@ static int renormalize_tracked_files(const struct pathspec *pathspec, int flags)
                        continue; /* do not touch unmerged paths */
                if (!S_ISREG(ce->ce_mode) && !S_ISLNK(ce->ce_mode))
                        continue; /* do not touch non blobs */
-               if (pathspec && !ce_path_match(ce, pathspec, NULL))
+               if (pathspec && !ce_path_match(&the_index, ce, pathspec, NULL))
                        continue;
                retval |= add_file_to_cache(ce->name, flags | HASH_RENORMALIZE);
        }
@@ -155,7 +155,7 @@ static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec,
        i = dir->nr;
        while (--i >= 0) {
                struct dir_entry *entry = *src++;
-               if (dir_path_match(entry, pathspec, prefix, seen))
+               if (dir_path_match(&the_index, entry, pathspec, prefix, seen))
                        *dst++ = entry;
        }
        dir->nr = dst - dir->entries;
index 2c19e69..9f7ecf6 100644 (file)
@@ -1464,7 +1464,7 @@ static int run_apply(const struct am_state *state, const char *index_file)
        int force_apply = 0;
        int options = 0;
 
-       if (init_apply_state(&apply_state, NULL))
+       if (init_apply_state(&apply_state, the_repository, NULL))
                BUG("init_apply_state() failed");
 
        argv_array_push(&apply_opts, "apply");
index 48d3989..3f099b9 100644 (file)
@@ -16,7 +16,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix)
        int ret;
        struct apply_state state;
 
-       if (init_apply_state(&state, prefix))
+       if (init_apply_state(&state, the_repository, prefix))
                exit(128);
 
        argc = apply_parse_options(argc, argv,
index 73971d0..e74f675 100644 (file)
@@ -105,5 +105,5 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
 
        setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
 
-       return write_archive(argc, argv, prefix, output, 0);
+       return write_archive(argc, argv, prefix, the_repository, output, 0);
 }
index 97f6eca..c2da673 100644 (file)
@@ -988,6 +988,7 @@ parse_done:
        sb.revs = &revs;
        sb.contents_from = contents_from;
        sb.reverse = reverse;
+       sb.repo = the_repository;
        setup_scoreboard(&sb, path, &o);
        lno = sb.num_lines;
 
index 08dced2..64ec174 100644 (file)
@@ -40,7 +40,7 @@ static int filter_object(const char *path, unsigned mode,
                             oid_to_hex(oid), path);
        if ((type == OBJ_BLOB) && S_ISREG(mode)) {
                struct strbuf strbuf = STRBUF_INIT;
-               if (convert_to_working_tree(path, *buf, *size, &strbuf)) {
+               if (convert_to_working_tree(&the_index, path, *buf, *size, &strbuf)) {
                        free(*buf);
                        *size = strbuf.len;
                        *buf = strbuf_detach(&strbuf, NULL);
index 91444dc..c05573f 100644 (file)
@@ -63,9 +63,9 @@ static void check_attr(const char *prefix,
                prefix_path(prefix, prefix ? strlen(prefix) : 0, file);
 
        if (collect_all) {
-               git_all_attrs(full_path, check);
+               git_all_attrs(&the_index, full_path, check);
        } else {
-               if (git_check_attr(full_path, check))
+               if (git_check_attr(&the_index, full_path, check))
                        die("git_check_attr died");
        }
        output_attr(check, file);
@@ -120,7 +120,7 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)
        }
 
        if (cached_attrs)
-               git_attr_set_direction(GIT_ATTR_INDEX, NULL);
+               git_attr_set_direction(GIT_ATTR_INDEX);
 
        doubledash = -1;
        for (i = 0; doubledash < 0 && i < argc; i++) {
index a730f6a..d92db62 100644 (file)
@@ -190,6 +190,7 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix)
 
        argc = parse_options(argc, argv, prefix, builtin_checkout_index_options,
                        builtin_checkout_index_usage, 0);
+       state.istate = &the_index;
        state.force = force;
        state.quiet = quiet;
        state.not_new = not_new;
index cb6bb76..29ef500 100644 (file)
@@ -318,7 +318,7 @@ static int checkout_paths(const struct checkout_opts *opts,
                 * match_pathspec() for _all_ entries when
                 * opts->source_tree != NULL.
                 */
-               if (ce_path_match(ce, &opts->pathspec, ps_matched))
+               if (ce_path_match(&the_index, ce, &opts->pathspec, ps_matched))
                        ce->ce_flags |= CE_MATCHED;
        }
 
index ab402c2..8d9a7dc 100644 (file)
@@ -976,7 +976,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
                        continue;
 
                if (pathspec.nr)
-                       matches = dir_path_match(ent, &pathspec, 0, NULL);
+                       matches = dir_path_match(&the_index, ent, &pathspec, 0, NULL);
 
                if (pathspec.nr && !matches)
                        continue;
index 213fca2..0d9828e 100644 (file)
@@ -251,7 +251,7 @@ static int list_paths(struct string_list *list, const char *with_tree,
 
                if (ce->ce_flags & CE_UPDATE)
                        continue;
-               if (!ce_path_match(ce, pattern, m))
+               if (!ce_path_match(&the_index, ce, pattern, m))
                        continue;
                item = string_list_insert(list, ce->name);
                if (ce_skip_worktree(ce))
index 91ba670..d07bf2e 100644 (file)
@@ -163,9 +163,11 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
                int saved_nrl = 0;
                int saved_dcctc = 0;
 
-               if (opt->diffopt.detect_rename)
-                       opt->diffopt.setup |= (DIFF_SETUP_USE_SIZE_CACHE |
-                                              DIFF_SETUP_USE_CACHE);
+               if (opt->diffopt.detect_rename) {
+                       if (!the_index.cache)
+                               read_index(&the_index);
+                       opt->diffopt.setup |= DIFF_SETUP_USE_SIZE_CACHE;
+               }
                while (fgets(line, sizeof(line), stdin)) {
                        struct object_id oid;
 
index ee5a1bd..601f801 100644 (file)
@@ -497,7 +497,7 @@ static int grep_cache(struct grep_opt *opt, struct repository *repo,
                strbuf_addstr(&name, ce->name);
 
                if (S_ISREG(ce->ce_mode) &&
-                   match_pathspec(pathspec, name.buf, name.len, 0, NULL,
+                   match_pathspec(repo->index, pathspec, name.buf, name.len, 0, NULL,
                                   S_ISDIR(ce->ce_mode) ||
                                   S_ISGITLINK(ce->ce_mode))) {
                        /*
@@ -515,7 +515,7 @@ static int grep_cache(struct grep_opt *opt, struct repository *repo,
                                hit |= grep_file(opt, name.buf);
                        }
                } else if (recurse_submodules && S_ISGITLINK(ce->ce_mode) &&
-                          submodule_path_match(pathspec, name.buf, NULL)) {
+                          submodule_path_match(repo->index, pathspec, name.buf, NULL)) {
                        hit |= grep_submodule(opt, repo, pathspec, NULL, ce->name, ce->name);
                } else {
                        continue;
@@ -679,7 +679,7 @@ static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec,
 
        fill_directory(&dir, &the_index, pathspec);
        for (i = 0; i < dir.nr; i++) {
-               if (!dir_path_match(dir.entries[i], pathspec, 0, NULL))
+               if (!dir_path_match(&the_index, dir.entries[i], pathspec, 0, NULL))
                        continue;
                hit |= grep_file(opt, dir.entries[i]->name);
                if (hit && opt->status_only)
index 88bb201..7f9919a 100644 (file)
@@ -63,7 +63,7 @@ static void write_eolinfo(const struct index_state *istate,
                struct stat st;
                const char *i_txt = "";
                const char *w_txt = "";
-               const char *a_txt = get_convert_attr_ascii(path);
+               const char *a_txt = get_convert_attr_ascii(istate, path);
                if (ce && S_ISREG(ce->ce_mode))
                        i_txt = get_cached_convert_stats_ascii(istate,
                                                               ce->name);
@@ -121,18 +121,19 @@ static void print_debug(const struct cache_entry *ce)
        }
 }
 
-static void show_dir_entry(const char *tag, struct dir_entry *ent)
+static void show_dir_entry(const struct index_state *istate,
+                          const char *tag, struct dir_entry *ent)
 {
        int len = max_prefix_len;
 
        if (len > ent->len)
                die("git ls-files: internal error - directory entry not superset of prefix");
 
-       if (!dir_path_match(ent, &pathspec, len, ps_matched))
+       if (!dir_path_match(istate, ent, &pathspec, len, ps_matched))
                return;
 
        fputs(tag, stdout);
-       write_eolinfo(NULL, NULL, ent->name);
+       write_eolinfo(istate, NULL, ent->name);
        write_name(ent->name);
 }
 
@@ -145,7 +146,7 @@ static void show_other_files(const struct index_state *istate,
                struct dir_entry *ent = dir->entries[i];
                if (!index_name_is_other(istate, ent->name, ent->len))
                        continue;
-               show_dir_entry(tag_other, ent);
+               show_dir_entry(istate, tag_other, ent);
        }
 }
 
@@ -196,7 +197,7 @@ static void show_killed_files(const struct index_state *istate,
                        }
                }
                if (killed)
-                       show_dir_entry(tag_killed, dir->entries[i]);
+                       show_dir_entry(istate, tag_killed, dir->entries[i]);
        }
 }
 
@@ -228,7 +229,7 @@ static void show_ce(struct repository *repo, struct dir_struct *dir,
        if (recurse_submodules && S_ISGITLINK(ce->ce_mode) &&
            is_submodule_active(repo, ce->name)) {
                show_submodule(repo, dir, ce->name);
-       } else if (match_pathspec(&pathspec, fullname, strlen(fullname),
+       } else if (match_pathspec(repo->index, &pathspec, fullname, strlen(fullname),
                                  max_prefix_len, ps_matched,
                                  S_ISDIR(ce->ce_mode) ||
                                  S_ISGITLINK(ce->ce_mode))) {
@@ -264,7 +265,7 @@ static void show_ru_info(const struct index_state *istate)
                len = strlen(path);
                if (len < max_prefix_len)
                        continue; /* outside of the prefix */
-               if (!match_pathspec(&pathspec, path, len,
+               if (!match_pathspec(istate, &pathspec, path, len,
                                    max_prefix_len, ps_matched, 0))
                        continue; /* uninterested */
                for (i = 0; i < 3; i++) {
index c0741ba..0d80dee 100644 (file)
@@ -951,7 +951,7 @@ static int no_try_delta(const char *path)
 
        if (!check)
                check = attr_check_initl("delta", NULL);
-       if (git_check_attr(path, check))
+       if (git_check_attr(&the_index, path, check))
                return 0;
        if (ATTR_FALSE(check->items[0].value))
                return 1;
index f4d3f00..2cbe89e 100644 (file)
@@ -278,7 +278,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
 
        for (i = 0; i < active_nr; i++) {
                const struct cache_entry *ce = active_cache[i];
-               if (!ce_path_match(ce, &pathspec, seen))
+               if (!ce_path_match(&the_index, ce, &pathspec, seen))
                        continue;
                ALLOC_GROW(list.entry, list.nr + 1, list.alloc);
                list.entry[list.nr].name = xstrdup(ce->name);
index a3c4564..a4440a3 100644 (file)
@@ -331,7 +331,7 @@ static int module_list_compute(int argc, const char **argv,
        for (i = 0; i < active_nr; i++) {
                const struct cache_entry *ce = active_cache[i];
 
-               if (!match_pathspec(pathspec, ce->name, ce_namelen(ce),
+               if (!match_pathspec(&the_index, pathspec, ce->name, ce_namelen(ce),
                                    0, ps_matched, 1) ||
                    !S_ISGITLINK(ce->ce_mode))
                        continue;
index 5aee2ea..fe84003 100644 (file)
@@ -748,7 +748,7 @@ static int do_reupdate(int ac, const char **av,
                int save_nr;
                char *path;
 
-               if (ce_stage(ce) || !ce_path_match(ce, &pathspec, NULL))
+               if (ce_stage(ce) || !ce_path_match(&the_index, ce, &pathspec, NULL))
                        continue;
                if (has_head)
                        old = read_one_ent(NULL, &head_oid,
index 84532ae..25d9116 100644 (file)
@@ -43,7 +43,8 @@ int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix)
        }
 
        /* parse all options sent by the client */
-       return write_archive(sent_argv.argc, sent_argv.argv, prefix, NULL, 1);
+       return write_archive(sent_argv.argc, sent_argv.argv, prefix,
+                            the_repository, NULL, 1);
 }
 
 __attribute__((format (printf, 1, 2)))
index 181d591..16ea022 100644 (file)
@@ -652,11 +652,6 @@ out:
        return ret;
 }
 
-int write_cache_as_tree(struct object_id *oid, int flags, const char *prefix)
-{
-       return write_index_as_tree(oid, &the_index, get_index_file(), flags, prefix);
-}
-
 static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree)
 {
        struct tree_desc desc;
@@ -723,10 +718,3 @@ int cache_tree_matches_traversal(struct cache_tree *root,
                return it->entry_count;
        return 0;
 }
-
-int update_main_cache_tree(int flags)
-{
-       if (!the_index.cache_tree)
-               the_index.cache_tree = cache_tree();
-       return cache_tree_update(&the_index, flags);
-}
index 9799e89..fc0c842 100644 (file)
@@ -33,8 +33,6 @@ struct cache_tree *cache_tree_read(const char *buffer, unsigned long size);
 int cache_tree_fully_valid(struct cache_tree *);
 int cache_tree_update(struct index_state *, int);
 
-int update_main_cache_tree(int);
-
 /* bitmasks to write_cache_as_tree flags */
 #define WRITE_TREE_MISSING_OK 1
 #define WRITE_TREE_IGNORE_CACHE_TREE 2
@@ -48,9 +46,22 @@ int update_main_cache_tree(int);
 #define WRITE_TREE_PREFIX_ERROR (-3)
 
 int write_index_as_tree(struct object_id *oid, struct index_state *index_state, const char *index_path, int flags, const char *prefix);
-int write_cache_as_tree(struct object_id *oid, int flags, const char *prefix);
 void prime_cache_tree(struct index_state *, struct tree *);
 
 int cache_tree_matches_traversal(struct cache_tree *, struct name_entry *ent, struct traverse_info *info);
 
+#ifndef NO_THE_INDEX_COMPATIBILITY_MACROS
+static inline int write_cache_as_tree(struct object_id *oid, int flags, const char *prefix)
+{
+       return write_index_as_tree(oid, &the_index, get_index_file(), flags, prefix);
+}
+
+static inline int update_main_cache_tree(int flags)
+{
+       if (!the_index.cache_tree)
+               the_index.cache_tree = cache_tree();
+       return cache_tree_update(&the_index, flags);
+}
+#endif
+
 #endif
index ce7ea0d..6057f1f 100644 (file)
--- a/convert.c
+++ b/convert.c
@@ -1293,7 +1293,8 @@ struct conv_attrs {
        const char *working_tree_encoding; /* Supported encoding or default encoding if NULL */
 };
 
-static void convert_attrs(struct conv_attrs *ca, const char *path)
+static void convert_attrs(const struct index_state *istate,
+                         struct conv_attrs *ca, const char *path)
 {
        static struct attr_check *check;
 
@@ -1305,7 +1306,7 @@ static void convert_attrs(struct conv_attrs *ca, const char *path)
                git_config(read_convert_config, NULL);
        }
 
-       if (!git_check_attr(path, check)) {
+       if (!git_check_attr(istate, path, check)) {
                struct attr_check_item *ccheck = check->items;
                ca->crlf_action = git_path_check_crlf(ccheck + 4);
                if (ca->crlf_action == CRLF_UNDEFINED)
@@ -1342,11 +1343,11 @@ static void convert_attrs(struct conv_attrs *ca, const char *path)
                ca->crlf_action = CRLF_AUTO_INPUT;
 }
 
-int would_convert_to_git_filter_fd(const char *path)
+int would_convert_to_git_filter_fd(const struct index_state *istate, const char *path)
 {
        struct conv_attrs ca;
 
-       convert_attrs(&ca, path);
+       convert_attrs(istate, &ca, path);
        if (!ca.drv)
                return 0;
 
@@ -1361,11 +1362,11 @@ int would_convert_to_git_filter_fd(const char *path)
        return apply_filter(path, NULL, 0, -1, NULL, ca.drv, CAP_CLEAN, NULL);
 }
 
-const char *get_convert_attr_ascii(const char *path)
+const char *get_convert_attr_ascii(const struct index_state *istate, const char *path)
 {
        struct conv_attrs ca;
 
-       convert_attrs(&ca, path);
+       convert_attrs(istate, &ca, path);
        switch (ca.attr_action) {
        case CRLF_UNDEFINED:
                return "";
@@ -1394,7 +1395,7 @@ int convert_to_git(const struct index_state *istate,
        int ret = 0;
        struct conv_attrs ca;
 
-       convert_attrs(&ca, path);
+       convert_attrs(istate, &ca, path);
 
        ret |= apply_filter(path, src, len, -1, dst, ca.drv, CAP_CLEAN, NULL);
        if (!ret && ca.drv && ca.drv->required)
@@ -1426,7 +1427,7 @@ void convert_to_git_filter_fd(const struct index_state *istate,
                              int conv_flags)
 {
        struct conv_attrs ca;
-       convert_attrs(&ca, path);
+       convert_attrs(istate, &ca, path);
 
        assert(ca.drv);
        assert(ca.drv->clean || ca.drv->process);
@@ -1439,14 +1440,15 @@ void convert_to_git_filter_fd(const struct index_state *istate,
        ident_to_git(path, dst->buf, dst->len, dst, ca.ident);
 }
 
-static int convert_to_working_tree_internal(const char *path, const char *src,
+static int convert_to_working_tree_internal(const struct index_state *istate,
+                                           const char *path, const char *src,
                                            size_t len, struct strbuf *dst,
                                            int normalizing, struct delayed_checkout *dco)
 {
        int ret = 0, ret_filter = 0;
        struct conv_attrs ca;
 
-       convert_attrs(&ca, path);
+       convert_attrs(istate, &ca, path);
 
        ret |= ident_to_worktree(path, src, len, dst, ca.ident);
        if (ret) {
@@ -1480,22 +1482,25 @@ static int convert_to_working_tree_internal(const char *path, const char *src,
        return ret | ret_filter;
 }
 
-int async_convert_to_working_tree(const char *path, const char *src,
+int async_convert_to_working_tree(const struct index_state *istate,
+                                 const char *path, const char *src,
                                  size_t len, struct strbuf *dst,
                                  void *dco)
 {
-       return convert_to_working_tree_internal(path, src, len, dst, 0, dco);
+       return convert_to_working_tree_internal(istate, path, src, len, dst, 0, dco);
 }
 
-int convert_to_working_tree(const char *path, const char *src, size_t len, struct strbuf *dst)
+int convert_to_working_tree(const struct index_state *istate,
+                           const char *path, const char *src,
+                           size_t len, struct strbuf *dst)
 {
-       return convert_to_working_tree_internal(path, src, len, dst, 0, NULL);
+       return convert_to_working_tree_internal(istate, path, src, len, dst, 0, NULL);
 }
 
 int renormalize_buffer(const struct index_state *istate, const char *path,
                       const char *src, size_t len, struct strbuf *dst)
 {
-       int ret = convert_to_working_tree_internal(path, src, len, dst, 1, NULL);
+       int ret = convert_to_working_tree_internal(istate, path, src, len, dst, 1, NULL);
        if (ret) {
                src = dst->buf;
                len = dst->len;
@@ -1929,12 +1934,14 @@ static struct stream_filter *ident_filter(const struct object_id *oid)
  * Note that you would be crazy to set CRLF, smuge/clean or ident to a
  * large binary blob you would want us not to slurp into the memory!
  */
-struct stream_filter *get_stream_filter(const char *path, const struct object_id *oid)
+struct stream_filter *get_stream_filter(const struct index_state *istate,
+                                       const char *path,
+                                       const struct object_id *oid)
 {
        struct conv_attrs ca;
        struct stream_filter *filter = NULL;
 
-       convert_attrs(&ca, path);
+       convert_attrs(istate, &ca, path);
        if (ca.drv && (ca.drv->process || ca.drv->smudge || ca.drv->clean))
                return NULL;
 
index 0a0fa15..6d0ee88 100644 (file)
--- a/convert.h
+++ b/convert.h
@@ -60,15 +60,18 @@ extern char *check_roundtrip_encoding;
 const char *get_cached_convert_stats_ascii(const struct index_state *istate,
                                           const char *path);
 const char *get_wt_convert_stats_ascii(const char *path);
-const char *get_convert_attr_ascii(const char *path);
+const char *get_convert_attr_ascii(const struct index_state *istate,
+                                  const char *path);
 
 /* returns 1 if *dst was used */
 int convert_to_git(const struct index_state *istate,
                   const char *path, const char *src, size_t len,
                   struct strbuf *dst, int conv_flags);
-int convert_to_working_tree(const char *path, const char *src,
+int convert_to_working_tree(const struct index_state *istate,
+                           const char *path, const char *src,
                            size_t len, struct strbuf *dst);
-int async_convert_to_working_tree(const char *path, const char *src,
+int async_convert_to_working_tree(const struct index_state *istate,
+                                 const char *path, const char *src,
                                  size_t len, struct strbuf *dst,
                                  void *dco);
 int async_query_available_blobs(const char *cmd,
@@ -86,7 +89,8 @@ void convert_to_git_filter_fd(const struct index_state *istate,
                              const char *path, int fd,
                              struct strbuf *dst,
                              int conv_flags);
-int would_convert_to_git_filter_fd(const char *path);
+int would_convert_to_git_filter_fd(const struct index_state *istate,
+                                  const char *path);
 
 /*****************************************************************
  *
@@ -96,7 +100,8 @@ int would_convert_to_git_filter_fd(const char *path);
 
 struct stream_filter; /* opaque */
 
-struct stream_filter *get_stream_filter(const char *path,
+struct stream_filter *get_stream_filter(const struct index_state *istate,
+                                       const char *path,
                                        const struct object_id *);
 void free_stream_filter(struct stream_filter *);
 int is_null_stream_filter(struct stream_filter *);
index 732f684..88a98b1 100644 (file)
@@ -109,7 +109,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
                if (diff_can_quit_early(&revs->diffopt))
                        break;
 
-               if (!ce_path_match(ce, &revs->prune_data, NULL))
+               if (!ce_path_match(&the_index, ce, &revs->prune_data, NULL))
                        continue;
 
                if (ce_stage(ce)) {
@@ -474,7 +474,7 @@ static int oneway_diff(const struct cache_entry * const *src,
        if (tree == o->df_conflict_entry)
                tree = NULL;
 
-       if (ce_path_match(idx ? idx : tree, &revs->prune_data, NULL)) {
+       if (ce_path_match(&the_index, idx ? idx : tree, &revs->prune_data, NULL)) {
                do_oneway_diff(o, idx, tree);
                if (diff_can_quit_early(&revs->diffopt)) {
                        o->exiting_early = 1;
diff --git a/diff.c b/diff.c
index f830afa..77e4684 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -3895,7 +3895,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
        temp->tempfile = mks_tempfile_ts(tempfile.buf, strlen(base) + 1);
        if (!temp->tempfile)
                die_errno("unable to create temp-file");
-       if (convert_to_working_tree(path,
+       if (convert_to_working_tree(&the_index, path,
                        (const char *)blob, (size_t)size, &buf)) {
                blob = buf.buf;
                size = buf.len;
@@ -4416,16 +4416,6 @@ void diff_setup_done(struct diff_options *options)
 
        if (options->detect_rename && options->rename_limit < 0)
                options->rename_limit = diff_rename_limit_default;
-       if (options->setup & DIFF_SETUP_USE_CACHE) {
-               if (!active_cache)
-                       /* read-cache does not die even when it fails
-                        * so it is safe for us to do this here.  Also
-                        * it does not smudge active_cache or active_nr
-                        * when it fails, so we do not have to worry about
-                        * cleaning it up ourselves either.
-                        */
-                       read_cache();
-       }
        if (hexsz < options->abbrev)
                options->abbrev = hexsz; /* full */
 
diff --git a/diff.h b/diff.h
index 20c697d..3ada6ad 100644 (file)
--- a/diff.h
+++ b/diff.h
@@ -312,7 +312,6 @@ void diff_change(struct diff_options *,
 struct diff_filepair *diff_unmerge(struct diff_options *, const char *path);
 
 #define DIFF_SETUP_REVERSE             1
-#define DIFF_SETUP_USE_CACHE           2
 #define DIFF_SETUP_USE_SIZE_CACHE      4
 
 /*
diff --git a/dir.c b/dir.c
index 32f5f72..aceb0d4 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -276,12 +276,13 @@ static int do_read_blob(const struct object_id *oid, struct oid_stat *oid_stat,
 #define DO_MATCH_DIRECTORY (1<<1)
 #define DO_MATCH_SUBMODULE (1<<2)
 
-static int match_attrs(const char *name, int namelen,
+static int match_attrs(const struct index_state *istate,
+                      const char *name, int namelen,
                       const struct pathspec_item *item)
 {
        int i;
 
-       git_check_attr(name, item->attr_check);
+       git_check_attr(istate, name, item->attr_check);
        for (i = 0; i < item->attr_match_nr; i++) {
                const char *value;
                int matched;
@@ -318,7 +319,8 @@ static int match_attrs(const char *name, int namelen,
  *
  * It returns 0 when there is no match.
  */
-static int match_pathspec_item(const struct pathspec_item *item, int prefix,
+static int match_pathspec_item(const struct index_state *istate,
+                              const struct pathspec_item *item, int prefix,
                               const char *name, int namelen, unsigned flags)
 {
        /* name/namelen has prefix cut off by caller */
@@ -358,7 +360,7 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix,
            strncmp(item->match, name - prefix, item->prefix))
                return 0;
 
-       if (item->attr_match_nr && !match_attrs(name, namelen, item))
+       if (item->attr_match_nr && !match_attrs(istate, name, namelen, item))
                return 0;
 
        /* If the match was just the prefix, we matched */
@@ -426,7 +428,8 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix,
  * pathspec did not match any names, which could indicate that the
  * user mistyped the nth pathspec.
  */
-static int do_match_pathspec(const struct pathspec *ps,
+static int do_match_pathspec(const struct index_state *istate,
+                            const struct pathspec *ps,
                             const char *name, int namelen,
                             int prefix, char *seen,
                             unsigned flags)
@@ -472,7 +475,7 @@ static int do_match_pathspec(const struct pathspec *ps,
                 */
                if (seen && ps->items[i].magic & PATHSPEC_EXCLUDE)
                        seen[i] = MATCHED_FNMATCH;
-               how = match_pathspec_item(ps->items+i, prefix, name,
+               how = match_pathspec_item(istate, ps->items+i, prefix, name,
                                          namelen, flags);
                if (ps->recursive &&
                    (ps->magic & PATHSPEC_MAXDEPTH) &&
@@ -496,17 +499,18 @@ static int do_match_pathspec(const struct pathspec *ps,
        return retval;
 }
 
-int match_pathspec(const struct pathspec *ps,
+int match_pathspec(const struct index_state *istate,
+                  const struct pathspec *ps,
                   const char *name, int namelen,
                   int prefix, char *seen, int is_dir)
 {
        int positive, negative;
        unsigned flags = is_dir ? DO_MATCH_DIRECTORY : 0;
-       positive = do_match_pathspec(ps, name, namelen,
+       positive = do_match_pathspec(istate, ps, name, namelen,
                                     prefix, seen, flags);
        if (!(ps->magic & PATHSPEC_EXCLUDE) || !positive)
                return positive;
-       negative = do_match_pathspec(ps, name, namelen,
+       negative = do_match_pathspec(istate, ps, name, namelen,
                                     prefix, seen,
                                     flags | DO_MATCH_EXCLUDE);
        return negative ? 0 : positive;
@@ -515,11 +519,12 @@ int match_pathspec(const struct pathspec *ps,
 /**
  * Check if a submodule is a superset of the pathspec
  */
-int submodule_path_match(const struct pathspec *ps,
+int submodule_path_match(const struct index_state *istate,
+                        const struct pathspec *ps,
                         const char *submodule_name,
                         char *seen)
 {
-       int matched = do_match_pathspec(ps, submodule_name,
+       int matched = do_match_pathspec(istate, ps, submodule_name,
                                        strlen(submodule_name),
                                        0, seen,
                                        DO_MATCH_DIRECTORY |
diff --git a/dir.h b/dir.h
index f5fdedb..e3ec261 100644 (file)
--- a/dir.h
+++ b/dir.h
@@ -216,7 +216,8 @@ extern int count_slashes(const char *s);
 extern int simple_length(const char *match);
 extern int no_wildcard(const char *string);
 extern char *common_prefix(const struct pathspec *pathspec);
-extern int match_pathspec(const struct pathspec *pathspec,
+extern int match_pathspec(const struct index_state *istate,
+                         const struct pathspec *pathspec,
                          const char *name, int namelen,
                          int prefix, char *seen, int is_dir);
 extern int report_path_error(const char *ps_matched, const struct pathspec *pathspec, const char *prefix);
@@ -326,25 +327,28 @@ extern int git_fnmatch(const struct pathspec_item *item,
                       const char *pattern, const char *string,
                       int prefix);
 
-extern int submodule_path_match(const struct pathspec *ps,
+extern int submodule_path_match(const struct index_state *istate,
+                               const struct pathspec *ps,
                                const char *submodule_name,
                                char *seen);
 
-static inline int ce_path_match(const struct cache_entry *ce,
+static inline int ce_path_match(const struct index_state *istate,
+                               const struct cache_entry *ce,
                                const struct pathspec *pathspec,
                                char *seen)
 {
-       return match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, seen,
+       return match_pathspec(istate, pathspec, ce->name, ce_namelen(ce), 0, seen,
                              S_ISDIR(ce->ce_mode) || S_ISGITLINK(ce->ce_mode));
 }
 
-static inline int dir_path_match(const struct dir_entry *ent,
+static inline int dir_path_match(const struct index_state *istate,
+                                const struct dir_entry *ent,
                                 const struct pathspec *pathspec,
                                 int prefix, char *seen)
 {
        int has_trailing_dir = ent->len && ent->name[ent->len - 1] == '/';
        int len = has_trailing_dir ? ent->len - 1 : ent->len;
-       return match_pathspec(pathspec, ent->name, len, prefix, seen,
+       return match_pathspec(istate, pathspec, ent->name, len, prefix, seen,
                              has_trailing_dir);
 }
 
diff --git a/entry.c b/entry.c
index b5d1d3c..2a2ab6c 100644 (file)
--- a/entry.c
+++ b/entry.c
@@ -266,7 +266,7 @@ static int write_entry(struct cache_entry *ce,
        const struct submodule *sub;
 
        if (ce_mode_s_ifmt == S_IFREG) {
-               struct stream_filter *filter = get_stream_filter(ce->name,
+               struct stream_filter *filter = get_stream_filter(state->istate, ce->name,
                                                                 &ce->oid);
                if (filter &&
                    !streaming_write_entry(ce, path, filter,
@@ -314,14 +314,14 @@ static int write_entry(struct cache_entry *ce,
                 * Convert from git internal format to working tree format
                 */
                if (dco && dco->state != CE_NO_DELAY) {
-                       ret = async_convert_to_working_tree(ce->name, new_blob,
+                       ret = async_convert_to_working_tree(state->istate, ce->name, new_blob,
                                                            size, &buf, dco);
                        if (ret && string_list_has_string(&dco->paths, ce->name)) {
                                free(new_blob);
                                goto delayed;
                        }
                } else
-                       ret = convert_to_working_tree(ce->name, new_blob, size, &buf);
+                       ret = convert_to_working_tree(state->istate, ce->name, new_blob, size, &buf);
 
                if (ret) {
                        free(new_blob);
@@ -422,7 +422,8 @@ int checkout_entry(struct cache_entry *ce,
 
        if (!check_path(path.buf, path.len, &st, state->base_dir_len)) {
                const struct submodule *sub;
-               unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE);
+               unsigned changed = ie_match_stat(state->istate, ce, &st,
+                                                CE_MATCH_IGNORE_VALID | CE_MATCH_IGNORE_SKIP_WORKTREE);
                /*
                 * Needs to be checked before !changed returns early,
                 * as the possibly empty directory was not changed
index a6ad2ec..0e2800f 100644 (file)
@@ -371,7 +371,7 @@ int ll_merge(mmbuffer_t *result_buf,
        if (!check)
                check = attr_check_initl("merge", "conflict-marker-size", NULL);
 
-       if (!git_check_attr(path, check)) {
+       if (!git_check_attr(&the_index, path, check)) {
                ll_driver_name = check->items[0].value;
                if (check->items[1].value) {
                        marker_size = atoi(check->items[1].value);
@@ -398,7 +398,7 @@ int ll_merge_marker_size(const char *path)
 
        if (!check)
                check = attr_check_initl("conflict-marker-size", NULL);
-       if (!git_check_attr(path, check) && check->items[0].value) {
+       if (!git_check_attr(&the_index, path, check) && check->items[0].value) {
                marker_size = atoi(check->items[0].value);
                if (marker_size <= 0)
                        marker_size = DEFAULT_CONFLICT_MARKER_SIZE;
index bd053c7..dcdc930 100644 (file)
@@ -966,7 +966,7 @@ static int update_file_flags(struct merge_options *o,
                }
                if (S_ISREG(mode)) {
                        struct strbuf strbuf = STRBUF_INIT;
-                       if (convert_to_working_tree(path, buf, size, &strbuf)) {
+                       if (convert_to_working_tree(&the_index, path, buf, size, &strbuf)) {
                                free(buf);
                                size = strbuf.len;
                                buf = strbuf_detach(&strbuf, NULL);
index 27cd606..6f00599 100644 (file)
@@ -37,7 +37,7 @@ void add_pathspec_matches_against_index(const struct pathspec *pathspec,
                return;
        for (i = 0; i < istate->cache_nr; i++) {
                const struct cache_entry *ce = istate->cache[i];
-               ce_path_match(ce, pathspec, seen);
+               ce_path_match(istate, ce, pathspec, seen);
        }
 }
 
index 4d08d44..71cd243 100644 (file)
@@ -58,7 +58,7 @@ static void *preload_thread(void *_data)
                        continue;
                if (ce->ce_flags & CE_FSMONITOR_VALID)
                        continue;
-               if (!ce_path_match(ce, &p->pathspec, NULL))
+               if (!ce_path_match(index, ce, &p->pathspec, NULL))
                        continue;
                if (threaded_has_symlink_leading_path(&cache, ce->name, ce_namelen(ce)))
                        continue;
index c5fabc8..7b1354d 100644 (file)
@@ -1493,7 +1493,7 @@ int refresh_index(struct index_state *istate, unsigned int flags,
                if (ignore_submodules && S_ISGITLINK(ce->ce_mode))
                        continue;
 
-               if (pathspec && !ce_path_match(ce, pathspec, seen))
+               if (pathspec && !ce_path_match(&the_index, ce, pathspec, seen))
                        filtered = 1;
 
                if (ce_stage(ce)) {
index 16c8aac..c7787aa 100644 (file)
--- a/rerere.c
+++ b/rerere.c
@@ -1120,7 +1120,7 @@ int rerere_forget(struct pathspec *pathspec)
        find_conflict(&conflict);
        for (i = 0; i < conflict.nr; i++) {
                struct string_list_item *it = &conflict.items[i];
-               if (!match_pathspec(pathspec, it->string,
+               if (!match_pathspec(&the_index, pathspec, it->string,
                                    strlen(it->string), 0, NULL, 0))
                        continue;
                rerere_forget_one_path(it->string, &merge_rr);
index c30ae5c..236320f 100644 (file)
@@ -188,7 +188,7 @@ void unmerge_index(struct index_state *istate, const struct pathspec *pathspec)
 
        for (i = 0; i < istate->cache_nr; i++) {
                const struct cache_entry *ce = istate->cache[i];
-               if (!ce_path_match(ce, pathspec, NULL))
+               if (!ce_path_match(istate, ce, pathspec, NULL))
                        continue;
                i = unmerge_index_entry_at(istate, i);
        }
index 0627494..de4dce6 100644 (file)
@@ -1517,7 +1517,7 @@ static void prepare_show_merge(struct rev_info *revs)
                const struct cache_entry *ce = active_cache[i];
                if (!ce_stage(ce))
                        continue;
-               if (ce_path_match(ce, &revs->prune_data, NULL)) {
+               if (ce_path_match(&the_index, ce, &revs->prune_data, NULL)) {
                        prune_num++;
                        REALLOC_ARRAY(prune, prune_num);
                        prune[prune_num-2] = ce->name;
index b8f274b..c00eedd 100644 (file)
@@ -1253,7 +1253,7 @@ static int try_to_commit(struct strbuf *msg, const char *author,
                commit_list_insert(current_head, &parents);
        }
 
-       if (write_cache_as_tree(&tree, 0, NULL)) {
+       if (write_index_as_tree(&tree, &the_index, get_index_file(), 0, NULL)) {
                res = error(_("git write-tree failed to write a tree"));
                goto out;
        }
@@ -1639,7 +1639,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
                 * that represents the "current" state for merge-recursive
                 * to work on.
                 */
-               if (write_cache_as_tree(&head, 0, NULL))
+               if (write_index_as_tree(&head, &the_index, get_index_file(), 0, NULL))
                        return error(_("your index file is unmerged."));
        } else {
                unborn = get_oid("HEAD", &head);
index 56e5329..97b7423 100644 (file)
@@ -1860,7 +1860,7 @@ static int index_stream_convert_blob(struct object_id *oid, int fd,
        struct strbuf sbuf = STRBUF_INIT;
 
        assert(path);
-       assert(would_convert_to_git_filter_fd(path));
+       assert(would_convert_to_git_filter_fd(&the_index, path));
 
        convert_to_git_filter_fd(&the_index, path, fd, &sbuf,
                                 get_conv_flags(flags));
@@ -1950,7 +1950,7 @@ int index_fd(struct object_id *oid, int fd, struct stat *st,
         * Call xsize_t() only when needed to avoid potentially unnecessary
         * die() for large files.
         */
-       if (type == OBJ_BLOB && path && would_convert_to_git_filter_fd(path))
+       if (type == OBJ_BLOB && path && would_convert_to_git_filter_fd(&the_index, path))
                ret = index_stream_convert_blob(oid, fd, path, flags);
        else if (!S_ISREG(st->st_mode))
                ret = index_pipe(oid, fd, type, path, flags);
index 6e14547..50cbf5f 100644 (file)
@@ -93,7 +93,7 @@ int update_path_in_gitmodules(const char *oldpath, const char *newpath)
        if (!file_exists(GITMODULES_FILE)) /* Do nothing without .gitmodules */
                return -1;
 
-       if (is_gitmodules_unmerged(&the_index))
+       if (is_gitmodules_unmerged(the_repository->index))
                die(_("Cannot change unmerged .gitmodules, resolve merge conflicts first"));
 
        submodule = submodule_from_path(the_repository, &null_oid, oldpath);
@@ -127,7 +127,7 @@ int remove_path_from_gitmodules(const char *path)
        if (!file_exists(GITMODULES_FILE)) /* Do nothing without .gitmodules */
                return -1;
 
-       if (is_gitmodules_unmerged(&the_index))
+       if (is_gitmodules_unmerged(the_repository->index))
                die(_("Cannot change unmerged .gitmodules, resolve merge conflicts first"));
 
        submodule = submodule_from_path(the_repository, &null_oid, path);
@@ -188,7 +188,7 @@ void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,
 
                if (ignore)
                        handle_ignore_submodules_arg(diffopt, ignore);
-               else if (is_gitmodules_unmerged(&the_index))
+               else if (is_gitmodules_unmerged(the_repository->index))
                        diffopt->flags.ignore_submodules = 1;
        }
 }
@@ -258,7 +258,7 @@ int is_submodule_active(struct repository *repo, const char *path)
                }
 
                parse_pathspec(&ps, 0, 0, NULL, args.argv);
-               ret = match_pathspec(&ps, path, strlen(path), 0, NULL, 1);
+               ret = match_pathspec(repo->index, &ps, path, strlen(path), 0, NULL, 1);
 
                argv_array_clear(&args);
                clear_pathspec(&ps);
index f9efee0..f25089b 100644 (file)
@@ -353,7 +353,7 @@ static int check_updates(struct unpack_trees_options *o)
        progress = get_progress(o);
 
        if (o->update)
-               git_attr_set_direction(GIT_ATTR_CHECKOUT, index);
+               git_attr_set_direction(GIT_ATTR_CHECKOUT);
 
        if (should_update_submodules() && o->update && !o->dry_run)
                load_gitmodules_file(index, NULL);
@@ -413,7 +413,7 @@ static int check_updates(struct unpack_trees_options *o)
        stop_progress(&progress);
        errs |= finish_delayed_checkout(&state);
        if (o->update)
-               git_attr_set_direction(GIT_ATTR_CHECKIN, NULL);
+               git_attr_set_direction(GIT_ATTR_CHECKIN);
        return errs != 0;
 }
 
@@ -1092,13 +1092,15 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str
        return mask;
 }
 
-static int clear_ce_flags_1(struct cache_entry **cache, int nr,
+static int clear_ce_flags_1(struct index_state *istate,
+                           struct cache_entry **cache, int nr,
                            struct strbuf *prefix,
                            int select_mask, int clear_mask,
                            struct exclude_list *el, int defval);
 
 /* Whole directory matching */
-static int clear_ce_flags_dir(struct cache_entry **cache, int nr,
+static int clear_ce_flags_dir(struct index_state *istate,
+                             struct cache_entry **cache, int nr,
                              struct strbuf *prefix,
                              char *basename,
                              int select_mask, int clear_mask,
@@ -1107,7 +1109,7 @@ static int clear_ce_flags_dir(struct cache_entry **cache, int nr,
        struct cache_entry **cache_end;
        int dtype = DT_DIR;
        int ret = is_excluded_from_list(prefix->buf, prefix->len,
-                                       basename, &dtype, el, &the_index);
+                                       basename, &dtype, el, istate);
        int rc;
 
        strbuf_addch(prefix, '/');
@@ -1129,7 +1131,7 @@ static int clear_ce_flags_dir(struct cache_entry **cache, int nr,
         * calling clear_ce_flags_1(). That function will call
         * the expensive is_excluded_from_list() on every entry.
         */
-       rc = clear_ce_flags_1(cache, cache_end - cache,
+       rc = clear_ce_flags_1(istate, cache, cache_end - cache,
                              prefix,
                              select_mask, clear_mask,
                              el, ret);
@@ -1152,7 +1154,8 @@ static int clear_ce_flags_dir(struct cache_entry **cache, int nr,
  *   cache[0]->name[0..(prefix_len-1)]
  * Top level path has prefix_len zero.
  */
-static int clear_ce_flags_1(struct cache_entry **cache, int nr,
+static int clear_ce_flags_1(struct index_state *istate,
+                           struct cache_entry **cache, int nr,
                            struct strbuf *prefix,
                            int select_mask, int clear_mask,
                            struct exclude_list *el, int defval)
@@ -1186,7 +1189,7 @@ static int clear_ce_flags_1(struct cache_entry **cache, int nr,
                        len = slash - name;
                        strbuf_add(prefix, name, len);
 
-                       processed = clear_ce_flags_dir(cache, cache_end - cache,
+                       processed = clear_ce_flags_dir(istate, cache, cache_end - cache,
                                                       prefix,
                                                       prefix->buf + prefix->len - len,
                                                       select_mask, clear_mask,
@@ -1200,7 +1203,7 @@ static int clear_ce_flags_1(struct cache_entry **cache, int nr,
                        }
 
                        strbuf_addch(prefix, '/');
-                       cache += clear_ce_flags_1(cache, cache_end - cache,
+                       cache += clear_ce_flags_1(istate, cache, cache_end - cache,
                                                  prefix,
                                                  select_mask, clear_mask, el, defval);
                        strbuf_setlen(prefix, prefix->len - len - 1);
@@ -1210,7 +1213,7 @@ static int clear_ce_flags_1(struct cache_entry **cache, int nr,
                /* Non-directory */
                dtype = ce_to_dtype(ce);
                ret = is_excluded_from_list(ce->name, ce_namelen(ce),
-                                           name, &dtype, el, &the_index);
+                                           name, &dtype, el, istate);
                if (ret < 0)
                        ret = defval;
                if (ret > 0)
@@ -1220,15 +1223,17 @@ static int clear_ce_flags_1(struct cache_entry **cache, int nr,
        return nr - (cache_end - cache);
 }
 
-static int clear_ce_flags(struct cache_entry **cache, int nr,
-                           int select_mask, int clear_mask,
-                           struct exclude_list *el)
+static int clear_ce_flags(struct index_state *istate,
+                         int select_mask, int clear_mask,
+                         struct exclude_list *el)
 {
        static struct strbuf prefix = STRBUF_INIT;
 
        strbuf_reset(&prefix);
 
-       return clear_ce_flags_1(cache, nr,
+       return clear_ce_flags_1(istate,
+                               istate->cache,
+                               istate->cache_nr,
                                &prefix,
                                select_mask, clear_mask,
                                el, 0);
@@ -1238,7 +1243,7 @@ static int clear_ce_flags(struct cache_entry **cache, int nr,
  * Set/Clear CE_NEW_SKIP_WORKTREE according to $GIT_DIR/info/sparse-checkout
  */
 static void mark_new_skip_worktree(struct exclude_list *el,
-                                  struct index_state *the_index,
+                                  struct index_state *istate,
                                   int select_flag, int skip_wt_flag)
 {
        int i;
@@ -1247,8 +1252,8 @@ static void mark_new_skip_worktree(struct exclude_list *el,
         * 1. Pretend the narrowest worktree: only unmerged entries
         * are checked out
         */
-       for (i = 0; i < the_index->cache_nr; i++) {
-               struct cache_entry *ce = the_index->cache[i];
+       for (i = 0; i < istate->cache_nr; i++) {
+               struct cache_entry *ce = istate->cache[i];
 
                if (select_flag && !(ce->ce_flags & select_flag))
                        continue;
@@ -1263,8 +1268,7 @@ static void mark_new_skip_worktree(struct exclude_list *el,
         * 2. Widen worktree according to sparse-checkout file.
         * Matched entries will have skip_wt_flag cleared (i.e. "in")
         */
-       clear_ce_flags(the_index->cache, the_index->cache_nr,
-                      select_flag, skip_wt_flag, el);
+       clear_ce_flags(istate, select_flag, skip_wt_flag, el);
 }
 
 static int verify_absent(const struct cache_entry *,
@@ -1552,6 +1556,17 @@ static int verify_uptodate_sparse(const struct cache_entry *ce,
        return verify_uptodate_1(ce, o, ERROR_SPARSE_NOT_UPTODATE_FILE);
 }
 
+/*
+ * TODO: We should actually invalidate o->result, not src_index [1].
+ * But since cache tree and untracked cache both are not copied to
+ * o->result until unpacking is complete, we invalidate them on
+ * src_index instead with the assumption that they will be copied to
+ * dst_index at the end.
+ *
+ * [1] src_index->cache_tree is also used in unpack_callback() so if
+ * we invalidate o->result, we need to update it to use
+ * o->result.cache_tree as well.
+ */
 static void invalidate_ce_path(const struct cache_entry *ce,
                               struct unpack_trees_options *o)
 {
@@ -1643,7 +1658,7 @@ static int verify_clean_subdirectory(const struct cache_entry *ce,
        memset(&d, 0, sizeof(d));
        if (o->dir)
                d.exclude_per_dir = o->dir->exclude_per_dir;
-       i = read_directory(&d, &the_index, pathbuf, namelen+1, NULL);
+       i = read_directory(&d, o->src_index, pathbuf, namelen+1, NULL);
        if (i)
                return o->gently ? -1 :
                        add_rejected_path(o, ERROR_NOT_UPTODATE_DIR, ce->name);
@@ -1685,7 +1700,7 @@ static int check_ok_to_remove(const char *name, int len, int dtype,
                return 0;
 
        if (o->dir &&
-           is_excluded(o->dir, &the_index, name, &dtype))
+           is_excluded(o->dir, o->src_index, name, &dtype))
                /*
                 * ce->name is explicitly excluded, so it is Ok to
                 * overwrite it.
index c2b434c..534358f 100644 (file)
@@ -82,8 +82,8 @@ struct unpack_trees_options {
        struct exclude_list *el; /* for internal use */
 };
 
-extern int unpack_trees(unsigned n, struct tree_desc *t,
-               struct unpack_trees_options *options);
+int unpack_trees(unsigned n, struct tree_desc *t,
+                struct unpack_trees_options *options);
 
 int verify_uptodate(const struct cache_entry *ce,
                    struct unpack_trees_options *o);
index 36af25e..f3f4be5 100644 (file)
@@ -278,7 +278,7 @@ struct userdiff_driver *userdiff_find_by_path(const char *path)
                check = attr_check_initl("diff", NULL);
        if (!path)
                return NULL;
-       if (git_check_attr(path, check))
+       if (git_check_attr(&the_index, path, check))
                return NULL;
 
        if (ATTR_TRUE(check->items[0].value))
diff --git a/ws.c b/ws.c
index a07caed..5b67b42 100644 (file)
--- a/ws.c
+++ b/ws.c
@@ -78,7 +78,7 @@ unsigned whitespace_rule(const char *pathname)
        if (!attr_whitespace_rule)
                attr_whitespace_rule = attr_check_initl("whitespace", NULL);
 
-       if (!git_check_attr(pathname, attr_whitespace_rule)) {
+       if (!git_check_attr(&the_index, pathname, attr_whitespace_rule)) {
                const char *value;
 
                value = attr_whitespace_rule->items[0].value;
index 6bf2fdb..5ffab61 100644 (file)
@@ -647,7 +647,7 @@ static void wt_status_collect_changes_initial(struct wt_status *s)
                struct wt_status_change_data *d;
                const struct cache_entry *ce = active_cache[i];
 
-               if (!ce_path_match(ce, &s->pathspec, NULL))
+               if (!ce_path_match(&the_index, ce, &s->pathspec, NULL))
                        continue;
                if (ce_intent_to_add(ce))
                        continue;
@@ -703,7 +703,7 @@ static void wt_status_collect_untracked(struct wt_status *s)
        for (i = 0; i < dir.nr; i++) {
                struct dir_entry *ent = dir.entries[i];
                if (cache_name_is_other(ent->name, ent->len) &&
-                   dir_path_match(ent, &s->pathspec, 0, NULL))
+                   dir_path_match(&the_index, ent, &s->pathspec, 0, NULL))
                        string_list_insert(&s->untracked, ent->name);
                free(ent);
        }
@@ -711,7 +711,7 @@ static void wt_status_collect_untracked(struct wt_status *s)
        for (i = 0; i < dir.ignored_nr; i++) {
                struct dir_entry *ent = dir.ignored[i];
                if (cache_name_is_other(ent->name, ent->len) &&
-                   dir_path_match(ent, &s->pathspec, 0, NULL))
+                   dir_path_match(&the_index, ent, &s->pathspec, 0, NULL))
                        string_list_insert(&s->ignored, ent->name);
                free(ent);
        }