1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-05-04 03:06:13 +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 * Prepare `struct diff_options` to record the set of diff options, and
then call `diff_setup()` to initialize this structure. This sets up then call `repo_diff_setup()` to initialize this structure. This
the vanilla default. sets up the vanilla default.
* Fill in the options structure to specify desired output format, rename * Fill in the options structure to specify desired output format, rename
detection, etc. `diff_opt_parse()` can be used to parse options given detection, etc. `diff_opt_parse()` can be used to parse options given

View File

@ -15,9 +15,9 @@ revision list.
Functions 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` 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 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 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)) if (!use_patch(state, patch))
patch->ws_rule = 0; patch->ws_rule = 0;
else if (patch->new_name)
patch->ws_rule = whitespace_rule(state->repo->index,
patch->new_name);
else else
patch->ws_rule = whitespace_rule(patch->new_name patch->ws_rule = whitespace_rule(state->repo->index,
? patch->new_name patch->old_name);
: patch->old_name);
patchsize = parse_single_patch(state, patchsize = parse_single_patch(state,
buffer + offset + hdrsize, buffer + offset + hdrsize,
@ -3467,7 +3469,8 @@ static int load_preimage(struct apply_state *state,
return 0; return 0;
} }
static int three_way_merge(struct image *image, static int three_way_merge(struct apply_state *state,
struct image *image,
char *path, char *path,
const struct object_id *base, const struct object_id *base,
const struct object_id *ours, const struct object_id *ours,
@ -3483,7 +3486,9 @@ static int three_way_merge(struct image *image,
status = ll_merge(&result, path, status = ll_merge(&result, path,
&base_file, "base", &base_file, "base",
&our_file, "ours", &our_file, "ours",
&their_file, "theirs", NULL); &their_file, "theirs",
state->repo->index,
NULL);
free(base_file.ptr); free(base_file.ptr);
free(our_file.ptr); free(our_file.ptr);
free(their_file.ptr); free(their_file.ptr);
@ -3595,7 +3600,7 @@ static int try_threeway(struct apply_state *state,
clear_image(&tmp_image); clear_image(&tmp_image);
/* in-core three-way merge between post and our using pre as base */ /* 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); &pre_oid, &our_oid, &post_oid);
if (status < 0) { if (status < 0) {
if (state->apply_verbosity > verbosity_silent) 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); string_list_clear(&cpath, 0);
rerere(0); repo_rerere(state->repo, 0);
} }
return errs; 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) if (!driver)
driver = userdiff_find_by_name("default"); driver = userdiff_find_by_name("default");
if (driver->binary != -1) if (driver->binary != -1)
@ -352,7 +353,8 @@ static int write_zip_entry(struct archiver_args *args,
return error(_("cannot read %s"), return error(_("cannot read %s"),
oid_to_hex(oid)); oid_to_hex(oid));
crc = crc32(crc, buffer, size); 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); buffer, size);
out = buffer; out = buffer;
} }
@ -428,7 +430,8 @@ static int write_zip_entry(struct archiver_args *args,
break; break;
crc = crc32(crc, buf, readlen); crc = crc32(crc, buf, readlen);
if (is_binary == -1) 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); buf, readlen);
write_or_die(1, buf, readlen); write_or_die(1, buf, readlen);
} }
@ -460,7 +463,8 @@ static int write_zip_entry(struct archiver_args *args,
break; break;
crc = crc32(crc, buf, readlen); crc = crc32(crc, buf, readlen);
if (is_binary == -1) 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); buf, readlen);
zstream.next_in = buf; zstream.next_in = buf;

View File

@ -392,7 +392,7 @@ static void parse_treeish_arg(const char **argv,
if (get_oid(name, &oid)) if (get_oid(name, &oid))
die("Not a valid object name"); 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) { if (commit) {
commit_sha1 = commit->object.oid.hash; commit_sha1 = commit->object.oid.hash;
archive_time = commit->date; 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; struct argv_array rev_argv = ARGV_ARRAY_INIT;
int i; int i;
init_revisions(revs, prefix); repo_init_revisions(the_repository, revs, prefix);
revs->abbrev = 0; revs->abbrev = 0;
revs->commit_format = CMIT_FMT_UNSPECIFIED; 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; struct rev_info opt;
/* diff-tree init */ /* 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 */ git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
opt.abbrev = 0; opt.abbrev = 0;
opt.diff = 1; 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 *work_tree, const char *path)
{ {
struct commit_list *parents; struct commit_list *parents;
@ -102,15 +102,15 @@ static void verify_working_tree_path(struct repository *repo,
unsigned mode; unsigned mode;
if (!get_tree_entry(commit_oid, path, &blob_oid, &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; return;
} }
pos = index_name_pos(repo->index, path, strlen(path)); pos = index_name_pos(r->index, path, strlen(path));
if (pos >= 0) if (pos >= 0)
; /* path is in the index */ ; /* path is in the index */
else if (-1 - pos < repo->index->cache_nr && else if (-1 - pos < r->index->cache_nr &&
!strcmp(repo->index->cache[-1 - pos]->name, path)) !strcmp(r->index->cache[-1 - pos]->name, path))
; /* path is in the index, unmerged */ ; /* path is in the index, unmerged */
else else
die("no such path '%s' in HEAD", path); 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. * Prepare a dummy commit that represents the work tree (or staged) item.
* Note that annotating work tree item never works in the reverse. * 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, struct diff_options *opt,
const char *path, const char *path,
const char *contents_from) const char *contents_from)
@ -183,7 +183,7 @@ static struct commit *fake_working_tree_commit(struct repository *repo,
unsigned mode; unsigned mode;
struct strbuf msg = STRBUF_INIT; struct strbuf msg = STRBUF_INIT;
read_index(repo->index); read_index(r->index);
time(&now); time(&now);
commit = alloc_commit_node(the_repository); commit = alloc_commit_node(the_repository);
commit->object.parsed = 1; 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); parent_tail = append_parent(parent_tail, &head_oid);
append_merge_parents(parent_tail); append_merge_parents(parent_tail);
verify_working_tree_path(repo, commit, path); verify_working_tree_path(r, commit, path);
origin = make_origin(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) { switch (st.st_mode & S_IFMT) {
case S_IFREG: case S_IFREG:
if (opt->flags.allow_textconv && 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); strbuf_attach(&buf, buf_ptr, buf_len, buf_len + 1);
else if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size) else if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size)
die_errno("cannot open or read '%s'", read_from); 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) if (strbuf_read(&buf, 0, 0) < 0)
die_errno("failed to read from stdin"); 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.ptr = buf.buf;
origin->file.size = buf.len; origin->file.size = buf.len;
pretend_object_file(buf.buf, buf.len, OBJ_BLOB, &origin->blob_oid); 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 * bits; we are not going to write this index out -- we just
* want to run "diff-index --cached". * want to run "diff-index --cached".
*/ */
discard_index(repo->index); discard_index(r->index);
read_index(repo->index); read_index(r->index);
len = strlen(path); len = strlen(path);
if (!mode) { if (!mode) {
int pos = index_name_pos(repo->index, path, len); int pos = index_name_pos(r->index, path, len);
if (0 <= pos) if (0 <= pos)
mode = repo->index->cache[pos]->ce_mode; mode = r->index->cache[pos]->ce_mode;
else else
/* Let's not bother reading from HEAD tree */ /* Let's not bother reading from HEAD tree */
mode = S_IFREG | 0644; 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); oidcpy(&ce->oid, &origin->blob_oid);
memcpy(ce->name, path, len); memcpy(ce->name, path, len);
ce->ce_flags = create_ce_flags(0); ce->ce_flags = create_ce_flags(0);
ce->ce_namelen = len; ce->ce_namelen = len;
ce->ce_mode = create_ce_mode(mode); 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); 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; return commit;
} }
@ -318,7 +318,8 @@ static void fill_origin_blob(struct diff_options *opt,
(*num_read_blob)++; (*num_read_blob)++;
if (opt->flags.allow_textconv && 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 else
file->ptr = read_object_file(&o->blob_oid, &type, 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. * 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) struct blame_origin *origin)
{ {
if (!is_null_oid(&origin->blob_oid)) if (!is_null_oid(&origin->blob_oid))
return 0; return 0;
if (get_tree_entry(&origin->commit->object.oid, origin->path, &origin->blob_oid, &origin->mode)) if (get_tree_entry(&origin->commit->object.oid, origin->path, &origin->blob_oid, &origin->mode))
goto error_out; 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; goto error_out;
return 0; return 0;
error_out: 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 * We have an origin -- check if the same path exists in the
* parent and return an origin structure to represent it. * parent and return an origin structure to represent it.
*/ */
static struct blame_origin *find_origin(struct commit *parent, static struct blame_origin *find_origin(struct repository *r,
struct blame_origin *origin) struct commit *parent,
struct blame_origin *origin)
{ {
struct blame_origin *porigin; struct blame_origin *porigin;
struct diff_options diff_opts; 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 * and origin first. Most of the time they are the
* same and diff-tree is fairly efficient about this. * 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.flags.recursive = 1;
diff_opts.detect_rename = 0; diff_opts.detect_rename = 0;
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; 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 * We have an origin -- find the path that corresponds to it in its
* parent and return an origin structure to represent it. * parent and return an origin structure to represent it.
*/ */
static struct blame_origin *find_rename(struct commit *parent, static struct blame_origin *find_rename(struct repository *r,
struct blame_origin *origin) struct commit *parent,
struct blame_origin *origin)
{ {
struct blame_origin *porigin = NULL; struct blame_origin *porigin = NULL;
struct diff_options diff_opts; struct diff_options diff_opts;
int i; int i;
diff_setup(&diff_opts); repo_diff_setup(r, &diff_opts);
diff_opts.flags.recursive = 1; diff_opts.flags.recursive = 1;
diff_opts.detect_rename = DIFF_DETECT_RENAME; diff_opts.detect_rename = DIFF_DETECT_RENAME;
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
@ -1259,7 +1262,7 @@ static void find_copy_in_parent(struct blame_scoreboard *sb,
if (!unblamed) if (!unblamed)
return; /* nothing remains for this target */ return; /* nothing remains for this target */
diff_setup(&diff_opts); repo_diff_setup(sb->repo, &diff_opts);
diff_opts.flags.recursive = 1; diff_opts.flags.recursive = 1;
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; 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. * common cases, then we look for renames in the second pass.
*/ */
for (pass = 0; pass < 2 - sb->no_whole_file_rename; 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; find = pass ? find_rename : find_origin;
for (i = 0, sg = first_scapegoat(revs, commit, sb->reverse); 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; continue;
if (parse_commit(p)) if (parse_commit(p))
continue; continue;
porigin = find(p, origin); porigin = find(sb->repo, p, origin);
if (!porigin) if (!porigin)
continue; continue;
if (oideq(&porigin->blob_oid, &origin->blob_oid)) { 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); die(_("no such path %s in %s"), path, final_commit_name);
if (sb->revs->diffopt.flags.allow_textconv && 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)) &sb->final_buf_size))
; ;
else else

View File

@ -110,7 +110,7 @@ int add_files_to_cache(const char *prefix,
memset(&data, 0, sizeof(data)); memset(&data, 0, sizeof(data));
data.flags = flags; data.flags = flags;
init_revisions(&rev, prefix); repo_init_revisions(the_repository, &rev, prefix);
setup_revisions(0, NULL, &rev, NULL); setup_revisions(0, NULL, &rev, NULL);
if (pathspec) if (pathspec)
copy_pathspec(&rev.prune_data, 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) if (read_cache() < 0)
die(_("Could not read the index")); die(_("Could not read the index"));
init_revisions(&rev, prefix); repo_init_revisions(the_repository, &rev, prefix);
rev.diffopt.context = 7; rev.diffopt.context = 7;
argc = setup_revisions(argc, argv, &rev, NULL); 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; FILE *fp;
fp = xfopen(am_path(state, "patch"), "w"); 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.diff = 1;
rev_info.abbrev = 0; rev_info.abbrev = 0;
rev_info.disable_stdin = 1; 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); the_repository->hash_algo->empty_tree);
fp = xfopen(am_path(state, "patch"), "w"); 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.diff = 1;
rev_info.disable_stdin = 1; rev_info.disable_stdin = 1;
rev_info.no_commit_id = 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; struct rev_info rev_info;
const char *diff_filter_str = "--diff-filter=AM"; 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; rev_info.diffopt.output_format = DIFF_FORMAT_NAME_STATUS;
diff_opt_parse(&rev_info.diffopt, &diff_filter_str, 1, rev_info.prefix); diff_opt_parse(&rev_info.diffopt, &diff_filter_str, 1, rev_info.prefix);
add_pending_oid(&rev_info, "HEAD", &our_tree, 0); 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; o.verbosity = 0;
if (merge_recursive_generic(&o, &our_tree, &their_tree, 1, bases, &result)) { 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); free(their_tree_name);
return error(_("Failed to merge in the changes.")); return error(_("Failed to merge in the changes."));
} }
@ -1903,7 +1903,7 @@ static void am_resolve(struct am_state *state)
goto next; goto next;
} }
rerere(0); repo_rerere(the_repository, 0);
do_commit(state); 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(); setup_default_color_by_age();
git_config(git_blame_config, &output_option); 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.date_mode = blame_date_mode;
revs.diffopt.flags.allow_textconv = 1; revs.diffopt.flags.allow_textconv = 1;
revs.diffopt.flags.follow_renames = 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; long bottom, top;
if (parse_range_arg(range_list.items[range_i].string, if (parse_range_arg(range_list.items[range_i].string,
nth_line_cb, &sb, lno, anchor, nth_line_cb, &sb, lno, anchor,
&bottom, &top, sb.path)) &bottom, &top, sb.path, &the_index))
usage(blame_usage); usage(blame_usage);
if ((!lno && (top || bottom)) || lno < bottom) if ((!lno && (top || bottom)) || lno < bottom)
die(Q_("file %s has only %lu line", 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>", die("git cat-file --textconv %s: <object> must be <sha1:path>",
obj_name); 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; break;
/* else fallthrough */ /* 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); oid_to_hex(oid), data->rest);
} else if (opt->cmdmode == 'c') { } else if (opt->cmdmode == 'c') {
enum object_type type; enum object_type type;
if (!textconv_object(data->rest, 0100644, oid, if (!textconv_object(the_repository,
data->rest, 0100644, oid,
1, &contents, &size)) 1, &contents, &size))
contents = read_object_file(oid, contents = read_object_file(oid,
&type, &type,

View File

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

View File

@ -983,7 +983,7 @@ static const char *find_author_by_nickname(const char *name)
const char *av[20]; const char *av[20];
int ac = 0; int ac = 0;
init_revisions(&revs, NULL); repo_init_revisions(the_repository, &revs, NULL);
strbuf_addf(&buf, "--author=%s", name); strbuf_addf(&buf, "--author=%s", name);
av[++ac] = "--all"; av[++ac] = "--all";
av[++ac] = "-i"; 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)) if (git_env_bool(GIT_TEST_COMMIT_GRAPH, 0))
write_commit_graph_reachable(get_object_directory(), 0, 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_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
run_commit_hook(use_editor, get_index_file(), "post-commit", NULL); run_commit_hook(use_editor, get_index_file(), "post-commit", NULL);
if (amend && !no_post_rewrite) { 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", "--objects", "--in-commit-order", "--reverse", "HEAD",
NULL); NULL);
init_revisions(&revs, NULL); repo_init_revisions(the_repository, &revs, NULL);
if (setup_revisions(args.argc, args.argv, &revs, NULL) > 1) if (setup_revisions(args.argc, args.argv, &revs, NULL) > 1)
BUG("setup_revisions could not handle all args?"); 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) if (0 <= fd)
update_index_if_able(&the_index, &index_lock); 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); argv_array_pushv(&args, diff_index_args);
if (setup_revisions(args.argc, args.argv, &revs, NULL) != 1) if (setup_revisions(args.argc, args.argv, &revs, NULL) != 1)
BUG("malformed internal diff-index command line"); 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); usage(diff_files_usage);
git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ 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; rev.abbrev = 0;
precompose_argv(argc, argv); 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); usage(diff_cache_usage);
git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ 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; rev.abbrev = 0;
precompose_argv(argc, argv); 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); usage(diff_tree_usage);
git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ 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) if (read_cache() < 0)
die(_("index file corrupt")); die(_("index file corrupt"));
opt->abbrev = 0; 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); git_config(git_diff_ui_config, NULL);
precompose_argv(argc, argv); precompose_argv(argc, argv);
init_revisions(&rev, prefix); repo_init_revisions(the_repository, &rev, prefix);
if (no_index && argc != i + 2) { if (no_index && argc != i + 2) {
if (no_index == DIFF_NO_INDEX_IMPLICIT) { 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 (no_index)
/* If this is a no-index diff, just run it and exit there. */ /* 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 */ /* Otherwise, we are doing the usual "git" diff */
rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index; 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); int fd = open(buf.buf, O_RDONLY);
if (fd >= 0 && 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)) { if (is_null_oid(oid)) {
oidcpy(oid, &wt_oid); oidcpy(oid, &wt_oid);
use = 1; use = 1;

View File

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

View File

@ -643,7 +643,7 @@ int fmt_merge_msg(struct strbuf *in, struct strbuf *out,
struct rev_info rev; struct rev_info rev;
head = lookup_commit_or_die(&head_oid, "HEAD"); 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.commit_format = CMIT_FMT_ONELINE;
rev.ignore_merges = 1; rev.ignore_merges = 1;
rev.limited = 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; todo[todo_end].source = *gs;
if (opt->binary != GREP_BINARY_TEXT) 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; todo[todo_end].done = 0;
strbuf_reset(&todo[todo_end].out); strbuf_reset(&todo[todo_end].out);
todo_end = (todo_end + 1) % ARRAY_SIZE(todo); 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() OPT_END()
}; };
init_grep_defaults(); init_grep_defaults(the_repository);
git_config(grep_cmd_config, NULL); 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 * 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 || if (fstat(fd, &st) < 0 ||
(literally (literally
? hash_literally(&oid, fd, type, flags) ? 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) die((flags & HASH_WRITE_OBJECT)
? "Unable to add %s to database" ? "Unable to add %s to database"
: "Unable to hash %s", path); : "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) static void init_log_defaults(void)
{ {
init_grep_defaults(); init_grep_defaults(the_repository);
init_diff_ui_defaults(); init_diff_ui_defaults();
decoration_style = auto_decoration_style(); decoration_style = auto_decoration_style();
@ -470,7 +470,7 @@ int cmd_whatchanged(int argc, const char **argv, const char *prefix)
init_log_defaults(); init_log_defaults();
git_config(git_log_config, NULL); git_config(git_log_config, NULL);
init_revisions(&rev, prefix); repo_init_revisions(the_repository, &rev, prefix);
rev.diff = 1; rev.diff = 1;
rev.simplify_history = 0; rev.simplify_history = 0;
memset(&opt, 0, sizeof(opt)); 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)) &oidc, &obj_context))
die(_("Not a valid object name %s"), obj_name); die(_("Not a valid object name %s"), obj_name);
if (!obj_context.path || 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); free(obj_context.path);
return stream_blob_to_fd(1, oid, NULL, 0); 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); git_config(git_log_config, NULL);
memset(&match_all, 0, sizeof(match_all)); memset(&match_all, 0, sizeof(match_all));
init_revisions(&rev, prefix); repo_init_revisions(the_repository, &rev, prefix);
rev.diff = 1; rev.diff = 1;
rev.always_show_header = 1; rev.always_show_header = 1;
rev.no_walk = REVISION_WALK_NO_WALK_SORTED; 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(); init_log_defaults();
git_config(git_log_config, NULL); git_config(git_log_config, NULL);
init_revisions(&rev, prefix); repo_init_revisions(the_repository, &rev, prefix);
init_reflog_walk(&rev.reflog_info); init_reflog_walk(&rev.reflog_info);
rev.verbose_header = 1; rev.verbose_header = 1;
memset(&opt, 0, sizeof(opt)); memset(&opt, 0, sizeof(opt));
@ -706,7 +707,7 @@ int cmd_log(int argc, const char **argv, const char *prefix)
init_log_defaults(); init_log_defaults();
git_config(git_log_config, NULL); git_config(git_log_config, NULL);
init_revisions(&rev, prefix); repo_init_revisions(the_repository, &rev, prefix);
rev.always_show_header = 1; rev.always_show_header = 1;
memset(&opt, 0, sizeof(opt)); memset(&opt, 0, sizeof(opt));
opt.def = "HEAD"; 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)) if ((flags1 & UNINTERESTING) == (flags2 & UNINTERESTING))
die(_("Not a range.")); 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 */ /* 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; check_rev.max_parents = 1;
o1->flags ^= UNINTERESTING; o1->flags ^= UNINTERESTING;
o2->flags ^= UNINTERESTING; o2->flags ^= UNINTERESTING;
@ -1377,13 +1378,13 @@ static void prepare_bases(struct base_tree_info *bases,
return; return;
init_commit_base(&commit_base); init_commit_base(&commit_base);
diff_setup(&diffopt); repo_diff_setup(the_repository, &diffopt);
diffopt.flags.recursive = 1; diffopt.flags.recursive = 1;
diff_setup_done(&diffopt); diff_setup_done(&diffopt);
oidcpy(&bases->base_commit, &base->object.oid); oidcpy(&bases->base_commit, &base->object.oid);
init_revisions(&revs, NULL); repo_init_revisions(the_repository, &revs, NULL);
revs.max_parents = 1; revs.max_parents = 1;
revs.topo_order = 1; revs.topo_order = 1;
for (i = 0; i < total; i++) { 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; extra_cc.strdup_strings = 1;
init_log_defaults(); init_log_defaults();
git_config(git_format_config, NULL); git_config(git_format_config, NULL);
init_revisions(&rev, prefix); repo_init_revisions(the_repository, &rev, prefix);
rev.commit_format = CMIT_FMT_EMAIL; rev.commit_format = CMIT_FMT_EMAIL;
rev.expand_tabs_in_log_default = 0; rev.expand_tabs_in_log_default = 0;
rev.verbose_header = 1; 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; revs.max_parents = 1;
if (add_pending_commit(head, &revs, 0)) 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; their = NULL;
if (entry) if (entry)
their = entry->blob; 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) 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")); printf(_("Squash commit -- not updating HEAD\n"));
init_revisions(&rev, NULL); repo_init_revisions(the_repository, &rev, NULL);
rev.ignore_merges = 1; rev.ignore_merges = 1;
rev.commit_format = CMIT_FMT_MEDIUM; rev.commit_format = CMIT_FMT_MEDIUM;
@ -453,7 +453,7 @@ static void finish(struct commit *head_commit,
} }
if (new_head && show_diffstat) { if (new_head && show_diffstat) {
struct diff_options opts; struct diff_options opts;
diff_setup(&opts); repo_diff_setup(the_repository, &opts);
opts.stat_width = -1; /* use full terminal width */ opts.stat_width = -1; /* use full terminal width */
opts.stat_graph_width = -1; /* respect statGraphWidth config */ opts.stat_graph_width = -1; /* respect statGraphWidth config */
opts.output_format |= 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()); die(_("unable to write %s"), get_index_file());
return clean ? 0 : 1; return clean ? 0 : 1;
} else { } else {
return try_merge_command(strategy, xopts_nr, xopts, return try_merge_command(the_repository,
common, head_arg, remoteheads); strategy, xopts_nr, xopts,
common, head_arg, remoteheads);
} }
} }
@ -899,7 +900,7 @@ static int suggest_conflicts(void)
fputs(msgbuf.buf, fp); fputs(msgbuf.buf, fp);
strbuf_release(&msgbuf); strbuf_release(&msgbuf);
fclose(fp); fclose(fp);
rerere(allow_rerere_auto); repo_rerere(the_repository, allow_rerere_auto);
printf(_("Automatic merge failed; " printf(_("Automatic merge failed; "
"fix conflicts and then commit the result.\n")); "fix conflicts and then commit the result.\n"));
return 1; return 1;
@ -911,7 +912,7 @@ static int evaluate_result(void)
struct rev_info rev; struct rev_info rev;
/* Check how many files differ. */ /* Check how many files differ. */
init_revisions(&rev, ""); repo_init_revisions(the_repository, &rev, "");
setup_revisions(0, NULL, &rev, NULL); setup_revisions(0, NULL, &rev, NULL);
rev.diffopt.output_format |= rev.diffopt.output_format |=
DIFF_FORMAT_CALLBACK; DIFF_FORMAT_CALLBACK;
@ -1471,7 +1472,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
goto done; goto done;
} }
if (checkout_fast_forward(&head_commit->object.oid, if (checkout_fast_forward(the_repository,
&head_commit->object.oid,
&commit->object.oid, &commit->object.oid,
overwrite_ignore)) { overwrite_ignore)) {
ret = 1; ret = 1;

View File

@ -3106,7 +3106,7 @@ static void get_object_list(int ac, const char **av)
char line[1000]; char line[1000];
int flags = 0; int flags = 0;
init_revisions(&revs, NULL); repo_init_revisions(the_repository, &revs, NULL);
save_commit_buffer = 0; save_commit_buffer = 0;
setup_revisions(ac, av, &revs, NULL); 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; save_commit_buffer = 0;
read_replace_refs = 0; read_replace_refs = 0;
ref_paranoia = 1; ref_paranoia = 1;
init_revisions(&revs, prefix); repo_init_revisions(the_repository, &revs, prefix);
argc = parse_options(argc, argv, prefix, options, prune_usage, 0); 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 * index/worktree changes that the user already made on the unborn
* branch. * 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; return 1;
if (update_ref("initial pull", "HEAD", merge_head, curr_head, 0, UPDATE_REFS_DIE_ON_ERR)) 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" "fast-forwarding your working tree from\n"
"commit %s."), oid_to_hex(&orig_head)); "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" die(_("Cannot fast-forward your working tree.\n"
"After making sure that you saved anything precious from\n" "After making sure that you saved anything precious from\n"
"$ git diff %s\n" "$ git diff %s\n"
@ -942,7 +945,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
int ret = 0; int ret = 0;
if ((recurse_submodules == RECURSE_SUBMODULES_ON || if ((recurse_submodules == RECURSE_SUBMODULES_ON ||
recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) && 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")); die(_("cannot rebase with locally recorded submodule modifications"));
if (!autostash) { if (!autostash) {
struct commit_list *list = NULL; 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); git_config(git_diff_ui_config, NULL);
diff_setup(&diffopt); repo_diff_setup(the_repository, &diffopt);
argc = parse_options(argc, argv, NULL, options, argc = parse_options(argc, argv, NULL, options,
builtin_range_diff_usage, PARSE_OPT_KEEP_UNKNOWN | 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. * from reflog if the repository was pruned with older git.
*/ */
if (cb.cmd.stalefix) { if (cb.cmd.stalefix) {
init_revisions(&cb.cmd.revs, prefix); repo_init_revisions(the_repository, &cb.cmd.revs, prefix);
if (flags & EXPIRE_REFLOGS_VERBOSE) if (flags & EXPIRE_REFLOGS_VERBOSE)
printf("Marking reachable objects..."); printf("Marking reachable objects...");
mark_reachable_objects(&cb.cmd.revs, 0, 0, NULL); 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); close(fd);
return -1; 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")); return error(_("unable to write object to database"));
/* index_fd close()s fd for us */ /* 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; flags = RERERE_NOAUTOUPDATE;
if (argc < 1) if (argc < 1)
return rerere(flags); return repo_rerere(the_repository, flags);
if (!strcmp(argv[0], "forget")) { if (!strcmp(argv[0], "forget")) {
struct pathspec pathspec; 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")); warning(_("'git rerere forget' without paths is deprecated"));
parse_pathspec(&pathspec, 0, PATHSPEC_PREFER_CWD, parse_pathspec(&pathspec, 0, PATHSPEC_PREFER_CWD,
prefix, argv + 1); prefix, argv + 1);
return rerere_forget(&pathspec); return rerere_forget(the_repository, &pathspec);
} }
if (!strcmp(argv[0], "clear")) { 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++) for (i = 0; i < merge_rr.nr; i++)
printf("%s\n", merge_rr.items[i].string); printf("%s\n", merge_rr.items[i].string);
} else if (!strcmp(argv[0], "remaining")) { } else if (!strcmp(argv[0], "remaining")) {
rerere_remaining(&merge_rr); rerere_remaining(the_repository, &merge_rr);
for (i = 0; i < merge_rr.nr; i++) { for (i = 0; i < merge_rr.nr; i++) {
if (merge_rr.items[i].util != RERERE_RESOLVED) if (merge_rr.items[i].util != RERERE_RESOLVED)
printf("%s\n", merge_rr.items[i].string); 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 = update_index_from_diff;
opt.format_callback_data = &intent_to_add; opt.format_callback_data = &intent_to_add;
opt.flags.override_submodule_config = 1; opt.flags.override_submodule_config = 1;
opt.repo = the_repository;
if (do_diff_cache(tree_oid, &opt)) if (do_diff_cache(tree_oid, &opt))
return 1; return 1;

View File

@ -370,7 +370,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
usage(rev_list_usage); usage(rev_list_usage);
git_config(git_default_config, NULL); git_config(git_default_config, NULL);
init_revisions(&revs, prefix); repo_init_revisions(the_repository, &revs, prefix);
revs.abbrev = DEFAULT_ABBREV; revs.abbrev = DEFAULT_ABBREV;
revs.commit_format = CMIT_FMT_UNSPECIFIED; 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 { } else {
struct setup_revision_opt s_r_opt; struct setup_revision_opt s_r_opt;
opts->revs = xmalloc(sizeof(*opts->revs)); 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; opts->revs->no_walk = REVISION_WALK_NO_WALK_UNSORTED;
if (argc < 2) if (argc < 2)
usage_with_options(usage_str, options); 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); git_config(git_default_config, NULL);
shortlog_init(&log); shortlog_init(&log);
init_revisions(&rev, prefix); repo_init_revisions(the_repository, &rev, prefix);
parse_options_start(&ctx, argc, argv, prefix, options, parse_options_start(&ctx, argc, argv, prefix, options,
PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0); 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); path, NULL);
git_config(git_diff_basic_config, NULL); git_config(git_diff_basic_config, NULL);
init_revisions(&rev, prefix); repo_init_revisions(the_repository, &rev, prefix);
rev.abbrev = 0; rev.abbrev = 0;
diff_files_args.argc = setup_revisions(diff_files_args.argc, diff_files_args.argc = setup_revisions(diff_files_args.argc,
diff_files_args.argv, 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); fill_stat_cache_info(ce, st);
ce->ce_mode = ce_mode_from_stat(old, st->st_mode); 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)) { info_only ? 0 : HASH_WRITE_OBJECT)) {
discard_cache_entry(ce); discard_cache_entry(ce);
return -1; return -1;

View File

@ -140,7 +140,7 @@ int verify_bundle(struct bundle_header *header, int verbose)
int i, ret = 0, req_nr; int i, ret = 0, req_nr;
const char *message = _("Repository lacks these prerequisite commits:"); 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++) { for (i = 0; i < p->nr; i++) {
struct ref_list_entry *e = p->list + i; struct ref_list_entry *e = p->list + i;
struct object *o = parse_object(the_repository, &e->oid); 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 */ /* init revs to list objects for pack-objects later */
save_commit_buffer = 0; save_commit_buffer = 0;
init_revisions(&revs, NULL); repo_init_revisions(the_repository, &revs, NULL);
/* write prerequisites */ /* write prerequisites */
if (compute_and_write_prerequisites(bundle_fd, &revs, argc, argv)) 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 * provided, the space-separated list of files that differ will be appended
* to it. * 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 tree *tree,
struct strbuf *sb); 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_WRITE_OBJECT 1
#define HASH_FORMAT_CHECK 2 #define HASH_FORMAT_CHECK 2
#define HASH_RENORMALIZE 4 #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_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 object_id *oid, const char *path, struct stat *st, 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 * 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 */ /* All WS_* -- when extended, adapt diff.c emit_symbol */
#define WS_RULE_MASK 07777 #define WS_RULE_MASK 07777
extern unsigned whitespace_rule_cfg; 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 parse_whitespace_rule(const char *);
extern unsigned ws_check(const char *line, int len, unsigned ws_rule); 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); 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 */ /* merge.c */
struct commit_list; 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 **xopts, struct commit_list *common,
const char *head_arg, struct commit_list *remotes); 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, const struct object_id *to,
int overwrite_ignore); int overwrite_ignore);

View File

@ -285,7 +285,8 @@ static struct lline *coalesce_lines(struct lline *base, int *lenbase,
return base; 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, unsigned long *size, struct userdiff_driver *textconv,
const char *path) const char *path)
{ {
@ -304,7 +305,7 @@ static char *grab_blob(const struct object_id *oid, unsigned int mode,
} else if (textconv) { } else if (textconv) {
struct diff_filespec *df = alloc_filespec(path); struct diff_filespec *df = alloc_filespec(path);
fill_filespec(df, oid, 1, mode); fill_filespec(df, oid, 1, mode);
*size = fill_textconv(textconv, df, &blob); *size = fill_textconv(r, textconv, df, &blob);
free_filespec(df); free_filespec(df);
} else { } else {
blob = read_object_file(oid, &type, size); 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, mmfile_t *result_file,
struct sline *sline, unsigned int cnt, int n, struct sline *sline, unsigned int cnt, int n,
int num_parent, int result_deleted, 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) if (result_deleted)
return; /* 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; parent_file.size = sz;
memset(&xpp, 0, sizeof(xpp)); memset(&xpp, 0, sizeof(xpp));
xpp.flags = flags; 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); const char *line_prefix = diff_line_prefix(opt);
context = opt->context; context = opt->context;
userdiff = userdiff_find_by_path(elem->path); userdiff = userdiff_find_by_path(opt->repo->index, elem->path);
if (!userdiff) if (!userdiff)
userdiff = userdiff_find_by_name("default"); userdiff = userdiff_find_by_name("default");
if (opt->flags.allow_textconv) 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 */ /* Read the result of merge first */
if (!working_tree_file) 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); textconv, elem->path);
else { else {
/* Used by diff-tree to read from the working tree */ /* 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)) { } else if (S_ISDIR(st.st_mode)) {
struct object_id oid; struct object_id oid;
if (resolve_gitlink_ref(elem->path, "HEAD", &oid) < 0) if (resolve_gitlink_ref(elem->path, "HEAD", &oid) < 0)
result = grab_blob(&elem->oid, elem->mode, result = grab_blob(opt->repo, &elem->oid,
&result_size, NULL, NULL); elem->mode, &result_size,
NULL, NULL);
else else
result = grab_blob(&oid, elem->mode, result = grab_blob(opt->repo, &oid, elem->mode,
&result_size, NULL, NULL); &result_size, NULL, NULL);
} else if (textconv) { } else if (textconv) {
struct diff_filespec *df = alloc_filespec(elem->path); struct diff_filespec *df = alloc_filespec(elem->path);
fill_filespec(df, &null_oid, 0, st.st_mode); 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); free_filespec(df);
} else if (0 <= (fd = open(elem->path, O_RDONLY))) { } else if (0 <= (fd = open(elem->path, O_RDONLY))) {
size_t len = xsize_t(st.st_size); 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) { if (is_file) {
struct strbuf buf = STRBUF_INIT; 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); free(result);
result = strbuf_detach(&buf, &len); result = strbuf_detach(&buf, &len);
result_size = 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++) { for (i = 0; !is_binary && i < num_parent; i++) {
char *buf; char *buf;
unsigned long size; unsigned long size;
buf = grab_blob(&elem->parent[i].oid, buf = grab_blob(opt->repo,
&elem->parent[i].oid,
elem->parent[i].mode, elem->parent[i].mode,
&size, NULL, NULL); &size, NULL, NULL);
if (buffer_is_binary(buf, size)) 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) if (i <= j)
combine_diff(&elem->parent[i].oid, combine_diff(opt->repo,
&elem->parent[i].oid,
elem->parent[i].mode, elem->parent[i].mode,
&result_file, sline, &result_file, sline,
cnt, i, num_parent, result_deleted, 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, struct stat *st, unsigned ce_option,
unsigned *dirty_submodule) 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)) { if (S_ISGITLINK(ce->ce_mode)) {
struct diff_flags orig_flags = diffopt->flags; struct diff_flags orig_flags = diffopt->flags;
if (!diffopt->flags.override_submodule_config) 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) unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED)
? CE_MATCH_RACY_IS_DIRTY : 0); ? CE_MATCH_RACY_IS_DIRTY : 0);
uint64_t start = getnanotime(); uint64_t start = getnanotime();
struct index_state *istate = revs->diffopt.repo->index;
diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/"); diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/");
if (diff_unmerged_stage < 0) if (diff_unmerged_stage < 0)
diff_unmerged_stage = 2; diff_unmerged_stage = 2;
entries = active_nr; entries = istate->cache_nr;
for (i = 0; i < entries; i++) { for (i = 0; i < entries; i++) {
unsigned int oldmode, newmode; unsigned int oldmode, newmode;
struct cache_entry *ce = active_cache[i]; struct cache_entry *ce = istate->cache[i];
int changed; int changed;
unsigned dirty_submodule = 0; unsigned dirty_submodule = 0;
const struct object_id *old_oid, *new_oid; 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)) if (diff_can_quit_early(&revs->diffopt))
break; break;
if (!ce_path_match(&the_index, ce, &revs->prune_data, NULL)) if (!ce_path_match(istate, ce, &revs->prune_data, NULL))
continue; continue;
if (ce_stage(ce)) { if (ce_stage(ce)) {
@ -145,7 +146,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
dpath->mode = wt_mode; dpath->mode = wt_mode;
while (i < entries) { while (i < entries) {
struct cache_entry *nce = active_cache[i]; struct cache_entry *nce = istate->cache[i];
int stage; int stage;
if (strcmp(ce->name, nce->name)) 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) if (tree == o->df_conflict_entry)
tree = NULL; 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); do_oneway_diff(o, idx, tree);
if (diff_can_quit_early(&revs->diffopt)) { if (diff_can_quit_early(&revs->diffopt)) {
o->exiting_early = 1; o->exiting_early = 1;
@ -506,7 +509,7 @@ static int diff_cache(struct rev_info *revs,
opts.merge = 1; opts.merge = 1;
opts.fn = oneway_diff; opts.fn = oneway_diff;
opts.unpack_data = revs; opts.unpack_data = revs;
opts.src_index = &the_index; opts.src_index = revs->diffopt.repo->index;
opts.dst_index = NULL; opts.dst_index = NULL;
opts.pathspec = &revs->diffopt.pathspec; opts.pathspec = &revs->diffopt.pathspec;
opts.pathspec->recursive = 1; 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; struct rev_info revs;
init_revisions(&revs, NULL); repo_init_revisions(the_repository, &revs, NULL);
copy_pathspec(&revs.prune_data, &opt->pathspec); copy_pathspec(&revs.prune_data, &opt->pathspec);
revs.diffopt = *opt; revs.diffopt = *opt;
@ -554,7 +557,7 @@ int index_differs_from(const char *def, const struct diff_flags *flags,
struct rev_info rev; struct rev_info rev;
struct setup_revision_opt opt; struct setup_revision_opt opt;
init_revisions(&rev, NULL); repo_init_revisions(the_repository, &rev, NULL);
memset(&opt, 0, sizeof(opt)); memset(&opt, 0, sizeof(opt));
opt.def = def; opt.def = def;
setup_revisions(0, NULL, &rev, &opt); 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 argc, const char **argv)
{ {
int i; int i;
@ -241,7 +242,11 @@ void diff_no_index(struct rev_info *revs,
struct strbuf replacement = STRBUF_INIT; struct strbuf replacement = STRBUF_INIT;
const char *prefix = revs->prefix; 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; ) { for (i = 1; i < argc - 2; ) {
int j; int j;
if (!strcmp(argv[i], "--no-index")) 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; 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)) { if (!DIFF_FILE_VALID(one)) {
mf->ptr = (char *)""; /* does not matter */ mf->ptr = (char *)""; /* does not matter */
mf->size = 0; mf->size = 0;
return 0; return 0;
} }
else if (diff_populate_filespec(one, 0)) else if (diff_populate_filespec(r, one, 0))
return -1; return -1;
mf->ptr = one->data; 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 */ /* 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)) if (!DIFF_FILE_VALID(one))
return 0; return 0;
diff_populate_filespec(one, CHECK_SIZE_ONLY); diff_populate_filespec(r, one, CHECK_SIZE_ONLY);
return one->size; 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(&a_name, a_prefix, name_a, 0);
quote_two_c_style(&b_name, b_prefix, name_b, 0); quote_two_c_style(&b_name, b_prefix, name_b, 0);
size_one = fill_textconv(textconv_one, one, &data_one); size_one = fill_textconv(o->repo, textconv_one, one, &data_one);
size_two = fill_textconv(textconv_two, two, &data_two); size_two = fill_textconv(o->repo, textconv_two, two, &data_two);
memset(&ecbdata, 0, sizeof(ecbdata)); memset(&ecbdata, 0, sizeof(ecbdata));
ecbdata.color_diff = want_color(o->use_color); 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; ecbdata.opt = o;
if (ecbdata.ws_rule & WS_BLANK_AT_EOF) { if (ecbdata.ws_rule & WS_BLANK_AT_EOF) {
mmfile_t mf1, mf2; 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 */ /* Use already-loaded driver */
if (one->driver) if (one->driver)
return; return;
if (S_ISREG(one->mode)) 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 */ /* Fallback to default settings */
if (!one->driver) if (!one->driver)
one->driver = userdiff_find_by_name("default"); 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; 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)); xcalloc(1, sizeof(struct emitted_diff_symbols));
if (!o->word_regex) 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) 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) if (!o->word_regex)
o->word_regex = diff_word_regex_cfg; o->word_regex = diff_word_regex_cfg;
if (o->word_regex) { 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)) { if (DIFF_FILE_VALID(p->one) && DIFF_FILE_VALID(p->two)) {
diff_populate_filespec(p->one, 0); diff_populate_filespec(options->repo, p->one, 0);
diff_populate_filespec(p->two, 0); diff_populate_filespec(options->repo, p->two, 0);
diffcore_count_changes(p->one, p->two, NULL, NULL, diffcore_count_changes(options->repo,
p->one, p->two, NULL, NULL,
&copied, &added); &copied, &added);
diff_free_filespec_data(p->one); diff_free_filespec_data(p->one);
diff_free_filespec_data(p->two); diff_free_filespec_data(p->two);
} else if (DIFF_FILE_VALID(p->one)) { } 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; copied = added = 0;
diff_free_filespec_data(p->one); diff_free_filespec_data(p->one);
} else if (DIFF_FILE_VALID(p->two)) { } 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; copied = 0;
added = p->two->size; added = p->two->size;
diff_free_filespec_data(p->two); 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); 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) { if (one->is_binary == -1) {
diff_filespec_load_driver(one); diff_filespec_load_driver(one, r->index);
if (one->driver->binary != -1) if (one->driver->binary != -1)
one->is_binary = one->driver->binary; one->is_binary = one->driver->binary;
else { else {
if (!one->data && DIFF_FILE_VALID(one)) 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) if (one->is_binary == -1 && one->data)
one->is_binary = buffer_is_binary(one->data, one->is_binary = buffer_is_binary(one->data,
one->size); one->size);
@ -3280,9 +3286,10 @@ int diff_filespec_is_binary(struct diff_filespec *one)
return one->is_binary; 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; 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; 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)) if (!DIFF_FILE_VALID(one))
return NULL; return NULL;
diff_filespec_load_driver(one); diff_filespec_load_driver(one, istate);
return userdiff_get_textconv(one->driver); return userdiff_get_textconv(one->driver);
} }
@ -3349,8 +3357,8 @@ static void builtin_diff(const char *name_a,
} }
if (o->flags.allow_textconv) { if (o->flags.allow_textconv) {
textconv_one = get_textconv(one); textconv_one = get_textconv(o->repo->index, one);
textconv_two = get_textconv(two); textconv_two = get_textconv(o->repo->index, two);
} }
/* Never use a non-valid filename anywhere if at all possible */ /* 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) if ((one->mode ^ two->mode) & S_IFMT)
goto free_ab_and_return; goto free_ab_and_return;
if (complete_rewrite && if (complete_rewrite &&
(textconv_one || !diff_filespec_is_binary(one)) && (textconv_one || !diff_filespec_is_binary(o->repo, one)) &&
(textconv_two || !diff_filespec_is_binary(two))) { (textconv_two || !diff_filespec_is_binary(o->repo, two))) {
emit_diff_symbol(o, DIFF_SYMBOL_HEADER, emit_diff_symbol(o, DIFF_SYMBOL_HEADER,
header.buf, header.len, 0); header.buf, header.len, 0);
strbuf_reset(&header); strbuf_reset(&header);
emit_rewrite_diff(name_a, name_b, one, two, emit_rewrite_diff(name_a, name_b, one, two,
textconv_one, textconv_two, o); textconv_one, textconv_two, o);
o->found_changes = 1; o->found_changes = 1;
goto free_ab_and_return; goto free_ab_and_return;
} }
@ -3409,8 +3417,8 @@ static void builtin_diff(const char *name_a,
strbuf_reset(&header); strbuf_reset(&header);
goto free_ab_and_return; goto free_ab_and_return;
} else if (!o->flags.text && } else if (!o->flags.text &&
( (!textconv_one && diff_filespec_is_binary(one)) || ( (!textconv_one && diff_filespec_is_binary(o->repo, one)) ||
(!textconv_two && diff_filespec_is_binary(two)) )) { (!textconv_two && diff_filespec_is_binary(o->repo, two)) )) {
struct strbuf sb = STRBUF_INIT; struct strbuf sb = STRBUF_INIT;
if (!one->data && !two->data && if (!one->data && !two->data &&
S_ISREG(one->mode) && S_ISREG(two->mode) && S_ISREG(one->mode) && S_ISREG(two->mode) &&
@ -3431,7 +3439,8 @@ static void builtin_diff(const char *name_a,
strbuf_release(&sb); strbuf_release(&sb);
goto free_ab_and_return; 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"); die("unable to read files to diff");
/* Quite common confusing case */ /* Quite common confusing case */
if (mf1.size == mf2.size && if (mf1.size == mf2.size &&
@ -3468,12 +3477,12 @@ static void builtin_diff(const char *name_a,
strbuf_reset(&header); strbuf_reset(&header);
} }
mf1.size = fill_textconv(textconv_one, one, &mf1.ptr); mf1.size = fill_textconv(o->repo, textconv_one, one, &mf1.ptr);
mf2.size = fill_textconv(textconv_two, two, &mf2.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) if (!pe)
pe = diff_funcname_pattern(two); pe = diff_funcname_pattern(o, two);
memset(&xpp, 0, sizeof(xpp)); memset(&xpp, 0, sizeof(xpp));
memset(&xecfg, 0, sizeof(xecfg)); memset(&xecfg, 0, sizeof(xecfg));
@ -3482,7 +3491,7 @@ static void builtin_diff(const char *name_a,
lbl[0] = NULL; lbl[0] = NULL;
ecbdata.label_path = lbl; ecbdata.label_path = lbl;
ecbdata.color_diff = want_color(o->use_color); 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) if (ecbdata.ws_rule & WS_BLANK_AT_EOF)
check_blank_at_eof(&mf1, &mf2, &ecbdata); check_blank_at_eof(&mf1, &mf2, &ecbdata);
ecbdata.opt = o; 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); 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; data->is_binary = 1;
if (same_contents) { if (same_contents) {
data->added = 0; data->added = 0;
data->deleted = 0; data->deleted = 0;
} else { } else {
data->added = diff_filespec_size(two); data->added = diff_filespec_size(o->repo, two);
data->deleted = diff_filespec_size(one); data->deleted = diff_filespec_size(o->repo, one);
} }
} }
else if (complete_rewrite) { else if (complete_rewrite) {
diff_populate_filespec(one, 0); diff_populate_filespec(o->repo, one, 0);
diff_populate_filespec(two, 0); diff_populate_filespec(o->repo, two, 0);
data->deleted = count_lines(one->data, one->size); data->deleted = count_lines(one->data, one->size);
data->added = count_lines(two->data, two->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; xpparam_t xpp;
xdemitconf_t xecfg; 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"); die("unable to read files to diff");
memset(&xpp, 0, sizeof(xpp)); 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.filename = name_b ? name_b : name_a;
data.lineno = 0; data.lineno = 0;
data.o = o; data.o = o;
data.ws_rule = whitespace_rule(attr_path); data.ws_rule = whitespace_rule(o->repo->index, attr_path);
data.conflict_marker_size = ll_merge_marker_size(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"); 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 * introduced changes, and as long as the "new" side is text, we
* can and should check what it introduces. * 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; goto free_and_return;
else { else {
/* Crazy xdl interfaces.. */ /* 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 * the work tree has that object contents, return true, so that
* prepare_temp_file() does not have to inflate and extract. * 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; const struct cache_entry *ce;
struct stat st; 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 * by diff-cache --cached, which does read the cache before
* calling us. * calling us.
*/ */
if (!active_cache) if (!istate->cache)
return 0; return 0;
/* We want to avoid the working directory if our caller /* 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 * Similarly, if we'd have to convert the file contents anyway, that
* makes the optimization not worthwhile. * 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; return 0;
len = strlen(name); len = strlen(name);
pos = cache_name_pos(name, len); pos = index_name_pos(istate, name, len);
if (pos < 0) if (pos < 0)
return 0; return 0;
ce = active_cache[pos]; ce = istate->cache[pos];
/* /*
* This is not the sha1 we are looking for, or * 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 matches the file in the work tree, we can reuse it.
*/ */
if (ce_uptodate(ce) || 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 1;
return 0; 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. * grab the data for the blob (or file) for our own in-core comparison.
* diff_filespec has data and size fields for this purpose. * 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 size_only = flags & CHECK_SIZE_ONLY;
int err = 0; 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); return diff_populate_gitlink(s, size_only);
if (!s->oid_valid || 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 strbuf buf = STRBUF_INIT;
struct stat st; struct stat st;
int fd; 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 * point if the path requires us to run the content
* conversion. * 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; 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 * 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; size_t size = 0;
munmap(s->data, s->size); munmap(s->data, s->size);
s->should_munmap = 0; s->should_munmap = 0;
@ -3922,8 +3939,7 @@ int diff_populate_filespec(struct diff_filespec *s, unsigned int flags)
else { else {
enum object_type type; enum object_type type;
if (size_only || (flags & CHECK_BINARY)) { if (size_only || (flags & CHECK_BINARY)) {
type = oid_object_info(the_repository, &s->oid, type = oid_object_info(r, &s->oid, &s->size);
&s->size);
if (type < 0) if (type < 0)
die("unable to read %s", die("unable to read %s",
oid_to_hex(&s->oid)); oid_to_hex(&s->oid));
@ -3961,7 +3977,8 @@ void diff_free_filespec_data(struct diff_filespec *s)
FREE_AND_NULL(s->cnt_data); 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, void *blob,
unsigned long size, unsigned long size,
const struct object_id *oid, 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); temp->tempfile = mks_tempfile_ts(tempfile.buf, strlen(base) + 1);
if (!temp->tempfile) if (!temp->tempfile)
die_errno("unable to create temp-file"); 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)) { (const char *)blob, (size_t)size, &buf)) {
blob = buf.buf; blob = buf.buf;
size = buf.len; size = buf.len;
@ -3995,8 +4012,9 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
free(path_dup); free(path_dup);
} }
static struct diff_tempfile *prepare_temp_file(const char *name, static struct diff_tempfile *prepare_temp_file(struct repository *r,
struct diff_filespec *one) const char *name,
struct diff_filespec *one)
{ {
struct diff_tempfile *temp = claim_diff_tempfile(); 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) && if (!S_ISGITLINK(one->mode) &&
(!one->oid_valid || (!one->oid_valid ||
reuse_worktree_file(name, &one->oid, 1))) { reuse_worktree_file(r->index, name, &one->oid, 1))) {
struct stat st; struct stat st;
if (lstat(name, &st) < 0) { if (lstat(name, &st) < 0) {
if (errno == ENOENT) if (errno == ENOENT)
@ -4024,7 +4042,7 @@ static struct diff_tempfile *prepare_temp_file(const char *name,
struct strbuf sb = STRBUF_INIT; struct strbuf sb = STRBUF_INIT;
if (strbuf_readlink(&sb, name, st.st_size) < 0) if (strbuf_readlink(&sb, name, st.st_size) < 0)
die_errno("readlink(%s)", name); 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_valid ?
&one->oid : &null_oid), &one->oid : &null_oid),
(one->oid_valid ? (one->oid_valid ?
@ -4049,19 +4067,21 @@ static struct diff_tempfile *prepare_temp_file(const char *name,
return temp; return temp;
} }
else { else {
if (diff_populate_filespec(one, 0)) if (diff_populate_filespec(r, one, 0))
die("cannot read data blob for %s", one->path); 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); &one->oid, one->mode);
} }
return temp; 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, const char *name,
struct diff_filespec *df) 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->name);
argv_array_push(argv, temp->hex); argv_array_push(argv, temp->hex);
argv_array_push(argv, temp->mode); argv_array_push(argv, temp->mode);
@ -4090,11 +4110,11 @@ static void run_external_diff(const char *pgm,
argv_array_push(&argv, name); argv_array_push(&argv, name);
if (one && two) { if (one && two) {
add_external_diff_name(&argv, name, one); add_external_diff_name(o->repo, &argv, name, one);
if (!other) if (!other)
add_external_diff_name(&argv, name, two); add_external_diff_name(o->repo, &argv, name, two);
else { 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, other);
argv_array_push(&argv, xfrm_msg); argv_array_push(&argv, xfrm_msg);
} }
@ -4187,8 +4207,10 @@ static void fill_metainfo(struct strbuf *msg,
if (o->flags.binary) { if (o->flags.binary) {
mmfile_t mf; mmfile_t mf;
if ((!fill_mmfile(&mf, one) && diff_filespec_is_binary(one)) || if ((!fill_mmfile(o->repo, &mf, one) &&
(!fill_mmfile(&mf, two) && diff_filespec_is_binary(two))) diff_filespec_is_binary(o->repo, one)) ||
(!fill_mmfile(o->repo, &mf, two) &&
diff_filespec_is_binary(o->repo, two)))
abbrev = hexsz; abbrev = hexsz;
} }
strbuf_addf(msg, "%s%sindex %s..%s", line_prefix, set, 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) { 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) if (drv && drv->external)
pgm = 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); 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 (DIFF_FILE_VALID(one)) {
if (!one->oid_valid) { if (!one->oid_valid) {
@ -4256,7 +4280,7 @@ static void diff_fill_oid_info(struct diff_filespec *one)
} }
if (lstat(one->path, &st) < 0) if (lstat(one->path, &st) < 0)
die_errno("stat '%s'", one->path); 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); die("cannot hash %s", one->path);
} }
} }
@ -4304,8 +4328,8 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
return; return;
} }
diff_fill_oid_info(one); diff_fill_oid_info(one, o->repo->index);
diff_fill_oid_info(two); diff_fill_oid_info(two, o->repo->index);
if (!pgm && if (!pgm &&
DIFF_FILE_VALID(one) && DIFF_FILE_VALID(two) && 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); struct diff_filespec *null = alloc_filespec(two->path);
run_diff_cmd(NULL, name, other, attr_path, run_diff_cmd(NULL, name, other, attr_path,
one, null, &msg, o, p); one, null, &msg,
o, p);
free(null); free(null);
strbuf_release(&msg); strbuf_release(&msg);
@ -4340,7 +4365,8 @@ static void run_diffstat(struct diff_filepair *p, struct diff_options *o,
if (DIFF_PAIR_UNMERGED(p)) { if (DIFF_PAIR_UNMERGED(p)) {
/* unmerged */ /* unmerged */
builtin_diffstat(p->one->path, NULL, NULL, NULL, diffstat, o, p); builtin_diffstat(p->one->path, NULL, NULL, NULL,
diffstat, o, p);
return; return;
} }
@ -4350,10 +4376,11 @@ static void run_diffstat(struct diff_filepair *p, struct diff_options *o,
if (o->prefix_length) if (o->prefix_length)
strip_prefix(o->prefix_length, &name, &other); strip_prefix(o->prefix_length, &name, &other);
diff_fill_oid_info(p->one); diff_fill_oid_info(p->one, o->repo->index);
diff_fill_oid_info(p->two); 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) 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) if (o->prefix_length)
strip_prefix(o->prefix_length, &name, &other); strip_prefix(o->prefix_length, &name, &other);
diff_fill_oid_info(p->one); diff_fill_oid_info(p->one, o->repo->index);
diff_fill_oid_info(p->two); diff_fill_oid_info(p->two, o->repo->index);
builtin_checkdiff(name, other, attr_path, p->one, p->two, o); 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)); memcpy(options, &default_diff_options, sizeof(*options));
options->file = stdout; options->file = stdout;
options->repo = r;
options->output_indicators[OUTPUT_INDICATOR_NEW] = '+'; options->output_indicators[OUTPUT_INDICATOR_NEW] = '+';
options->output_indicators[OUTPUT_INDICATOR_OLD] = '-'; 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)) if (DIFF_PAIR_UNMERGED(p))
continue; continue;
diff_fill_oid_info(p->one); diff_fill_oid_info(p->one, options->repo->index);
diff_fill_oid_info(p->two); diff_fill_oid_info(p->two, options->repo->index);
len1 = remove_space(p->one->path, strlen(p->one->path)); len1 = remove_space(p->one->path, strlen(p->one->path));
len2 = remove_space(p->two->path, strlen(p->two->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) if (diff_header_only)
continue; continue;
if (fill_mmfile(&mf1, p->one) < 0 || if (fill_mmfile(options->repo, &mf1, p->one) < 0 ||
fill_mmfile(&mf2, p->two) < 0) fill_mmfile(options->repo, &mf2, p->two) < 0)
return error("unable to read files to diff"); return error("unable to read files to diff");
if (diff_filespec_is_binary(p->one) || if (diff_filespec_is_binary(options->repo, p->one) ||
diff_filespec_is_binary(p->two)) { diff_filespec_is_binary(options->repo, p->two)) {
git_SHA1_Update(&ctx, oid_to_hex(&p->one->oid), git_SHA1_Update(&ctx, oid_to_hex(&p->one->oid),
GIT_SHA1_HEXSZ); GIT_SHA1_HEXSZ);
git_SHA1_Update(&ctx, oid_to_hex(&p->two->oid), 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 */ /* 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) struct diff_filespec *two)
{ {
if (S_ISGITLINK(one->mode)) if (S_ISGITLINK(one->mode))
return 0; return 0;
if (diff_populate_filespec(one, 0)) if (diff_populate_filespec(r, one, 0))
return 0; return 0;
if (diff_populate_filespec(two, 0)) if (diff_populate_filespec(r, two, 0))
return 0; return 0;
return !memcmp(one->data, two->data, one->size); 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) if (p->done_skip_stat_unmatch)
return p->skip_stat_unmatch_result; 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) || !DIFF_FILE_VALID(p->two) ||
(p->one->oid_valid && p->two->oid_valid) || (p->one->oid_valid && p->two->oid_valid) ||
(p->one->mode != p->two->mode) || (p->one->mode != p->two->mode) ||
diff_populate_filespec(p->one, CHECK_SIZE_ONLY) || diff_populate_filespec(r, p->one, CHECK_SIZE_ONLY) ||
diff_populate_filespec(p->two, CHECK_SIZE_ONLY) || diff_populate_filespec(r, p->two, CHECK_SIZE_ONLY) ||
(p->one->size != p->two->size) || (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; p->skip_stat_unmatch_result = 1;
return p->skip_stat_unmatch_result; 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++) { for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[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); diff_q(&outq, p);
else { else {
/* /*
@ -6120,7 +6150,8 @@ void diffcore_std(struct diff_options *options)
if (!options->found_follow) { if (!options->found_follow) {
/* See try_to_follow_renames() in tree-diff.c */ /* See try_to_follow_renames() in tree-diff.c */
if (options->break_opt != -1) if (options->break_opt != -1)
diffcore_break(options->break_opt); diffcore_break(options->repo,
options->break_opt);
if (options->detect_rename) if (options->detect_rename)
diffcore_rename(options); diffcore_rename(options);
if (options->break_opt != -1) if (options->break_opt != -1)
@ -6271,7 +6302,7 @@ void diff_change(struct diff_options *options,
return; return;
if (options->flags.quick && options->skip_stat_unmatch && if (options->flags.quick && options->skip_stat_unmatch &&
!diff_filespec_check_stat_unmatch(p)) !diff_filespec_check_stat_unmatch(options->repo, p))
return; return;
options->flags.has_changes = 1; options->flags.has_changes = 1;
@ -6293,8 +6324,10 @@ struct diff_filepair *diff_unmerge(struct diff_options *options, const char *pat
return pair; return pair;
} }
static char *run_textconv(const char *pgm, struct diff_filespec *spec, static char *run_textconv(struct repository *r,
size_t *outsize) const char *pgm,
struct diff_filespec *spec,
size_t *outsize)
{ {
struct diff_tempfile *temp; struct diff_tempfile *temp;
const char *argv[3]; const char *argv[3];
@ -6303,7 +6336,7 @@ static char *run_textconv(const char *pgm, struct diff_filespec *spec,
struct strbuf buf = STRBUF_INIT; struct strbuf buf = STRBUF_INIT;
int err = 0; int err = 0;
temp = prepare_temp_file(spec->path, spec); temp = prepare_temp_file(r, spec->path, spec);
*arg++ = pgm; *arg++ = pgm;
*arg++ = temp->name; *arg++ = temp->name;
*arg = NULL; *arg = NULL;
@ -6330,7 +6363,8 @@ static char *run_textconv(const char *pgm, struct diff_filespec *spec,
return strbuf_detach(&buf, outsize); 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, struct diff_filespec *df,
char **outbuf) char **outbuf)
{ {
@ -6341,7 +6375,7 @@ size_t fill_textconv(struct userdiff_driver *driver,
*outbuf = ""; *outbuf = "";
return 0; return 0;
} }
if (diff_populate_filespec(df, 0)) if (diff_populate_filespec(r, df, 0))
die("unable to read files to diff"); die("unable to read files to diff");
*outbuf = df->data; *outbuf = df->data;
return df->size; return df->size;
@ -6358,7 +6392,7 @@ size_t fill_textconv(struct userdiff_driver *driver,
return size; return size;
} }
*outbuf = run_textconv(driver->textconv, df, &size); *outbuf = run_textconv(r, driver->textconv, df, &size);
if (!*outbuf) if (!*outbuf)
die("unable to read files to diff"); die("unable to read files to diff");
@ -6378,7 +6412,8 @@ size_t fill_textconv(struct userdiff_driver *driver,
return size; return size;
} }
int textconv_object(const char *path, int textconv_object(struct repository *r,
const char *path,
unsigned mode, unsigned mode,
const struct object_id *oid, const struct object_id *oid,
int oid_valid, int oid_valid,
@ -6390,13 +6425,13 @@ int textconv_object(const char *path,
df = alloc_filespec(path); df = alloc_filespec(path);
fill_filespec(df, oid, oid_valid, mode); fill_filespec(df, oid, oid_valid, mode);
textconv = get_textconv(df); textconv = get_textconv(r->index, df);
if (!textconv) { if (!textconv) {
free_filespec(df); free_filespec(df);
return 0; return 0;
} }
*buf_size = fill_textconv(textconv, df, buf); *buf_size = fill_textconv(r, textconv, df, buf);
free_filespec(df); free_filespec(df);
return 1; return 1;
} }

22
diff.h
View File

@ -18,6 +18,7 @@ struct userdiff_driver;
struct oid_array; struct oid_array;
struct commit; struct commit;
struct combine_diff_path; struct combine_diff_path;
struct repository;
typedef int (*pathchange_fn_t)(struct diff_options *options, typedef int (*pathchange_fn_t)(struct diff_options *options,
struct combine_diff_path *path); struct combine_diff_path *path);
@ -225,6 +226,8 @@ struct diff_options {
/* XDF_WHITESPACE_FLAGS regarding block detection are set at 2, 3, 4 */ /* XDF_WHITESPACE_FLAGS regarding block detection are set at 2, 3, 4 */
#define COLOR_MOVED_WS_ALLOW_INDENTATION_CHANGE (1<<5) #define COLOR_MOVED_WS_ALLOW_INDENTATION_CHANGE (1<<5)
int color_moved_ws_handling; int color_moved_ws_handling;
struct repository *repo;
}; };
void diff_emit_submodule_del(struct diff_options *o, const char *line); 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); int git_diff_heuristic_config(const char *var, const char *value, void *cb);
void init_diff_ui_defaults(void); void init_diff_ui_defaults(void);
int git_diff_ui_config(const char *var, const char *value, void *cb); 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 *); int diff_opt_parse(struct diff_options *, const char **, int, const char *);
void diff_setup_done(struct diff_options *); void diff_setup_done(struct diff_options *);
int git_config_rename(const char *var, const char *value); 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); 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 index_differs_from(const char *def, const struct diff_flags *flags,
int ita_invisible_in_index); 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 * struct. If it is non-NULL, then "outbuf" points to a newly allocated buffer
* that should be freed by the caller. * 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, struct diff_filespec *df,
char **outbuf); 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 * and only if it has textconv enabled (otherwise return NULL). The result
* can be passed to fill_textconv(). * 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 * Prepare diff_filespec and convert it using diff textconv API
* if the textconv driver exists. * if the textconv driver exists.
* Return 1 if the conversion succeeds, 0 otherwise. * 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); int parse_rename_score(const char **cp_p);

View File

@ -5,7 +5,8 @@
#include "diff.h" #include "diff.h"
#include "diffcore.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, struct diff_filespec *dst,
int break_score, int break_score,
int *merge_score_p) int *merge_score_p)
@ -61,7 +62,8 @@ static int should_break(struct diff_filespec *src,
oideq(&src->oid, &dst->oid)) oideq(&src->oid, &dst->oid))
return 0; /* they are the same */ 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 */ return 0; /* error but caught downstream */
max_size = ((src->size > dst->size) ? src->size : dst->size); 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) if (!src->size)
return 0; /* we do not let empty files get renamed */ 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->cnt_data, &dst->cnt_data,
&src_copied, &literal_added)) &src_copied, &literal_added))
return 0; return 0;
@ -114,7 +116,7 @@ static int should_break(struct diff_filespec *src,
return 1; 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 *q = &diff_queued_diff;
struct diff_queue_struct outq; 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->one->mode) == OBJ_BLOB &&
object_type(p->two->mode) == OBJ_BLOB && object_type(p->two->mode) == OBJ_BLOB &&
!strcmp(p->one->path, p->two->path)) { !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)) { break_score, &score)) {
/* Split this into delete and create */ /* Split this into delete and create */
struct diff_filespec *null_one, *null_two; 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; 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; int i, n;
unsigned int accum1, accum2, hashval; unsigned int accum1, accum2, hashval;
struct spanhash_top *hash; struct spanhash_top *hash;
unsigned char *buf = one->data; unsigned char *buf = one->data;
unsigned int sz = one->size; 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; i = INITIAL_HASH_SIZE;
hash = xmalloc(st_add(sizeof(*hash), hash = xmalloc(st_add(sizeof(*hash),
@ -162,7 +163,8 @@ static struct spanhash_top *hash_chars(struct diff_filespec *one)
return hash; 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, struct diff_filespec *dst,
void **src_count_p, void **src_count_p,
void **dst_count_p, void **dst_count_p,
@ -177,14 +179,14 @@ int diffcore_count_changes(struct diff_filespec *src,
if (src_count_p) if (src_count_p)
src_count = *src_count_p; src_count = *src_count_p;
if (!src_count) { if (!src_count) {
src_count = hash_chars(src); src_count = hash_chars(r, src);
if (src_count_p) if (src_count_p)
*src_count_p = src_count; *src_count_p = src_count;
} }
if (dst_count_p) if (dst_count_p)
dst_count = *dst_count_p; dst_count = *dst_count_p;
if (!dst_count) { if (!dst_count) {
dst_count = hash_chars(dst); dst_count = hash_chars(r, dst);
if (dst_count_p) if (dst_count_p)
*dst_count_p = dst_count; *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; return 0;
if (o->flags.allow_textconv) { if (o->flags.allow_textconv) {
textconv_one = get_textconv(p->one); textconv_one = get_textconv(o->repo->index, p->one);
textconv_two = get_textconv(p->two); 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)) if (textconv_one == textconv_two && diff_unmodified_pair(p))
return 0; return 0;
mf1.size = fill_textconv(textconv_one, p->one, &mf1.ptr); mf1.size = fill_textconv(o->repo, textconv_one, p->one, &mf1.ptr);
mf2.size = fill_textconv(textconv_two, p->two, &mf2.ptr); mf2.size = fill_textconv(o->repo, textconv_two, p->two, &mf2.ptr);
ret = fn(DIFF_FILE_VALID(p->one) ? &mf1 : NULL, ret = fn(DIFF_FILE_VALID(p->one) ? &mf1 : NULL,
DIFF_FILE_VALID(p->two) ? &mf2 : NULL, DIFF_FILE_VALID(p->two) ? &mf2 : NULL,

View File

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

View File

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

34
grep.c
View File

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

10
grep.h
View File

@ -36,6 +36,8 @@ typedef int pcre2_jit_stack;
#include "thread-utils.h" #include "thread-utils.h"
#include "userdiff.h" #include "userdiff.h"
struct repository;
enum grep_pat_token { enum grep_pat_token {
GREP_PATTERN, GREP_PATTERN,
GREP_PATTERN_HEAD, GREP_PATTERN_HEAD,
@ -136,6 +138,7 @@ struct grep_opt {
struct grep_pat *header_list; struct grep_pat *header_list;
struct grep_pat **header_tail; struct grep_pat **header_tail;
struct grep_expr *pattern_expression; struct grep_expr *pattern_expression;
struct repository *repo;
const char *prefix; const char *prefix;
int prefix_length; int prefix_length;
regex_t regexp; regex_t regexp;
@ -183,9 +186,9 @@ struct grep_opt {
void *output_priv; 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 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); 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); 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); const void *identifier);
void grep_source_clear_data(struct grep_source *gs); void grep_source_clear_data(struct grep_source *gs);
void grep_source_clear(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); 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)) if (!push_all && !is_null_oid(&ref->old_oid))
argv_array_pushf(&commit_argv, "^%s", argv_array_pushf(&commit_argv, "^%s",
oid_to_hex(&ref->old_oid)); 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); setup_revisions(commit_argv.argc, commit_argv.argv, &revs, NULL);
revs.edge_hint = 0; /* just in case */ 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; 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) unsigned long **line_ends)
{ {
int num = 0, size = 50; int num = 0, size = 50;
@ -516,7 +518,7 @@ static void fill_line_ends(struct diff_filespec *spec, long *lines,
unsigned long *ends = NULL; unsigned long *ends = NULL;
char *data = 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)); die("Cannot read blob %s", oid_to_hex(&spec->oid));
ALLOC_ARRAY(ends, size); ALLOC_ARRAY(ends, size);
@ -555,7 +557,8 @@ static const char *nth_line(void *data, long line)
} }
static struct line_log_data * 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; long lines = 0;
unsigned long *ends = NULL; 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 begin = 0, end = 0;
long anchor; 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]) if (!name_part || *name_part != ':' || !name_part[1])
die("-L argument not 'start,end:file' or ':funcname:file': %s", die("-L argument not 'start,end:file' or ':funcname:file': %s",
item->string); item->string);
@ -583,7 +586,7 @@ parse_lines(struct commit *commit, const char *prefix, struct string_list *args)
spec = alloc_filespec(full_name); spec = alloc_filespec(full_name);
fill_blob_sha1(commit, spec); fill_blob_sha1(commit, spec);
fill_line_ends(spec, &lines, &ends); fill_line_ends(r, spec, &lines, &ends);
cb_data.spec = spec; cb_data.spec = spec;
cb_data.lines = lines; cb_data.lines = lines;
cb_data.line_ends = ends; 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, if (parse_range_arg(range_part, nth_line, &cb_data,
lines, anchor, &begin, &end, lines, anchor, &begin, &end,
full_name)) full_name, r->index))
die("malformed -L argument '%s'", range_part); die("malformed -L argument '%s'", range_part);
if ((!lines && (begin || end)) || lines < begin) if ((!lines && (begin || end)) || lines < begin)
die("file %s has only %lu lines", name_part, lines); 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; struct line_log_data *range;
commit = check_single_commit(rev); 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); add_line_range(rev, commit, range);
if (!rev->diffopt.detect_rename) { 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; return;
if (pair->one->oid_valid) if (pair->one->oid_valid)
fill_line_ends(pair->one, &p_lines, &p_ends); fill_line_ends(rev->diffopt.repo, pair->one, &p_lines, &p_ends);
fill_line_ends(pair->two, &t_lines, &t_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%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, 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; return 0;
assert(pair->two->oid_valid); 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.ptr = pair->two->data;
file_target.size = pair->two->size; file_target.size = pair->two->size;
if (pair->one->oid_valid) { 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.ptr = pair->one->data;
file_parent.size = pair->one->size; file_parent.size = pair->one->size;
} else { } 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, static const char *parse_range_funcname(
void *cb_data, long lines, long anchor, long *begin, long *end, const char *arg, nth_line_fn_t nth_line_cb,
const char *path) void *cb_data, long lines, long anchor, long *begin, long *end,
const char *path, struct index_state *istate)
{ {
char *pattern; char *pattern;
const char *term; 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 */ anchor--; /* input is in human terms */
start = nth_line_cb(cb_data, anchor); 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) { if (drv && drv->funcname.pattern) {
const struct userdiff_funcname *pe = &drv->funcname; const struct userdiff_funcname *pe = &drv->funcname;
xecfg = xcalloc(1, sizeof(*xecfg)); 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, int parse_range_arg(const char *arg, nth_line_fn_t nth_line_cb,
void *cb_data, long lines, long anchor, 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; *begin = *end = 0;
@ -254,7 +256,9 @@ int parse_range_arg(const char *arg, nth_line_fn_t nth_line_cb,
anchor = lines + 1; anchor = lines + 1;
if (*arg == ':' || (*arg == '^' && *(arg + 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) if (!arg || *arg)
return -1; return -1;
return 0; return 0;
@ -275,10 +279,12 @@ int parse_range_arg(const char *arg, nth_line_fn_t nth_line_cb,
return 0; 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) == ':')) 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); arg = parse_loc(arg, NULL, NULL, 0, -1, NULL);

View File

@ -1,6 +1,8 @@
#ifndef LINE_RANGE_H #ifndef LINE_RANGE_H
#define 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 * Parse one item in an -L begin,end option w.r.t. the notional file
* object 'cb_data' consisting of 'lines' lines. * 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, nth_line_fn_t nth_line_cb,
void *cb_data, long lines, long anchor, void *cb_data, long lines, long anchor,
long *begin, long *end, long *begin, long *end,
const char *path); const char *path, struct index_state *istate);
/* /*
* Scan past a range argument that could be parsed by * 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. * 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 */ #endif /* LINE_RANGE_H */

View File

@ -196,7 +196,7 @@ static void mark_edge_parents_uninteresting(struct commit *commit,
struct commit *parent = parents->item; struct commit *parent = parents->item;
if (!(parent->object.flags & UNINTERESTING)) if (!(parent->object.flags & UNINTERESTING))
continue; 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)) { if (revs->edge_hint && !(parent->object.flags & SHOWN)) {
parent->object.flags |= SHOWN; parent->object.flags |= SHOWN;
show_edge(parent); 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; struct commit *commit = list->item;
if (commit->object.flags & UNINTERESTING) { 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)) { if (revs->edge_hint_aggressive && !(commit->object.flags & SHOWN)) {
commit->object.flags |= SHOWN; commit->object.flags |= SHOWN;
show_edge(commit); 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; struct commit *commit = (struct commit *)obj;
if (obj->type != OBJ_COMMIT || !(obj->flags & UNINTERESTING)) if (obj->type != OBJ_COMMIT || !(obj->flags & UNINTERESTING))
continue; continue;
mark_tree_uninteresting(get_commit_tree(commit)); mark_tree_uninteresting(revs->repo,
get_commit_tree(commit));
if (!(obj->flags & SHOWN)) { if (!(obj->flags & SHOWN)) {
obj->flags |= SHOWN; obj->flags |= SHOWN;
show_edge(commit); 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]; 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; 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); free(mm->ptr);
mm->size = strbuf.len; mm->size = strbuf.len;
mm->ptr = strbuf_detach(&strbuf, NULL); 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 *ancestor, const char *ancestor_label,
mmfile_t *ours, const char *our_label, mmfile_t *ours, const char *our_label,
mmfile_t *theirs, const char *their_label, mmfile_t *theirs, const char *their_label,
struct index_state *istate,
const struct ll_merge_options *opts) const struct ll_merge_options *opts)
{ {
static struct attr_check *check; static struct attr_check *check;
@ -363,15 +364,15 @@ int ll_merge(mmbuffer_t *result_buf,
opts = &default_opts; opts = &default_opts;
if (opts->renormalize) { if (opts->renormalize) {
normalize_file(ancestor, path); normalize_file(ancestor, path, istate);
normalize_file(ours, path); normalize_file(ours, path, istate);
normalize_file(theirs, path); normalize_file(theirs, path, istate);
} }
if (!check) if (!check)
check = attr_check_initl("merge", "conflict-marker-size", NULL); 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; ll_driver_name = check->items[0].value;
if (check->items[1].value) { if (check->items[1].value) {
marker_size = atoi(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); 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; static struct attr_check *check;
int marker_size = DEFAULT_CONFLICT_MARKER_SIZE; int marker_size = DEFAULT_CONFLICT_MARKER_SIZE;
if (!check) if (!check)
check = attr_check_initl("conflict-marker-size", NULL); 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) { if (check->items[0].value) {
marker_size = atoi(check->items[0].value); marker_size = atoi(check->items[0].value);
if (marker_size <= 0) if (marker_size <= 0)

View File

@ -7,6 +7,8 @@
#include "xdiff/xdiff.h" #include "xdiff/xdiff.h"
struct index_state;
struct ll_merge_options { struct ll_merge_options {
unsigned virtual_ancestor : 1; unsigned virtual_ancestor : 1;
unsigned variant : 2; /* favor ours, favor theirs, or union merge */ 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 *ancestor, const char *ancestor_label,
mmfile_t *ours, const char *our_label, mmfile_t *ours, const char *our_label,
mmfile_t *theirs, const char *their_label, mmfile_t *theirs, const char *their_label,
struct index_state *istate,
const struct ll_merge_options *opts); 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 #endif

View File

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

View File

@ -1,8 +1,11 @@
#ifndef MERGE_BLOBS_H #ifndef MERGE_BLOBS_H
#define 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 */ #endif /* MERGE_BLOBS_H */

View File

@ -1084,7 +1084,8 @@ static int merge_3way(struct merge_options *o,
read_mmblob(&src2, &b->oid); read_mmblob(&src2, &b->oid);
merge_status = ll_merge(result_buf, a->path, &orig, base_name, 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(base_name);
free(name1); 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 */ /* get all revisions that merge commit a */
xsnprintf(merged_revision, sizeof(merged_revision), "^%s", xsnprintf(merged_revision, sizeof(merged_revision), "^%s",
oid_to_hex(&a->object.oid)); oid_to_hex(&a->object.oid));
init_revisions(&revs, NULL); repo_init_revisions(the_repository, &revs, NULL);
rev_opts.submodule = path; rev_opts.submodule = path;
/* FIXME: can't handle linked worktrees in submodules yet */ /* FIXME: can't handle linked worktrees in submodules yet */
revs.single_worktree = path != NULL; 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_queue_struct *ret;
struct diff_options opts; struct diff_options opts;
diff_setup(&opts); repo_diff_setup(the_repository, &opts);
opts.flags.recursive = 1; opts.flags.recursive = 1;
opts.flags.rename_empty = 0; opts.flags.rename_empty = 0;
opts.detect_rename = merge_detect_rename(o); 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); 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 **xopts, struct commit_list *common,
const char *head_arg, struct commit_list *remotes) 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); ret = run_command_v_opt(args.argv, RUN_GIT_CMD);
argv_array_clear(&args); argv_array_clear(&args);
discard_cache(); discard_index(r->index);
if (read_cache() < 0) if (read_index(r->index) < 0)
die(_("failed to read the cache")); die(_("failed to read the cache"));
resolve_undo_clear(); resolve_undo_clear_index(r->index);
return ret; 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, const struct object_id *remote,
int overwrite_ignore) int overwrite_ignore)
{ {
@ -54,7 +56,7 @@ int checkout_fast_forward(const struct object_id *head,
struct dir_struct dir; struct dir_struct dir;
struct lock_file lock_file = LOCK_INIT; 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) if (hold_locked_index(&lock_file, LOCK_REPORT_ON_ERROR) < 0)
return -1; return -1;
@ -86,8 +88,8 @@ int checkout_fast_forward(const struct object_id *head,
} }
opts.head_idx = 1; opts.head_idx = 1;
opts.src_index = &the_index; opts.src_index = r->index;
opts.dst_index = &the_index; opts.dst_index = r->index;
opts.update = 1; opts.update = 1;
opts.verbose_update = 1; opts.verbose_update = 1;
opts.merge = 1; opts.merge = 1;
@ -101,7 +103,7 @@ int checkout_fast_forward(const struct object_id *head,
} }
clear_unpack_trees_porcelain(&opts); 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 error(_("unable to write new index file"));
return 0; 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", trace_printf("\tdiff_tree_remote(base = %.7s, remote = %.7s)\n",
oid_to_hex(base), oid_to_hex(remote)); oid_to_hex(base), oid_to_hex(remote));
diff_setup(&opt); repo_diff_setup(the_repository, &opt);
opt.flags.recursive = 1; opt.flags.recursive = 1;
opt.output_format = DIFF_FORMAT_NO_OUTPUT; opt.output_format = DIFF_FORMAT_NO_OUTPUT;
diff_setup_done(&opt); 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", trace_printf("\tdiff_tree_local(len = %i, base = %.7s, local = %.7s)\n",
len, oid_to_hex(base), oid_to_hex(local)); len, oid_to_hex(base), oid_to_hex(local));
diff_setup(&opt); repo_diff_setup(the_repository, &opt);
opt.flags.recursive = 1; opt.flags.recursive = 1;
opt.output_format = DIFF_FORMAT_NO_OUTPUT; opt.output_format = DIFF_FORMAT_NO_OUTPUT;
diff_setup_done(&opt); diff_setup_done(&opt);
@ -349,7 +349,8 @@ static int ll_merge_in_worktree(struct notes_merge_options *o,
read_mmblob(&remote, &p->remote); read_mmblob(&remote, &p->remote);
status = ll_merge(&result_buf, oid_to_hex(&p->obj), &base, NULL, 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(base.ptr);
free(local.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 */ /* write file as blob, and add to partial_tree */
if (stat(path.buf, &st)) if (stat(path.buf, &st))
die_errno("Failed to stat '%s'", path.buf); 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); die("Failed to write blob object from '%s'", path.buf);
if (add_note(partial_tree, &obj_oid, &blob_oid, NULL)) if (add_note(partial_tree, &obj_oid, &blob_oid, NULL))
die("Failed to add resolved note '%s' to notes tree", 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) if (writer.show_progress)
writer.progress = start_progress("Building bitmaps", writer.selected_nr); 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.tag_objects = 1;
revs.tree_objects = 1; revs.tree_objects = 1;
revs.blob_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); 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)); memset(ids, 0, sizeof(*ids));
diff_setup(&ids->diffopts); repo_diff_setup(r, &ids->diffopts);
ids->diffopts.detect_rename = 0; ids->diffopts.detect_rename = 0;
ids->diffopts.flags.recursive = 1; ids->diffopts.flags.recursive = 1;
diff_setup_done(&ids->diffopts); diff_setup_done(&ids->diffopts);

View File

@ -6,6 +6,7 @@
struct commit; struct commit;
struct object_id; struct object_id;
struct repository;
struct patch_id { struct patch_id {
struct hashmap_entry ent; struct hashmap_entry ent;
@ -20,7 +21,7 @@ struct patch_ids {
int commit_patch_id(struct commit *commit, struct diff_options *options, int commit_patch_id(struct commit *commit, struct diff_options *options,
struct object_id *oid, int); 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 *); int free_patch_ids(struct patch_ids *);
struct patch_id *add_commit_patch_id(struct commit *, 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 *); 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 match = -1;
int fd = git_open_cloexec(ce->name, O_RDONLY); int fd = git_open_cloexec(ce->name, O_RDONLY);
if (fd >= 0) { if (fd >= 0) {
struct object_id oid; 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); match = !oideq(&oid, &ce->oid);
/* index_fd() closed the file descriptor already */ /* 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); 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) { switch (st->st_mode & S_IFMT) {
case S_IFREG: case S_IFREG:
if (ce_compare_data(ce, st)) if (ce_compare_data(istate, ce, st))
return DATA_CHANGED; return DATA_CHANGED;
break; break;
case S_IFLNK: case S_IFLNK:
@ -407,7 +411,7 @@ int ie_match_stat(struct index_state *istate,
if (assume_racy_is_modified) if (assume_racy_is_modified)
changed |= DATA_CHANGED; changed |= DATA_CHANGED;
else else
changed |= ce_modified_check_fs(ce, st); changed |= ce_modified_check_fs(istate, ce, st);
} }
return changed; 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)) (S_ISGITLINK(ce->ce_mode) || ce->ce_stat_data.sd_size != 0))
return changed; return changed;
changed_fs = ce_modified_check_fs(ce, st); changed_fs = ce_modified_check_fs(istate, ce, st);
if (changed_fs) if (changed_fs)
return changed | changed_fs; return changed | changed_fs;
return 0; return 0;
@ -753,7 +757,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
} }
} }
if (!intent_only) { if (!intent_only) {
if (index_path(&ce->oid, path, st, newflags)) { if (index_path(istate, &ce->oid, path, st, newflags)) {
discard_cache_entry(ce); discard_cache_entry(ce);
return error("unable to index file %s", path); 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_namelen = len;
ce->ce_mode = create_ce_mode(mode); 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) if (ret != ce)
discard_cache_entry(ce); discard_cache_entry(ce);
return ret; return ret;
@ -1493,7 +1497,7 @@ int refresh_index(struct index_state *istate, unsigned int flags,
if (ignore_submodules && S_ISGITLINK(ce->ce_mode)) if (ignore_submodules && S_ISGITLINK(ce->ce_mode))
continue; continue;
if (pathspec && !ce_path_match(&the_index, ce, pathspec, seen)) if (pathspec && !ce_path_match(istate, ce, pathspec, seen))
filtered = 1; filtered = 1;
if (ce_stage(ce)) { if (ce_stage(ce)) {
@ -2123,7 +2127,7 @@ int unmerged_index(const struct index_state *istate)
return 0; return 0;
} }
int index_has_changes(const struct index_state *istate, int index_has_changes(struct index_state *istate,
struct tree *tree, struct tree *tree,
struct strbuf *sb) struct strbuf *sb)
{ {
@ -2138,7 +2142,7 @@ int index_has_changes(const struct index_state *istate,
if (tree || !get_oid_tree("HEAD", &cmp)) { if (tree || !get_oid_tree("HEAD", &cmp)) {
struct diff_options opt; struct diff_options opt;
diff_setup(&opt); repo_diff_setup(the_repository, &opt);
opt.flags.exit_with_status = 1; opt.flags.exit_with_status = 1;
if (!sb) if (!sb)
opt.flags.quick = 1; 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; 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 * 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; return;
if (ce_match_stat_basic(ce, &st)) if (ce_match_stat_basic(ce, &st))
return; 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 /* This is "racily clean"; smudge it. Note that this
* is a tricky code. At first glance, it may appear * is a tricky code. At first glance, it may appear
* that it can break with this sequence: * 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) if (ce->ce_flags & CE_REMOVE)
continue; continue;
if (!ce_uptodate(ce) && is_racy_timestamp(istate, ce)) 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)) { if (is_null_oid(&ce->oid)) {
static const char msg[] = "cache entry has null sha1: %s"; static const char msg[] = "cache entry has null sha1: %s";
static int allow = -1; 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 ref_array *array = ref_cbdata->array;
struct commit **to_clear = xcalloc(sizeof(struct commit *), array->nr); 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++) { for (i = 0; i < array->nr; i++) {
struct ref_array_item *item = array->items[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)); oid_to_hex(&theirs->object.oid));
argv_array_push(&argv, "--"); argv_array_push(&argv, "--");
init_revisions(&revs, NULL); repo_init_revisions(the_repository, &revs, NULL);
setup_revisions(argv.argc, argv.argv, &revs, NULL); setup_revisions(argv.argc, argv.argv, &revs, NULL);
if (prepare_revision_walk(&revs)) if (prepare_revision_walk(&revs))
die("revision walk setup failed"); 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 * Scan the path for conflicts, do the "handle_path()" thing above, and
* return the number of conflict hunks found. * 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; int has_conflicts = 0;
struct rerere_io_file io; 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)); memset(&io, 0, sizeof(io));
io.io.getline = rerere_file_getline; 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 * stages we have already looked at in this invocation of this
* function. * 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)) { if (!ce_stage(e)) {
*type = RESOLVED; *type = RESOLVED;
@ -521,13 +522,13 @@ static int check_one_conflict(int i, int *type)
} }
*type = PUNTED; *type = PUNTED;
while (i < active_nr && ce_stage(active_cache[i]) == 1) while (i < istate->cache_nr && ce_stage(istate->cache[i]) == 1)
i++; i++;
/* Only handle regular files with both stages #2 and #3 */ /* Only handle regular files with both stages #2 and #3 */
if (i + 1 < active_nr) { if (i + 1 < istate->cache_nr) {
const struct cache_entry *e2 = active_cache[i]; const struct cache_entry *e2 = istate->cache[i];
const struct cache_entry *e3 = active_cache[i + 1]; const struct cache_entry *e3 = istate->cache[i + 1];
if (ce_stage(e2) == 2 && if (ce_stage(e2) == 2 &&
ce_stage(e3) == 3 && ce_stage(e3) == 3 &&
ce_same_name(e, e3) && 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 */ /* 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++; i++;
return 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, * are identical to the previous round, might want to be handled,
* though. * though.
*/ */
static int find_conflict(struct string_list *conflict) static int find_conflict(struct repository *r, struct string_list *conflict)
{ {
int i; int i;
if (read_cache() < 0)
if (read_index(r->index) < 0)
return error(_("index file corrupt")); return error(_("index file corrupt"));
for (i = 0; i < active_nr;) { for (i = 0; i < r->index->cache_nr;) {
int conflict_type; int conflict_type;
const struct cache_entry *e = active_cache[i]; const struct cache_entry *e = r->index->cache[i];
i = check_one_conflict(i, &conflict_type); i = check_one_conflict(r->index, i, &conflict_type);
if (conflict_type == THREE_STAGED) if (conflict_type == THREE_STAGED)
string_list_insert(conflict, (const char *)e->name); 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 * NEEDSWORK: we may want to fix the caller that implements "rerere
* remaining" to do this without abusing merge_rr. * 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; int i;
if (setup_rerere(merge_rr, RERERE_READONLY)) if (setup_rerere(merge_rr, RERERE_READONLY))
return 0; return 0;
if (read_cache() < 0) if (read_index(r->index) < 0)
return error(_("index file corrupt")); return error(_("index file corrupt"));
for (i = 0; i < active_nr;) { for (i = 0; i < r->index->cache_nr;) {
int conflict_type; int conflict_type;
const struct cache_entry *e = active_cache[i]; const struct cache_entry *e = r->index->cache[i];
i = check_one_conflict(i, &conflict_type); i = check_one_conflict(r->index, i, &conflict_type);
if (conflict_type == PUNTED) if (conflict_type == PUNTED)
string_list_insert(merge_rr, (const char *)e->name); string_list_insert(merge_rr, (const char *)e->name);
else if (conflict_type == RESOLVED) { 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 * if that recorded conflict resolves cleanly what we
* got in the "cur". * 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) mmfile_t *cur, mmbuffer_t *result)
{ {
int ret; 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 * A three-way merge. Note that this honors user-customizable
* low-level merge driver settings. * 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(base.ptr);
free(other.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 * Returns 0 for successful replay of recorded resolution, or non-zero
* for failure. * 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; FILE *f;
int ret; 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 * Normalize the conflicts in path and write it out to
* "thisimage" temporary file. * "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"))) { read_mmfile(&cur, rerere_path(id, "thisimage"))) {
ret = 1; ret = 1;
goto out; goto out;
} }
ret = try_merge(id, path, &cur, &result); ret = try_merge(istate, id, path, &cur, &result);
if (ret) if (ret)
goto out; goto out;
@ -692,7 +697,7 @@ static int merge(const struct rerere_id *id, const char *path)
return ret; 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; struct lock_file index_lock = LOCK_INIT;
int i; int i;
@ -701,13 +706,13 @@ static void update_paths(struct string_list *update)
for (i = 0; i < update->nr; i++) { for (i = 0; i < update->nr; i++) {
struct string_list_item *item = &update->items[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); exit(128);
fprintf_ln(stderr, _("Staged '%s' using previous resolution."), fprintf_ln(stderr, _("Staged '%s' using previous resolution."),
item->string); item->string);
} }
if (write_locked_index(&the_index, &index_lock, if (write_locked_index(r->index, &index_lock,
COMMIT_LOCK | SKIP_IF_UNCHANGED)) COMMIT_LOCK | SKIP_IF_UNCHANGED))
die(_("unable to write new index file")); 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 * only have the preimage for that conflict, in which case the result
* needs to be recorded as a resolution in a postimage file. * 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) struct string_list *update)
{ {
const char *path = rr_item->string; 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? */ /* Has the user resolved it already? */
if (variant >= 0) { if (variant >= 0) {
if (!handle_file(path, NULL, NULL)) { if (!handle_file(istate, path, NULL, NULL)) {
copy_file(rerere_path(id, "postimage"), path, 0666); copy_file(rerere_path(id, "postimage"), path, 0666);
id->collection->status[variant] |= RR_HAS_POSTIMAGE; id->collection->status[variant] |= RR_HAS_POSTIMAGE;
fprintf_ln(stderr, _("Recorded resolution for '%s'."), path); 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; continue;
vid.variant = variant; vid.variant = variant;
if (merge(&vid, path)) if (merge(istate, &vid, path))
continue; /* failed to replay */ continue; /* failed to replay */
/* /*
@ -787,7 +793,7 @@ static void do_rerere_one_path(struct string_list_item *rr_item,
assign_variant(id); assign_variant(id);
variant = id->variant; 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) { if (id->collection->status[variant] & RR_HAS_POSTIMAGE) {
const char *path = rerere_path(id, "postimage"); const char *path = rerere_path(id, "postimage");
if (unlink(path)) 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); 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 conflict = STRING_LIST_INIT_DUP;
struct string_list update = STRING_LIST_INIT_DUP; struct string_list update = STRING_LIST_INIT_DUP;
int i; int i;
find_conflict(&conflict); find_conflict(r, &conflict);
/* /*
* MERGE_RR records paths with conflicts immediately after * 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 * conflict ID. No need to write anything out
* yet. * yet.
*/ */
ret = handle_file(path, sha1, NULL); ret = handle_file(r->index, path, sha1, NULL);
if (ret != 0 && string_list_has_string(rr, path)) { if (ret != 0 && string_list_has_string(rr, path)) {
remove_variant(string_list_lookup(rr, path)->util); remove_variant(string_list_lookup(rr, path)->util);
string_list_remove(rr, path, 1); 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++) 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) if (update.nr)
update_paths(&update); update_paths(r, &update);
return write_rr(rr, fd); 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 * perform mergy operations, possibly leaving conflicted index entries
* and working tree files. * 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; struct string_list merge_rr = STRING_LIST_INIT_DUP;
int fd, status; int fd, status;
@ -905,7 +912,7 @@ int rerere(int flags)
fd = setup_rerere(&merge_rr, flags); fd = setup_rerere(&merge_rr, flags);
if (fd < 0) if (fd < 0)
return 0; return 0;
status = do_plain_rerere(&merge_rr, fd); status = do_plain_rerere(r, &merge_rr, fd);
free_rerere_dirs(); free_rerere_dirs();
return status; return status;
} }
@ -942,29 +949,30 @@ static int rerere_mem_getline(struct strbuf *sb, struct rerere_io *io_)
return 0; 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}}; mmfile_t mmfile[3] = {{NULL}};
mmbuffer_t result = {NULL, 0}; mmbuffer_t result = {NULL, 0};
const struct cache_entry *ce; const struct cache_entry *ce;
int pos, len, i, has_conflicts; int pos, len, i, has_conflicts;
struct rerere_io_mem io; 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 * Reproduce the conflicted merge in-core
*/ */
len = strlen(path); len = strlen(path);
pos = cache_name_pos(path, len); pos = index_name_pos(istate, path, len);
if (0 <= pos) if (0 <= pos)
return -1; return -1;
pos = -pos - 1; pos = -pos - 1;
while (pos < active_nr) { while (pos < istate->cache_nr) {
enum object_type type; enum object_type type;
unsigned long size; unsigned long size;
ce = active_cache[pos++]; ce = istate->cache[pos++];
if (ce_namelen(ce) != len || memcmp(ce->name, path, len)) if (ce_namelen(ce) != len || memcmp(ce->name, path, len))
break; break;
i = ce_stage(ce) - 1; 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, ll_merge(&result, path, &mmfile[0], NULL,
&mmfile[1], "ours", &mmfile[1], "ours",
&mmfile[2], "theirs", NULL); &mmfile[2], "theirs",
istate, NULL);
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
free(mmfile[i].ptr); free(mmfile[i].ptr);
@ -1008,7 +1017,9 @@ static int handle_cache(const char *path, unsigned char *sha1, const char *outpu
return has_conflicts; 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; const char *filename;
struct rerere_id *id; 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 * Recreate the original conflict from the stages in the
* index and compute the conflict ID * index and compute the conflict ID
*/ */
ret = handle_cache(path, sha1, NULL); ret = handle_cache(istate, path, sha1, NULL);
if (ret < 1) if (ret < 1)
return error(_("could not parse conflict hunks in '%s'"), path); 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)) if (!has_rerere_resolution(id))
continue; 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"))) { if (read_mmfile(&cur, rerere_path(id, "thisimage"))) {
free(cur.ptr); free(cur.ptr);
error(_("failed to update conflicted state in '%s'"), path); error(_("failed to update conflicted state in '%s'"), path);
goto fail_exit; goto fail_exit;
} }
cleanly_resolved = !try_merge(id, path, &cur, &result); cleanly_resolved = !try_merge(istate, id, path, &cur, &result);
free(result.ptr); free(result.ptr);
free(cur.ptr); free(cur.ptr);
if (cleanly_resolved) 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 * conflict in the working tree, run us again to record
* the postimage. * 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); 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; return -1;
} }
int rerere_forget(struct pathspec *pathspec) int rerere_forget(struct repository *r, struct pathspec *pathspec)
{ {
int i, fd; int i, fd;
struct string_list conflict = STRING_LIST_INIT_DUP; struct string_list conflict = STRING_LIST_INIT_DUP;
struct string_list merge_rr = 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")); return error(_("index file corrupt"));
fd = setup_rerere(&merge_rr, RERERE_NOAUTOUPDATE); fd = setup_rerere(&merge_rr, RERERE_NOAUTOUPDATE);
@ -1105,14 +1116,14 @@ int rerere_forget(struct pathspec *pathspec)
* recover the original conflicted state and then * recover the original conflicted state and then
* find the conflicted paths. * find the conflicted paths.
*/ */
unmerge_cache(pathspec); unmerge_index(r->index, pathspec);
find_conflict(&conflict); find_conflict(r, &conflict);
for (i = 0; i < conflict.nr; i++) { for (i = 0; i < conflict.nr; i++) {
struct string_list_item *it = &conflict.items[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)) strlen(it->string), 0, NULL, 0))
continue; 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); return write_rr(&merge_rr, fd);
} }

View File

@ -4,6 +4,7 @@
#include "string-list.h" #include "string-list.h"
struct pathspec; struct pathspec;
struct repository;
#define RERERE_AUTOUPDATE 01 #define RERERE_AUTOUPDATE 01
#define RERERE_NOAUTOUPDATE 02 #define RERERE_NOAUTOUPDATE 02
@ -23,7 +24,10 @@ struct rerere_id {
}; };
int setup_rerere(struct string_list *, int); 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 * Given the conflict ID and the name of a "file" used for replaying
* the recorded resolution (e.g. "preimage", "postimage"), return the * 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. * return the path to the directory that houses these files.
*/ */
const char *rerere_path(const struct rerere_id *, const char *file); const char *rerere_path(const struct rerere_id *, const char *file);
int rerere_forget(struct pathspec *); int rerere_forget(struct repository *, struct pathspec *);
int rerere_remaining(struct string_list *); int rerere_remaining(struct repository *, struct string_list *);
void rerere_clear(struct string_list *); void rerere_clear(struct string_list *);
void rerere_gc(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; 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 tree_desc desc;
struct name_entry entry; struct name_entry entry;
@ -64,10 +65,10 @@ static void mark_tree_contents_uninteresting(struct tree *tree)
while (tree_entry(&desc, &entry)) { while (tree_entry(&desc, &entry)) {
switch (object_type(entry.mode)) { switch (object_type(entry.mode)) {
case OBJ_TREE: case OBJ_TREE:
mark_tree_uninteresting(lookup_tree(the_repository, entry.oid)); mark_tree_uninteresting(r, lookup_tree(r, entry.oid));
break; break;
case OBJ_BLOB: case OBJ_BLOB:
mark_blob_uninteresting(lookup_blob(the_repository, entry.oid)); mark_blob_uninteresting(lookup_blob(r, entry.oid));
break; break;
default: default:
/* Subproject commit - not in this repository */ /* Subproject commit - not in this repository */
@ -82,7 +83,7 @@ static void mark_tree_contents_uninteresting(struct tree *tree)
free_tree_buffer(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; struct object *obj;
@ -93,7 +94,7 @@ void mark_tree_uninteresting(struct tree *tree)
if (obj->flags & UNINTERESTING) if (obj->flags & UNINTERESTING)
return; return;
obj->flags |= UNINTERESTING; obj->flags |= UNINTERESTING;
mark_tree_contents_uninteresting(tree); mark_tree_contents_uninteresting(r, tree);
} }
struct commit_stack { struct commit_stack {
@ -199,7 +200,7 @@ void add_head_to_pending(struct rev_info *revs)
struct object *obj; struct object *obj;
if (get_oid("HEAD", &oid)) if (get_oid("HEAD", &oid))
return; return;
obj = parse_object(the_repository, &oid); obj = parse_object(revs->repo, &oid);
if (!obj) if (!obj)
return; return;
add_pending_object(revs, obj, "HEAD"); 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; struct object *object;
object = parse_object(the_repository, oid); object = parse_object(revs->repo, oid);
if (!object) { if (!object) {
if (revs->ignore_missing) if (revs->ignore_missing)
return object; return object;
@ -248,7 +249,7 @@ static struct commit *handle_commit(struct rev_info *revs,
add_pending_object(revs, object, tag->tag); add_pending_object(revs, object, tag->tag);
if (!tag->tagged) if (!tag->tagged)
die("bad tag"); die("bad tag");
object = parse_object(the_repository, &tag->tagged->oid); object = parse_object(revs->repo, &tag->tagged->oid);
if (!object) { if (!object) {
if (revs->ignore_missing_links || (flags & UNINTERESTING)) if (revs->ignore_missing_links || (flags & UNINTERESTING))
return NULL; return NULL;
@ -298,7 +299,7 @@ static struct commit *handle_commit(struct rev_info *revs,
if (!revs->tree_objects) if (!revs->tree_objects)
return NULL; return NULL;
if (flags & UNINTERESTING) { if (flags & UNINTERESTING) {
mark_tree_contents_uninteresting(tree); mark_tree_contents_uninteresting(revs->repo, tree);
return NULL; return NULL;
} }
add_pending_object_with_path(revs, object, name, mode, path); 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; return;
left_first = left_count < right_count; left_first = left_count < right_count;
init_patch_ids(&ids); init_patch_ids(revs->repo, &ids);
ids.diffopts.pathspec = revs->diffopt.pathspec; ids.diffopts.pathspec = revs->diffopt.pathspec;
/* Compute patch-ids for one side */ /* 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; struct all_refs_cb *cb = cb_data;
if (!is_null_oid(oid)) { 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) { if (o) {
o->flags |= cb->all_flags; o->flags |= cb->all_flags;
/* ??? CMDLINEFLAGS ??? */ /* ??? CMDLINEFLAGS ??? */
@ -1313,7 +1314,7 @@ void add_reflogs_to_pending(struct rev_info *revs, unsigned flags)
cb.all_revs = revs; cb.all_revs = revs;
cb.all_flags = flags; 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); for_each_reflog(handle_one_reflog, &cb);
if (!revs->single_worktree) if (!revs->single_worktree)
@ -1327,7 +1328,7 @@ static void add_cache_tree(struct cache_tree *it, struct rev_info *revs,
int i; int i;
if (it->entry_count >= 0) { 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, "", add_pending_object_with_path(revs, &tree->object, "",
040000, path->buf); 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)) if (S_ISGITLINK(ce->ce_mode))
continue; continue;
blob = lookup_blob(the_repository, &ce->oid); blob = lookup_blob(revs->repo, &ce->oid);
if (!blob) if (!blob)
die("unable to add index blob to traversal"); die("unable to add index blob to traversal");
add_pending_object_with_path(revs, &blob->object, "", 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; struct worktree **worktrees, **p;
read_cache(); read_index(revs->repo->index);
do_add_index_objects_to_pending(revs, &the_index); do_add_index_objects_to_pending(revs, revs->repo->index);
if (revs->single_worktree) if (revs->single_worktree)
return; return;
@ -1440,10 +1441,13 @@ static int add_parents_only(struct rev_info *revs, const char *arg_, int flags,
return 1; 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)); memset(revs, 0, sizeof(*revs));
revs->repo = r;
revs->abbrev = DEFAULT_ABBREV; revs->abbrev = DEFAULT_ABBREV;
revs->ignore_merges = 1; revs->ignore_merges = 1;
revs->simplify_history = 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->commit_format = CMIT_FMT_DEFAULT;
revs->expand_tabs_in_log_default = 8; revs->expand_tabs_in_log_default = 8;
init_grep_defaults(); init_grep_defaults(revs->repo);
grep_init(&revs->grep_filter, prefix); grep_init(&revs->grep_filter, revs->repo, prefix);
revs->grep_filter.status_only = 1; revs->grep_filter.status_only = 1;
diff_setup(&revs->diffopt); repo_diff_setup(revs->repo, &revs->diffopt);
if (prefix && !revs->diffopt.prefix) { if (prefix && !revs->diffopt.prefix) {
revs->diffopt.prefix = prefix; revs->diffopt.prefix = prefix;
revs->diffopt.prefix_length = strlen(prefix); revs->diffopt.prefix_length = strlen(prefix);
@ -1497,6 +1501,7 @@ static void prepare_show_merge(struct rev_info *revs)
struct object_id oid; struct object_id oid;
const char **prune = NULL; const char **prune = NULL;
int i, prune_num = 1; /* counting terminating NULL */ int i, prune_num = 1; /* counting terminating NULL */
struct index_state *istate = revs->repo->index;
if (get_oid("HEAD", &oid)) if (get_oid("HEAD", &oid))
die("--merge without HEAD?"); die("--merge without HEAD?");
@ -1512,20 +1517,20 @@ static void prepare_show_merge(struct rev_info *revs)
free_commit_list(bases); free_commit_list(bases);
head->object.flags |= SYMMETRIC_LEFT; head->object.flags |= SYMMETRIC_LEFT;
if (!active_nr) if (!istate->cache_nr)
read_cache(); read_index(istate);
for (i = 0; i < active_nr; i++) { for (i = 0; i < istate->cache_nr; i++) {
const struct cache_entry *ce = active_cache[i]; const struct cache_entry *ce = istate->cache[i];
if (!ce_stage(ce)) if (!ce_stage(ce))
continue; continue;
if (ce_path_match(&the_index, ce, &revs->prune_data, NULL)) { if (ce_path_match(istate, ce, &revs->prune_data, NULL)) {
prune_num++; prune_num++;
REALLOC_ARRAY(prune, prune_num); REALLOC_ARRAY(prune, prune_num);
prune[prune_num-2] = ce->name; prune[prune_num-2] = ce->name;
prune[prune_num-1] = NULL; prune[prune_num-1] = NULL;
} }
while ((i+1 < active_nr) && while ((i+1 < istate->cache_nr) &&
ce_same_name(ce, active_cache[i+1])) ce_same_name(ce, istate->cache[i+1]))
i++; i++;
} }
clear_pathspec(&revs->prune_data); clear_pathspec(&revs->prune_data);
@ -1582,8 +1587,8 @@ static int handle_dotdot_1(const char *arg, char *dotdot,
*dotdot = '\0'; *dotdot = '\0';
} }
a_obj = parse_object(the_repository, &a_oid); a_obj = parse_object(revs->repo, &a_oid);
b_obj = parse_object(the_repository, &b_oid); b_obj = parse_object(revs->repo, &b_oid);
if (!a_obj || !b_obj) if (!a_obj || !b_obj)
return dotdot_missing(arg, dotdot, revs, symmetric); 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 *a, *b;
struct commit_list *exclude; struct commit_list *exclude;
a = lookup_commit_reference(the_repository, &a_obj->oid); a = lookup_commit_reference(revs->repo, &a_obj->oid);
b = lookup_commit_reference(the_repository, &b_obj->oid); b = lookup_commit_reference(revs->repo, &b_obj->oid);
if (!a || !b) if (!a || !b)
return dotdot_missing(arg, dotdot, revs, symmetric); 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"); BUG("--single-worktree cannot be used together with submodule");
refs = get_submodule_ref_store(submodule); refs = get_submodule_ref_store(submodule);
} else } else
refs = get_main_ref_store(the_repository); refs = get_main_ref_store(revs->repo);
/* /*
* NOTE! * NOTE!
@ -2885,9 +2890,10 @@ void reset_revision_walk(void)
static int mark_uninteresting(const struct object_id *oid, static int mark_uninteresting(const struct object_id *oid,
struct packed_git *pack, struct packed_git *pack,
uint32_t pos, 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; o->flags |= UNINTERESTING | SEEN;
return 0; return 0;
} }
@ -2920,7 +2926,7 @@ int prepare_revision_walk(struct rev_info *revs)
revs->treesame.name = "treesame"; revs->treesame.name = "treesame";
if (revs->exclude_promisor_objects) { if (revs->exclude_promisor_objects) {
for_each_packed_object(mark_uninteresting, NULL, for_each_packed_object(mark_uninteresting, revs,
FOR_EACH_OBJECT_PROMISOR_ONLY); FOR_EACH_OBJECT_PROMISOR_ONLY);
} }

View File

@ -28,8 +28,9 @@
#define DECORATE_SHORT_REFS 1 #define DECORATE_SHORT_REFS 1
#define DECORATE_FULL_REFS 2 #define DECORATE_FULL_REFS 2
struct rev_info;
struct log_info; struct log_info;
struct repository;
struct rev_info;
struct string_list; struct string_list;
struct saved_parents; struct saved_parents;
define_shared_commit_slab(revision_sources, char *); define_shared_commit_slab(revision_sources, char *);
@ -60,6 +61,7 @@ struct rev_info {
/* Starting list */ /* Starting list */
struct commit_list *commits; struct commit_list *commits;
struct object_array pending; struct object_array pending;
struct repository *repo;
/* Parents of shown commits */ /* Parents of shown commits */
struct object_array boundary_commits; struct object_array boundary_commits;
@ -264,12 +266,17 @@ extern volatile show_early_output_fn_t show_early_output;
struct setup_revision_opt { struct setup_revision_opt {
const char *def; const char *def;
void (*tweak)(struct rev_info *, struct setup_revision_opt *); 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; int assume_dashdash;
unsigned revarg_opt; 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, int setup_revisions(int argc, const char **argv, struct rev_info *revs,
struct setup_revision_opt *); struct setup_revision_opt *);
void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx, 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); const struct commit *commit);
void mark_parents_uninteresting(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 *); 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 sb = STRBUF_INIT;
struct strbuf err = STRBUF_INIT; struct strbuf err = STRBUF_INIT;
read_cache(); read_index(&the_index);
if (checkout_fast_forward(from, to, 1)) if (checkout_fast_forward(the_repository, from, to, 1))
return -1; /* the callee should have complained already */ return -1; /* the callee should have complained already */
strbuf_addf(&sb, _("%s: fast-forward"), _(action_name(opts))); 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(&author_ident);
strbuf_release(&committer_ident); strbuf_release(&committer_ident);
init_revisions(&rev, prefix); repo_init_revisions(the_repository, &rev, prefix);
setup_revisions(0, NULL, &rev, NULL); setup_revisions(0, NULL, &rev, NULL);
rev.diff = 1; 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(base, &common);
commit_list_insert(next, &remotes); 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, opts->xopts_nr, (const char **)opts->xopts,
common, oid_to_hex(&head), remotes); common, oid_to_hex(&head), remotes);
free_commit_list(common); 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"), : _("could not apply %s... %s"),
short_commit_name(commit), msg.subject); short_commit_name(commit), msg.subject);
print_advice(res == 1, opts); print_advice(res == 1, opts);
rerere(opts->allow_rerere_auto); repo_rerere(the_repository, opts->allow_rerere_auto);
goto leave; 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)); strbuf_addf(&buf, "%s/patch", get_dir(opts));
memset(&log_tree_opt, 0, sizeof(log_tree_opt)); 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.abbrev = 0;
log_tree_opt.diff = 1; log_tree_opt.diff = 1;
log_tree_opt.diffopt.output_format = DIFF_FORMAT_PATCH; 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); rollback_lock_file(&lock);
if (ret) if (ret)
rerere(opts->allow_rerere_auto); repo_rerere(the_repository, opts->allow_rerere_auto);
else else
/* /*
* In case of problems, we now want to return a positive * 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; struct object_id orig, head;
memset(&log_tree_opt, 0, sizeof(log_tree_opt)); 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.diff = 1;
log_tree_opt.diffopt.output_format = log_tree_opt.diffopt.output_format =
DIFF_FORMAT_DIFFSTAT; 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"; const char *insn = flags & TODO_LIST_ABBREVIATE_CMDS ? "p" : "pick";
int rebase_merges = flags & TODO_LIST_REBASE_MERGES; int rebase_merges = flags & TODO_LIST_REBASE_MERGES;
init_revisions(&revs, NULL); repo_init_revisions(the_repository, &revs, NULL);
revs.verbose_header = 1; revs.verbose_header = 1;
if (!rebase_merges) if (!rebase_merges)
revs.max_parents = 1; revs.max_parents = 1;

View File

@ -1813,7 +1813,8 @@ static void check_tag(const void *buf, size_t size)
die(_("corrupt tag")); 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, enum object_type type,
const char *path, unsigned flags) 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) { if ((type == OBJ_BLOB) && path) {
struct strbuf nbuf = STRBUF_INIT; 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))) { get_conv_flags(flags))) {
buf = strbuf_detach(&nbuf, &size); buf = strbuf_detach(&nbuf, &size);
re_allocated = 1; re_allocated = 1;
@ -1852,17 +1853,20 @@ static int index_mem(struct object_id *oid, void *buf, size_t size,
return ret; return ret;
} }
static int index_stream_convert_blob(struct object_id *oid, int fd, static int index_stream_convert_blob(struct index_state *istate,
const char *path, unsigned flags) struct object_id *oid,
int fd,
const char *path,
unsigned flags)
{ {
int ret; int ret;
const int write_object = flags & HASH_WRITE_OBJECT; const int write_object = flags & HASH_WRITE_OBJECT;
struct strbuf sbuf = STRBUF_INIT; struct strbuf sbuf = STRBUF_INIT;
assert(path); 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)); get_conv_flags(flags));
if (write_object) if (write_object)
@ -1875,14 +1879,15 @@ static int index_stream_convert_blob(struct object_id *oid, int fd,
return ret; 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) const char *path, unsigned flags)
{ {
struct strbuf sbuf = STRBUF_INIT; struct strbuf sbuf = STRBUF_INIT;
int ret; int ret;
if (strbuf_read(&sbuf, fd, 4096) >= 0) 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 else
ret = -1; ret = -1;
strbuf_release(&sbuf); 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) #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, enum object_type type, const char *path,
unsigned flags) unsigned flags)
{ {
int ret; int ret;
if (!size) { 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) { } else if (size <= SMALL_FILE_SIZE) {
char *buf = xmalloc(size); char *buf = xmalloc(size);
ssize_t read_result = read_in_full(fd, buf, 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"), ret = error(_("short read while indexing %s"),
path ? path : "<unknown>"); path ? path : "<unknown>");
else else
ret = index_mem(oid, buf, size, type, path, flags); ret = index_mem(istate, oid, buf, size, type, path, flags);
free(buf); free(buf);
} else { } else {
void *buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); 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); munmap(buf, size);
} }
return ret; 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); 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) enum object_type type, const char *path, unsigned flags)
{ {
int ret; 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 * Call xsize_t() only when needed to avoid potentially unnecessary
* die() for large files. * die() for large files.
*/ */
if (type == OBJ_BLOB && path && would_convert_to_git_filter_fd(&the_index, path)) if (type == OBJ_BLOB && path && would_convert_to_git_filter_fd(istate, path))
ret = index_stream_convert_blob(oid, fd, path, flags); ret = index_stream_convert_blob(istate, oid, fd, path, flags);
else if (!S_ISREG(st->st_mode)) 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 || else if (st->st_size <= big_file_threshold || type != OBJ_BLOB ||
(path && would_convert_to_git(&the_index, path))) (path && would_convert_to_git(istate, path)))
ret = index_core(oid, fd, xsize_t(st->st_size), type, path, ret = index_core(istate, oid, fd, xsize_t(st->st_size),
flags); type, path, flags);
else else
ret = index_stream(oid, fd, xsize_t(st->st_size), type, path, ret = index_stream(oid, fd, xsize_t(st->st_size), type, path,
flags); flags);
@ -1965,7 +1972,8 @@ int index_fd(struct object_id *oid, int fd, struct stat *st,
return ret; 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; int fd;
struct strbuf sb = STRBUF_INIT; 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); fd = open(path, O_RDONLY);
if (fd < 0) if (fd < 0)
return error_errno("open(\"%s\")", path); 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"), return error(_("%s: failed to insert into database"),
path); path);
break; 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 */ 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; save_commit_buffer = 0;
setup_revisions(ac, av, &revs, NULL); 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; struct commit_list *list;
init_revisions(rev, NULL); repo_init_revisions(the_repository, rev, NULL);
setup_revisions(0, NULL, rev, NULL); setup_revisions(0, NULL, rev, NULL);
rev->left_right = 1; rev->left_right = 1;
rev->first_parent_only = 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 * have a corresponding 'struct oid_array' (in the 'util' field) which lists
* what the submodule pointers were updated to during the change. * 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 argv_array *argv)
{ {
struct rev_info rev; struct rev_info rev;
const struct commit *commit; const struct commit *commit;
init_revisions(&rev, NULL); repo_init_revisions(the_repository, &rev, NULL);
setup_revisions(argv->argc, argv->argv, &rev, NULL); setup_revisions(argv->argc, argv->argv, &rev, NULL);
if (prepare_revision_walk(&rev)) if (prepare_revision_walk(&rev))
die("revision walk setup failed"); die("revision walk setup failed");
@ -783,7 +784,7 @@ static void collect_changed_submodules(struct string_list *changed,
data.changed = changed; data.changed = changed;
data.commit_oid = &commit->object.oid; 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.output_format |= DIFF_FORMAT_CALLBACK;
diff_rev.diffopt.format_callback = collect_changed_submodules_cb; diff_rev.diffopt.format_callback = collect_changed_submodules_cb;
diff_rev.diffopt.format_callback_data = &data; 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; return 0;
} }
int find_unpushed_submodules(struct oid_array *commits, int find_unpushed_submodules(struct index_state *istate,
const char *remotes_name, struct string_list *needs_pushing) struct oid_array *commits,
const char *remotes_name,
struct string_list *needs_pushing)
{ {
struct string_list submodules = STRING_LIST_INIT_DUP; struct string_list submodules = STRING_LIST_INIT_DUP;
struct string_list_item *name; struct string_list_item *name;
@ -943,7 +946,7 @@ int find_unpushed_submodules(struct oid_array *commits,
argv_array_push(&argv, "--not"); argv_array_push(&argv, "--not");
argv_array_pushf(&argv, "--remotes=%s", remotes_name); 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) { for_each_string_list_item(name, &submodules) {
struct oid_array *commits = name->util; 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); 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 remote *remote,
const struct refspec *rs, const struct refspec *rs,
const struct string_list *push_options, const struct string_list *push_options,
@ -1053,7 +1057,8 @@ int push_unpushed_submodules(struct oid_array *commits,
int i, ret = 1; int i, ret = 1;
struct string_list needs_pushing = STRING_LIST_INIT_DUP; 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; return 1;
/* /*
@ -1110,7 +1115,7 @@ void check_for_new_submodule_commits(struct object_id *oid)
oid_array_append(&ref_tips_after_fetch, 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 argv_array argv = ARGV_ARRAY_INIT;
struct string_list changed_submodules = STRING_LIST_INIT_DUP; 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 * Collect all submodules (whether checked out or not) for which new
* commits have been recorded upstream in "changed_submodule_names". * 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) { for_each_string_list_item(name, &changed_submodules) {
struct oid_array *commits = name->util; struct oid_array *commits = name->util;
@ -1158,7 +1163,8 @@ static void calculate_changed_submodule_paths(void)
initialized_fetch_ref_tips = 0; 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 object_id *incl_oid)
{ {
struct string_list subs = STRING_LIST_INIT_DUP; 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)); argv_array_push(&args, oid_to_hex(excl_oid));
} }
collect_changed_submodules(&subs, &args); collect_changed_submodules(istate, &subs, &args);
ret = subs.nr; ret = subs.nr;
argv_array_clear(&args); argv_array_clear(&args);
@ -1346,7 +1352,7 @@ int fetch_populated_submodules(struct repository *r,
argv_array_push(&spf.args, "--recurse-submodules-default"); argv_array_push(&spf.args, "--recurse-submodules-default");
/* default value, "--submodule-prefix" and its value are added later */ /* 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, run_processes_parallel(max_parallel_jobs,
get_next_submodule, get_next_submodule,
fetch_start_failure, 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 if there are submodule changes in a..b. If a is the null OID,
* checks b and all its ancestors instead. * 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); 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, const char *remotes_name,
struct string_list *needs_pushing); struct string_list *needs_pushing);
struct refspec; 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 remote *remote,
const struct refspec *rs, const struct refspec *rs,
const struct string_list *push_options, 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 argc = ARRAY_SIZE(argv) - 1;
int got_revision = 0; int got_revision = 0;
init_revisions(&rev, NULL); repo_init_revisions(the_repository, &rev, NULL);
setup_revisions(argc, argv, &rev, NULL); setup_revisions(argc, argv, &rev, NULL);
if (prepare_revision_walk(&rev)) if (prepare_revision_walk(&rev))
die("revision walk setup failed"); die("revision walk setup failed");

View File

@ -1139,7 +1139,8 @@ int transport_push(struct transport *transport,
oid_array_append(&commits, oid_array_append(&commits,
&ref->new_oid); &ref->new_oid);
if (!push_unpushed_submodules(&commits, if (!push_unpushed_submodules(&the_index,
&commits,
transport->remote, transport->remote,
rs, rs,
transport->push_options, transport->push_options,
@ -1163,8 +1164,10 @@ int transport_push(struct transport *transport,
oid_array_append(&commits, oid_array_append(&commits,
&ref->new_oid); &ref->new_oid);
if (find_unpushed_submodules(&commits, transport->remote->name, if (find_unpushed_submodules(&the_index,
&needs_pushing)) { &commits,
transport->remote->name,
&needs_pushing)) {
oid_array_clear(&commits); oid_array_clear(&commits);
die_with_unpushed_submodules(&needs_pushing); 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]; choice = q->queue[0];
q->nr = 0; q->nr = 0;
diff_setup(&diff_opts); repo_diff_setup(opt->repo, &diff_opts);
diff_opts.flags.recursive = 1; diff_opts.flags.recursive = 1;
diff_opts.flags.find_copies_harder = 1; diff_opts.flags.find_copies_harder = 1;
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT; 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); 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; 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); check = attr_check_initl("diff", NULL);
if (!path) if (!path)
return NULL; return NULL;
git_check_attr(&the_index, path, check); git_check_attr(istate, path, check);
if (ATTR_TRUE(check->items[0].value)) if (ATTR_TRUE(check->items[0].value))
return &driver_true; return &driver_true;

View File

@ -3,6 +3,8 @@
#include "notes-cache.h" #include "notes-cache.h"
struct index_state;
struct userdiff_funcname { struct userdiff_funcname {
const char *pattern; const char *pattern;
int cflags; int cflags;
@ -21,7 +23,8 @@ struct userdiff_driver {
int userdiff_config(const char *k, const char *v); 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_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 * 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 * Copyright (c) 2007 Junio C Hamano
*/ */
#include "cache.h" #include "cache.h"
#include "attr.h" #include "attr.h"
@ -71,7 +70,7 @@ unsigned parse_whitespace_rule(const char *string)
return rule; 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; static struct attr_check *attr_whitespace_rule;
const char *value; const char *value;
@ -79,7 +78,7 @@ unsigned whitespace_rule(const char *pathname)
if (!attr_whitespace_rule) if (!attr_whitespace_rule)
attr_whitespace_rule = attr_check_initl("whitespace", NULL); 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; value = attr_whitespace_rule->items[0].value;
if (ATTR_TRUE(value)) { if (ATTR_TRUE(value)) {
/* true (whitespace) */ /* true (whitespace) */

View File

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