From: Junio C Hamano Date: Fri, 19 Jul 2019 18:30:21 +0000 (-0700) Subject: Merge branch 'jk/check-connected-with-alternates' X-Git-Tag: v2.23.0-rc0~33 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/68e65ded5b790bfd8a1072a7f551a8f283f62f29?ds=inline;hp=-c Merge branch 'jk/check-connected-with-alternates' The tips of refs from the alternate object store can be used as starting point for reachability computation now. * jk/check-connected-with-alternates: check_everything_connected: assume alternate ref tips are valid object-store.h: move for_each_alternate_ref() from transport.h --- 68e65ded5b790bfd8a1072a7f551a8f283f62f29 diff --combined Documentation/rev-list-options.txt index 286fc163f1,90a2c027ea..bb1251c036 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@@ -182,6 -182,14 +182,14 @@@ explicitly Pretend as if all objects mentioned by reflogs are listed on the command line as ``. + --alternate-refs:: + Pretend as if all objects mentioned as ref tips of alternate + repositories were listed on the command line. An alternate + repository is any repository whose object directory is specified + in `objects/info/alternates`. The set of included objects may + be modified by `core.alternateRefsCommand`, etc. See + linkgit:git-config[1]. + --single-worktree:: By default, all working trees will be examined by the following options when there are more than one (see @@@ -708,16 -716,6 +716,16 @@@ ifdef::git-rev-list[ Only useful with `--objects`; print the object IDs that are not in packs. +--object-names:: + Only useful with `--objects`; print the names of the object IDs + that are found. This is the default behavior. + +--no-object-names:: + Only useful with `--objects`; does not print the names of the object + IDs that are found. This inverts `--object-names`. This flag allows + the output to be more easily parsed by commands such as + linkgit:git-cat-file[1]. + --filter=:: Only useful with one of the `--objects*`; omits objects (usually blobs) from the list of printed objects. The '' diff --combined builtin/receive-pack.c index 610eadf5f0,4ab6dc1037..dcf385511f --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@@ -12,7 -12,6 +12,6 @@@ #include "object.h" #include "remote.h" #include "connect.h" - #include "transport.h" #include "string-list.h" #include "sha1-array.h" #include "connected.h" @@@ -1809,7 -1808,8 +1808,7 @@@ static const char *unpack_with_sideband return ret; } -static void prepare_shallow_update(struct command *commands, - struct shallow_info *si) +static void prepare_shallow_update(struct shallow_info *si) { int i, j, k, bitmap_size = DIV_ROUND_UP(si->ref->nr, 32); @@@ -1875,7 -1875,7 +1874,7 @@@ static void update_shallow_info(struct si->ref = ref; if (shallow_update) { - prepare_shallow_update(commands, si); + prepare_shallow_update(si); return; } @@@ -2042,7 -2042,7 +2041,7 @@@ int cmd_receive_pack(int argc, const ch proc.git_cmd = 1; proc.argv = argv_gc_auto; - close_all_packs(the_repository->objects); + close_object_store(the_repository->objects); if (!start_command(&proc)) { if (use_sideband) copy_to_sideband(proc.err, -1, NULL); diff --combined object-store.h index 49f56ab8d9,74d6860a9f..7f7b3cdd80 --- a/object-store.h +++ b/object-store.h @@@ -33,6 -33,8 +33,8 @@@ void prepare_alt_odb(struct repository char *compute_alternate_path(const char *path, struct strbuf *err); typedef int alt_odb_fn(struct object_directory *, void *); int foreach_alt_odb(alt_odb_fn, void*); + typedef void alternate_ref_fn(const struct object_id *oid, void *); + void for_each_alternate_ref(alternate_ref_fn, void *); /* * Add the directory to the on-disk alternates file; the new entry will also @@@ -277,14 -279,10 +279,14 @@@ struct object_info #define OBJECT_INFO_IGNORE_LOOSE 16 /* * Do not attempt to fetch the object if missing (even if fetch_is_missing is - * nonzero). This is meant for bulk prefetching of missing blobs in a partial - * clone. Implies OBJECT_INFO_QUICK. + * nonzero). */ -#define OBJECT_INFO_FOR_PREFETCH (32 + OBJECT_INFO_QUICK) +#define OBJECT_INFO_SKIP_FETCH_OBJECT 32 +/* + * This is meant for bulk prefetching of missing blobs in a partial + * clone. Implies OBJECT_INFO_SKIP_FETCH_OBJECT and OBJECT_INFO_QUICK + */ +#define OBJECT_INFO_FOR_PREFETCH (OBJECT_INFO_SKIP_FETCH_OBJECT | OBJECT_INFO_QUICK) int oid_object_info_extended(struct repository *r, const struct object_id *, diff --combined revision.c index 621feb9df7,0d1a30a7d7..07412297f0 --- a/revision.c +++ b/revision.c @@@ -436,9 -436,7 +436,9 @@@ static struct commit *handle_commit(str die("unable to parse commit %s", name); if (flags & UNINTERESTING) { mark_parents_uninteresting(commit); - revs->limited = 1; + + if (!revs->topo_order || !generation_numbers_enabled(the_repository)) + revs->limited = 1; } if (revs->sources) { char **slot = revision_sources_at(revs->sources, commit); @@@ -1554,6 -1552,32 +1554,32 @@@ void add_index_objects_to_pending(struc free_worktrees(worktrees); } + struct add_alternate_refs_data { + struct rev_info *revs; + unsigned int flags; + }; + + static void add_one_alternate_ref(const struct object_id *oid, + void *vdata) + { + const char *name = ".alternate"; + struct add_alternate_refs_data *data = vdata; + struct object *obj; + + obj = get_reference(data->revs, name, oid, data->flags); + add_rev_cmdline(data->revs, obj, name, REV_CMD_REV, data->flags); + add_pending_object(data->revs, obj, name); + } + + static void add_alternate_refs_to_pending(struct rev_info *revs, + unsigned int flags) + { + struct add_alternate_refs_data data; + data.revs = revs; + data.flags = flags; + for_each_alternate_ref(add_one_alternate_ref, &data); + } + static int add_parents_only(struct rev_info *revs, const char *arg_, int flags, int exclude_parent) { @@@ -1956,6 -1980,7 +1982,7 @@@ static int handle_revision_opt(struct r !strcmp(arg, "--no-walk") || !strcmp(arg, "--do-walk") || !strcmp(arg, "--bisect") || starts_with(arg, "--glob=") || !strcmp(arg, "--indexed-objects") || + !strcmp(arg, "--alternate-refs") || starts_with(arg, "--exclude=") || starts_with(arg, "--branches=") || starts_with(arg, "--tags=") || starts_with(arg, "--remotes=") || starts_with(arg, "--no-walk=")) @@@ -2442,6 -2467,8 +2469,8 @@@ static int handle_revision_pseudo_opt(c add_reflogs_to_pending(revs, *flags); } else if (!strcmp(arg, "--indexed-objects")) { add_index_objects_to_pending(revs, *flags); + } else if (!strcmp(arg, "--alternate-refs")) { + add_alternate_refs_to_pending(revs, *flags); } else if (!strcmp(arg, "--not")) { *flags ^= UNINTERESTING | BOTTOM; } else if (!strcmp(arg, "--no-walk")) { @@@ -3265,9 -3292,6 +3294,9 @@@ static void expand_topo_walk(struct rev struct commit *parent = p->item; int *pi; + if (parent->object.flags & UNINTERESTING) + continue; + if (parse_commit_gently(parent, 1) < 0) continue; diff --combined sha1-file.c index 59b2e40cf3,ccd5bf30bd..84fd02f107 --- a/sha1-file.c +++ b/sha1-file.c @@@ -743,6 -743,103 +743,103 @@@ out return ref_git; } + static void fill_alternate_refs_command(struct child_process *cmd, + const char *repo_path) + { + const char *value; + + if (!git_config_get_value("core.alternateRefsCommand", &value)) { + cmd->use_shell = 1; + + argv_array_push(&cmd->args, value); + argv_array_push(&cmd->args, repo_path); + } else { + cmd->git_cmd = 1; + + argv_array_pushf(&cmd->args, "--git-dir=%s", repo_path); + argv_array_push(&cmd->args, "for-each-ref"); + argv_array_push(&cmd->args, "--format=%(objectname)"); + + if (!git_config_get_value("core.alternateRefsPrefixes", &value)) { + argv_array_push(&cmd->args, "--"); + argv_array_split(&cmd->args, value); + } + } + + cmd->env = local_repo_env; + cmd->out = -1; + } + + static void read_alternate_refs(const char *path, + alternate_ref_fn *cb, + void *data) + { + struct child_process cmd = CHILD_PROCESS_INIT; + struct strbuf line = STRBUF_INIT; + FILE *fh; + + fill_alternate_refs_command(&cmd, path); + + if (start_command(&cmd)) + return; + + fh = xfdopen(cmd.out, "r"); + while (strbuf_getline_lf(&line, fh) != EOF) { + struct object_id oid; + const char *p; + + if (parse_oid_hex(line.buf, &oid, &p) || *p) { + warning(_("invalid line while parsing alternate refs: %s"), + line.buf); + break; + } + + cb(&oid, data); + } + + fclose(fh); + finish_command(&cmd); + } + + struct alternate_refs_data { + alternate_ref_fn *fn; + void *data; + }; + + static int refs_from_alternate_cb(struct object_directory *e, + void *data) + { + struct strbuf path = STRBUF_INIT; + size_t base_len; + struct alternate_refs_data *cb = data; + + if (!strbuf_realpath(&path, e->path, 0)) + goto out; + if (!strbuf_strip_suffix(&path, "/objects")) + goto out; + base_len = path.len; + + /* Is this a git repository with refs? */ + strbuf_addstr(&path, "/refs"); + if (!is_directory(path.buf)) + goto out; + strbuf_setlen(&path, base_len); + + read_alternate_refs(path.buf, cb->fn, cb->data); + + out: + strbuf_release(&path); + return 0; + } + + void for_each_alternate_ref(alternate_ref_fn fn, void *data) + { + struct alternate_refs_data cb; + cb.fn = fn; + cb.data = data; + foreach_alt_odb(refs_from_alternate_cb, &cb); + } + int foreach_alt_odb(alt_odb_fn fn, void *cb) { struct object_directory *ent; @@@ -1379,7 -1476,7 +1476,7 @@@ int oid_object_info_extended(struct rep /* Check if it is a missing object */ if (fetch_if_missing && repository_format_partial_clone && !already_retried && r == the_repository && - !(flags & OBJECT_INFO_FOR_PREFETCH)) { + !(flags & OBJECT_INFO_SKIP_FETCH_OBJECT)) { /* * TODO Investigate having fetch_object() return * TODO error/success and stopping the music here. @@@ -1505,8 -1602,7 +1602,8 @@@ void *read_object_file_extended(struct return NULL; } -void *read_object_with_reference(const struct object_id *oid, +void *read_object_with_reference(struct repository *r, + const struct object_id *oid, const char *required_type_name, unsigned long *size, struct object_id *actual_oid_return) @@@ -1522,7 -1618,7 +1619,7 @@@ int ref_length = -1; const char *ref_type = NULL; - buffer = read_object_file(&actual_oid, &type, &isize); + buffer = repo_read_object_file(r, &actual_oid, &type, &isize); if (!buffer) return NULL; if (type == required_type) {