Browse Source

Merge branch 'maint'

* maint:
  fsck: reduce stack footprint
  make sure packs to be replaced are closed beforehand
maint
Junio C Hamano 16 years ago
parent
commit
de0db42278
  1. 38
      builtin-fsck.c
  2. 1
      builtin-pack-objects.c
  3. 1
      cache.h
  4. 31
      sha1_file.c

38
builtin-fsck.c

@ -64,11 +64,11 @@ static int fsck_error_func(struct object *obj, int type, const char *err, ...) @@ -64,11 +64,11 @@ static int fsck_error_func(struct object *obj, int type, const char *err, ...)
return (type == FSCK_WARN) ? 0 : 1;
}

static struct object_array pending;

static int mark_object(struct object *obj, int type, void *data)
{
struct tree *tree = NULL;
struct object *parent = data;
int result;

if (!obj) {
printf("broken link from %7s %s\n",
@ -96,6 +96,20 @@ static int mark_object(struct object *obj, int type, void *data) @@ -96,6 +96,20 @@ static int mark_object(struct object *obj, int type, void *data)
return 1;
}

add_object_array(obj, (void *) parent, &pending);
return 0;
}

static void mark_object_reachable(struct object *obj)
{
mark_object(obj, OBJ_ANY, 0);
}

static int traverse_one_object(struct object *obj, struct object *parent)
{
int result;
struct tree *tree = NULL;

if (obj->type == OBJ_TREE) {
obj->parsed = 0;
tree = (struct tree *)obj;
@ -107,15 +121,22 @@ static int mark_object(struct object *obj, int type, void *data) @@ -107,15 +121,22 @@ static int mark_object(struct object *obj, int type, void *data)
free(tree->buffer);
tree->buffer = NULL;
}
if (result < 0)
result = 1;

return result;
}

static void mark_object_reachable(struct object *obj)
static int traverse_reachable(void)
{
mark_object(obj, OBJ_ANY, 0);
int result = 0;
while (pending.nr) {
struct object_array_entry *entry;
struct object *obj, *parent;

entry = pending.objects + --pending.nr;
obj = entry->item;
parent = (struct object *) entry->name;
result |= traverse_one_object(obj, parent);
}
return !!result;
}

static int mark_used(struct object *obj, int type, void *data)
@ -237,6 +258,9 @@ static void check_connectivity(void) @@ -237,6 +258,9 @@ static void check_connectivity(void)
{
int i, max;

/* Traverse the pending reachable objects */
traverse_reachable();

/* Look up all the requirements, warn about missing objects.. */
max = get_max_object_index();
if (verbose)

1
builtin-pack-objects.c

@ -535,6 +535,7 @@ static void write_pack_file(void) @@ -535,6 +535,7 @@ static void write_pack_file(void)

snprintf(tmpname, sizeof(tmpname), "%s-%s.pack",
base_name, sha1_to_hex(sha1));
free_pack_by_name(tmpname);
if (adjust_perm(pack_tmp_name, mode))
die("unable to make temporary pack file readable: %s",
strerror(errno));

1
cache.h

@ -820,6 +820,7 @@ extern int open_pack_index(struct packed_git *); @@ -820,6 +820,7 @@ extern int open_pack_index(struct packed_git *);
extern unsigned char* use_pack(struct packed_git *, struct pack_window **, off_t, unsigned int *);
extern void close_pack_windows(struct packed_git *);
extern void unuse_pack(struct pack_window **);
extern void free_pack_by_name(const char *);
extern struct packed_git *add_packed_git(const char *, int, int);
extern const unsigned char *nth_packed_object_sha1(struct packed_git *, uint32_t);
extern off_t nth_packed_object_offset(const struct packed_git *, uint32_t);

31
sha1_file.c

@ -672,6 +672,37 @@ void unuse_pack(struct pack_window **w_cursor) @@ -672,6 +672,37 @@ void unuse_pack(struct pack_window **w_cursor)
}
}

/*
* This is used by git-repack in case a newly created pack happens to
* contain the same set of objects as an existing one. In that case
* the resulting file might be different even if its name would be the
* same. It is best to close any reference to the old pack before it is
* replaced on disk. Of course no index pointers nor windows for given pack
* must subsist at this point. If ever objects from this pack are requested
* again, the new version of the pack will be reinitialized through
* reprepare_packed_git().
*/
void free_pack_by_name(const char *pack_name)
{
struct packed_git *p, **pp = &packed_git;

while (*pp) {
p = *pp;
if (strcmp(pack_name, p->pack_name) == 0) {
close_pack_windows(p);
if (p->pack_fd != -1)
close(p->pack_fd);
if (p->index_data)
munmap((void *)p->index_data, p->index_size);
free(p->bad_object_sha1);
*pp = p->next;
free(p);
return;
}
pp = &p->next;
}
}

/*
* Do not call this directly as this leaks p->pack_fd on error return;
* call open_packed_git() instead.

Loading…
Cancel
Save