1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-04-23 18:25:08 +02:00

Merge branch 'nd/the-index'

Various codepaths in the core-ish part learn to work on an
arbitrary in-core index structure, not necessarily the default
instance "the_index".

* nd/the-index: (23 commits)
  revision.c: reduce implicit dependency the_repository
  revision.c: remove implicit dependency on the_index
  ws.c: remove implicit dependency on the_index
  tree-diff.c: remove implicit dependency on the_index
  submodule.c: remove implicit dependency on the_index
  line-range.c: remove implicit dependency on the_index
  userdiff.c: remove implicit dependency on the_index
  rerere.c: remove implicit dependency on the_index
  sha1-file.c: remove implicit dependency on the_index
  patch-ids.c: remove implicit dependency on the_index
  merge.c: remove implicit dependency on the_index
  merge-blobs.c: remove implicit dependency on the_index
  ll-merge.c: remove implicit dependency on the_index
  diff-lib.c: remove implicit dependency on the_index
  read-cache.c: remove implicit dependency on the_index
  diff.c: remove implicit dependency on the_index
  grep.c: remove implicit dependency on the_index
  diff.c: remove the_index dependency in textconv() functions
  blame.c: rename "repo" argument to "r"
  combine-diff.c: remove implicit dependency on the_index
  ...
This commit is contained in:
Junio C Hamano 2018-10-19 13:34:02 +09:00
commit 11877b9ebe
87 changed files with 751 additions and 552 deletions

View File

@ -18,8 +18,8 @@ Calling sequence
----------------
* Prepare `struct diff_options` to record the set of diff options, and
then call `diff_setup()` to initialize this structure. This sets up
the vanilla default.
then call `repo_diff_setup()` to initialize this structure. This
sets up the vanilla default.
* Fill in the options structure to specify desired output format, rename
detection, etc. `diff_opt_parse()` can be used to parse options given

View File

@ -15,9 +15,9 @@ revision list.
Functions
---------
`init_revisions`::
`repo_init_revisions`::
Initialize a rev_info structure with default values. The second
Initialize a rev_info structure with default values. The third
parameter may be NULL or can be prefix path, and then the `.prefix`
variable will be set to it. This is typically the first function you
want to call when you want to deal with a revision list. After calling

19
apply.c
View File

@ -2131,10 +2131,12 @@ static int parse_chunk(struct apply_state *state, char *buffer, unsigned long si
if (!use_patch(state, patch))
patch->ws_rule = 0;
else if (patch->new_name)
patch->ws_rule = whitespace_rule(state->repo->index,
patch->new_name);
else
patch->ws_rule = whitespace_rule(patch->new_name
? patch->new_name
: patch->old_name);
patch->ws_rule = whitespace_rule(state->repo->index,
patch->old_name);
patchsize = parse_single_patch(state,
buffer + offset + hdrsize,
@ -3467,7 +3469,8 @@ static int load_preimage(struct apply_state *state,
return 0;
}
static int three_way_merge(struct image *image,
static int three_way_merge(struct apply_state *state,
struct image *image,
char *path,
const struct object_id *base,
const struct object_id *ours,
@ -3483,7 +3486,9 @@ static int three_way_merge(struct image *image,
status = ll_merge(&result, path,
&base_file, "base",
&our_file, "ours",
&their_file, "theirs", NULL);
&their_file, "theirs",
state->repo->index,
NULL);
free(base_file.ptr);
free(our_file.ptr);
free(their_file.ptr);
@ -3595,7 +3600,7 @@ static int try_threeway(struct apply_state *state,
clear_image(&tmp_image);
/* in-core three-way merge between post and our using pre as base */
status = three_way_merge(image, patch->new_name,
status = three_way_merge(state, image, patch->new_name,
&pre_oid, &our_oid, &post_oid);
if (status < 0) {
if (state->apply_verbosity > verbosity_silent)
@ -4627,7 +4632,7 @@ static int write_out_results(struct apply_state *state, struct patch *list)
}
string_list_clear(&cpath, 0);
rerere(0);
repo_rerere(state->repo, 0);
}
return errs;

View File

@ -264,9 +264,10 @@ static int has_only_ascii(const char *s)
}
}
static int entry_is_binary(const char *path, const void *buffer, size_t size)
static int entry_is_binary(struct index_state *istate, const char *path,
const void *buffer, size_t size)
{
struct userdiff_driver *driver = userdiff_find_by_path(path);
struct userdiff_driver *driver = userdiff_find_by_path(istate, path);
if (!driver)
driver = userdiff_find_by_name("default");
if (driver->binary != -1)
@ -352,7 +353,8 @@ static int write_zip_entry(struct archiver_args *args,
return error(_("cannot read %s"),
oid_to_hex(oid));
crc = crc32(crc, buffer, size);
is_binary = entry_is_binary(path_without_prefix,
is_binary = entry_is_binary(args->repo->index,
path_without_prefix,
buffer, size);
out = buffer;
}
@ -428,7 +430,8 @@ static int write_zip_entry(struct archiver_args *args,
break;
crc = crc32(crc, buf, readlen);
if (is_binary == -1)
is_binary = entry_is_binary(path_without_prefix,
is_binary = entry_is_binary(args->repo->index,
path_without_prefix,
buf, readlen);
write_or_die(1, buf, readlen);
}
@ -460,7 +463,8 @@ static int write_zip_entry(struct archiver_args *args,
break;
crc = crc32(crc, buf, readlen);
if (is_binary == -1)
is_binary = entry_is_binary(path_without_prefix,
is_binary = entry_is_binary(args->repo->index,
path_without_prefix,
buf, readlen);
zstream.next_in = buf;

View File

@ -392,7 +392,7 @@ static void parse_treeish_arg(const char **argv,
if (get_oid(name, &oid))
die("Not a valid object name");
commit = lookup_commit_reference_gently(the_repository, &oid, 1);
commit = lookup_commit_reference_gently(ar_args->repo, &oid, 1);
if (commit) {
commit_sha1 = commit->object.oid.hash;
archive_time = commit->date;

View File

@ -633,7 +633,7 @@ static void bisect_rev_setup(struct rev_info *revs, const char *prefix,
struct argv_array rev_argv = ARGV_ARRAY_INIT;
int i;
init_revisions(revs, prefix);
repo_init_revisions(the_repository, revs, prefix);
revs->abbrev = 0;
revs->commit_format = CMIT_FMT_UNSPECIFIED;
@ -890,7 +890,7 @@ static void show_diff_tree(const char *prefix, struct commit *commit)
struct rev_info opt;
/* diff-tree init */
init_revisions(&opt, prefix);
repo_init_revisions(the_repository, &opt, prefix);
git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
opt.abbrev = 0;
opt.diff = 1;

63
blame.c
View File

@ -90,7 +90,7 @@ static struct blame_origin *get_origin(struct commit *commit, const char *path)
static void verify_working_tree_path(struct repository *repo,
static void verify_working_tree_path(struct repository *r,
struct commit *work_tree, const char *path)
{
struct commit_list *parents;
@ -102,15 +102,15 @@ static void verify_working_tree_path(struct repository *repo,
unsigned mode;
if (!get_tree_entry(commit_oid, path, &blob_oid, &mode) &&
oid_object_info(repo, &blob_oid, NULL) == OBJ_BLOB)
oid_object_info(r, &blob_oid, NULL) == OBJ_BLOB)
return;
}
pos = index_name_pos(repo->index, path, strlen(path));
pos = index_name_pos(r->index, path, strlen(path));
if (pos >= 0)
; /* path is in the index */
else if (-1 - pos < repo->index->cache_nr &&
!strcmp(repo->index->cache[-1 - pos]->name, path))
else if (-1 - pos < r->index->cache_nr &&
!strcmp(r->index->cache[-1 - pos]->name, path))
; /* path is in the index, unmerged */
else
die("no such path '%s' in HEAD", path);
@ -166,7 +166,7 @@ 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 repository *repo,
static struct commit *fake_working_tree_commit(struct repository *r,
struct diff_options *opt,
const char *path,
const char *contents_from)
@ -183,7 +183,7 @@ static struct commit *fake_working_tree_commit(struct repository *repo,
unsigned mode;
struct strbuf msg = STRBUF_INIT;
read_index(repo->index);
read_index(r->index);
time(&now);
commit = alloc_commit_node(the_repository);
commit->object.parsed = 1;
@ -195,7 +195,7 @@ static struct commit *fake_working_tree_commit(struct repository *repo,
parent_tail = append_parent(parent_tail, &head_oid);
append_merge_parents(parent_tail);
verify_working_tree_path(repo, commit, path);
verify_working_tree_path(r, commit, path);
origin = make_origin(commit, path);
@ -234,7 +234,7 @@ static struct commit *fake_working_tree_commit(struct repository *repo,
switch (st.st_mode & S_IFMT) {
case S_IFREG:
if (opt->flags.allow_textconv &&
textconv_object(read_from, mode, &null_oid, 0, &buf_ptr, &buf_len))
textconv_object(r, read_from, mode, &null_oid, 0, &buf_ptr, &buf_len))
strbuf_attach(&buf, buf_ptr, buf_len, buf_len + 1);
else if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size)
die_errno("cannot open or read '%s'", read_from);
@ -253,7 +253,7 @@ static struct commit *fake_working_tree_commit(struct repository *repo,
if (strbuf_read(&buf, 0, 0) < 0)
die_errno("failed to read from stdin");
}
convert_to_git(repo->index, path, buf.buf, buf.len, &buf, 0);
convert_to_git(r->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);
@ -264,28 +264,28 @@ static struct commit *fake_working_tree_commit(struct repository *repo,
* bits; we are not going to write this index out -- we just
* want to run "diff-index --cached".
*/
discard_index(repo->index);
read_index(repo->index);
discard_index(r->index);
read_index(r->index);
len = strlen(path);
if (!mode) {
int pos = index_name_pos(repo->index, path, len);
int pos = index_name_pos(r->index, path, len);
if (0 <= pos)
mode = repo->index->cache[pos]->ce_mode;
mode = r->index->cache[pos]->ce_mode;
else
/* Let's not bother reading from HEAD tree */
mode = S_IFREG | 0644;
}
ce = make_empty_cache_entry(repo->index, len);
ce = make_empty_cache_entry(r->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_index_entry(repo->index, ce,
add_index_entry(r->index, ce,
ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE);
cache_tree_invalidate_path(repo->index, path);
cache_tree_invalidate_path(r->index, path);
return commit;
}
@ -318,7 +318,8 @@ static void fill_origin_blob(struct diff_options *opt,
(*num_read_blob)++;
if (opt->flags.allow_textconv &&
textconv_object(o->path, o->mode, &o->blob_oid, 1, &file->ptr, &file_size))
textconv_object(opt->repo, o->path, o->mode,
&o->blob_oid, 1, &file->ptr, &file_size))
;
else
file->ptr = read_object_file(&o->blob_oid, &type,
@ -520,14 +521,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 repository *repo,
static int fill_blob_sha1_and_mode(struct repository *r,
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(repo, &origin->blob_oid, NULL) != OBJ_BLOB)
if (oid_object_info(r, &origin->blob_oid, NULL) != OBJ_BLOB)
goto error_out;
return 0;
error_out:
@ -540,8 +541,9 @@ static int fill_blob_sha1_and_mode(struct repository *repo,
* We have an origin -- check if the same path exists in the
* parent and return an origin structure to represent it.
*/
static struct blame_origin *find_origin(struct commit *parent,
struct blame_origin *origin)
static struct blame_origin *find_origin(struct repository *r,
struct commit *parent,
struct blame_origin *origin)
{
struct blame_origin *porigin;
struct diff_options diff_opts;
@ -561,7 +563,7 @@ static struct blame_origin *find_origin(struct commit *parent,
* and origin first. Most of the time they are the
* same and diff-tree is fairly efficient about this.
*/
diff_setup(&diff_opts);
repo_diff_setup(r, &diff_opts);
diff_opts.flags.recursive = 1;
diff_opts.detect_rename = 0;
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
@ -628,14 +630,15 @@ static struct blame_origin *find_origin(struct commit *parent,
* We have an origin -- find the path that corresponds to it in its
* parent and return an origin structure to represent it.
*/
static struct blame_origin *find_rename(struct commit *parent,
struct blame_origin *origin)
static struct blame_origin *find_rename(struct repository *r,
struct commit *parent,
struct blame_origin *origin)
{
struct blame_origin *porigin = NULL;
struct diff_options diff_opts;
int i;
diff_setup(&diff_opts);
repo_diff_setup(r, &diff_opts);
diff_opts.flags.recursive = 1;
diff_opts.detect_rename = DIFF_DETECT_RENAME;
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
@ -1259,7 +1262,7 @@ static void find_copy_in_parent(struct blame_scoreboard *sb,
if (!unblamed)
return; /* nothing remains for this target */
diff_setup(&diff_opts);
repo_diff_setup(sb->repo, &diff_opts);
diff_opts.flags.recursive = 1;
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
@ -1441,7 +1444,7 @@ static void pass_blame(struct blame_scoreboard *sb, struct blame_origin *origin,
* common cases, then we look for renames in the second pass.
*/
for (pass = 0; pass < 2 - sb->no_whole_file_rename; pass++) {
struct blame_origin *(*find)(struct commit *, struct blame_origin *);
struct blame_origin *(*find)(struct repository *, struct commit *, struct blame_origin *);
find = pass ? find_rename : find_origin;
for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse);
@ -1454,7 +1457,7 @@ static void pass_blame(struct blame_scoreboard *sb, struct blame_origin *origin,
continue;
if (parse_commit(p))
continue;
porigin = find(p, origin);
porigin = find(sb->repo, p, origin);
if (!porigin)
continue;
if (oideq(&porigin->blob_oid, &origin->blob_oid)) {
@ -1857,7 +1860,7 @@ void setup_scoreboard(struct blame_scoreboard *sb,
die(_("no such path %s in %s"), path, final_commit_name);
if (sb->revs->diffopt.flags.allow_textconv &&
textconv_object(path, o->mode, &o->blob_oid, 1, (char **) &sb->final_buf,
textconv_object(sb->repo, path, o->mode, &o->blob_oid, 1, (char **) &sb->final_buf,
&sb->final_buf_size))
;
else

View File

@ -110,7 +110,7 @@ int add_files_to_cache(const char *prefix,
memset(&data, 0, sizeof(data));
data.flags = flags;
init_revisions(&rev, prefix);
repo_init_revisions(the_repository, &rev, prefix);
setup_revisions(0, NULL, &rev, NULL);
if (pathspec)
copy_pathspec(&rev.prune_data, pathspec);
@ -232,7 +232,7 @@ static int edit_patch(int argc, const char **argv, const char *prefix)
if (read_cache() < 0)
die(_("Could not read the index"));
init_revisions(&rev, prefix);
repo_init_revisions(the_repository, &rev, prefix);
rev.diffopt.context = 7;
argc = setup_revisions(argc, argv, &rev, NULL);

View File

@ -1376,7 +1376,7 @@ static void write_commit_patch(const struct am_state *state, struct commit *comm
FILE *fp;
fp = xfopen(am_path(state, "patch"), "w");
init_revisions(&rev_info, NULL);
repo_init_revisions(the_repository, &rev_info, NULL);
rev_info.diff = 1;
rev_info.abbrev = 0;
rev_info.disable_stdin = 1;
@ -1411,7 +1411,7 @@ static void write_index_patch(const struct am_state *state)
the_repository->hash_algo->empty_tree);
fp = xfopen(am_path(state, "patch"), "w");
init_revisions(&rev_info, NULL);
repo_init_revisions(the_repository, &rev_info, NULL);
rev_info.diff = 1;
rev_info.disable_stdin = 1;
rev_info.no_commit_id = 1;
@ -1569,7 +1569,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
struct rev_info rev_info;
const char *diff_filter_str = "--diff-filter=AM";
init_revisions(&rev_info, NULL);
repo_init_revisions(the_repository, &rev_info, NULL);
rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS;
diff_opt_parse(&rev_info.diffopt, &diff_filter_str, 1, rev_info.prefix);
add_pending_oid(&rev_info, "HEAD", &our_tree, 0);
@ -1608,7 +1608,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
o.verbosity = 0;
if (merge_recursive_generic(&o, &our_tree, &their_tree, 1, bases, &result)) {
rerere(state->allow_rerere_autoupdate);
repo_rerere(the_repository, state->allow_rerere_autoupdate);
free(their_tree_name);
return error(_("Failed to merge in the changes."));
}
@ -1903,7 +1903,7 @@ static void am_resolve(struct am_state *state)
goto next;
}
rerere(0);
repo_rerere(the_repository, 0);
do_commit(state);

View File

@ -830,7 +830,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
setup_default_color_by_age();
git_config(git_blame_config, &output_option);
init_revisions(&revs, NULL);
repo_init_revisions(the_repository, &revs, NULL);
revs.date_mode = blame_date_mode;
revs.diffopt.flags.allow_textconv = 1;
revs.diffopt.flags.follow_renames = 1;
@ -1001,7 +1001,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
long bottom, top;
if (parse_range_arg(range_list.items[range_i].string,
nth_line_cb, &sb, lno, anchor,
&bottom, &top, sb.path))
&bottom, &top, sb.path, &the_index))
usage(blame_usage);
if ((!lno && (top || bottom)) || lno < bottom)
die(Q_("file %s has only %lu line",

View File

@ -113,7 +113,8 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
die("git cat-file --textconv %s: <object> must be <sha1:path>",
obj_name);
if (textconv_object(path, obj_context.mode, &oid, 1, &buf, &size))
if (textconv_object(the_repository, path, obj_context.mode,
&oid, 1, &buf, &size))
break;
/* else fallthrough */
@ -305,7 +306,8 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
oid_to_hex(oid), data->rest);
} else if (opt->cmdmode == 'c') {
enum object_type type;
if (!textconv_object(data->rest, 0100644, oid,
if (!textconv_object(the_repository,
data->rest, 0100644, oid,
1, &contents, &size))
contents = read_object_file(oid,
&type,

View File

@ -214,7 +214,8 @@ static int checkout_merged(int pos, const struct checkout *state)
* merge.renormalize set, too
*/
status = ll_merge(&result_buf, path, &ancestor, "base",
&ours, "ours", &theirs, "theirs", NULL);
&ours, "ours", &theirs, "theirs",
state->istate, NULL);
free(ancestor.ptr);
free(ours.ptr);
free(theirs.ptr);
@ -397,7 +398,7 @@ static void show_local_changes(struct object *head,
{
struct rev_info rev;
/* I think we want full paths, even if we're in a subdirectory. */
init_revisions(&rev, NULL);
repo_init_revisions(the_repository, &rev, NULL);
rev.diffopt.flags = opts->flags;
rev.diffopt.output_format |= DIFF_FORMAT_NAME_STATUS;
diff_setup_done(&rev.diffopt);
@ -899,7 +900,7 @@ static void orphaned_commit_warning(struct commit *old_commit, struct commit *ne
struct rev_info revs;
struct object *object = &old_commit->object;
init_revisions(&revs, NULL);
repo_init_revisions(the_repository, &revs, NULL);
setup_revisions(0, NULL, &revs, NULL);
object->flags &= ~UNINTERESTING;

View File

@ -983,7 +983,7 @@ static const char *find_author_by_nickname(const char *name)
const char *av[20];
int ac = 0;
init_revisions(&revs, NULL);
repo_init_revisions(the_repository, &revs, NULL);
strbuf_addf(&buf, "--author=%s", name);
av[++ac] = "--all";
av[++ac] = "-i";
@ -1657,7 +1657,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
if (git_env_bool(GIT_TEST_COMMIT_GRAPH, 0))
write_commit_graph_reachable(get_object_directory(), 0, 0);
rerere(0);
repo_rerere(the_repository, 0);
run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
run_commit_hook(use_editor, get_index_file(), "post-commit", NULL);
if (amend && !no_post_rewrite) {

View File

@ -488,7 +488,7 @@ static void describe_blob(struct object_id oid, struct strbuf *dst)
"--objects", "--in-commit-order", "--reverse", "HEAD",
NULL);
init_revisions(&revs, NULL);
repo_init_revisions(the_repository, &revs, NULL);
if (setup_revisions(args.argc, args.argv, &revs, NULL) > 1)
BUG("setup_revisions could not handle all args?");
@ -636,7 +636,7 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
if (0 <= fd)
update_index_if_able(&the_index, &index_lock);
init_revisions(&revs, prefix);
repo_init_revisions(the_repository, &revs, prefix);
argv_array_pushv(&args, diff_index_args);
if (setup_revisions(args.argc, args.argv, &revs, NULL) != 1)
BUG("malformed internal diff-index command line");

View File

@ -25,7 +25,7 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix)
usage(diff_files_usage);
git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
init_revisions(&rev, prefix);
repo_init_revisions(the_repository, &rev, prefix);
rev.abbrev = 0;
precompose_argv(argc, argv);

View File

@ -22,7 +22,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix)
usage(diff_cache_usage);
git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
init_revisions(&rev, prefix);
repo_init_revisions(the_repository, &rev, prefix);
rev.abbrev = 0;
precompose_argv(argc, argv);

View File

@ -110,7 +110,7 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
usage(diff_tree_usage);
git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
init_revisions(opt, prefix);
repo_init_revisions(the_repository, opt, prefix);
if (read_cache() < 0)
die(_("index file corrupt"));
opt->abbrev = 0;

View File

@ -318,7 +318,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
git_config(git_diff_ui_config, NULL);
precompose_argv(argc, argv);
init_revisions(&rev, prefix);
repo_init_revisions(the_repository, &rev, prefix);
if (no_index && argc != i + 2) {
if (no_index == DIFF_NO_INDEX_IMPLICIT) {
@ -339,7 +339,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
}
if (no_index)
/* If this is a no-index diff, just run it and exit there. */
diff_no_index(&rev, argc, argv);
diff_no_index(the_repository, &rev, argc, argv);
/* Otherwise, we are doing the usual "git" diff */
rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index;

View File

@ -112,7 +112,7 @@ static int use_wt_file(const char *workdir, const char *name,
int fd = open(buf.buf, O_RDONLY);
if (fd >= 0 &&
!index_fd(&wt_oid, fd, &st, OBJ_BLOB, name, 0)) {
!index_fd(&the_index, &wt_oid, fd, &st, OBJ_BLOB, name, 0)) {
if (is_null_oid(oid)) {
oidcpy(oid, &wt_oid);
use = 1;

View File

@ -1033,7 +1033,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
/* we handle encodings */
git_config(git_default_config, NULL);
init_revisions(&revs, prefix);
repo_init_revisions(the_repository, &revs, prefix);
init_revision_sources(&revision_sources);
revs.topo_order = 1;
revs.sources = &revision_sources;

View File

@ -643,7 +643,7 @@ int fmt_merge_msg(struct strbuf *in, struct strbuf *out,
struct rev_info rev;
head = lookup_commit_or_die(&head_oid, "HEAD");
init_revisions(&rev, NULL);
repo_init_revisions(the_repository, &rev, NULL);
rev.commit_format = CMIT_FMT_ONELINE;
rev.ignore_merges = 1;
rev.limited = 1;

View File

@ -103,7 +103,8 @@ static void add_work(struct grep_opt *opt, const struct grep_source *gs)
todo[todo_end].source = *gs;
if (opt->binary != GREP_BINARY_TEXT)
grep_source_load_driver(&todo[todo_end].source);
grep_source_load_driver(&todo[todo_end].source,
opt->repo->index);
todo[todo_end].done = 0;
strbuf_reset(&todo[todo_end].out);
todo_end = (todo_end + 1) % ARRAY_SIZE(todo);
@ -904,9 +905,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
OPT_END()
};
init_grep_defaults();
init_grep_defaults(the_repository);
git_config(grep_cmd_config, NULL);
grep_init(&opt, prefix);
grep_init(&opt, the_repository, prefix);
/*
* If there is no -- then the paths must exist in the working

View File

@ -40,7 +40,7 @@ static void hash_fd(int fd, const char *type, const char *path, unsigned flags,
if (fstat(fd, &st) < 0 ||
(literally
? hash_literally(&oid, fd, type, flags)
: index_fd(&oid, fd, &st, type_from_string(type), path, flags)))
: index_fd(&the_index, &oid, fd, &st, type_from_string(type), path, flags)))
die((flags & HASH_WRITE_OBJECT)
? "Unable to add %s to database"
: "Unable to hash %s", path);

View File

@ -118,7 +118,7 @@ static int log_line_range_callback(const struct option *option, const char *arg,
static void init_log_defaults(void)
{
init_grep_defaults();
init_grep_defaults(the_repository);
init_diff_ui_defaults();
decoration_style = auto_decoration_style();
@ -470,7 +470,7 @@ int cmd_whatchanged(int argc, const char **argv, const char *prefix)
init_log_defaults();
git_config(git_log_config, NULL);
init_revisions(&rev, prefix);
repo_init_revisions(the_repository, &rev, prefix);
rev.diff = 1;
rev.simplify_history = 0;
memset(&opt, 0, sizeof(opt));
@ -510,7 +510,8 @@ static int show_blob_object(const struct object_id *oid, struct rev_info *rev, c
&oidc, &obj_context))
die(_("Not a valid object name %s"), obj_name);
if (!obj_context.path ||
!textconv_object(obj_context.path, obj_context.mode, &oidc, 1, &buf, &size)) {
!textconv_object(the_repository, obj_context.path,
obj_context.mode, &oidc, 1, &buf, &size)) {
free(obj_context.path);
return stream_blob_to_fd(1, oid, NULL, 0);
}
@ -587,7 +588,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
git_config(git_log_config, NULL);
memset(&match_all, 0, sizeof(match_all));
init_revisions(&rev, prefix);
repo_init_revisions(the_repository, &rev, prefix);
rev.diff = 1;
rev.always_show_header = 1;
rev.no_walk = REVISION_WALK_NO_WALK_SORTED;
@ -667,7 +668,7 @@ int cmd_log_reflog(int argc, const char **argv, const char *prefix)
init_log_defaults();
git_config(git_log_config, NULL);
init_revisions(&rev, prefix);
repo_init_revisions(the_repository, &rev, prefix);
init_reflog_walk(&rev.reflog_info);
rev.verbose_header = 1;
memset(&opt, 0, sizeof(opt));
@ -706,7 +707,7 @@ int cmd_log(int argc, const char **argv, const char *prefix)
init_log_defaults();
git_config(git_log_config, NULL);
init_revisions(&rev, prefix);
repo_init_revisions(the_repository, &rev, prefix);
rev.always_show_header = 1;
memset(&opt, 0, sizeof(opt));
opt.def = "HEAD";
@ -916,10 +917,10 @@ static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids)
if ((flags1 & UNINTERESTING) == (flags2 & UNINTERESTING))
die(_("Not a range."));
init_patch_ids(ids);
init_patch_ids(the_repository, ids);
/* given a range a..b get all patch ids for b..a */
init_revisions(&check_rev, rev->prefix);
repo_init_revisions(the_repository, &check_rev, rev->prefix);
check_rev.max_parents = 1;
o1->flags ^= UNINTERESTING;
o2->flags ^= UNINTERESTING;
@ -1377,13 +1378,13 @@ static void prepare_bases(struct base_tree_info *bases,
return;
init_commit_base(&commit_base);
diff_setup(&diffopt);
repo_diff_setup(the_repository, &diffopt);
diffopt.flags.recursive = 1;
diff_setup_done(&diffopt);
oidcpy(&bases->base_commit, &base->object.oid);
init_revisions(&revs, NULL);
repo_init_revisions(the_repository, &revs, NULL);
revs.max_parents = 1;
revs.topo_order = 1;
for (i = 0; i < total; i++) {
@ -1588,7 +1589,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
extra_cc.strdup_strings = 1;
init_log_defaults();
git_config(git_format_config, NULL);
init_revisions(&rev, prefix);
repo_init_revisions(the_repository, &rev, prefix);
rev.commit_format = CMIT_FMT_EMAIL;
rev.expand_tabs_in_log_default = 0;
rev.verbose_header = 1;
@ -2038,7 +2039,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
}
}
init_revisions(&revs, prefix);
repo_init_revisions(the_repository, &revs, prefix);
revs.max_parents = 1;
if (add_pending_commit(head, &revs, 0))

View File

@ -76,7 +76,7 @@ static void *result(struct merge_list *entry, unsigned long *size)
their = NULL;
if (entry)
their = entry->blob;
return merge_blobs(path, base, our, their, size);
return merge_blobs(&the_index, path, base, our, their, size);
}
static void *origin(struct merge_list *entry, unsigned long *size)

View File

@ -390,7 +390,7 @@ static void squash_message(struct commit *commit, struct commit_list *remotehead
printf(_("Squash commit -- not updating HEAD\n"));
init_revisions(&rev, NULL);
repo_init_revisions(the_repository, &rev, NULL);
rev.ignore_merges = 1;
rev.commit_format = CMIT_FMT_MEDIUM;
@ -453,7 +453,7 @@ static void finish(struct commit *head_commit,
}
if (new_head && show_diffstat) {
struct diff_options opts;
diff_setup(&opts);
repo_diff_setup(the_repository, &opts);
opts.stat_width = -1; /* use full terminal width */
opts.stat_graph_width = -1; /* respect statGraphWidth config */
opts.output_format |=
@ -729,8 +729,9 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
die(_("unable to write %s"), get_index_file());
return clean ? 0 : 1;
} else {
return try_merge_command(strategy, xopts_nr, xopts,
common, head_arg, remoteheads);
return try_merge_command(the_repository,
strategy, xopts_nr, xopts,
common, head_arg, remoteheads);
}
}
@ -899,7 +900,7 @@ static int suggest_conflicts(void)
fputs(msgbuf.buf, fp);
strbuf_release(&msgbuf);
fclose(fp);
rerere(allow_rerere_auto);
repo_rerere(the_repository, allow_rerere_auto);
printf(_("Automatic merge failed; "
"fix conflicts and then commit the result.\n"));
return 1;
@ -911,7 +912,7 @@ static int evaluate_result(void)
struct rev_info rev;
/* Check how many files differ. */
init_revisions(&rev, "");
repo_init_revisions(the_repository, &rev, "");
setup_revisions(0, NULL, &rev, NULL);
rev.diffopt.output_format |=
DIFF_FORMAT_CALLBACK;
@ -1471,7 +1472,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
goto done;
}
if (checkout_fast_forward(&head_commit->object.oid,
if (checkout_fast_forward(the_repository,
&head_commit->object.oid,
&commit->object.oid,
overwrite_ignore)) {
ret = 1;

View File

@ -3106,7 +3106,7 @@ static void get_object_list(int ac, const char **av)
char line[1000];
int flags = 0;
init_revisions(&revs, NULL);
repo_init_revisions(the_repository, &revs, NULL);
save_commit_buffer = 0;
setup_revisions(ac, av, &revs, NULL);

View File

@ -120,7 +120,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
save_commit_buffer = 0;
read_replace_refs = 0;
ref_paranoia = 1;
init_revisions(&revs, prefix);
repo_init_revisions(the_repository, &revs, prefix);
argc = parse_options(argc, argv, prefix, options, prune_usage, 0);

View File

@ -563,7 +563,9 @@ static int pull_into_void(const struct object_id *merge_head,
* index/worktree changes that the user already made on the unborn
* branch.
*/
if (checkout_fast_forward(the_hash_algo->empty_tree, merge_head, 0))
if (checkout_fast_forward(the_repository,
the_hash_algo->empty_tree,
merge_head, 0))
return 1;
if (update_ref("initial pull", "HEAD", merge_head, curr_head, 0, UPDATE_REFS_DIE_ON_ERR))
@ -916,7 +918,8 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
"fast-forwarding your working tree from\n"
"commit %s."), oid_to_hex(&orig_head));
if (checkout_fast_forward(&orig_head, &curr_head, 0))
if (checkout_fast_forward(the_repository, &orig_head,
&curr_head, 0))
die(_("Cannot fast-forward your working tree.\n"
"After making sure that you saved anything precious from\n"
"$ git diff %s\n"
@ -942,7 +945,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
int ret = 0;
if ((recurse_submodules == RECURSE_SUBMODULES_ON ||
recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) &&
submodule_touches_in_range(&rebase_fork_point, &curr_head))
submodule_touches_in_range(&the_index, &rebase_fork_point, &curr_head))
die(_("cannot rebase with locally recorded submodule modifications"));
if (!autostash) {
struct commit_list *list = NULL;

View File

@ -28,7 +28,7 @@ int cmd_range_diff(int argc, const char **argv, const char *prefix)
git_config(git_diff_ui_config, NULL);
diff_setup(&diffopt);
repo_diff_setup(the_repository, &diffopt);
argc = parse_options(argc, argv, NULL, options,
builtin_range_diff_usage, PARSE_OPT_KEEP_UNKNOWN |

View File

@ -567,7 +567,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
* from reflog if the repository was pruned with older git.
*/
if (cb.cmd.stalefix) {
init_revisions(&cb.cmd.revs, prefix);
repo_init_revisions(the_repository, &cb.cmd.revs, prefix);
if (flags & EXPIRE_REFLOGS_VERBOSE)
printf("Marking reachable objects...");
mark_reachable_objects(&cb.cmd.revs, 0, 0, NULL);

View File

@ -295,7 +295,7 @@ static int import_object(struct object_id *oid, enum object_type type,
close(fd);
return -1;
}
if (index_fd(oid, fd, &st, type, NULL, flags) < 0)
if (index_fd(&the_index, oid, fd, &st, type, NULL, flags) < 0)
return error(_("unable to write object to database"));
/* index_fd close()s fd for us */
}

View File

@ -70,7 +70,7 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
flags = RERERE_NOAUTOUPDATE;
if (argc < 1)
return rerere(flags);
return repo_rerere(the_repository, flags);
if (!strcmp(argv[0], "forget")) {
struct pathspec pathspec;
@ -78,7 +78,7 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
warning(_("'git rerere forget' without paths is deprecated"));
parse_pathspec(&pathspec, 0, PATHSPEC_PREFER_CWD,
prefix, argv + 1);
return rerere_forget(&pathspec);
return rerere_forget(the_repository, &pathspec);
}
if (!strcmp(argv[0], "clear")) {
@ -91,7 +91,7 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
for (i = 0; i < merge_rr.nr; i++)
printf("%s\n", merge_rr.items[i].string);
} else if (!strcmp(argv[0], "remaining")) {
rerere_remaining(&merge_rr);
rerere_remaining(the_repository, &merge_rr);
for (i = 0; i < merge_rr.nr; i++) {
if (merge_rr.items[i].util != RERERE_RESOLVED)
printf("%s\n", merge_rr.items[i].string);

View File

@ -159,6 +159,7 @@ static int read_from_tree(const struct pathspec *pathspec,
opt.format_callback = update_index_from_diff;
opt.format_callback_data = &intent_to_add;
opt.flags.override_submodule_config = 1;
opt.repo = the_repository;
if (do_diff_cache(tree_oid, &opt))
return 1;

View File

@ -370,7 +370,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
usage(rev_list_usage);
git_config(git_default_config, NULL);
init_revisions(&revs, prefix);
repo_init_revisions(the_repository, &revs, prefix);
revs.abbrev = DEFAULT_ABBREV;
revs.commit_format = CMIT_FMT_UNSPECIFIED;

View File

@ -174,7 +174,7 @@ static int run_sequencer(int argc, const char **argv, struct replay_opts *opts)
} else {
struct setup_revision_opt s_r_opt;
opts->revs = xmalloc(sizeof(*opts->revs));
init_revisions(opts->revs, NULL);
repo_init_revisions(the_repository, opts->revs, NULL);
opts->revs->no_walk = REVISION_WALK_NO_WALK_UNSORTED;
if (argc < 2)
usage_with_options(usage_str, options);

View File

@ -278,7 +278,7 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix)
git_config(git_default_config, NULL);
shortlog_init(&log);
init_revisions(&rev, prefix);
repo_init_revisions(the_repository, &rev, prefix);
parse_options_start(&ctx, argc, argv, prefix, options,
PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0);

View File

@ -792,7 +792,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
path, NULL);
git_config(git_diff_basic_config, NULL);
init_revisions(&rev, prefix);
repo_init_revisions(the_repository, &rev, prefix);
rev.abbrev = 0;
diff_files_args.argc = setup_revisions(diff_files_args.argc,
diff_files_args.argv,

View File

@ -282,7 +282,7 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len
fill_stat_cache_info(ce, st);
ce->ce_mode = ce_mode_from_stat(old, st->st_mode);
if (index_path(&ce->oid, path, st,
if (index_path(&the_index, &ce->oid, path, st,
info_only ? 0 : HASH_WRITE_OBJECT)) {
discard_cache_entry(ce);
return -1;

View File

@ -140,7 +140,7 @@ int verify_bundle(struct bundle_header *header, int verbose)
int i, ret = 0, req_nr;
const char *message = _("Repository lacks these prerequisite commits:");
init_revisions(&revs, NULL);
repo_init_revisions(the_repository, &revs, NULL);
for (i = 0; i < p->nr; i++) {
struct ref_list_entry *e = p->list + i;
struct object *o = parse_object(the_repository, &e->oid);
@ -441,7 +441,7 @@ int create_bundle(struct bundle_header *header, const char *path,
/* init revs to list objects for pack-objects later */
save_commit_buffer = 0;
init_revisions(&revs, NULL);
repo_init_revisions(the_repository, &revs, NULL);
/* write prerequisites */
if (compute_and_write_prerequisites(bundle_fd, &revs, argc, argv))

14
cache.h
View File

@ -703,7 +703,7 @@ extern int unmerged_index(const struct index_state *);
* provided, the space-separated list of files that differ will be appended
* to it.
*/
extern int index_has_changes(const struct index_state *istate,
extern int index_has_changes(struct index_state *istate,
struct tree *tree,
struct strbuf *sb);
@ -787,8 +787,8 @@ extern int ie_modified(struct index_state *, const struct cache_entry *, struct
#define HASH_WRITE_OBJECT 1
#define HASH_FORMAT_CHECK 2
#define HASH_RENORMALIZE 4
extern int index_fd(struct object_id *oid, int fd, struct stat *st, enum object_type type, const char *path, unsigned flags);
extern int index_path(struct object_id *oid, const char *path, struct stat *st, unsigned flags);
extern int index_fd(struct index_state *istate, struct object_id *oid, int fd, struct stat *st, enum object_type type, const char *path, unsigned flags);
extern int index_path(struct index_state *istate, struct object_id *oid, const char *path, struct stat *st, unsigned flags);
/*
* Record to sd the data from st that we use to check whether a file
@ -1705,7 +1705,7 @@ void shift_tree_by(const struct object_id *, const struct object_id *, struct ob
/* All WS_* -- when extended, adapt diff.c emit_symbol */
#define WS_RULE_MASK 07777
extern unsigned whitespace_rule_cfg;
extern unsigned whitespace_rule(const char *);
extern unsigned whitespace_rule(struct index_state *, const char *);
extern unsigned parse_whitespace_rule(const char *);
extern unsigned ws_check(const char *line, int len, unsigned ws_rule);
extern void ws_check_emit(const char *line, int len, unsigned ws_rule, FILE *stream, const char *set, const char *reset, const char *ws);
@ -1727,10 +1727,12 @@ extern struct startup_info *startup_info;
/* merge.c */
struct commit_list;
int try_merge_command(const char *strategy, size_t xopts_nr,
int try_merge_command(struct repository *r,
const char *strategy, size_t xopts_nr,
const char **xopts, struct commit_list *common,
const char *head_arg, struct commit_list *remotes);
int checkout_fast_forward(const struct object_id *from,
int checkout_fast_forward(struct repository *r,
const struct object_id *from,
const struct object_id *to,
int overwrite_ignore);

View File

@ -285,7 +285,8 @@ static struct lline *coalesce_lines(struct lline *base, int *lenbase,
return base;
}
static char *grab_blob(const struct object_id *oid, unsigned int mode,
static char *grab_blob(struct repository *r,
const struct object_id *oid, unsigned int mode,
unsigned long *size, struct userdiff_driver *textconv,
const char *path)
{
@ -304,7 +305,7 @@ static char *grab_blob(const struct object_id *oid, unsigned int mode,
} else if (textconv) {
struct diff_filespec *df = alloc_filespec(path);
fill_filespec(df, oid, 1, mode);
*size = fill_textconv(textconv, df, &blob);
*size = fill_textconv(r, textconv, df, &blob);
free_filespec(df);
} else {
blob = read_object_file(oid, &type, size);
@ -389,7 +390,8 @@ static void consume_line(void *state_, char *line, unsigned long len)
}
}
static void combine_diff(const struct object_id *parent, unsigned int mode,
static void combine_diff(struct repository *r,
const struct object_id *parent, unsigned int mode,
mmfile_t *result_file,
struct sline *sline, unsigned int cnt, int n,
int num_parent, int result_deleted,
@ -407,7 +409,7 @@ static void combine_diff(const struct object_id *parent, unsigned int mode,
if (result_deleted)
return; /* result deleted */
parent_file.ptr = grab_blob(parent, mode, &sz, textconv, path);
parent_file.ptr = grab_blob(r, parent, mode, &sz, textconv, path);
parent_file.size = sz;
memset(&xpp, 0, sizeof(xpp));
xpp.flags = flags;
@ -985,7 +987,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
const char *line_prefix = diff_line_prefix(opt);
context = opt->context;
userdiff = userdiff_find_by_path(elem->path);
userdiff = userdiff_find_by_path(opt->repo->index, elem->path);
if (!userdiff)
userdiff = userdiff_find_by_name("default");
if (opt->flags.allow_textconv)
@ -993,7 +995,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
/* Read the result of merge first */
if (!working_tree_file)
result = grab_blob(&elem->oid, elem->mode, &result_size,
result = grab_blob(opt->repo, &elem->oid, elem->mode, &result_size,
textconv, elem->path);
else {
/* Used by diff-tree to read from the working tree */
@ -1016,15 +1018,16 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
} else if (S_ISDIR(st.st_mode)) {
struct object_id oid;
if (resolve_gitlink_ref(elem->path, "HEAD", &oid) < 0)
result = grab_blob(&elem->oid, elem->mode,
&result_size, NULL, NULL);
result = grab_blob(opt->repo, &elem->oid,
elem->mode, &result_size,
NULL, NULL);
else
result = grab_blob(&oid, elem->mode,
result = grab_blob(opt->repo, &oid, elem->mode,
&result_size, NULL, NULL);
} else if (textconv) {
struct diff_filespec *df = alloc_filespec(elem->path);
fill_filespec(df, &null_oid, 0, st.st_mode);
result_size = fill_textconv(textconv, df, &result);
result_size = fill_textconv(opt->repo, textconv, df, &result);
free_filespec(df);
} else if (0 <= (fd = open(elem->path, O_RDONLY))) {
size_t len = xsize_t(st.st_size);
@ -1054,7 +1057,8 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
if (is_file) {
struct strbuf buf = STRBUF_INIT;
if (convert_to_git(&the_index, elem->path, result, len, &buf, global_conv_flags_eol)) {
if (convert_to_git(rev->diffopt.repo->index,
elem->path, result, len, &buf, global_conv_flags_eol)) {
free(result);
result = strbuf_detach(&buf, &len);
result_size = len;
@ -1089,7 +1093,8 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
for (i = 0; !is_binary && i < num_parent; i++) {
char *buf;
unsigned long size;
buf = grab_blob(&elem->parent[i].oid,
buf = grab_blob(opt->repo,
&elem->parent[i].oid,
elem->parent[i].mode,
&size, NULL, NULL);
if (buffer_is_binary(buf, size))
@ -1145,7 +1150,8 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
}
}
if (i <= j)
combine_diff(&elem->parent[i].oid,
combine_diff(opt->repo,
&elem->parent[i].oid,
elem->parent[i].mode,
&result_file, sline,
cnt, i, num_parent, result_deleted,

View File

@ -70,7 +70,7 @@ static int match_stat_with_submodule(struct diff_options *diffopt,
struct stat *st, unsigned ce_option,
unsigned *dirty_submodule)
{
int changed = ce_match_stat(ce, st, ce_option);
int changed = ie_match_stat(diffopt->repo->index, ce, st, ce_option);
if (S_ISGITLINK(ce->ce_mode)) {
struct diff_flags orig_flags = diffopt->flags;
if (!diffopt->flags.override_submodule_config)
@ -93,15 +93,16 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED)
? CE_MATCH_RACY_IS_DIRTY : 0);
uint64_t start = getnanotime();
struct index_state *istate = revs->diffopt.repo->index;
diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/");
if (diff_unmerged_stage < 0)
diff_unmerged_stage = 2;
entries = active_nr;
entries = istate->cache_nr;
for (i = 0; i < entries; i++) {
unsigned int oldmode, newmode;
struct cache_entry *ce = active_cache[i];
struct cache_entry *ce = istate->cache[i];
int changed;
unsigned dirty_submodule = 0;
const struct object_id *old_oid, *new_oid;
@ -109,7 +110,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
if (diff_can_quit_early(&revs->diffopt))
break;
if (!ce_path_match(&the_index, ce, &revs->prune_data, NULL))
if (!ce_path_match(istate, ce, &revs->prune_data, NULL))
continue;
if (ce_stage(ce)) {
@ -145,7 +146,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
dpath->mode = wt_mode;
while (i < entries) {
struct cache_entry *nce = active_cache[i];
struct cache_entry *nce = istate->cache[i];
int stage;
if (strcmp(ce->name, nce->name))
@ -474,7 +475,9 @@ static int oneway_diff(const struct cache_entry * const *src,
if (tree == o->df_conflict_entry)
tree = NULL;
if (ce_path_match(&the_index, idx ? idx : tree, &revs->prune_data, NULL)) {
if (ce_path_match(revs->diffopt.repo->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;
@ -506,7 +509,7 @@ static int diff_cache(struct rev_info *revs,
opts.merge = 1;
opts.fn = oneway_diff;
opts.unpack_data = revs;
opts.src_index = &the_index;
opts.src_index = revs->diffopt.repo->index;
opts.dst_index = NULL;
opts.pathspec = &revs->diffopt.pathspec;
opts.pathspec->recursive = 1;
@ -539,7 +542,7 @@ int do_diff_cache(const struct object_id *tree_oid, struct diff_options *opt)
{
struct rev_info revs;
init_revisions(&revs, NULL);
repo_init_revisions(the_repository, &revs, NULL);
copy_pathspec(&revs.prune_data, &opt->pathspec);
revs.diffopt = *opt;
@ -554,7 +557,7 @@ int index_differs_from(const char *def, const struct diff_flags *flags,
struct rev_info rev;
struct setup_revision_opt opt;
init_revisions(&rev, NULL);
repo_init_revisions(the_repository, &rev, NULL);
memset(&opt, 0, sizeof(opt));
opt.def = def;
setup_revisions(0, NULL, &rev, &opt);

View File

@ -233,7 +233,8 @@ static void fixup_paths(const char **path, struct strbuf *replacement)
}
}
void diff_no_index(struct rev_info *revs,
void diff_no_index(struct repository *r,
struct rev_info *revs,
int argc, const char **argv)
{
int i;
@ -241,7 +242,11 @@ void diff_no_index(struct rev_info *revs,
struct strbuf replacement = STRBUF_INIT;
const char *prefix = revs->prefix;
diff_setup(&revs->diffopt);
/*
* FIXME: --no-index should not look at index and we should be
* able to pass NULL repo. Maybe later.
*/
repo_diff_setup(r, &revs->diffopt);
for (i = 1; i < argc - 2; ) {
int j;
if (!strcmp(argv[i], "--no-index"))

261
diff.c
View File

@ -554,14 +554,15 @@ static int count_lines(const char *data, int size)
return count;
}
static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one)
static int fill_mmfile(struct repository *r, mmfile_t *mf,
struct diff_filespec *one)
{
if (!DIFF_FILE_VALID(one)) {
mf->ptr = (char *)""; /* does not matter */
mf->size = 0;
return 0;
}
else if (diff_populate_filespec(one, 0))
else if (diff_populate_filespec(r, one, 0))
return -1;
mf->ptr = one->data;
@ -570,11 +571,12 @@ static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one)
}
/* like fill_mmfile, but only for size, so we can avoid retrieving blob */
static unsigned long diff_filespec_size(struct diff_filespec *one)
static unsigned long diff_filespec_size(struct repository *r,
struct diff_filespec *one)
{
if (!DIFF_FILE_VALID(one))
return 0;
diff_populate_filespec(one, CHECK_SIZE_ONLY);
diff_populate_filespec(r, one, CHECK_SIZE_ONLY);
return one->size;
}
@ -1714,12 +1716,12 @@ static void emit_rewrite_diff(const char *name_a,
quote_two_c_style(&a_name, a_prefix, name_a, 0);
quote_two_c_style(&b_name, b_prefix, name_b, 0);
size_one = fill_textconv(textconv_one, one, &data_one);
size_two = fill_textconv(textconv_two, two, &data_two);
size_one = fill_textconv(o->repo, textconv_one, one, &data_one);
size_two = fill_textconv(o->repo, textconv_two, two, &data_two);
memset(&ecbdata, 0, sizeof(ecbdata));
ecbdata.color_diff = want_color(o->use_color);
ecbdata.ws_rule = whitespace_rule(name_b);
ecbdata.ws_rule = whitespace_rule(o->repo->index, name_b);
ecbdata.opt = o;
if (ecbdata.ws_rule & WS_BLANK_AT_EOF) {
mmfile_t mf1, mf2;
@ -2107,23 +2109,25 @@ static void diff_words_flush(struct emit_callback *ecbdata)
}
}
static void diff_filespec_load_driver(struct diff_filespec *one)
static void diff_filespec_load_driver(struct diff_filespec *one,
struct index_state *istate)
{
/* Use already-loaded driver */
if (one->driver)
return;
if (S_ISREG(one->mode))
one->driver = userdiff_find_by_path(one->path);
one->driver = userdiff_find_by_path(istate, one->path);
/* Fallback to default settings */
if (!one->driver)
one->driver = userdiff_find_by_name("default");
}
static const char *userdiff_word_regex(struct diff_filespec *one)
static const char *userdiff_word_regex(struct diff_filespec *one,
struct index_state *istate)
{
diff_filespec_load_driver(one);
diff_filespec_load_driver(one, istate);
return one->driver->word_regex;
}
@ -2146,9 +2150,9 @@ static void init_diff_words_data(struct emit_callback *ecbdata,
xcalloc(1, sizeof(struct emitted_diff_symbols));
if (!o->word_regex)
o->word_regex = userdiff_word_regex(one);
o->word_regex = userdiff_word_regex(one, o->repo->index);
if (!o->word_regex)
o->word_regex = userdiff_word_regex(two);
o->word_regex = userdiff_word_regex(two, o->repo->index);
if (!o->word_regex)
o->word_regex = diff_word_regex_cfg;
if (o->word_regex) {
@ -2976,18 +2980,19 @@ static void show_dirstat(struct diff_options *options)
}
if (DIFF_FILE_VALID(p->one) && DIFF_FILE_VALID(p->two)) {
diff_populate_filespec(p->one, 0);
diff_populate_filespec(p->two, 0);
diffcore_count_changes(p->one, p->two, NULL, NULL,
diff_populate_filespec(options->repo, p->one, 0);
diff_populate_filespec(options->repo, p->two, 0);
diffcore_count_changes(options->repo,
p->one, p->two, NULL, NULL,
&copied, &added);
diff_free_filespec_data(p->one);
diff_free_filespec_data(p->two);
} else if (DIFF_FILE_VALID(p->one)) {
diff_populate_filespec(p->one, CHECK_SIZE_ONLY);
diff_populate_filespec(options->repo, p->one, CHECK_SIZE_ONLY);
copied = added = 0;
diff_free_filespec_data(p->one);
} else if (DIFF_FILE_VALID(p->two)) {
diff_populate_filespec(p->two, CHECK_SIZE_ONLY);
diff_populate_filespec(options->repo, p->two, CHECK_SIZE_ONLY);
copied = 0;
added = p->two->size;
diff_free_filespec_data(p->two);
@ -3261,15 +3266,16 @@ static void emit_binary_diff(struct diff_options *o,
emit_binary_diff_body(o, two, one);
}
int diff_filespec_is_binary(struct diff_filespec *one)
int diff_filespec_is_binary(struct repository *r,
struct diff_filespec *one)
{
if (one->is_binary == -1) {
diff_filespec_load_driver(one);
diff_filespec_load_driver(one, r->index);
if (one->driver->binary != -1)
one->is_binary = one->driver->binary;
else {
if (!one->data && DIFF_FILE_VALID(one))
diff_populate_filespec(one, CHECK_BINARY);
diff_populate_filespec(r, one, CHECK_BINARY);
if (one->is_binary == -1 && one->data)
one->is_binary = buffer_is_binary(one->data,
one->size);
@ -3280,9 +3286,10 @@ int diff_filespec_is_binary(struct diff_filespec *one)
return one->is_binary;
}
static const struct userdiff_funcname *diff_funcname_pattern(struct diff_filespec *one)
static const struct userdiff_funcname *
diff_funcname_pattern(struct diff_options *o, struct diff_filespec *one)
{
diff_filespec_load_driver(one);
diff_filespec_load_driver(one, o->repo->index);
return one->driver->funcname.pattern ? &one->driver->funcname : NULL;
}
@ -3294,12 +3301,13 @@ void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const
options->b_prefix = b;
}
struct userdiff_driver *get_textconv(struct diff_filespec *one)
struct userdiff_driver *get_textconv(struct index_state *istate,
struct diff_filespec *one)
{
if (!DIFF_FILE_VALID(one))
return NULL;
diff_filespec_load_driver(one);
diff_filespec_load_driver(one, istate);
return userdiff_get_textconv(one->driver);
}
@ -3349,8 +3357,8 @@ static void builtin_diff(const char *name_a,
}
if (o->flags.allow_textconv) {
textconv_one = get_textconv(one);
textconv_two = get_textconv(two);
textconv_one = get_textconv(o->repo->index, one);
textconv_two = get_textconv(o->repo->index, two);
}
/* Never use a non-valid filename anywhere if at all possible */
@ -3391,13 +3399,13 @@ static void builtin_diff(const char *name_a,
if ((one->mode ^ two->mode) & S_IFMT)
goto free_ab_and_return;
if (complete_rewrite &&
(textconv_one || !diff_filespec_is_binary(one)) &&
(textconv_two || !diff_filespec_is_binary(two))) {
(textconv_one || !diff_filespec_is_binary(o->repo, one)) &&
(textconv_two || !diff_filespec_is_binary(o->repo, two))) {
emit_diff_symbol(o, DIFF_SYMBOL_HEADER,
header.buf, header.len, 0);
strbuf_reset(&header);
emit_rewrite_diff(name_a, name_b, one, two,
textconv_one, textconv_two, o);
textconv_one, textconv_two, o);
o->found_changes = 1;
goto free_ab_and_return;
}
@ -3409,8 +3417,8 @@ static void builtin_diff(const char *name_a,
strbuf_reset(&header);
goto free_ab_and_return;
} else if (!o->flags.text &&
( (!textconv_one && diff_filespec_is_binary(one)) ||
(!textconv_two && diff_filespec_is_binary(two)) )) {
( (!textconv_one && diff_filespec_is_binary(o->repo, one)) ||
(!textconv_two && diff_filespec_is_binary(o->repo, two)) )) {
struct strbuf sb = STRBUF_INIT;
if (!one->data && !two->data &&
S_ISREG(one->mode) && S_ISREG(two->mode) &&
@ -3431,7 +3439,8 @@ static void builtin_diff(const char *name_a,
strbuf_release(&sb);
goto free_ab_and_return;
}
if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
if (fill_mmfile(o->repo, &mf1, one) < 0 ||
fill_mmfile(o->repo, &mf2, two) < 0)
die("unable to read files to diff");
/* Quite common confusing case */
if (mf1.size == mf2.size &&
@ -3468,12 +3477,12 @@ static void builtin_diff(const char *name_a,
strbuf_reset(&header);
}
mf1.size = fill_textconv(textconv_one, one, &mf1.ptr);
mf2.size = fill_textconv(textconv_two, two, &mf2.ptr);
mf1.size = fill_textconv(o->repo, textconv_one, one, &mf1.ptr);
mf2.size = fill_textconv(o->repo, textconv_two, two, &mf2.ptr);
pe = diff_funcname_pattern(one);
pe = diff_funcname_pattern(o, one);
if (!pe)
pe = diff_funcname_pattern(two);
pe = diff_funcname_pattern(o, two);
memset(&xpp, 0, sizeof(xpp));
memset(&xecfg, 0, sizeof(xecfg));
@ -3482,7 +3491,7 @@ static void builtin_diff(const char *name_a,
lbl[0] = NULL;
ecbdata.label_path = lbl;
ecbdata.color_diff = want_color(o->use_color);
ecbdata.ws_rule = whitespace_rule(name_b);
ecbdata.ws_rule = whitespace_rule(o->repo->index, name_b);
if (ecbdata.ws_rule & WS_BLANK_AT_EOF)
check_blank_at_eof(&mf1, &mf2, &ecbdata);
ecbdata.opt = o;
@ -3582,20 +3591,21 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
same_contents = oideq(&one->oid, &two->oid);
if (diff_filespec_is_binary(one) || diff_filespec_is_binary(two)) {
if (diff_filespec_is_binary(o->repo, one) ||
diff_filespec_is_binary(o->repo, two)) {
data->is_binary = 1;
if (same_contents) {
data->added = 0;
data->deleted = 0;
} else {
data->added = diff_filespec_size(two);
data->deleted = diff_filespec_size(one);
data->added = diff_filespec_size(o->repo, two);
data->deleted = diff_filespec_size(o->repo, one);
}
}
else if (complete_rewrite) {
diff_populate_filespec(one, 0);
diff_populate_filespec(two, 0);
diff_populate_filespec(o->repo, one, 0);
diff_populate_filespec(o->repo, two, 0);
data->deleted = count_lines(one->data, one->size);
data->added = count_lines(two->data, two->size);
}
@ -3605,7 +3615,8 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
xpparam_t xpp;
xdemitconf_t xecfg;
if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
if (fill_mmfile(o->repo, &mf1, one) < 0 ||
fill_mmfile(o->repo, &mf2, two) < 0)
die("unable to read files to diff");
memset(&xpp, 0, sizeof(xpp));
@ -3640,10 +3651,11 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
data.filename = name_b ? name_b : name_a;
data.lineno = 0;
data.o = o;
data.ws_rule = whitespace_rule(attr_path);
data.conflict_marker_size = ll_merge_marker_size(attr_path);
data.ws_rule = whitespace_rule(o->repo->index, attr_path);
data.conflict_marker_size = ll_merge_marker_size(o->repo->index, attr_path);
if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
if (fill_mmfile(o->repo, &mf1, one) < 0 ||
fill_mmfile(o->repo, &mf2, two) < 0)
die("unable to read files to diff");
/*
@ -3652,7 +3664,7 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
* introduced changes, and as long as the "new" side is text, we
* can and should check what it introduces.
*/
if (diff_filespec_is_binary(two))
if (diff_filespec_is_binary(o->repo, two))
goto free_and_return;
else {
/* Crazy xdl interfaces.. */
@ -3725,7 +3737,10 @@ void fill_filespec(struct diff_filespec *spec, const struct object_id *oid,
* the work tree has that object contents, return true, so that
* prepare_temp_file() does not have to inflate and extract.
*/
static int reuse_worktree_file(const char *name, const struct object_id *oid, int want_file)
static int reuse_worktree_file(struct index_state *istate,
const char *name,
const struct object_id *oid,
int want_file)
{
const struct cache_entry *ce;
struct stat st;
@ -3744,7 +3759,7 @@ static int reuse_worktree_file(const char *name, const struct object_id *oid, in
* by diff-cache --cached, which does read the cache before
* calling us.
*/
if (!active_cache)
if (!istate->cache)
return 0;
/* We want to avoid the working directory if our caller
@ -3763,14 +3778,14 @@ static int reuse_worktree_file(const char *name, const struct object_id *oid, in
* Similarly, if we'd have to convert the file contents anyway, that
* makes the optimization not worthwhile.
*/
if (!want_file && would_convert_to_git(&the_index, name))
if (!want_file && would_convert_to_git(istate, name))
return 0;
len = strlen(name);
pos = cache_name_pos(name, len);
pos = index_name_pos(istate, name, len);
if (pos < 0)
return 0;
ce = active_cache[pos];
ce = istate->cache[pos];
/*
* This is not the sha1 we are looking for, or
@ -3790,7 +3805,7 @@ static int reuse_worktree_file(const char *name, const struct object_id *oid, in
* If ce matches the file in the work tree, we can reuse it.
*/
if (ce_uptodate(ce) ||
(!lstat(name, &st) && !ce_match_stat(ce, &st, 0)))
(!lstat(name, &st) && !ie_match_stat(istate, ce, &st, 0)))
return 1;
return 0;
@ -3823,7 +3838,9 @@ static int diff_populate_gitlink(struct diff_filespec *s, int size_only)
* grab the data for the blob (or file) for our own in-core comparison.
* diff_filespec has data and size fields for this purpose.
*/
int diff_populate_filespec(struct diff_filespec *s, unsigned int flags)
int diff_populate_filespec(struct repository *r,
struct diff_filespec *s,
unsigned int flags)
{
int size_only = flags & CHECK_SIZE_ONLY;
int err = 0;
@ -3850,7 +3867,7 @@ int diff_populate_filespec(struct diff_filespec *s, unsigned int flags)
return diff_populate_gitlink(s, size_only);
if (!s->oid_valid ||
reuse_worktree_file(s->path, &s->oid, 0)) {
reuse_worktree_file(r->index, s->path, &s->oid, 0)) {
struct strbuf buf = STRBUF_INIT;
struct stat st;
int fd;
@ -3883,7 +3900,7 @@ int diff_populate_filespec(struct diff_filespec *s, unsigned int flags)
* point if the path requires us to run the content
* conversion.
*/
if (size_only && !would_convert_to_git(&the_index, s->path))
if (size_only && !would_convert_to_git(r->index, s->path))
return 0;
/*
@ -3910,7 +3927,7 @@ int diff_populate_filespec(struct diff_filespec *s, unsigned int flags)
/*
* Convert from working tree format to canonical git format
*/
if (convert_to_git(&the_index, s->path, s->data, s->size, &buf, conv_flags)) {
if (convert_to_git(r->index, s->path, s->data, s->size, &buf, conv_flags)) {
size_t size = 0;
munmap(s->data, s->size);
s->should_munmap = 0;
@ -3922,8 +3939,7 @@ int diff_populate_filespec(struct diff_filespec *s, unsigned int flags)
else {
enum object_type type;
if (size_only || (flags & CHECK_BINARY)) {
type = oid_object_info(the_repository, &s->oid,
&s->size);
type = oid_object_info(r, &s->oid, &s->size);
if (type < 0)
die("unable to read %s",
oid_to_hex(&s->oid));
@ -3961,7 +3977,8 @@ void diff_free_filespec_data(struct diff_filespec *s)
FREE_AND_NULL(s->cnt_data);
}
static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
static void prep_temp_blob(struct index_state *istate,
const char *path, struct diff_tempfile *temp,
void *blob,
unsigned long size,
const struct object_id *oid,
@ -3979,7 +3996,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(&the_index, path,
if (convert_to_working_tree(istate, path,
(const char *)blob, (size_t)size, &buf)) {
blob = buf.buf;
size = buf.len;
@ -3995,8 +4012,9 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
free(path_dup);
}
static struct diff_tempfile *prepare_temp_file(const char *name,
struct diff_filespec *one)
static struct diff_tempfile *prepare_temp_file(struct repository *r,
const char *name,
struct diff_filespec *one)
{
struct diff_tempfile *temp = claim_diff_tempfile();
@ -4013,7 +4031,7 @@ static struct diff_tempfile *prepare_temp_file(const char *name,
if (!S_ISGITLINK(one->mode) &&
(!one->oid_valid ||
reuse_worktree_file(name, &one->oid, 1))) {
reuse_worktree_file(r->index, name, &one->oid, 1))) {
struct stat st;
if (lstat(name, &st) < 0) {
if (errno == ENOENT)
@ -4024,7 +4042,7 @@ static struct diff_tempfile *prepare_temp_file(const char *name,
struct strbuf sb = STRBUF_INIT;
if (strbuf_readlink(&sb, name, st.st_size) < 0)
die_errno("readlink(%s)", name);
prep_temp_blob(name, temp, sb.buf, sb.len,
prep_temp_blob(r->index, name, temp, sb.buf, sb.len,
(one->oid_valid ?
&one->oid : &null_oid),
(one->oid_valid ?
@ -4049,19 +4067,21 @@ static struct diff_tempfile *prepare_temp_file(const char *name,
return temp;
}
else {
if (diff_populate_filespec(one, 0))
if (diff_populate_filespec(r, one, 0))
die("cannot read data blob for %s", one->path);
prep_temp_blob(name, temp, one->data, one->size,
prep_temp_blob(r->index, name, temp,
one->data, one->size,
&one->oid, one->mode);
}
return temp;
}
static void add_external_diff_name(struct argv_array *argv,
static void add_external_diff_name(struct repository *r,
struct argv_array *argv,
const char *name,
struct diff_filespec *df)
{
struct diff_tempfile *temp = prepare_temp_file(name, df);
struct diff_tempfile *temp = prepare_temp_file(r, name, df);
argv_array_push(argv, temp->name);
argv_array_push(argv, temp->hex);
argv_array_push(argv, temp->mode);
@ -4090,11 +4110,11 @@ static void run_external_diff(const char *pgm,
argv_array_push(&argv, name);
if (one && two) {
add_external_diff_name(&argv, name, one);
add_external_diff_name(o->repo, &argv, name, one);
if (!other)
add_external_diff_name(&argv, name, two);
add_external_diff_name(o->repo, &argv, name, two);
else {
add_external_diff_name(&argv, other, two);
add_external_diff_name(o->repo, &argv, other, two);
argv_array_push(&argv, other);
argv_array_push(&argv, xfrm_msg);
}
@ -4187,8 +4207,10 @@ static void fill_metainfo(struct strbuf *msg,
if (o->flags.binary) {
mmfile_t mf;
if ((!fill_mmfile(&mf, one) && diff_filespec_is_binary(one)) ||
(!fill_mmfile(&mf, two) && diff_filespec_is_binary(two)))
if ((!fill_mmfile(o->repo, &mf, one) &&
diff_filespec_is_binary(o->repo, one)) ||
(!fill_mmfile(o->repo, &mf, two) &&
diff_filespec_is_binary(o->repo, two)))
abbrev = hexsz;
}
strbuf_addf(msg, "%s%sindex %s..%s", line_prefix, set,
@ -4216,7 +4238,9 @@ static void run_diff_cmd(const char *pgm,
if (o->flags.allow_external) {
struct userdiff_driver *drv = userdiff_find_by_path(attr_path);
struct userdiff_driver *drv;
drv = userdiff_find_by_path(o->repo->index, attr_path);
if (drv && drv->external)
pgm = drv->external;
}
@ -4245,7 +4269,7 @@ static void run_diff_cmd(const char *pgm,
fprintf(o->file, "* Unmerged path %s\n", name);
}
static void diff_fill_oid_info(struct diff_filespec *one)
static void diff_fill_oid_info(struct diff_filespec *one, struct index_state *istate)
{
if (DIFF_FILE_VALID(one)) {
if (!one->oid_valid) {
@ -4256,7 +4280,7 @@ static void diff_fill_oid_info(struct diff_filespec *one)
}
if (lstat(one->path, &st) < 0)
die_errno("stat '%s'", one->path);
if (index_path(&one->oid, one->path, &st, 0))
if (index_path(istate, &one->oid, one->path, &st, 0))
die("cannot hash %s", one->path);
}
}
@ -4304,8 +4328,8 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
return;
}
diff_fill_oid_info(one);
diff_fill_oid_info(two);
diff_fill_oid_info(one, o->repo->index);
diff_fill_oid_info(two, o->repo->index);
if (!pgm &&
DIFF_FILE_VALID(one) && DIFF_FILE_VALID(two) &&
@ -4316,7 +4340,8 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
*/
struct diff_filespec *null = alloc_filespec(two->path);
run_diff_cmd(NULL, name, other, attr_path,
one, null, &msg, o, p);
one, null, &msg,
o, p);
free(null);
strbuf_release(&msg);
@ -4340,7 +4365,8 @@ static void run_diffstat(struct diff_filepair *p, struct diff_options *o,
if (DIFF_PAIR_UNMERGED(p)) {
/* unmerged */
builtin_diffstat(p->one->path, NULL, NULL, NULL, diffstat, o, p);
builtin_diffstat(p->one->path, NULL, NULL, NULL,
diffstat, o, p);
return;
}
@ -4350,10 +4376,11 @@ static void run_diffstat(struct diff_filepair *p, struct diff_options *o,
if (o->prefix_length)
strip_prefix(o->prefix_length, &name, &other);
diff_fill_oid_info(p->one);
diff_fill_oid_info(p->two);
diff_fill_oid_info(p->one, o->repo->index);
diff_fill_oid_info(p->two, o->repo->index);
builtin_diffstat(name, other, p->one, p->two, diffstat, o, p);
builtin_diffstat(name, other, p->one, p->two,
diffstat, o, p);
}
static void run_checkdiff(struct diff_filepair *p, struct diff_options *o)
@ -4374,17 +4401,18 @@ static void run_checkdiff(struct diff_filepair *p, struct diff_options *o)
if (o->prefix_length)
strip_prefix(o->prefix_length, &name, &other);
diff_fill_oid_info(p->one);
diff_fill_oid_info(p->two);
diff_fill_oid_info(p->one, o->repo->index);
diff_fill_oid_info(p->two, o->repo->index);
builtin_checkdiff(name, other, attr_path, p->one, p->two, o);
}
void diff_setup(struct diff_options *options)
void repo_diff_setup(struct repository *r, struct diff_options *options)
{
memcpy(options, &default_diff_options, sizeof(*options));
options->file = stdout;
options->repo = r;
options->output_indicators[OUTPUT_INDICATOR_NEW] = '+';
options->output_indicators[OUTPUT_INDICATOR_OLD] = '-';
@ -5683,8 +5711,8 @@ static int diff_get_patch_id(struct diff_options *options, struct object_id *oid
if (DIFF_PAIR_UNMERGED(p))
continue;
diff_fill_oid_info(p->one);
diff_fill_oid_info(p->two);
diff_fill_oid_info(p->one, options->repo->index);
diff_fill_oid_info(p->two, options->repo->index);
len1 = remove_space(p->one->path, strlen(p->one->path));
len2 = remove_space(p->two->path, strlen(p->two->path));
@ -5716,12 +5744,12 @@ static int diff_get_patch_id(struct diff_options *options, struct object_id *oid
if (diff_header_only)
continue;
if (fill_mmfile(&mf1, p->one) < 0 ||
fill_mmfile(&mf2, p->two) < 0)
if (fill_mmfile(options->repo, &mf1, p->one) < 0 ||
fill_mmfile(options->repo, &mf2, p->two) < 0)
return error("unable to read files to diff");
if (diff_filespec_is_binary(p->one) ||
diff_filespec_is_binary(p->two)) {
if (diff_filespec_is_binary(options->repo, p->one) ||
diff_filespec_is_binary(options->repo, p->two)) {
git_SHA1_Update(&ctx, oid_to_hex(&p->one->oid),
GIT_SHA1_HEXSZ);
git_SHA1_Update(&ctx, oid_to_hex(&p->two->oid),
@ -6024,19 +6052,21 @@ static void diffcore_apply_filter(struct diff_options *options)
}
/* Check whether two filespecs with the same mode and size are identical */
static int diff_filespec_is_identical(struct diff_filespec *one,
static int diff_filespec_is_identical(struct repository *r,
struct diff_filespec *one,
struct diff_filespec *two)
{
if (S_ISGITLINK(one->mode))
return 0;
if (diff_populate_filespec(one, 0))
if (diff_populate_filespec(r, one, 0))
return 0;
if (diff_populate_filespec(two, 0))
if (diff_populate_filespec(r, two, 0))
return 0;
return !memcmp(one->data, two->data, one->size);
}
static int diff_filespec_check_stat_unmatch(struct diff_filepair *p)
static int diff_filespec_check_stat_unmatch(struct repository *r,
struct diff_filepair *p)
{
if (p->done_skip_stat_unmatch)
return p->skip_stat_unmatch_result;
@ -6060,10 +6090,10 @@ static int diff_filespec_check_stat_unmatch(struct diff_filepair *p)
!DIFF_FILE_VALID(p->two) ||
(p->one->oid_valid && p->two->oid_valid) ||
(p->one->mode != p->two->mode) ||
diff_populate_filespec(p->one, CHECK_SIZE_ONLY) ||
diff_populate_filespec(p->two, CHECK_SIZE_ONLY) ||
diff_populate_filespec(r, p->one, CHECK_SIZE_ONLY) ||
diff_populate_filespec(r, p->two, CHECK_SIZE_ONLY) ||
(p->one->size != p->two->size) ||
!diff_filespec_is_identical(p->one, p->two)) /* (2) */
!diff_filespec_is_identical(r, p->one, p->two)) /* (2) */
p->skip_stat_unmatch_result = 1;
return p->skip_stat_unmatch_result;
}
@ -6078,7 +6108,7 @@ static void diffcore_skip_stat_unmatch(struct diff_options *diffopt)
for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];
if (diff_filespec_check_stat_unmatch(p))
if (diff_filespec_check_stat_unmatch(diffopt->repo, p))
diff_q(&outq, p);
else {
/*
@ -6120,7 +6150,8 @@ void diffcore_std(struct diff_options *options)
if (!options->found_follow) {
/* See try_to_follow_renames() in tree-diff.c */
if (options->break_opt != -1)
diffcore_break(options->break_opt);
diffcore_break(options->repo,
options->break_opt);
if (options->detect_rename)
diffcore_rename(options);
if (options->break_opt != -1)
@ -6271,7 +6302,7 @@ void diff_change(struct diff_options *options,
return;
if (options->flags.quick && options->skip_stat_unmatch &&
!diff_filespec_check_stat_unmatch(p))
!diff_filespec_check_stat_unmatch(options->repo, p))
return;
options->flags.has_changes = 1;
@ -6293,8 +6324,10 @@ struct diff_filepair *diff_unmerge(struct diff_options *options, const char *pat
return pair;
}
static char *run_textconv(const char *pgm, struct diff_filespec *spec,
size_t *outsize)
static char *run_textconv(struct repository *r,
const char *pgm,
struct diff_filespec *spec,
size_t *outsize)
{
struct diff_tempfile *temp;
const char *argv[3];
@ -6303,7 +6336,7 @@ static char *run_textconv(const char *pgm, struct diff_filespec *spec,
struct strbuf buf = STRBUF_INIT;
int err = 0;
temp = prepare_temp_file(spec->path, spec);
temp = prepare_temp_file(r, spec->path, spec);
*arg++ = pgm;
*arg++ = temp->name;
*arg = NULL;
@ -6330,7 +6363,8 @@ static char *run_textconv(const char *pgm, struct diff_filespec *spec,
return strbuf_detach(&buf, outsize);
}
size_t fill_textconv(struct userdiff_driver *driver,
size_t fill_textconv(struct repository *r,
struct userdiff_driver *driver,
struct diff_filespec *df,
char **outbuf)
{
@ -6341,7 +6375,7 @@ size_t fill_textconv(struct userdiff_driver *driver,
*outbuf = "";
return 0;
}
if (diff_populate_filespec(df, 0))
if (diff_populate_filespec(r, df, 0))
die("unable to read files to diff");
*outbuf = df->data;
return df->size;
@ -6358,7 +6392,7 @@ size_t fill_textconv(struct userdiff_driver *driver,
return size;
}
*outbuf = run_textconv(driver->textconv, df, &size);
*outbuf = run_textconv(r, driver->textconv, df, &size);
if (!*outbuf)
die("unable to read files to diff");
@ -6378,7 +6412,8 @@ size_t fill_textconv(struct userdiff_driver *driver,
return size;
}
int textconv_object(const char *path,
int textconv_object(struct repository *r,
const char *path,
unsigned mode,
const struct object_id *oid,
int oid_valid,
@ -6390,13 +6425,13 @@ int textconv_object(const char *path,
df = alloc_filespec(path);
fill_filespec(df, oid, oid_valid, mode);
textconv = get_textconv(df);
textconv = get_textconv(r->index, df);
if (!textconv) {
free_filespec(df);
return 0;
}
*buf_size = fill_textconv(textconv, df, buf);
*buf_size = fill_textconv(r, textconv, df, buf);
free_filespec(df);
return 1;
}

22
diff.h
View File

@ -18,6 +18,7 @@ struct userdiff_driver;
struct oid_array;
struct commit;
struct combine_diff_path;
struct repository;
typedef int (*pathchange_fn_t)(struct diff_options *options,
struct combine_diff_path *path);
@ -225,6 +226,8 @@ struct diff_options {
/* XDF_WHITESPACE_FLAGS regarding block detection are set at 2, 3, 4 */
#define COLOR_MOVED_WS_ALLOW_INDENTATION_CHANGE (1<<5)
int color_moved_ws_handling;
struct repository *repo;
};
void diff_emit_submodule_del(struct diff_options *o, const char *line);
@ -338,7 +341,10 @@ int git_diff_basic_config(const char *var, const char *value, void *cb);
int git_diff_heuristic_config(const char *var, const char *value, void *cb);
void init_diff_ui_defaults(void);
int git_diff_ui_config(const char *var, const char *value, void *cb);
void diff_setup(struct diff_options *);
#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS
#define diff_setup(diffopts) repo_diff_setup(the_repository, diffopts)
#endif
void repo_diff_setup(struct repository *, struct diff_options *);
int diff_opt_parse(struct diff_options *, const char **, int, const char *);
void diff_setup_done(struct diff_options *);
int git_config_rename(const char *var, const char *value);
@ -428,7 +434,7 @@ int diff_flush_patch_id(struct diff_options *, struct object_id *, int);
int diff_result_code(struct diff_options *, int);
void diff_no_index(struct rev_info *, int, const char **);
void diff_no_index(struct repository *, struct rev_info *, int, const char **);
int index_differs_from(const char *def, const struct diff_flags *flags,
int ita_invisible_in_index);
@ -444,7 +450,8 @@ int index_differs_from(const char *def, const struct diff_flags *flags,
* struct. If it is non-NULL, then "outbuf" points to a newly allocated buffer
* that should be freed by the caller.
*/
size_t fill_textconv(struct userdiff_driver *driver,
size_t fill_textconv(struct repository *r,
struct userdiff_driver *driver,
struct diff_filespec *df,
char **outbuf);
@ -453,14 +460,19 @@ size_t fill_textconv(struct userdiff_driver *driver,
* and only if it has textconv enabled (otherwise return NULL). The result
* can be passed to fill_textconv().
*/
struct userdiff_driver *get_textconv(struct diff_filespec *one);
struct userdiff_driver *get_textconv(struct index_state *istate,
struct diff_filespec *one);
/*
* Prepare diff_filespec and convert it using diff textconv API
* if the textconv driver exists.
* Return 1 if the conversion succeeds, 0 otherwise.
*/
int textconv_object(const char *path, unsigned mode, const struct object_id *oid, int oid_valid, char **buf, unsigned long *buf_size);
int textconv_object(struct repository *repo,
const char *path,
unsigned mode,
const struct object_id *oid, int oid_valid,
char **buf, unsigned long *buf_size);
int parse_rename_score(const char **cp_p);

View File

@ -5,7 +5,8 @@
#include "diff.h"
#include "diffcore.h"
static int should_break(struct diff_filespec *src,
static int should_break(struct repository *r,
struct diff_filespec *src,
struct diff_filespec *dst,
int break_score,
int *merge_score_p)
@ -61,7 +62,8 @@ static int should_break(struct diff_filespec *src,
oideq(&src->oid, &dst->oid))
return 0; /* they are the same */
if (diff_populate_filespec(src, 0) || diff_populate_filespec(dst, 0))
if (diff_populate_filespec(r, src, 0) ||
diff_populate_filespec(r, dst, 0))
return 0; /* error but caught downstream */
max_size = ((src->size > dst->size) ? src->size : dst->size);
@ -71,7 +73,7 @@ static int should_break(struct diff_filespec *src,
if (!src->size)
return 0; /* we do not let empty files get renamed */
if (diffcore_count_changes(src, dst,
if (diffcore_count_changes(r, src, dst,
&src->cnt_data, &dst->cnt_data,
&src_copied, &literal_added))
return 0;
@ -114,7 +116,7 @@ static int should_break(struct diff_filespec *src,
return 1;
}
void diffcore_break(int break_score)
void diffcore_break(struct repository *r, int break_score)
{
struct diff_queue_struct *q = &diff_queued_diff;
struct diff_queue_struct outq;
@ -178,7 +180,7 @@ void diffcore_break(int break_score)
object_type(p->one->mode) == OBJ_BLOB &&
object_type(p->two->mode) == OBJ_BLOB &&
!strcmp(p->one->path, p->two->path)) {
if (should_break(p->one, p->two,
if (should_break(r, p->one, p->two,
break_score, &score)) {
/* Split this into delete and create */
struct diff_filespec *null_one, *null_two;

View File

@ -121,14 +121,15 @@ static int spanhash_cmp(const void *a_, const void *b_)
a->hashval > b->hashval ? 1 : 0;
}
static struct spanhash_top *hash_chars(struct diff_filespec *one)
static struct spanhash_top *hash_chars(struct repository *r,
struct diff_filespec *one)
{
int i, n;
unsigned int accum1, accum2, hashval;
struct spanhash_top *hash;
unsigned char *buf = one->data;
unsigned int sz = one->size;
int is_text = !diff_filespec_is_binary(one);
int is_text = !diff_filespec_is_binary(r, one);
i = INITIAL_HASH_SIZE;
hash = xmalloc(st_add(sizeof(*hash),
@ -162,7 +163,8 @@ static struct spanhash_top *hash_chars(struct diff_filespec *one)
return hash;
}
int diffcore_count_changes(struct diff_filespec *src,
int diffcore_count_changes(struct repository *r,
struct diff_filespec *src,
struct diff_filespec *dst,
void **src_count_p,
void **dst_count_p,
@ -177,14 +179,14 @@ int diffcore_count_changes(struct diff_filespec *src,
if (src_count_p)
src_count = *src_count_p;
if (!src_count) {
src_count = hash_chars(src);
src_count = hash_chars(r, src);
if (src_count_p)
*src_count_p = src_count;
}
if (dst_count_p)
dst_count = *dst_count_p;
if (!dst_count) {
dst_count = hash_chars(dst);
dst_count = hash_chars(r, dst);
if (dst_count_p)
*dst_count_p = dst_count;
}

View File

@ -139,8 +139,8 @@ static int pickaxe_match(struct diff_filepair *p, struct diff_options *o,
return 0;
if (o->flags.allow_textconv) {
textconv_one = get_textconv(p->one);
textconv_two = get_textconv(p->two);
textconv_one = get_textconv(o->repo->index, p->one);
textconv_two = get_textconv(o->repo->index, p->two);
}
/*
@ -153,8 +153,8 @@ static int pickaxe_match(struct diff_filepair *p, struct diff_options *o,
if (textconv_one == textconv_two && diff_unmodified_pair(p))
return 0;
mf1.size = fill_textconv(textconv_one, p->one, &mf1.ptr);
mf2.size = fill_textconv(textconv_two, p->two, &mf2.ptr);
mf1.size = fill_textconv(o->repo, textconv_one, p->one, &mf1.ptr);
mf2.size = fill_textconv(o->repo, textconv_two, p->two, &mf2.ptr);
ret = fn(DIFF_FILE_VALID(p->one) ? &mf1 : NULL,
DIFF_FILE_VALID(p->two) ? &mf2 : NULL,

View File

@ -128,7 +128,8 @@ struct diff_score {
short name_score;
};
static int estimate_similarity(struct diff_filespec *src,
static int estimate_similarity(struct repository *r,
struct diff_filespec *src,
struct diff_filespec *dst,
int minimum_score)
{
@ -165,10 +166,10 @@ static int estimate_similarity(struct diff_filespec *src,
* say whether the size is valid or not!)
*/
if (!src->cnt_data &&
diff_populate_filespec(src, CHECK_SIZE_ONLY))
diff_populate_filespec(r, src, CHECK_SIZE_ONLY))
return 0;
if (!dst->cnt_data &&
diff_populate_filespec(dst, CHECK_SIZE_ONLY))
diff_populate_filespec(r, dst, CHECK_SIZE_ONLY))
return 0;
max_size = ((src->size > dst->size) ? src->size : dst->size);
@ -186,12 +187,12 @@ static int estimate_similarity(struct diff_filespec *src,
if (max_size * (MAX_SCORE-minimum_score) < delta_size * MAX_SCORE)
return 0;
if (!src->cnt_data && diff_populate_filespec(src, 0))
if (!src->cnt_data && diff_populate_filespec(r, src, 0))
return 0;
if (!dst->cnt_data && diff_populate_filespec(dst, 0))
if (!dst->cnt_data && diff_populate_filespec(r, dst, 0))
return 0;
if (diffcore_count_changes(src, dst,
if (diffcore_count_changes(r, src, dst,
&src->cnt_data, &dst->cnt_data,
&src_copied, &literal_added))
return 0;
@ -256,10 +257,11 @@ struct file_similarity {
struct diff_filespec *filespec;
};
static unsigned int hash_filespec(struct diff_filespec *filespec)
static unsigned int hash_filespec(struct repository *r,
struct diff_filespec *filespec)
{
if (!filespec->oid_valid) {
if (diff_populate_filespec(filespec, 0))
if (diff_populate_filespec(r, filespec, 0))
return 0;
hash_object_file(filespec->data, filespec->size, "blob",
&filespec->oid);
@ -280,7 +282,9 @@ static int find_identical_files(struct hashmap *srcs,
/*
* Find the best source match for specified destination.
*/
p = hashmap_get_from_hash(srcs, hash_filespec(target), NULL);
p = hashmap_get_from_hash(srcs,
hash_filespec(options->repo, target),
NULL);
for (; p; p = hashmap_get_next(srcs, p)) {
int score;
struct diff_filespec *source = p->filespec;
@ -316,14 +320,16 @@ static int find_identical_files(struct hashmap *srcs,
return renames;
}
static void insert_file_table(struct hashmap *table, int index, struct diff_filespec *filespec)
static void insert_file_table(struct repository *r,
struct hashmap *table, int index,
struct diff_filespec *filespec)
{
struct file_similarity *entry = xmalloc(sizeof(*entry));
entry->index = index;
entry->filespec = filespec;
hashmap_entry_init(entry, hash_filespec(filespec));
hashmap_entry_init(entry, hash_filespec(r, filespec));
hashmap_add(table, entry);
}
@ -344,7 +350,9 @@ static int find_exact_renames(struct diff_options *options)
*/
hashmap_init(&file_table, NULL, NULL, rename_src_nr);
for (i = rename_src_nr-1; i >= 0; i--)
insert_file_table(&file_table, i, rename_src[i].p->one);
insert_file_table(options->repo,
&file_table, i,
rename_src[i].p->one);
/* Walk the destinations and find best source match */
for (i = 0; i < rename_dst_nr; i++)
@ -557,7 +565,8 @@ void diffcore_rename(struct diff_options *options)
diff_unmodified_pair(rename_src[j].p))
continue;
this_src.score = estimate_similarity(one, two,
this_src.score = estimate_similarity(options->repo,
one, two,
minimum_score);
this_src.name_score = basename_same(one, two);
this_src.dst = i;

View File

@ -7,6 +7,8 @@
#include "cache.h"
struct diff_options;
struct repository;
struct userdiff_driver;
/* This header file is internal between diff.c and its diff transformers
* (e.g. diffcore-rename, diffcore-pickaxe). Never include this header
@ -26,8 +28,6 @@ struct diff_options;
#define MINIMUM_BREAK_SIZE 400 /* do not break a file smaller than this */
struct userdiff_driver;
struct diff_filespec {
struct object_id oid;
char *path;
@ -61,10 +61,10 @@ void fill_filespec(struct diff_filespec *, const struct object_id *,
#define CHECK_SIZE_ONLY 1
#define CHECK_BINARY 2
int diff_populate_filespec(struct diff_filespec *, unsigned int);
int diff_populate_filespec(struct repository *, struct diff_filespec *, unsigned int);
void diff_free_filespec_data(struct diff_filespec *);
void diff_free_filespec_blob(struct diff_filespec *);
int diff_filespec_is_binary(struct diff_filespec *);
int diff_filespec_is_binary(struct repository *, struct diff_filespec *);
struct diff_filepair {
struct diff_filespec *one;
@ -111,7 +111,7 @@ struct diff_filepair *diff_queue(struct diff_queue_struct *,
struct diff_filespec *);
void diff_q(struct diff_queue_struct *, struct diff_filepair *);
void diffcore_break(int);
void diffcore_break(struct repository *, int);
void diffcore_rename(struct diff_options *);
void diffcore_merge_broken(void);
void diffcore_pickaxe(struct diff_options *);
@ -142,7 +142,8 @@ void diff_debug_queue(const char *, struct diff_queue_struct *);
#define diff_debug_queue(a,b) do { /* nothing */ } while (0)
#endif
int diffcore_count_changes(struct diff_filespec *src,
int diffcore_count_changes(struct repository *r,
struct diff_filespec *src,
struct diff_filespec *dst,
void **src_count_p,
void **dst_count_p,

34
grep.c
View File

@ -11,7 +11,8 @@
#include "help.h"
static int grep_source_load(struct grep_source *gs);
static int grep_source_is_binary(struct grep_source *gs);
static int grep_source_is_binary(struct grep_source *gs,
struct index_state *istate);
static struct grep_opt grep_defaults;
@ -42,7 +43,7 @@ static void color_set(char *dst, const char *color_bytes)
* We could let the compiler do this, but without C99 initializers
* the code gets unwieldy and unreadable, so...
*/
void init_grep_defaults(void)
void init_grep_defaults(struct repository *repo)
{
struct grep_opt *opt = &grep_defaults;
static int run_once;
@ -52,6 +53,7 @@ void init_grep_defaults(void)
run_once++;
memset(opt, 0, sizeof(*opt));
opt->repo = repo;
opt->relative = 1;
opt->pathname = 1;
opt->max_depth = -1;
@ -149,12 +151,13 @@ int grep_config(const char *var, const char *value, void *cb)
* default values from the template we read the configuration
* information in an earlier call to git_config(grep_config).
*/
void grep_init(struct grep_opt *opt, const char *prefix)
void grep_init(struct grep_opt *opt, struct repository *repo, const char *prefix)
{
struct grep_opt *def = &grep_defaults;
int i;
memset(opt, 0, sizeof(*opt));
opt->repo = repo;
opt->prefix = prefix;
opt->prefix_length = (prefix && *prefix) ? strlen(prefix) : 0;
opt->pattern_tail = &opt->pattern_list;
@ -1545,7 +1548,7 @@ static int match_funcname(struct grep_opt *opt, struct grep_source *gs, char *bo
{
xdemitconf_t *xecfg = opt->priv;
if (xecfg && !xecfg->find_func) {
grep_source_load_driver(gs);
grep_source_load_driver(gs, opt->repo->index);
if (gs->driver->funcname.pattern) {
const struct userdiff_funcname *pe = &gs->driver->funcname;
xdiff_set_find_func(xecfg, pe->pattern, pe->cflags);
@ -1708,7 +1711,8 @@ static int look_ahead(struct grep_opt *opt,
return 0;
}
static int fill_textconv_grep(struct userdiff_driver *driver,
static int fill_textconv_grep(struct repository *r,
struct userdiff_driver *driver,
struct grep_source *gs)
{
struct diff_filespec *df;
@ -1741,7 +1745,7 @@ static int fill_textconv_grep(struct userdiff_driver *driver,
* structure.
*/
grep_read_lock();
size = fill_textconv(driver, df, &buf);
size = fill_textconv(r, driver, df, &buf);
grep_read_unlock();
free_filespec(df);
@ -1801,7 +1805,7 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle
opt->last_shown = 0;
if (opt->allow_textconv) {
grep_source_load_driver(gs);
grep_source_load_driver(gs, opt->repo->index);
/*
* We might set up the shared textconv cache data here, which
* is not thread-safe.
@ -1818,11 +1822,11 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle
if (!textconv) {
switch (opt->binary) {
case GREP_BINARY_DEFAULT:
if (grep_source_is_binary(gs))
if (grep_source_is_binary(gs, opt->repo->index))
binary_match_only = 1;
break;
case GREP_BINARY_NOMATCH:
if (grep_source_is_binary(gs))
if (grep_source_is_binary(gs, opt->repo->index))
return 0; /* Assume unmatch */
break;
case GREP_BINARY_TEXT:
@ -1837,7 +1841,7 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle
try_lookahead = should_lookahead(opt);
if (fill_textconv_grep(textconv, gs) < 0)
if (fill_textconv_grep(opt->repo, textconv, gs) < 0)
return 0;
bol = gs->buf;
@ -2168,22 +2172,24 @@ static int grep_source_load(struct grep_source *gs)
BUG("invalid grep_source type to load");
}
void grep_source_load_driver(struct grep_source *gs)
void grep_source_load_driver(struct grep_source *gs,
struct index_state *istate)
{
if (gs->driver)
return;
grep_attr_lock();
if (gs->path)
gs->driver = userdiff_find_by_path(gs->path);
gs->driver = userdiff_find_by_path(istate, gs->path);
if (!gs->driver)
gs->driver = userdiff_find_by_name("default");
grep_attr_unlock();
}
static int grep_source_is_binary(struct grep_source *gs)
static int grep_source_is_binary(struct grep_source *gs,
struct index_state *istate)
{
grep_source_load_driver(gs);
grep_source_load_driver(gs, istate);
if (gs->driver->binary != -1)
return gs->driver->binary;

10
grep.h
View File

@ -36,6 +36,8 @@ typedef int pcre2_jit_stack;
#include "thread-utils.h"
#include "userdiff.h"
struct repository;
enum grep_pat_token {
GREP_PATTERN,
GREP_PATTERN_HEAD,
@ -136,6 +138,7 @@ struct grep_opt {
struct grep_pat *header_list;
struct grep_pat **header_tail;
struct grep_expr *pattern_expression;
struct repository *repo;
const char *prefix;
int prefix_length;
regex_t regexp;
@ -183,9 +186,9 @@ struct grep_opt {
void *output_priv;
};
extern void init_grep_defaults(void);
extern void init_grep_defaults(struct repository *);
extern int grep_config(const char *var, const char *value, void *);
extern void grep_init(struct grep_opt *, const char *prefix);
extern void grep_init(struct grep_opt *, struct repository *repo, const char *prefix);
void grep_commit_pattern_type(enum grep_pattern_type, struct grep_opt *opt);
extern void append_grep_pat(struct grep_opt *opt, const char *pat, size_t patlen, const char *origin, int no, enum grep_pat_token t);
@ -217,7 +220,8 @@ void grep_source_init(struct grep_source *gs, enum grep_source_type type,
const void *identifier);
void grep_source_clear_data(struct grep_source *gs);
void grep_source_clear(struct grep_source *gs);
void grep_source_load_driver(struct grep_source *gs);
void grep_source_load_driver(struct grep_source *gs,
struct index_state *istate);
int grep_source(struct grep_opt *opt, struct grep_source *gs);

View File

@ -1925,7 +1925,7 @@ int cmd_main(int argc, const char **argv)
if (!push_all && !is_null_oid(&ref->old_oid))
argv_array_pushf(&commit_argv, "^%s",
oid_to_hex(&ref->old_oid));
init_revisions(&revs, setup_git_directory());
repo_init_revisions(the_repository, &revs, setup_git_directory());
setup_revisions(commit_argv.argc, commit_argv.argv, &revs, NULL);
revs.edge_hint = 0; /* just in case */

View File

@ -508,7 +508,9 @@ static void fill_blob_sha1(struct commit *commit, struct diff_filespec *spec)
return;
}
static void fill_line_ends(struct diff_filespec *spec, long *lines,
static void fill_line_ends(struct repository *r,
struct diff_filespec *spec,
long *lines,
unsigned long **line_ends)
{
int num = 0, size = 50;
@ -516,7 +518,7 @@ static void fill_line_ends(struct diff_filespec *spec, long *lines,
unsigned long *ends = NULL;
char *data = NULL;
if (diff_populate_filespec(spec, 0))
if (diff_populate_filespec(r, spec, 0))
die("Cannot read blob %s", oid_to_hex(&spec->oid));
ALLOC_ARRAY(ends, size);
@ -555,7 +557,8 @@ static const char *nth_line(void *data, long line)
}
static struct line_log_data *
parse_lines(struct commit *commit, const char *prefix, struct string_list *args)
parse_lines(struct repository *r, struct commit *commit,
const char *prefix, struct string_list *args)
{
long lines = 0;
unsigned long *ends = NULL;
@ -571,7 +574,7 @@ parse_lines(struct commit *commit, const char *prefix, struct string_list *args)
long begin = 0, end = 0;
long anchor;
name_part = skip_range_arg(item->string);
name_part = skip_range_arg(item->string, r->index);
if (!name_part || *name_part != ':' || !name_part[1])
die("-L argument not 'start,end:file' or ':funcname:file': %s",
item->string);
@ -583,7 +586,7 @@ parse_lines(struct commit *commit, const char *prefix, struct string_list *args)
spec = alloc_filespec(full_name);
fill_blob_sha1(commit, spec);
fill_line_ends(spec, &lines, &ends);
fill_line_ends(r, spec, &lines, &ends);
cb_data.spec = spec;
cb_data.lines = lines;
cb_data.line_ends = ends;
@ -596,7 +599,7 @@ parse_lines(struct commit *commit, const char *prefix, struct string_list *args)
if (parse_range_arg(range_part, nth_line, &cb_data,
lines, anchor, &begin, &end,
full_name))
full_name, r->index))
die("malformed -L argument '%s'", range_part);
if ((!lines && (begin || end)) || lines < begin)
die("file %s has only %lu lines", name_part, lines);
@ -739,7 +742,7 @@ void line_log_init(struct rev_info *rev, const char *prefix, struct string_list
struct line_log_data *range;
commit = check_single_commit(rev);
range = parse_lines(commit, prefix, args);
range = parse_lines(rev->diffopt.repo, commit, prefix, args);
add_line_range(rev, commit, range);
if (!rev->diffopt.detect_rename) {
@ -891,8 +894,8 @@ static void dump_diff_hacky_one(struct rev_info *rev, struct line_log_data *rang
return;
if (pair->one->oid_valid)
fill_line_ends(pair->one, &p_lines, &p_ends);
fill_line_ends(pair->two, &t_lines, &t_ends);
fill_line_ends(rev->diffopt.repo, pair->one, &p_lines, &p_ends);
fill_line_ends(rev->diffopt.repo, pair->two, &t_lines, &t_ends);
fprintf(opt->file, "%s%sdiff --git a/%s b/%s%s\n", prefix, c_meta, pair->one->path, pair->two->path, c_reset);
fprintf(opt->file, "%s%s--- %s%s%s\n", prefix, c_meta,
@ -1008,12 +1011,12 @@ static int process_diff_filepair(struct rev_info *rev,
return 0;
assert(pair->two->oid_valid);
diff_populate_filespec(pair->two, 0);
diff_populate_filespec(rev->diffopt.repo, pair->two, 0);
file_target.ptr = pair->two->data;
file_target.size = pair->two->size;
if (pair->one->oid_valid) {
diff_populate_filespec(pair->one, 0);
diff_populate_filespec(rev->diffopt.repo, pair->one, 0);
file_parent.ptr = pair->one->data;
file_parent.size = pair->one->size;
} else {

View File

@ -163,9 +163,10 @@ static const char *find_funcname_matching_regexp(xdemitconf_t *xecfg, const char
}
}
static const char *parse_range_funcname(const char *arg, nth_line_fn_t nth_line_cb,
void *cb_data, long lines, long anchor, long *begin, long *end,
const char *path)
static const char *parse_range_funcname(
const char *arg, nth_line_fn_t nth_line_cb,
void *cb_data, long lines, long anchor, long *begin, long *end,
const char *path, struct index_state *istate)
{
char *pattern;
const char *term;
@ -198,7 +199,7 @@ static const char *parse_range_funcname(const char *arg, nth_line_fn_t nth_line_
anchor--; /* input is in human terms */
start = nth_line_cb(cb_data, anchor);
drv = userdiff_find_by_path(path);
drv = userdiff_find_by_path(istate, path);
if (drv && drv->funcname.pattern) {
const struct userdiff_funcname *pe = &drv->funcname;
xecfg = xcalloc(1, sizeof(*xecfg));
@ -244,7 +245,8 @@ static const char *parse_range_funcname(const char *arg, nth_line_fn_t nth_line_
int parse_range_arg(const char *arg, nth_line_fn_t nth_line_cb,
void *cb_data, long lines, long anchor,
long *begin, long *end, const char *path)
long *begin, long *end,
const char *path, struct index_state *istate)
{
*begin = *end = 0;
@ -254,7 +256,9 @@ int parse_range_arg(const char *arg, nth_line_fn_t nth_line_cb,
anchor = lines + 1;
if (*arg == ':' || (*arg == '^' && *(arg + 1) == ':')) {
arg = parse_range_funcname(arg, nth_line_cb, cb_data, lines, anchor, begin, end, path);
arg = parse_range_funcname(arg, nth_line_cb, cb_data,
lines, anchor, begin, end,
path, istate);
if (!arg || *arg)
return -1;
return 0;
@ -275,10 +279,12 @@ int parse_range_arg(const char *arg, nth_line_fn_t nth_line_cb,
return 0;
}
const char *skip_range_arg(const char *arg)
const char *skip_range_arg(const char *arg, struct index_state *istate)
{
if (*arg == ':' || (*arg == '^' && *(arg + 1) == ':'))
return parse_range_funcname(arg, NULL, NULL, 0, 0, NULL, NULL, NULL);
return parse_range_funcname(arg, NULL, NULL,
0, 0, NULL, NULL,
NULL, istate);
arg = parse_loc(arg, NULL, NULL, 0, -1, NULL);

View File

@ -1,6 +1,8 @@
#ifndef LINE_RANGE_H
#define LINE_RANGE_H
struct index_state;
/*
* Parse one item in an -L begin,end option w.r.t. the notional file
* object 'cb_data' consisting of 'lines' lines.
@ -23,7 +25,7 @@ int parse_range_arg(const char *arg,
nth_line_fn_t nth_line_cb,
void *cb_data, long lines, long anchor,
long *begin, long *end,
const char *path);
const char *path, struct index_state *istate);
/*
* Scan past a range argument that could be parsed by
@ -34,6 +36,6 @@ int parse_range_arg(const char *arg,
* NULL in case the argument is obviously malformed.
*/
const char *skip_range_arg(const char *arg);
const char *skip_range_arg(const char *arg, struct index_state *istate);
#endif /* LINE_RANGE_H */

View File

@ -196,7 +196,7 @@ static void mark_edge_parents_uninteresting(struct commit *commit,
struct commit *parent = parents->item;
if (!(parent->object.flags & UNINTERESTING))
continue;
mark_tree_uninteresting(get_commit_tree(parent));
mark_tree_uninteresting(revs->repo, get_commit_tree(parent));
if (revs->edge_hint && !(parent->object.flags & SHOWN)) {
parent->object.flags |= SHOWN;
show_edge(parent);
@ -213,7 +213,8 @@ void mark_edges_uninteresting(struct rev_info *revs, show_edge_fn show_edge)
struct commit *commit = list->item;
if (commit->object.flags & UNINTERESTING) {
mark_tree_uninteresting(get_commit_tree(commit));
mark_tree_uninteresting(revs->repo,
get_commit_tree(commit));
if (revs->edge_hint_aggressive && !(commit->object.flags & SHOWN)) {
commit->object.flags |= SHOWN;
show_edge(commit);
@ -228,7 +229,8 @@ void mark_edges_uninteresting(struct rev_info *revs, show_edge_fn show_edge)
struct commit *commit = (struct commit *)obj;
if (obj->type != OBJ_COMMIT || !(obj->flags & UNINTERESTING))
continue;
mark_tree_uninteresting(get_commit_tree(commit));
mark_tree_uninteresting(revs->repo,
get_commit_tree(commit));
if (!(obj->flags & SHOWN)) {
obj->flags |= SHOWN;
show_edge(commit);

View File

@ -336,10 +336,10 @@ static const struct ll_merge_driver *find_ll_merge_driver(const char *merge_attr
return &ll_merge_drv[LL_TEXT_MERGE];
}
static void normalize_file(mmfile_t *mm, const char *path)
static void normalize_file(mmfile_t *mm, const char *path, struct index_state *istate)
{
struct strbuf strbuf = STRBUF_INIT;
if (renormalize_buffer(&the_index, path, mm->ptr, mm->size, &strbuf)) {
if (renormalize_buffer(istate, path, mm->ptr, mm->size, &strbuf)) {
free(mm->ptr);
mm->size = strbuf.len;
mm->ptr = strbuf_detach(&strbuf, NULL);
@ -351,6 +351,7 @@ int ll_merge(mmbuffer_t *result_buf,
mmfile_t *ancestor, const char *ancestor_label,
mmfile_t *ours, const char *our_label,
mmfile_t *theirs, const char *their_label,
struct index_state *istate,
const struct ll_merge_options *opts)
{
static struct attr_check *check;
@ -363,15 +364,15 @@ int ll_merge(mmbuffer_t *result_buf,
opts = &default_opts;
if (opts->renormalize) {
normalize_file(ancestor, path);
normalize_file(ours, path);
normalize_file(theirs, path);
normalize_file(ancestor, path, istate);
normalize_file(ours, path, istate);
normalize_file(theirs, path, istate);
}
if (!check)
check = attr_check_initl("merge", "conflict-marker-size", NULL);
git_check_attr(&the_index, path, check);
git_check_attr(istate, path, check);
ll_driver_name = check->items[0].value;
if (check->items[1].value) {
marker_size = atoi(check->items[1].value);
@ -390,14 +391,14 @@ int ll_merge(mmbuffer_t *result_buf,
opts, marker_size);
}
int ll_merge_marker_size(const char *path)
int ll_merge_marker_size(struct index_state *istate, const char *path)
{
static struct attr_check *check;
int marker_size = DEFAULT_CONFLICT_MARKER_SIZE;
if (!check)
check = attr_check_initl("conflict-marker-size", NULL);
git_check_attr(&the_index, path, check);
git_check_attr(istate, path, check);
if (check->items[0].value) {
marker_size = atoi(check->items[0].value);
if (marker_size <= 0)

View File

@ -7,6 +7,8 @@
#include "xdiff/xdiff.h"
struct index_state;
struct ll_merge_options {
unsigned virtual_ancestor : 1;
unsigned variant : 2; /* favor ours, favor theirs, or union merge */
@ -19,8 +21,9 @@ int ll_merge(mmbuffer_t *result_buf,
mmfile_t *ancestor, const char *ancestor_label,
mmfile_t *ours, const char *our_label,
mmfile_t *theirs, const char *their_label,
struct index_state *istate,
const struct ll_merge_options *opts);
int ll_merge_marker_size(const char *path);
int ll_merge_marker_size(struct index_state *istate, const char *path);
#endif

View File

@ -29,7 +29,12 @@ static void free_mmfile(mmfile_t *f)
free(f->ptr);
}
static void *three_way_filemerge(const char *path, mmfile_t *base, mmfile_t *our, mmfile_t *their, unsigned long *size)
static void *three_way_filemerge(struct index_state *istate,
const char *path,
mmfile_t *base,
mmfile_t *our,
mmfile_t *their,
unsigned long *size)
{
int merge_status;
mmbuffer_t res;
@ -41,7 +46,8 @@ static void *three_way_filemerge(const char *path, mmfile_t *base, mmfile_t *our
* common ancestor.
*/
merge_status = ll_merge(&res, path, base, NULL,
our, ".our", their, ".their", NULL);
our, ".our", their, ".their",
istate, NULL);
if (merge_status < 0)
return NULL;
@ -49,7 +55,9 @@ static void *three_way_filemerge(const char *path, mmfile_t *base, mmfile_t *our
return res.ptr;
}
void *merge_blobs(const char *path, struct blob *base, struct blob *our, struct blob *their, unsigned long *size)
void *merge_blobs(struct index_state *istate, const char *path,
struct blob *base, struct blob *our,
struct blob *their, unsigned long *size)
{
void *res = NULL;
mmfile_t f1, f2, common;
@ -82,7 +90,7 @@ void *merge_blobs(const char *path, struct blob *base, struct blob *our, struct
common.ptr = xstrdup("");
common.size = 0;
}
res = three_way_filemerge(path, &common, &f1, &f2, size);
res = three_way_filemerge(istate, path, &common, &f1, &f2, size);
free_mmfile(&common);
out_free_f2_f1:
free_mmfile(&f2);

View File

@ -1,8 +1,11 @@
#ifndef MERGE_BLOBS_H
#define MERGE_BLOBS_H
#include "blob.h"
struct blob;
struct index_state;
extern void *merge_blobs(const char *, struct blob *, struct blob *, struct blob *, unsigned long *);
extern void *merge_blobs(struct index_state *, const char *,
struct blob *, struct blob *,
struct blob *, unsigned long *);
#endif /* MERGE_BLOBS_H */

View File

@ -1084,7 +1084,8 @@ static int merge_3way(struct merge_options *o,
read_mmblob(&src2, &b->oid);
merge_status = ll_merge(result_buf, a->path, &orig, base_name,
&src1, name1, &src2, name2, &ll_opts);
&src1, name1, &src2, name2,
&the_index, &ll_opts);
free(base_name);
free(name1);
@ -1115,7 +1116,7 @@ static int find_first_merges(struct object_array *result, const char *path,
/* get all revisions that merge commit a */
xsnprintf(merged_revision, sizeof(merged_revision), "^%s",
oid_to_hex(&a->object.oid));
init_revisions(&revs, NULL);
repo_init_revisions(the_repository, &revs, NULL);
rev_opts.submodule = path;
/* FIXME: can't handle linked worktrees in submodules yet */
revs.single_worktree = path != NULL;
@ -1756,7 +1757,7 @@ static struct diff_queue_struct *get_diffpairs(struct merge_options *o,
struct diff_queue_struct *ret;
struct diff_options opts;
diff_setup(&opts);
repo_diff_setup(the_repository, &opts);
opts.flags.recursive = 1;
opts.flags.rename_empty = 0;
opts.detect_rename = merge_detect_rename(o);

20
merge.c
View File

@ -14,7 +14,8 @@ static const char *merge_argument(struct commit *commit)
return oid_to_hex(commit ? &commit->object.oid : the_hash_algo->empty_tree);
}
int try_merge_command(const char *strategy, size_t xopts_nr,
int try_merge_command(struct repository *r,
const char *strategy, size_t xopts_nr,
const char **xopts, struct commit_list *common,
const char *head_arg, struct commit_list *remotes)
{
@ -35,15 +36,16 @@ int try_merge_command(const char *strategy, size_t xopts_nr,
ret = run_command_v_opt(args.argv, RUN_GIT_CMD);
argv_array_clear(&args);
discard_cache();
if (read_cache() < 0)
discard_index(r->index);
if (read_index(r->index) < 0)
die(_("failed to read the cache"));
resolve_undo_clear();
resolve_undo_clear_index(r->index);
return ret;
}
int checkout_fast_forward(const struct object_id *head,
int checkout_fast_forward(struct repository *r,
const struct object_id *head,
const struct object_id *remote,
int overwrite_ignore)
{
@ -54,7 +56,7 @@ int checkout_fast_forward(const struct object_id *head,
struct dir_struct dir;
struct lock_file lock_file = LOCK_INIT;
refresh_cache(REFRESH_QUIET);
refresh_index(r->index, REFRESH_QUIET, NULL, NULL, NULL);
if (hold_locked_index(&lock_file, LOCK_REPORT_ON_ERROR) < 0)
return -1;
@ -86,8 +88,8 @@ int checkout_fast_forward(const struct object_id *head,
}
opts.head_idx = 1;
opts.src_index = &the_index;
opts.dst_index = &the_index;
opts.src_index = r->index;
opts.dst_index = r->index;
opts.update = 1;
opts.verbose_update = 1;
opts.merge = 1;
@ -101,7 +103,7 @@ int checkout_fast_forward(const struct object_id *head,
}
clear_unpack_trees_porcelain(&opts);
if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
if (write_locked_index(r->index, &lock_file, COMMIT_LOCK))
return error(_("unable to write new index file"));
return 0;
}

View File

@ -127,7 +127,7 @@ static struct notes_merge_pair *diff_tree_remote(struct notes_merge_options *o,
trace_printf("\tdiff_tree_remote(base = %.7s, remote = %.7s)\n",
oid_to_hex(base), oid_to_hex(remote));
diff_setup(&opt);
repo_diff_setup(the_repository, &opt);
opt.flags.recursive = 1;
opt.output_format = DIFF_FORMAT_NO_OUTPUT;
diff_setup_done(&opt);
@ -190,7 +190,7 @@ static void diff_tree_local(struct notes_merge_options *o,
trace_printf("\tdiff_tree_local(len = %i, base = %.7s, local = %.7s)\n",
len, oid_to_hex(base), oid_to_hex(local));
diff_setup(&opt);
repo_diff_setup(the_repository, &opt);
opt.flags.recursive = 1;
opt.output_format = DIFF_FORMAT_NO_OUTPUT;
diff_setup_done(&opt);
@ -349,7 +349,8 @@ static int ll_merge_in_worktree(struct notes_merge_options *o,
read_mmblob(&remote, &p->remote);
status = ll_merge(&result_buf, oid_to_hex(&p->obj), &base, NULL,
&local, o->local_ref, &remote, o->remote_ref, NULL);
&local, o->local_ref, &remote, o->remote_ref,
&the_index, NULL);
free(base.ptr);
free(local.ptr);
@ -710,7 +711,7 @@ int notes_merge_commit(struct notes_merge_options *o,
/* write file as blob, and add to partial_tree */
if (stat(path.buf, &st))
die_errno("Failed to stat '%s'", path.buf);
if (index_path(&blob_oid, path.buf, &st, HASH_WRITE_OBJECT))
if (index_path(&the_index, &blob_oid, path.buf, &st, HASH_WRITE_OBJECT))
die("Failed to write blob object from '%s'", path.buf);
if (add_note(partial_tree, &obj_oid, &blob_oid, NULL))
die("Failed to add resolved note '%s' to notes tree",

View File

@ -262,7 +262,7 @@ void bitmap_writer_build(struct packing_data *to_pack)
if (writer.show_progress)
writer.progress = start_progress("Building bitmaps", writer.selected_nr);
init_revisions(&revs, NULL);
repo_init_revisions(the_repository, &revs, NULL);
revs.tag_objects = 1;
revs.tree_objects = 1;
revs.blob_objects = 1;

View File

@ -56,10 +56,10 @@ static int patch_id_neq(const void *cmpfn_data,
return !oideq(&a->patch_id, &b->patch_id);
}
int init_patch_ids(struct patch_ids *ids)
int init_patch_ids(struct repository *r, struct patch_ids *ids)
{
memset(ids, 0, sizeof(*ids));
diff_setup(&ids->diffopts);
repo_diff_setup(r, &ids->diffopts);
ids->diffopts.detect_rename = 0;
ids->diffopts.flags.recursive = 1;
diff_setup_done(&ids->diffopts);

View File

@ -6,6 +6,7 @@
struct commit;
struct object_id;
struct repository;
struct patch_id {
struct hashmap_entry ent;
@ -20,7 +21,7 @@ struct patch_ids {
int commit_patch_id(struct commit *commit, struct diff_options *options,
struct object_id *oid, int);
int init_patch_ids(struct patch_ids *);
int init_patch_ids(struct repository *, struct patch_ids *);
int free_patch_ids(struct patch_ids *);
struct patch_id *add_commit_patch_id(struct commit *, struct patch_ids *);
struct patch_id *has_commit_patch_id(struct commit *, struct patch_ids *);

View File

@ -205,14 +205,16 @@ void fill_stat_cache_info(struct cache_entry *ce, struct stat *st)
}
}
static int ce_compare_data(const struct cache_entry *ce, struct stat *st)
static int ce_compare_data(struct index_state *istate,
const struct cache_entry *ce,
struct stat *st)
{
int match = -1;
int fd = git_open_cloexec(ce->name, O_RDONLY);
if (fd >= 0) {
struct object_id oid;
if (!index_fd(&oid, fd, st, OBJ_BLOB, ce->name, 0))
if (!index_fd(istate, &oid, fd, st, OBJ_BLOB, ce->name, 0))
match = !oideq(&oid, &ce->oid);
/* index_fd() closed the file descriptor already */
}
@ -257,11 +259,13 @@ static int ce_compare_gitlink(const struct cache_entry *ce)
return !oideq(&oid, &ce->oid);
}
static int ce_modified_check_fs(const struct cache_entry *ce, struct stat *st)
static int ce_modified_check_fs(struct index_state *istate,
const struct cache_entry *ce,
struct stat *st)
{
switch (st->st_mode & S_IFMT) {
case S_IFREG:
if (ce_compare_data(ce, st))
if (ce_compare_data(istate, ce, st))
return DATA_CHANGED;
break;
case S_IFLNK:
@ -407,7 +411,7 @@ int ie_match_stat(struct index_state *istate,
if (assume_racy_is_modified)
changed |= DATA_CHANGED;
else
changed |= ce_modified_check_fs(ce, st);
changed |= ce_modified_check_fs(istate, ce, st);
}
return changed;
@ -447,7 +451,7 @@ int ie_modified(struct index_state *istate,
(S_ISGITLINK(ce->ce_mode) || ce->ce_stat_data.sd_size != 0))
return changed;
changed_fs = ce_modified_check_fs(ce, st);
changed_fs = ce_modified_check_fs(istate, ce, st);
if (changed_fs)
return changed | changed_fs;
return 0;
@ -753,7 +757,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
}
}
if (!intent_only) {
if (index_path(&ce->oid, path, st, newflags)) {
if (index_path(istate, &ce->oid, path, st, newflags)) {
discard_cache_entry(ce);
return error("unable to index file %s", path);
}
@ -823,7 +827,7 @@ struct cache_entry *make_cache_entry(struct index_state *istate,
ce->ce_namelen = len;
ce->ce_mode = create_ce_mode(mode);
ret = refresh_cache_entry(&the_index, ce, refresh_options);
ret = refresh_cache_entry(istate, ce, refresh_options);
if (ret != ce)
discard_cache_entry(ce);
return ret;
@ -1493,7 +1497,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(&the_index, ce, pathspec, seen))
if (pathspec && !ce_path_match(istate, ce, pathspec, seen))
filtered = 1;
if (ce_stage(ce)) {
@ -2123,7 +2127,7 @@ int unmerged_index(const struct index_state *istate)
return 0;
}
int index_has_changes(const struct index_state *istate,
int index_has_changes(struct index_state *istate,
struct tree *tree,
struct strbuf *sb)
{
@ -2138,7 +2142,7 @@ int index_has_changes(const struct index_state *istate,
if (tree || !get_oid_tree("HEAD", &cmp)) {
struct diff_options opt;
diff_setup(&opt);
repo_diff_setup(the_repository, &opt);
opt.flags.exit_with_status = 1;
if (!sb)
opt.flags.quick = 1;
@ -2231,7 +2235,8 @@ static int ce_flush(git_hash_ctx *context, int fd, unsigned char *hash)
return (write_in_full(fd, write_buffer, left) < 0) ? -1 : 0;
}
static void ce_smudge_racily_clean_entry(struct cache_entry *ce)
static void ce_smudge_racily_clean_entry(struct index_state *istate,
struct cache_entry *ce)
{
/*
* The only thing we care about in this function is to smudge the
@ -2250,7 +2255,7 @@ static void ce_smudge_racily_clean_entry(struct cache_entry *ce)
return;
if (ce_match_stat_basic(ce, &st))
return;
if (ce_modified_check_fs(ce, &st)) {
if (ce_modified_check_fs(istate, ce, &st)) {
/* This is "racily clean"; smudge it. Note that this
* is a tricky code. At first glance, it may appear
* that it can break with this sequence:
@ -2495,7 +2500,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
if (ce->ce_flags & CE_REMOVE)
continue;
if (!ce_uptodate(ce) && is_racy_timestamp(istate, ce))
ce_smudge_racily_clean_entry(ce);
ce_smudge_racily_clean_entry(istate, ce);
if (is_null_oid(&ce->oid)) {
static const char msg[] = "cache entry has null sha1: %s";
static int allow = -1;

View File

@ -2010,7 +2010,7 @@ static void do_merge_filter(struct ref_filter_cbdata *ref_cbdata)
struct ref_array *array = ref_cbdata->array;
struct commit **to_clear = xcalloc(sizeof(struct commit *), array->nr);
init_revisions(&revs, NULL);
repo_init_revisions(the_repository, &revs, NULL);
for (i = 0; i < array->nr; i++) {
struct ref_array_item *item = array->items[i];

View File

@ -1855,7 +1855,7 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs,
oid_to_hex(&theirs->object.oid));
argv_array_push(&argv, "--");
init_revisions(&revs, NULL);
repo_init_revisions(the_repository, &revs, NULL);
setup_revisions(argv.argc, argv.argv, &revs, NULL);
if (prepare_revision_walk(&revs))
die("revision walk setup failed");

121
rerere.c
View File

@ -462,11 +462,12 @@ static int handle_path(unsigned char *sha1, struct rerere_io *io, int marker_siz
* Scan the path for conflicts, do the "handle_path()" thing above, and
* return the number of conflict hunks found.
*/
static int handle_file(const char *path, unsigned char *sha1, const char *output)
static int handle_file(struct index_state *istate, const char *path,
unsigned char *sha1, const char *output)
{
int has_conflicts = 0;
struct rerere_io_file io;
int marker_size = ll_merge_marker_size(path);
int marker_size = ll_merge_marker_size(istate, path);
memset(&io, 0, sizeof(io));
io.io.getline = rerere_file_getline;
@ -511,9 +512,9 @@ static int handle_file(const char *path, unsigned char *sha1, const char *output
* stages we have already looked at in this invocation of this
* function.
*/
static int check_one_conflict(int i, int *type)
static int check_one_conflict(struct index_state *istate, int i, int *type)
{
const struct cache_entry *e = active_cache[i];
const struct cache_entry *e = istate->cache[i];
if (!ce_stage(e)) {
*type = RESOLVED;
@ -521,13 +522,13 @@ static int check_one_conflict(int i, int *type)
}
*type = PUNTED;
while (i < active_nr && ce_stage(active_cache[i]) == 1)
while (i < istate->cache_nr && ce_stage(istate->cache[i]) == 1)
i++;
/* Only handle regular files with both stages #2 and #3 */
if (i + 1 < active_nr) {
const struct cache_entry *e2 = active_cache[i];
const struct cache_entry *e3 = active_cache[i + 1];
if (i + 1 < istate->cache_nr) {
const struct cache_entry *e2 = istate->cache[i];
const struct cache_entry *e3 = istate->cache[i + 1];
if (ce_stage(e2) == 2 &&
ce_stage(e3) == 3 &&
ce_same_name(e, e3) &&
@ -537,7 +538,7 @@ static int check_one_conflict(int i, int *type)
}
/* Skip the entries with the same name */
while (i < active_nr && ce_same_name(e, active_cache[i]))
while (i < istate->cache_nr && ce_same_name(e, istate->cache[i]))
i++;
return i;
}
@ -553,16 +554,17 @@ static int check_one_conflict(int i, int *type)
* are identical to the previous round, might want to be handled,
* though.
*/
static int find_conflict(struct string_list *conflict)
static int find_conflict(struct repository *r, struct string_list *conflict)
{
int i;
if (read_cache() < 0)
if (read_index(r->index) < 0)
return error(_("index file corrupt"));
for (i = 0; i < active_nr;) {
for (i = 0; i < r->index->cache_nr;) {
int conflict_type;
const struct cache_entry *e = active_cache[i];
i = check_one_conflict(i, &conflict_type);
const struct cache_entry *e = r->index->cache[i];
i = check_one_conflict(r->index, i, &conflict_type);
if (conflict_type == THREE_STAGED)
string_list_insert(conflict, (const char *)e->name);
}
@ -584,18 +586,19 @@ static int find_conflict(struct string_list *conflict)
* NEEDSWORK: we may want to fix the caller that implements "rerere
* remaining" to do this without abusing merge_rr.
*/
int rerere_remaining(struct string_list *merge_rr)
int rerere_remaining(struct repository *r, struct string_list *merge_rr)
{
int i;
if (setup_rerere(merge_rr, RERERE_READONLY))
return 0;
if (read_cache() < 0)
if (read_index(r->index) < 0)
return error(_("index file corrupt"));
for (i = 0; i < active_nr;) {
for (i = 0; i < r->index->cache_nr;) {
int conflict_type;
const struct cache_entry *e = active_cache[i];
i = check_one_conflict(i, &conflict_type);
const struct cache_entry *e = r->index->cache[i];
i = check_one_conflict(r->index, i, &conflict_type);
if (conflict_type == PUNTED)
string_list_insert(merge_rr, (const char *)e->name);
else if (conflict_type == RESOLVED) {
@ -615,7 +618,8 @@ int rerere_remaining(struct string_list *merge_rr)
* if that recorded conflict resolves cleanly what we
* got in the "cur".
*/
static int try_merge(const struct rerere_id *id, const char *path,
static int try_merge(struct index_state *istate,
const struct rerere_id *id, const char *path,
mmfile_t *cur, mmbuffer_t *result)
{
int ret;
@ -629,7 +633,8 @@ static int try_merge(const struct rerere_id *id, const char *path,
* A three-way merge. Note that this honors user-customizable
* low-level merge driver settings.
*/
ret = ll_merge(result, path, &base, NULL, cur, "", &other, "", NULL);
ret = ll_merge(result, path, &base, NULL, cur, "", &other, "",
istate, NULL);
free(base.ptr);
free(other.ptr);
@ -647,7 +652,7 @@ static int try_merge(const struct rerere_id *id, const char *path,
* Returns 0 for successful replay of recorded resolution, or non-zero
* for failure.
*/
static int merge(const struct rerere_id *id, const char *path)
static int merge(struct index_state *istate, const struct rerere_id *id, const char *path)
{
FILE *f;
int ret;
@ -658,13 +663,13 @@ static int merge(const struct rerere_id *id, const char *path)
* Normalize the conflicts in path and write it out to
* "thisimage" temporary file.
*/
if ((handle_file(path, NULL, rerere_path(id, "thisimage")) < 0) ||
if ((handle_file(istate, path, NULL, rerere_path(id, "thisimage")) < 0) ||
read_mmfile(&cur, rerere_path(id, "thisimage"))) {
ret = 1;
goto out;
}
ret = try_merge(id, path, &cur, &result);
ret = try_merge(istate, id, path, &cur, &result);
if (ret)
goto out;
@ -692,7 +697,7 @@ static int merge(const struct rerere_id *id, const char *path)
return ret;
}
static void update_paths(struct string_list *update)
static void update_paths(struct repository *r, struct string_list *update)
{
struct lock_file index_lock = LOCK_INIT;
int i;
@ -701,13 +706,13 @@ static void update_paths(struct string_list *update)
for (i = 0; i < update->nr; i++) {
struct string_list_item *item = &update->items[i];
if (add_file_to_cache(item->string, 0))
if (add_file_to_index(r->index, item->string, 0))
exit(128);
fprintf_ln(stderr, _("Staged '%s' using previous resolution."),
item->string);
}
if (write_locked_index(&the_index, &index_lock,
if (write_locked_index(r->index, &index_lock,
COMMIT_LOCK | SKIP_IF_UNCHANGED))
die(_("unable to write new index file"));
}
@ -726,7 +731,8 @@ static void remove_variant(struct rerere_id *id)
* only have the preimage for that conflict, in which case the result
* needs to be recorded as a resolution in a postimage file.
*/
static void do_rerere_one_path(struct string_list_item *rr_item,
static void do_rerere_one_path(struct index_state *istate,
struct string_list_item *rr_item,
struct string_list *update)
{
const char *path = rr_item->string;
@ -738,7 +744,7 @@ static void do_rerere_one_path(struct string_list_item *rr_item,
/* Has the user resolved it already? */
if (variant >= 0) {
if (!handle_file(path, NULL, NULL)) {
if (!handle_file(istate, path, NULL, NULL)) {
copy_file(rerere_path(id, "postimage"), path, 0666);
id->collection->status[variant] |= RR_HAS_POSTIMAGE;
fprintf_ln(stderr, _("Recorded resolution for '%s'."), path);
@ -762,7 +768,7 @@ static void do_rerere_one_path(struct string_list_item *rr_item,
continue;
vid.variant = variant;
if (merge(&vid, path))
if (merge(istate, &vid, path))
continue; /* failed to replay */
/*
@ -787,7 +793,7 @@ static void do_rerere_one_path(struct string_list_item *rr_item,
assign_variant(id);
variant = id->variant;
handle_file(path, NULL, rerere_path(id, "preimage"));
handle_file(istate, path, NULL, rerere_path(id, "preimage"));
if (id->collection->status[variant] & RR_HAS_POSTIMAGE) {
const char *path = rerere_path(id, "postimage");
if (unlink(path))
@ -798,13 +804,14 @@ static void do_rerere_one_path(struct string_list_item *rr_item,
fprintf_ln(stderr, _("Recorded preimage for '%s'"), path);
}
static int do_plain_rerere(struct string_list *rr, int fd)
static int do_plain_rerere(struct repository *r,
struct string_list *rr, int fd)
{
struct string_list conflict = STRING_LIST_INIT_DUP;
struct string_list update = STRING_LIST_INIT_DUP;
int i;
find_conflict(&conflict);
find_conflict(r, &conflict);
/*
* MERGE_RR records paths with conflicts immediately after
@ -823,7 +830,7 @@ static int do_plain_rerere(struct string_list *rr, int fd)
* conflict ID. No need to write anything out
* yet.
*/
ret = handle_file(path, sha1, NULL);
ret = handle_file(r->index, path, sha1, NULL);
if (ret != 0 && string_list_has_string(rr, path)) {
remove_variant(string_list_lookup(rr, path)->util);
string_list_remove(rr, path, 1);
@ -839,10 +846,10 @@ static int do_plain_rerere(struct string_list *rr, int fd)
}
for (i = 0; i < rr->nr; i++)
do_rerere_one_path(&rr->items[i], &update);
do_rerere_one_path(r->index, &rr->items[i], &update);
if (update.nr)
update_paths(&update);
update_paths(r, &update);
return write_rr(rr, fd);
}
@ -897,7 +904,7 @@ int setup_rerere(struct string_list *merge_rr, int flags)
* perform mergy operations, possibly leaving conflicted index entries
* and working tree files.
*/
int rerere(int flags)
int repo_rerere(struct repository *r, int flags)
{
struct string_list merge_rr = STRING_LIST_INIT_DUP;
int fd, status;
@ -905,7 +912,7 @@ int rerere(int flags)
fd = setup_rerere(&merge_rr, flags);
if (fd < 0)
return 0;
status = do_plain_rerere(&merge_rr, fd);
status = do_plain_rerere(r, &merge_rr, fd);
free_rerere_dirs();
return status;
}
@ -942,29 +949,30 @@ static int rerere_mem_getline(struct strbuf *sb, struct rerere_io *io_)
return 0;
}
static int handle_cache(const char *path, unsigned char *sha1, const char *output)
static int handle_cache(struct index_state *istate, const char *path,
unsigned char *sha1, const char *output)
{
mmfile_t mmfile[3] = {{NULL}};
mmbuffer_t result = {NULL, 0};
const struct cache_entry *ce;
int pos, len, i, has_conflicts;
struct rerere_io_mem io;
int marker_size = ll_merge_marker_size(path);
int marker_size = ll_merge_marker_size(istate, path);
/*
* Reproduce the conflicted merge in-core
*/
len = strlen(path);
pos = cache_name_pos(path, len);
pos = index_name_pos(istate, path, len);
if (0 <= pos)
return -1;
pos = -pos - 1;
while (pos < active_nr) {
while (pos < istate->cache_nr) {
enum object_type type;
unsigned long size;
ce = active_cache[pos++];
ce = istate->cache[pos++];
if (ce_namelen(ce) != len || memcmp(ce->name, path, len))
break;
i = ce_stage(ce) - 1;
@ -984,7 +992,8 @@ static int handle_cache(const char *path, unsigned char *sha1, const char *outpu
*/
ll_merge(&result, path, &mmfile[0], NULL,
&mmfile[1], "ours",
&mmfile[2], "theirs", NULL);
&mmfile[2], "theirs",
istate, NULL);
for (i = 0; i < 3; i++)
free(mmfile[i].ptr);
@ -1008,7 +1017,9 @@ static int handle_cache(const char *path, unsigned char *sha1, const char *outpu
return has_conflicts;
}
static int rerere_forget_one_path(const char *path, struct string_list *rr)
static int rerere_forget_one_path(struct index_state *istate,
const char *path,
struct string_list *rr)
{
const char *filename;
struct rerere_id *id;
@ -1020,7 +1031,7 @@ static int rerere_forget_one_path(const char *path, struct string_list *rr)
* Recreate the original conflict from the stages in the
* index and compute the conflict ID
*/
ret = handle_cache(path, sha1, NULL);
ret = handle_cache(istate, path, sha1, NULL);
if (ret < 1)
return error(_("could not parse conflict hunks in '%s'"), path);
@ -1037,13 +1048,13 @@ static int rerere_forget_one_path(const char *path, struct string_list *rr)
if (!has_rerere_resolution(id))
continue;
handle_cache(path, sha1, rerere_path(id, "thisimage"));
handle_cache(istate, path, sha1, rerere_path(id, "thisimage"));
if (read_mmfile(&cur, rerere_path(id, "thisimage"))) {
free(cur.ptr);
error(_("failed to update conflicted state in '%s'"), path);
goto fail_exit;
}
cleanly_resolved = !try_merge(id, path, &cur, &result);
cleanly_resolved = !try_merge(istate, id, path, &cur, &result);
free(result.ptr);
free(cur.ptr);
if (cleanly_resolved)
@ -1069,7 +1080,7 @@ static int rerere_forget_one_path(const char *path, struct string_list *rr)
* conflict in the working tree, run us again to record
* the postimage.
*/
handle_cache(path, sha1, rerere_path(id, "preimage"));
handle_cache(istate, path, sha1, rerere_path(id, "preimage"));
fprintf_ln(stderr, _("Updated preimage for '%s'"), path);
/*
@ -1087,13 +1098,13 @@ static int rerere_forget_one_path(const char *path, struct string_list *rr)
return -1;
}
int rerere_forget(struct pathspec *pathspec)
int rerere_forget(struct repository *r, struct pathspec *pathspec)
{
int i, fd;
struct string_list conflict = STRING_LIST_INIT_DUP;
struct string_list merge_rr = STRING_LIST_INIT_DUP;
if (read_cache() < 0)
if (read_index(r->index) < 0)
return error(_("index file corrupt"));
fd = setup_rerere(&merge_rr, RERERE_NOAUTOUPDATE);
@ -1105,14 +1116,14 @@ int rerere_forget(struct pathspec *pathspec)
* recover the original conflicted state and then
* find the conflicted paths.
*/
unmerge_cache(pathspec);
find_conflict(&conflict);
unmerge_index(r->index, pathspec);
find_conflict(r, &conflict);
for (i = 0; i < conflict.nr; i++) {
struct string_list_item *it = &conflict.items[i];
if (!match_pathspec(&the_index, pathspec, it->string,
if (!match_pathspec(r->index, pathspec, it->string,
strlen(it->string), 0, NULL, 0))
continue;
rerere_forget_one_path(it->string, &merge_rr);
rerere_forget_one_path(r->index, it->string, &merge_rr);
}
return write_rr(&merge_rr, fd);
}

View File

@ -4,6 +4,7 @@
#include "string-list.h"
struct pathspec;
struct repository;
#define RERERE_AUTOUPDATE 01
#define RERERE_NOAUTOUPDATE 02
@ -23,7 +24,10 @@ struct rerere_id {
};
int setup_rerere(struct string_list *, int);
int rerere(int);
#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS
#define rerere(flags) repo_rerere(the_repository, flags)
#endif
int repo_rerere(struct repository *, int);
/*
* Given the conflict ID and the name of a "file" used for replaying
* the recorded resolution (e.g. "preimage", "postimage"), return the
@ -31,8 +35,8 @@ int rerere(int);
* return the path to the directory that houses these files.
*/
const char *rerere_path(const struct rerere_id *, const char *file);
int rerere_forget(struct pathspec *);
int rerere_remaining(struct string_list *);
int rerere_forget(struct repository *, struct pathspec *);
int rerere_remaining(struct repository *, struct string_list *);
void rerere_clear(struct string_list *);
void rerere_gc(struct string_list *);

View File

@ -52,7 +52,8 @@ static void mark_blob_uninteresting(struct blob *blob)
blob->object.flags |= UNINTERESTING;
}
static void mark_tree_contents_uninteresting(struct tree *tree)
static void mark_tree_contents_uninteresting(struct repository *r,
struct tree *tree)
{
struct tree_desc desc;
struct name_entry entry;
@ -64,10 +65,10 @@ static void mark_tree_contents_uninteresting(struct tree *tree)
while (tree_entry(&desc, &entry)) {
switch (object_type(entry.mode)) {
case OBJ_TREE:
mark_tree_uninteresting(lookup_tree(the_repository, entry.oid));
mark_tree_uninteresting(r, lookup_tree(r, entry.oid));
break;
case OBJ_BLOB:
mark_blob_uninteresting(lookup_blob(the_repository, entry.oid));
mark_blob_uninteresting(lookup_blob(r, entry.oid));
break;
default:
/* Subproject commit - not in this repository */
@ -82,7 +83,7 @@ static void mark_tree_contents_uninteresting(struct tree *tree)
free_tree_buffer(tree);
}
void mark_tree_uninteresting(struct tree *tree)
void mark_tree_uninteresting(struct repository *r, struct tree *tree)
{
struct object *obj;
@ -93,7 +94,7 @@ void mark_tree_uninteresting(struct tree *tree)
if (obj->flags & UNINTERESTING)
return;
obj->flags |= UNINTERESTING;
mark_tree_contents_uninteresting(tree);
mark_tree_contents_uninteresting(r, tree);
}
struct commit_stack {
@ -199,7 +200,7 @@ void add_head_to_pending(struct rev_info *revs)
struct object *obj;
if (get_oid("HEAD", &oid))
return;
obj = parse_object(the_repository, &oid);
obj = parse_object(revs->repo, &oid);
if (!obj)
return;
add_pending_object(revs, obj, "HEAD");
@ -211,7 +212,7 @@ static struct object *get_reference(struct rev_info *revs, const char *name,
{
struct object *object;
object = parse_object(the_repository, oid);
object = parse_object(revs->repo, oid);
if (!object) {
if (revs->ignore_missing)
return object;
@ -248,7 +249,7 @@ static struct commit *handle_commit(struct rev_info *revs,
add_pending_object(revs, object, tag->tag);
if (!tag->tagged)
die("bad tag");
object = parse_object(the_repository, &tag->tagged->oid);
object = parse_object(revs->repo, &tag->tagged->oid);
if (!object) {
if (revs->ignore_missing_links || (flags & UNINTERESTING))
return NULL;
@ -298,7 +299,7 @@ static struct commit *handle_commit(struct rev_info *revs,
if (!revs->tree_objects)
return NULL;
if (flags & UNINTERESTING) {
mark_tree_contents_uninteresting(tree);
mark_tree_contents_uninteresting(revs->repo, tree);
return NULL;
}
add_pending_object_with_path(revs, object, name, mode, path);
@ -878,7 +879,7 @@ static void cherry_pick_list(struct commit_list *list, struct rev_info *revs)
return;
left_first = left_count < right_count;
init_patch_ids(&ids);
init_patch_ids(revs->repo, &ids);
ids.diffopts.pathspec = revs->diffopt.pathspec;
/* Compute patch-ids for one side */
@ -1254,7 +1255,7 @@ static void handle_one_reflog_commit(struct object_id *oid, void *cb_data)
{
struct all_refs_cb *cb = cb_data;
if (!is_null_oid(oid)) {
struct object *o = parse_object(the_repository, oid);
struct object *o = parse_object(cb->all_revs->repo, oid);
if (o) {
o->flags |= cb->all_flags;
/* ??? CMDLINEFLAGS ??? */
@ -1313,7 +1314,7 @@ void add_reflogs_to_pending(struct rev_info *revs, unsigned flags)
cb.all_revs = revs;
cb.all_flags = flags;
cb.refs = get_main_ref_store(the_repository);
cb.refs = get_main_ref_store(revs->repo);
for_each_reflog(handle_one_reflog, &cb);
if (!revs->single_worktree)
@ -1327,7 +1328,7 @@ static void add_cache_tree(struct cache_tree *it, struct rev_info *revs,
int i;
if (it->entry_count >= 0) {
struct tree *tree = lookup_tree(the_repository, &it->oid);
struct tree *tree = lookup_tree(revs->repo, &it->oid);
add_pending_object_with_path(revs, &tree->object, "",
040000, path->buf);
}
@ -1353,7 +1354,7 @@ static void do_add_index_objects_to_pending(struct rev_info *revs,
if (S_ISGITLINK(ce->ce_mode))
continue;
blob = lookup_blob(the_repository, &ce->oid);
blob = lookup_blob(revs->repo, &ce->oid);
if (!blob)
die("unable to add index blob to traversal");
add_pending_object_with_path(revs, &blob->object, "",
@ -1371,8 +1372,8 @@ void add_index_objects_to_pending(struct rev_info *revs, unsigned int flags)
{
struct worktree **worktrees, **p;
read_cache();
do_add_index_objects_to_pending(revs, &the_index);
read_index(revs->repo->index);
do_add_index_objects_to_pending(revs, revs->repo->index);
if (revs->single_worktree)
return;
@ -1440,10 +1441,13 @@ static int add_parents_only(struct rev_info *revs, const char *arg_, int flags,
return 1;
}
void init_revisions(struct rev_info *revs, const char *prefix)
void repo_init_revisions(struct repository *r,
struct rev_info *revs,
const char *prefix)
{
memset(revs, 0, sizeof(*revs));
revs->repo = r;
revs->abbrev = DEFAULT_ABBREV;
revs->ignore_merges = 1;
revs->simplify_history = 1;
@ -1465,11 +1469,11 @@ void init_revisions(struct rev_info *revs, const char *prefix)
revs->commit_format = CMIT_FMT_DEFAULT;
revs->expand_tabs_in_log_default = 8;
init_grep_defaults();
grep_init(&revs->grep_filter, prefix);
init_grep_defaults(revs->repo);
grep_init(&revs->grep_filter, revs->repo, prefix);
revs->grep_filter.status_only = 1;
diff_setup(&revs->diffopt);
repo_diff_setup(revs->repo, &revs->diffopt);
if (prefix && !revs->diffopt.prefix) {
revs->diffopt.prefix = prefix;
revs->diffopt.prefix_length = strlen(prefix);
@ -1497,6 +1501,7 @@ static void prepare_show_merge(struct rev_info *revs)
struct object_id oid;
const char **prune = NULL;
int i, prune_num = 1; /* counting terminating NULL */
struct index_state *istate = revs->repo->index;
if (get_oid("HEAD", &oid))
die("--merge without HEAD?");
@ -1512,20 +1517,20 @@ static void prepare_show_merge(struct rev_info *revs)
free_commit_list(bases);
head->object.flags |= SYMMETRIC_LEFT;
if (!active_nr)
read_cache();
for (i = 0; i < active_nr; i++) {
const struct cache_entry *ce = active_cache[i];
if (!istate->cache_nr)
read_index(istate);
for (i = 0; i < istate->cache_nr; i++) {
const struct cache_entry *ce = istate->cache[i];
if (!ce_stage(ce))
continue;
if (ce_path_match(&the_index, ce, &revs->prune_data, NULL)) {
if (ce_path_match(istate, ce, &revs->prune_data, NULL)) {
prune_num++;
REALLOC_ARRAY(prune, prune_num);
prune[prune_num-2] = ce->name;
prune[prune_num-1] = NULL;
}
while ((i+1 < active_nr) &&
ce_same_name(ce, active_cache[i+1]))
while ((i+1 < istate->cache_nr) &&
ce_same_name(ce, istate->cache[i+1]))
i++;
}
clear_pathspec(&revs->prune_data);
@ -1582,8 +1587,8 @@ static int handle_dotdot_1(const char *arg, char *dotdot,
*dotdot = '\0';
}
a_obj = parse_object(the_repository, &a_oid);
b_obj = parse_object(the_repository, &b_oid);
a_obj = parse_object(revs->repo, &a_oid);
b_obj = parse_object(revs->repo, &b_oid);
if (!a_obj || !b_obj)
return dotdot_missing(arg, dotdot, revs, symmetric);
@ -1596,8 +1601,8 @@ static int handle_dotdot_1(const char *arg, char *dotdot,
struct commit *a, *b;
struct commit_list *exclude;
a = lookup_commit_reference(the_repository, &a_obj->oid);
b = lookup_commit_reference(the_repository, &b_obj->oid);
a = lookup_commit_reference(revs->repo, &a_obj->oid);
b = lookup_commit_reference(revs->repo, &b_obj->oid);
if (!a || !b)
return dotdot_missing(arg, dotdot, revs, symmetric);
@ -2205,7 +2210,7 @@ static int handle_revision_pseudo_opt(const char *submodule,
BUG("--single-worktree cannot be used together with submodule");
refs = get_submodule_ref_store(submodule);
} else
refs = get_main_ref_store(the_repository);
refs = get_main_ref_store(revs->repo);
/*
* NOTE!
@ -2885,9 +2890,10 @@ void reset_revision_walk(void)
static int mark_uninteresting(const struct object_id *oid,
struct packed_git *pack,
uint32_t pos,
void *unused)
void *cb)
{
struct object *o = parse_object(the_repository, oid);
struct rev_info *revs = cb;
struct object *o = parse_object(revs->repo, oid);
o->flags |= UNINTERESTING | SEEN;
return 0;
}
@ -2920,7 +2926,7 @@ int prepare_revision_walk(struct rev_info *revs)
revs->treesame.name = "treesame";
if (revs->exclude_promisor_objects) {
for_each_packed_object(mark_uninteresting, NULL,
for_each_packed_object(mark_uninteresting, revs,
FOR_EACH_OBJECT_PROMISOR_ONLY);
}

View File

@ -28,8 +28,9 @@
#define DECORATE_SHORT_REFS 1
#define DECORATE_FULL_REFS 2
struct rev_info;
struct log_info;
struct repository;
struct rev_info;
struct string_list;
struct saved_parents;
define_shared_commit_slab(revision_sources, char *);
@ -60,6 +61,7 @@ struct rev_info {
/* Starting list */
struct commit_list *commits;
struct object_array pending;
struct repository *repo;
/* Parents of shown commits */
struct object_array boundary_commits;
@ -264,12 +266,17 @@ extern volatile show_early_output_fn_t show_early_output;
struct setup_revision_opt {
const char *def;
void (*tweak)(struct rev_info *, struct setup_revision_opt *);
const char *submodule;
const char *submodule; /* TODO: drop this and use rev_info->repo */
int assume_dashdash;
unsigned revarg_opt;
};
void init_revisions(struct rev_info *revs, const char *prefix);
#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS
#define init_revisions(revs, prefix) repo_init_revisions(the_repository, revs, prefix)
#endif
void repo_init_revisions(struct repository *r,
struct rev_info *revs,
const char *prefix);
int setup_revisions(int argc, const char **argv, struct rev_info *revs,
struct setup_revision_opt *);
void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx,
@ -289,7 +296,7 @@ void put_revision_mark(const struct rev_info *revs,
const struct commit *commit);
void mark_parents_uninteresting(struct commit *commit);
void mark_tree_uninteresting(struct tree *tree);
void mark_tree_uninteresting(struct repository *r, struct tree *tree);
void show_object_with_name(FILE *, struct object *, const char *);

View File

@ -474,8 +474,8 @@ static int fast_forward_to(const struct object_id *to, const struct object_id *f
struct strbuf sb = STRBUF_INIT;
struct strbuf err = STRBUF_INIT;
read_cache();
if (checkout_fast_forward(from, to, 1))
read_index(&the_index);
if (checkout_fast_forward(the_repository, from, to, 1))
return -1; /* the callee should have complained already */
strbuf_addf(&sb, _("%s: fast-forward"), _(action_name(opts)));
@ -1176,7 +1176,7 @@ void print_commit_summary(const char *prefix, const struct object_id *oid,
strbuf_release(&author_ident);
strbuf_release(&committer_ident);
init_revisions(&rev, prefix);
repo_init_revisions(the_repository, &rev, prefix);
setup_revisions(0, NULL, &rev, NULL);
rev.diff = 1;
@ -1831,7 +1831,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
commit_list_insert(base, &common);
commit_list_insert(next, &remotes);
res |= try_merge_command(opts->strategy,
res |= try_merge_command(the_repository, opts->strategy,
opts->xopts_nr, (const char **)opts->xopts,
common, oid_to_hex(&head), remotes);
free_commit_list(common);
@ -1860,7 +1860,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
: _("could not apply %s... %s"),
short_commit_name(commit), msg.subject);
print_advice(res == 1, opts);
rerere(opts->allow_rerere_auto);
repo_rerere(the_repository, opts->allow_rerere_auto);
goto leave;
}
@ -2599,7 +2599,7 @@ static int make_patch(struct commit *commit, struct replay_opts *opts)
strbuf_addf(&buf, "%s/patch", get_dir(opts));
memset(&log_tree_opt, 0, sizeof(log_tree_opt));
init_revisions(&log_tree_opt, NULL);
repo_init_revisions(the_repository, &log_tree_opt, NULL);
log_tree_opt.abbrev = 0;
log_tree_opt.diff = 1;
log_tree_opt.diffopt.output_format = DIFF_FORMAT_PATCH;
@ -3179,7 +3179,7 @@ static int do_merge(struct commit *commit, const char *arg, int arg_len,
rollback_lock_file(&lock);
if (ret)
rerere(opts->allow_rerere_auto);
repo_rerere(the_repository, opts->allow_rerere_auto);
else
/*
* In case of problems, we now want to return a positive
@ -3510,7 +3510,7 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
struct object_id orig, head;
memset(&log_tree_opt, 0, sizeof(log_tree_opt));
init_revisions(&log_tree_opt, NULL);
repo_init_revisions(the_repository, &log_tree_opt, NULL);
log_tree_opt.diff = 1;
log_tree_opt.diffopt.output_format =
DIFF_FORMAT_DIFFSTAT;
@ -4254,7 +4254,7 @@ int sequencer_make_script(FILE *out, int argc, const char **argv,
const char *insn = flags & TODO_LIST_ABBREVIATE_CMDS ? "p" : "pick";
int rebase_merges = flags & TODO_LIST_REBASE_MERGES;
init_revisions(&revs, NULL);
repo_init_revisions(the_repository, &revs, NULL);
revs.verbose_header = 1;
if (!rebase_merges)
revs.max_parents = 1;

View File

@ -1813,7 +1813,8 @@ static void check_tag(const void *buf, size_t size)
die(_("corrupt tag"));
}
static int index_mem(struct object_id *oid, void *buf, size_t size,
static int index_mem(struct index_state *istate,
struct object_id *oid, void *buf, size_t size,
enum object_type type,
const char *path, unsigned flags)
{
@ -1828,7 +1829,7 @@ static int index_mem(struct object_id *oid, void *buf, size_t size,
*/
if ((type == OBJ_BLOB) && path) {
struct strbuf nbuf = STRBUF_INIT;
if (convert_to_git(&the_index, path, buf, size, &nbuf,
if (convert_to_git(istate, path, buf, size, &nbuf,
get_conv_flags(flags))) {
buf = strbuf_detach(&nbuf, &size);
re_allocated = 1;
@ -1852,17 +1853,20 @@ static int index_mem(struct object_id *oid, void *buf, size_t size,
return ret;
}
static int index_stream_convert_blob(struct object_id *oid, int fd,
const char *path, unsigned flags)
static int index_stream_convert_blob(struct index_state *istate,
struct object_id *oid,
int fd,
const char *path,
unsigned flags)
{
int ret;
const int write_object = flags & HASH_WRITE_OBJECT;
struct strbuf sbuf = STRBUF_INIT;
assert(path);
assert(would_convert_to_git_filter_fd(&the_index, path));
assert(would_convert_to_git_filter_fd(istate, path));
convert_to_git_filter_fd(&the_index, path, fd, &sbuf,
convert_to_git_filter_fd(istate, path, fd, &sbuf,
get_conv_flags(flags));
if (write_object)
@ -1875,14 +1879,15 @@ static int index_stream_convert_blob(struct object_id *oid, int fd,
return ret;
}
static int index_pipe(struct object_id *oid, int fd, enum object_type type,
static int index_pipe(struct index_state *istate, struct object_id *oid,
int fd, enum object_type type,
const char *path, unsigned flags)
{
struct strbuf sbuf = STRBUF_INIT;
int ret;
if (strbuf_read(&sbuf, fd, 4096) >= 0)
ret = index_mem(oid, sbuf.buf, sbuf.len, type, path, flags);
ret = index_mem(istate, oid, sbuf.buf, sbuf.len, type, path, flags);
else
ret = -1;
strbuf_release(&sbuf);
@ -1891,14 +1896,15 @@ static int index_pipe(struct object_id *oid, int fd, enum object_type type,
#define SMALL_FILE_SIZE (32*1024)
static int index_core(struct object_id *oid, int fd, size_t size,
static int index_core(struct index_state *istate,
struct object_id *oid, int fd, size_t size,
enum object_type type, const char *path,
unsigned flags)
{
int ret;
if (!size) {
ret = index_mem(oid, "", size, type, path, flags);
ret = index_mem(istate, oid, "", size, type, path, flags);
} else if (size <= SMALL_FILE_SIZE) {
char *buf = xmalloc(size);
ssize_t read_result = read_in_full(fd, buf, size);
@ -1909,11 +1915,11 @@ static int index_core(struct object_id *oid, int fd, size_t size,
ret = error(_("short read while indexing %s"),
path ? path : "<unknown>");
else
ret = index_mem(oid, buf, size, type, path, flags);
ret = index_mem(istate, oid, buf, size, type, path, flags);
free(buf);
} else {
void *buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
ret = index_mem(oid, buf, size, type, path, flags);
ret = index_mem(istate, oid, buf, size, type, path, flags);
munmap(buf, size);
}
return ret;
@ -1941,7 +1947,8 @@ static int index_stream(struct object_id *oid, int fd, size_t size,
return index_bulk_checkin(oid, fd, size, type, path, flags);
}
int index_fd(struct object_id *oid, int fd, struct stat *st,
int index_fd(struct index_state *istate, struct object_id *oid,
int fd, struct stat *st,
enum object_type type, const char *path, unsigned flags)
{
int ret;
@ -1950,14 +1957,14 @@ 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(&the_index, path))
ret = index_stream_convert_blob(oid, fd, path, flags);
if (type == OBJ_BLOB && path && would_convert_to_git_filter_fd(istate, path))
ret = index_stream_convert_blob(istate, oid, fd, path, flags);
else if (!S_ISREG(st->st_mode))
ret = index_pipe(oid, fd, type, path, flags);
ret = index_pipe(istate, oid, fd, type, path, flags);
else if (st->st_size <= big_file_threshold || type != OBJ_BLOB ||
(path && would_convert_to_git(&the_index, path)))
ret = index_core(oid, fd, xsize_t(st->st_size), type, path,
flags);
(path && would_convert_to_git(istate, path)))
ret = index_core(istate, oid, fd, xsize_t(st->st_size),
type, path, flags);
else
ret = index_stream(oid, fd, xsize_t(st->st_size), type, path,
flags);
@ -1965,7 +1972,8 @@ int index_fd(struct object_id *oid, int fd, struct stat *st,
return ret;
}
int index_path(struct object_id *oid, const char *path, struct stat *st, unsigned flags)
int index_path(struct index_state *istate, struct object_id *oid,
const char *path, struct stat *st, unsigned flags)
{
int fd;
struct strbuf sb = STRBUF_INIT;
@ -1976,7 +1984,7 @@ int index_path(struct object_id *oid, const char *path, struct stat *st, unsigne
fd = open(path, O_RDONLY);
if (fd < 0)
return error_errno("open(\"%s\")", path);
if (index_fd(oid, fd, st, OBJ_BLOB, path, flags) < 0)
if (index_fd(istate, oid, fd, st, OBJ_BLOB, path, flags) < 0)
return error(_("%s: failed to insert into database"),
path);
break;

View File

@ -185,7 +185,7 @@ struct commit_list *get_shallow_commits_by_rev_list(int ac, const char **av,
is_repository_shallow(the_repository); /* make sure shallows are read */
init_revisions(&revs, NULL);
repo_init_revisions(the_repository, &revs, NULL);
save_commit_buffer = 0;
setup_revisions(ac, av, &revs, NULL);

View File

@ -428,7 +428,7 @@ static int prepare_submodule_summary(struct rev_info *rev, const char *path,
{
struct commit_list *list;
init_revisions(rev, NULL);
repo_init_revisions(the_repository, rev, NULL);
setup_revisions(0, NULL, rev, NULL);
rev->left_right = 1;
rev->first_parent_only = 1;
@ -766,13 +766,14 @@ static void collect_changed_submodules_cb(struct diff_queue_struct *q,
* have a corresponding 'struct oid_array' (in the 'util' field) which lists
* what the submodule pointers were updated to during the change.
*/
static void collect_changed_submodules(struct string_list *changed,
static void collect_changed_submodules(struct index_state *istate,
struct string_list *changed,
struct argv_array *argv)
{
struct rev_info rev;
const struct commit *commit;
init_revisions(&rev, NULL);
repo_init_revisions(the_repository, &rev, NULL);
setup_revisions(argv->argc, argv->argv, &rev, NULL);
if (prepare_revision_walk(&rev))
die("revision walk setup failed");
@ -783,7 +784,7 @@ static void collect_changed_submodules(struct string_list *changed,
data.changed = changed;
data.commit_oid = &commit->object.oid;
init_revisions(&diff_rev, NULL);
repo_init_revisions(the_repository, &diff_rev, NULL);
diff_rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
diff_rev.diffopt.format_callback = collect_changed_submodules_cb;
diff_rev.diffopt.format_callback_data = &data;
@ -930,8 +931,10 @@ static int submodule_needs_pushing(const char *path, struct oid_array *commits)
return 0;
}
int find_unpushed_submodules(struct oid_array *commits,
const char *remotes_name, struct string_list *needs_pushing)
int find_unpushed_submodules(struct index_state *istate,
struct oid_array *commits,
const char *remotes_name,
struct string_list *needs_pushing)
{
struct string_list submodules = STRING_LIST_INIT_DUP;
struct string_list_item *name;
@ -943,7 +946,7 @@ int find_unpushed_submodules(struct oid_array *commits,
argv_array_push(&argv, "--not");
argv_array_pushf(&argv, "--remotes=%s", remotes_name);
collect_changed_submodules(&submodules, &argv);
collect_changed_submodules(istate, &submodules, &argv);
for_each_string_list_item(name, &submodules) {
struct oid_array *commits = name->util;
@ -1044,7 +1047,8 @@ static void submodule_push_check(const char *path, const char *head,
die("process for submodule '%s' failed", path);
}
int push_unpushed_submodules(struct oid_array *commits,
int push_unpushed_submodules(struct index_state *istate,
struct oid_array *commits,
const struct remote *remote,
const struct refspec *rs,
const struct string_list *push_options,
@ -1053,7 +1057,8 @@ int push_unpushed_submodules(struct oid_array *commits,
int i, ret = 1;
struct string_list needs_pushing = STRING_LIST_INIT_DUP;
if (!find_unpushed_submodules(commits, remote->name, &needs_pushing))
if (!find_unpushed_submodules(istate, commits,
remote->name, &needs_pushing))
return 1;
/*
@ -1110,7 +1115,7 @@ void check_for_new_submodule_commits(struct object_id *oid)
oid_array_append(&ref_tips_after_fetch, oid);
}
static void calculate_changed_submodule_paths(void)
static void calculate_changed_submodule_paths(struct index_state *istate)
{
struct argv_array argv = ARGV_ARRAY_INIT;
struct string_list changed_submodules = STRING_LIST_INIT_DUP;
@ -1131,7 +1136,7 @@ static void calculate_changed_submodule_paths(void)
* Collect all submodules (whether checked out or not) for which new
* commits have been recorded upstream in "changed_submodule_names".
*/
collect_changed_submodules(&changed_submodules, &argv);
collect_changed_submodules(istate, &changed_submodules, &argv);
for_each_string_list_item(name, &changed_submodules) {
struct oid_array *commits = name->util;
@ -1158,7 +1163,8 @@ static void calculate_changed_submodule_paths(void)
initialized_fetch_ref_tips = 0;
}
int submodule_touches_in_range(struct object_id *excl_oid,
int submodule_touches_in_range(struct index_state *istate,
struct object_id *excl_oid,
struct object_id *incl_oid)
{
struct string_list subs = STRING_LIST_INIT_DUP;
@ -1176,7 +1182,7 @@ int submodule_touches_in_range(struct object_id *excl_oid,
argv_array_push(&args, oid_to_hex(excl_oid));
}
collect_changed_submodules(&subs, &args);
collect_changed_submodules(istate, &subs, &args);
ret = subs.nr;
argv_array_clear(&args);
@ -1346,7 +1352,7 @@ int fetch_populated_submodules(struct repository *r,
argv_array_push(&spf.args, "--recurse-submodules-default");
/* default value, "--submodule-prefix" and its value are added later */
calculate_changed_submodule_paths();
calculate_changed_submodule_paths(r->index);
run_processes_parallel(max_parallel_jobs,
get_next_submodule,
fetch_start_failure,

View File

@ -102,13 +102,16 @@ int add_submodule_odb(const char *path);
* Checks if there are submodule changes in a..b. If a is the null OID,
* checks b and all its ancestors instead.
*/
int submodule_touches_in_range(struct object_id *a,
int submodule_touches_in_range(struct index_state *istate,
struct object_id *a,
struct object_id *b);
int find_unpushed_submodules(struct oid_array *commits,
int find_unpushed_submodules(struct index_state *istate,
struct oid_array *commits,
const char *remotes_name,
struct string_list *needs_pushing);
struct refspec;
int push_unpushed_submodules(struct oid_array *commits,
int push_unpushed_submodules(struct index_state *istate,
struct oid_array *commits,
const struct remote *remote,
const struct refspec *rs,
const struct string_list *push_options,

View File

@ -32,7 +32,7 @@ static int run_revision_walk(void)
int argc = ARRAY_SIZE(argv) - 1;
int got_revision = 0;
init_revisions(&rev, NULL);
repo_init_revisions(the_repository, &rev, NULL);
setup_revisions(argc, argv, &rev, NULL);
if (prepare_revision_walk(&rev))
die("revision walk setup failed");

View File

@ -1139,7 +1139,8 @@ int transport_push(struct transport *transport,
oid_array_append(&commits,
&ref->new_oid);
if (!push_unpushed_submodules(&commits,
if (!push_unpushed_submodules(&the_index,
&commits,
transport->remote,
rs,
transport->push_options,
@ -1163,8 +1164,10 @@ int transport_push(struct transport *transport,
oid_array_append(&commits,
&ref->new_oid);
if (find_unpushed_submodules(&commits, transport->remote->name,
&needs_pushing)) {
if (find_unpushed_submodules(&the_index,
&commits,
transport->remote->name,
&needs_pushing)) {
oid_array_clear(&commits);
die_with_unpushed_submodules(&needs_pushing);
}

View File

@ -605,7 +605,7 @@ static void try_to_follow_renames(const struct object_id *old_oid,
choice = q->queue[0];
q->nr = 0;
diff_setup(&diff_opts);
repo_diff_setup(opt->repo, &diff_opts);
diff_opts.flags.recursive = 1;
diff_opts.flags.find_copies_harder = 1;
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;

View File

@ -270,7 +270,8 @@ struct userdiff_driver *userdiff_find_by_name(const char *name) {
return userdiff_find_by_namelen(name, len);
}
struct userdiff_driver *userdiff_find_by_path(const char *path)
struct userdiff_driver *userdiff_find_by_path(struct index_state *istate,
const char *path)
{
static struct attr_check *check;
@ -278,7 +279,7 @@ struct userdiff_driver *userdiff_find_by_path(const char *path)
check = attr_check_initl("diff", NULL);
if (!path)
return NULL;
git_check_attr(&the_index, path, check);
git_check_attr(istate, path, check);
if (ATTR_TRUE(check->items[0].value))
return &driver_true;

View File

@ -3,6 +3,8 @@
#include "notes-cache.h"
struct index_state;
struct userdiff_funcname {
const char *pattern;
int cflags;
@ -21,7 +23,8 @@ struct userdiff_driver {
int userdiff_config(const char *k, const char *v);
struct userdiff_driver *userdiff_find_by_name(const char *name);
struct userdiff_driver *userdiff_find_by_path(const char *path);
struct userdiff_driver *userdiff_find_by_path(struct index_state *istate,
const char *path);
/*
* Initialize any textconv-related fields in the driver and return it, or NULL

5
ws.c
View File

@ -3,7 +3,6 @@
*
* Copyright (c) 2007 Junio C Hamano
*/
#include "cache.h"
#include "attr.h"
@ -71,7 +70,7 @@ unsigned parse_whitespace_rule(const char *string)
return rule;
}
unsigned whitespace_rule(const char *pathname)
unsigned whitespace_rule(struct index_state *istate, const char *pathname)
{
static struct attr_check *attr_whitespace_rule;
const char *value;
@ -79,7 +78,7 @@ unsigned whitespace_rule(const char *pathname)
if (!attr_whitespace_rule)
attr_whitespace_rule = attr_check_initl("whitespace", NULL);
git_check_attr(&the_index, pathname, attr_whitespace_rule);
git_check_attr(istate, pathname, attr_whitespace_rule);
value = attr_whitespace_rule->items[0].value;
if (ATTR_TRUE(value)) {
/* true (whitespace) */

View File

@ -582,7 +582,7 @@ static void wt_status_collect_changes_worktree(struct wt_status *s)
{
struct rev_info rev;
init_revisions(&rev, NULL);
repo_init_revisions(the_repository, &rev, NULL);
setup_revisions(0, NULL, &rev, NULL);
rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
rev.diffopt.flags.dirty_submodules = 1;
@ -607,7 +607,7 @@ static void wt_status_collect_changes_index(struct wt_status *s)
struct rev_info rev;
struct setup_revision_opt opt;
init_revisions(&rev, NULL);
repo_init_revisions(the_repository, &rev, NULL);
memset(&opt, 0, sizeof(opt));
opt.def = s->is_initial ? empty_tree_oid_hex() : s->reference;
setup_revisions(0, NULL, &rev, &opt);
@ -982,7 +982,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s)
int dirty_submodules;
const char *c = color(WT_STATUS_HEADER, s);
init_revisions(&rev, NULL);
repo_init_revisions(the_repository, &rev, NULL);
rev.diffopt.flags.allow_textconv = 1;
rev.diffopt.ita_invisible_in_index = 1;
@ -2314,7 +2314,7 @@ int has_unstaged_changes(int ignore_submodules)
struct rev_info rev_info;
int result;
init_revisions(&rev_info, NULL);
repo_init_revisions(the_repository, &rev_info, NULL);
if (ignore_submodules) {
rev_info.diffopt.flags.ignore_submodules = 1;
rev_info.diffopt.flags.override_submodule_config = 1;
@ -2336,7 +2336,7 @@ int has_uncommitted_changes(int ignore_submodules)
if (is_cache_unborn())
return 0;
init_revisions(&rev_info, NULL);
repo_init_revisions(the_repository, &rev_info, NULL);
if (ignore_submodules)
rev_info.diffopt.flags.ignore_submodules = 1;
rev_info.diffopt.flags.quick = 1;