Browse Source

pack-objects --keep-unreachable

This new option is meant to be used in conjunction with the
options "git repack -a -d" usually invokes the underlying
pack-objects with.  When this option is given, objects unreachable
from the refs in packs named with --unpacked= option are added
to the resulting pack, in addition to the reachable objects that
are not in packs marked with *.keep files.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Junio C Hamano 18 years ago
parent
commit
08cdfb1337
  1. 95
      builtin-pack-objects.c

95
builtin-pack-objects.c

@ -21,7 +21,7 @@ git-pack-objects [{ -q | --progress | --all-progress }] \n\ @@ -21,7 +21,7 @@ git-pack-objects [{ -q | --progress | --all-progress }] \n\
[--window=N] [--window-memory=N] [--depth=N] \n\
[--no-reuse-delta] [--no-reuse-object] [--delta-base-offset] \n\
[--non-empty] [--revs [--unpacked | --all]*] [--reflog] \n\
[--stdout | base-name] [<ref-list | <object-list]";
[--stdout | base-name] [--keep-unreachable] [<ref-list | <object-list]";

struct object_entry {
struct pack_idx_entry idx;
@ -57,7 +57,7 @@ static struct object_entry **written_list; @@ -57,7 +57,7 @@ static struct object_entry **written_list;
static uint32_t nr_objects, nr_alloc, nr_result, nr_written;

static int non_empty;
static int no_reuse_delta, no_reuse_object;
static int no_reuse_delta, no_reuse_object, keep_unreachable;
static int local;
static int incremental;
static int allow_ofs_delta;
@ -1625,15 +1625,19 @@ static void read_object_list_from_stdin(void) @@ -1625,15 +1625,19 @@ static void read_object_list_from_stdin(void)
}
}

#define OBJECT_ADDED (1u<<20)

static void show_commit(struct commit *commit)
{
add_object_entry(commit->object.sha1, OBJ_COMMIT, NULL, 0);
commit->object.flags |= OBJECT_ADDED;
}

static void show_object(struct object_array_entry *p)
{
add_preferred_base_object(p->name);
add_object_entry(p->item->sha1, p->item->type, p->name, 0);
p->item->flags |= OBJECT_ADDED;
}

static void show_edge(struct commit *commit)
@ -1641,6 +1645,86 @@ static void show_edge(struct commit *commit) @@ -1641,6 +1645,86 @@ static void show_edge(struct commit *commit)
add_preferred_base(commit->object.sha1);
}

struct in_pack_object {
off_t offset;
struct object *object;
};

struct in_pack {
int alloc;
int nr;
struct in_pack_object *array;
};

static void mark_in_pack_object(struct object *object, struct packed_git *p, struct in_pack *in_pack)
{
in_pack->array[in_pack->nr].offset = find_pack_entry_one(object->sha1, p);
in_pack->array[in_pack->nr].object = object;
in_pack->nr++;
}

/*
* Compare the objects in the offset order, in order to emulate the
* "git-rev-list --objects" output that produced the pack originally.
*/
static int ofscmp(const void *a_, const void *b_)
{
struct in_pack_object *a = (struct in_pack_object *)a_;
struct in_pack_object *b = (struct in_pack_object *)b_;

if (a->offset < b->offset)
return -1;
else if (a->offset > b->offset)
return 1;
else
return hashcmp(a->object->sha1, b->object->sha1);
}

static void add_objects_in_unpacked_packs(struct rev_info *revs)
{
struct packed_git *p;
struct in_pack in_pack;
uint32_t i;

memset(&in_pack, 0, sizeof(in_pack));

for (p = packed_git; p; p = p->next) {
const unsigned char *sha1;
struct object *o;

for (i = 0; i < revs->num_ignore_packed; i++) {
if (matches_pack_name(p, revs->ignore_packed[i]))
break;
}
if (revs->num_ignore_packed <= i)
continue;
if (open_pack_index(p))
die("cannot open pack index");

ALLOC_GROW(in_pack.array,
in_pack.nr + p->num_objects,
in_pack.alloc);

for (i = 0; i < p->num_objects; i++) {
sha1 = nth_packed_object_sha1(p, i);
o = lookup_unknown_object(sha1);
if (!(o->flags & OBJECT_ADDED))
mark_in_pack_object(o, p, &in_pack);
o->flags |= OBJECT_ADDED;
}
}

if (in_pack.nr) {
qsort(in_pack.array, in_pack.nr, sizeof(in_pack.array[0]),
ofscmp);
for (i = 0; i < in_pack.nr; i++) {
struct object *o = in_pack.array[i].object;
add_object_entry(o->sha1, o->type, "", 0);
}
}
free(in_pack.array);
}

static void get_object_list(int ac, const char **av)
{
struct rev_info revs;
@ -1672,6 +1756,9 @@ static void get_object_list(int ac, const char **av) @@ -1672,6 +1756,9 @@ static void get_object_list(int ac, const char **av)
prepare_revision_walk(&revs);
mark_edges_uninteresting(revs.commits, &revs, show_edge);
traverse_commit_list(&revs, show_commit, show_object);

if (keep_unreachable)
add_objects_in_unpacked_packs(&revs);
}

static int adjust_perm(const char *path, mode_t mode)
@ -1789,6 +1876,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) @@ -1789,6 +1876,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
use_internal_rev_list = 1;
continue;
}
if (!strcmp("--keep-unreachable", arg)) {
keep_unreachable = 1;
continue;
}
if (!strcmp("--unpacked", arg) ||
!prefixcmp(arg, "--unpacked=") ||
!strcmp("--reflog", arg) ||

Loading…
Cancel
Save