Merge branch 'jh/fsck-promisors'

In preparation for implementing narrow/partial clone, the machinery
for checking object connectivity used by gc and fsck has been
taught that a missing object is OK when it is referenced by a
packfile specially marked as coming from trusted repository that
promises to make them available on-demand and lazily.

* jh/fsck-promisors:
  gc: do not repack promisor packfiles
  rev-list: support termination at promisor objects
  sha1_file: support lazily fetching missing objects
  introduce fetch-object: fetch one promisor object
  index-pack: refactor writing of .keep files
  fsck: support promisor objects as CLI argument
  fsck: support referenced promisor objects
  fsck: support refs pointing to promisor objects
  fsck: introduce partialclone extension
  extension.partialclone: introduce partial clone extension
This commit is contained in:
Junio C Hamano
2018-02-13 13:39:03 -08:00
32 changed files with 896 additions and 96 deletions

View File

@ -198,6 +198,8 @@ static struct object *get_reference(struct rev_info *revs, const char *name,
if (!object) {
if (revs->ignore_missing)
return object;
if (revs->exclude_promisor_objects && is_promisor_object(oid))
return NULL;
die("bad object %s", name);
}
object->flags |= flags;
@ -799,9 +801,17 @@ static int add_parents_to_list(struct rev_info *revs, struct commit *commit,
for (parent = commit->parents; parent; parent = parent->next) {
struct commit *p = parent->item;
if (parse_commit_gently(p, revs->ignore_missing_links) < 0)
int gently = revs->ignore_missing_links ||
revs->exclude_promisor_objects;
if (parse_commit_gently(p, gently) < 0) {
if (revs->exclude_promisor_objects &&
is_promisor_object(&p->object.oid)) {
if (revs->first_parent_only)
break;
continue;
}
return -1;
}
if (revs->show_source && !p->util)
p->util = commit->util;
p->object.flags |= left_flag;
@ -2100,6 +2110,10 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
revs->limited = 1;
} else if (!strcmp(arg, "--ignore-missing")) {
revs->ignore_missing = 1;
} else if (!strcmp(arg, "--exclude-promisor-objects")) {
if (fetch_if_missing)
die("BUG: exclude_promisor_objects can only be used when fetch_if_missing is 0");
revs->exclude_promisor_objects = 1;
} else {
int opts = diff_opt_parse(&revs->diffopt, argv, argc, revs->prefix);
if (!opts)
@ -2845,6 +2859,16 @@ void reset_revision_walk(void)
clear_object_flags(SEEN | ADDED | SHOWN);
}
static int mark_uninteresting(const struct object_id *oid,
struct packed_git *pack,
uint32_t pos,
void *unused)
{
struct object *o = parse_object(oid);
o->flags |= UNINTERESTING | SEEN;
return 0;
}
int prepare_revision_walk(struct rev_info *revs)
{
int i;
@ -2872,6 +2896,11 @@ int prepare_revision_walk(struct rev_info *revs)
(revs->limited && limiting_can_increase_treesame(revs)))
revs->treesame.name = "treesame";
if (revs->exclude_promisor_objects) {
for_each_packed_object(mark_uninteresting, NULL,
FOR_EACH_OBJECT_PROMISOR_ONLY);
}
if (revs->no_walk != REVISION_WALK_NO_WALK_UNSORTED)
commit_list_sort_by_date(&revs->commits);
if (revs->no_walk)