#endif
static const char pack_usage[] = "\
-git-pack-objects [{ -q | --progress | --all-progress }] \n\
+git pack-objects [{ -q | --progress | --all-progress }] \n\
[--max-pack-size=N] [--local] [--incremental] \n\
[--window=N] [--window-memory=N] [--depth=N] \n\
[--no-reuse-delta] [--no-reuse-object] [--delta-base-offset] \n\
static int keep_unreachable, unpack_unreachable, include_tag;
static int local;
static int incremental;
+static int ignore_packed_keep;
static int allow_ofs_delta;
static const char *base_name;
static int progress = 1;
type = entry->type;
/* write limit if limited packsize and not first object */
- limit = pack_size_limit && nr_written ?
- pack_size_limit - write_offset : 0;
+ if (!pack_size_limit || !nr_written)
+ limit = 0;
+ else if (pack_size_limit <= write_offset)
+ /*
+ * the earlier object did not fit the limit; avoid
+ * mistaking this with unlimited (i.e. limit = 0).
+ */
+ limit = 1;
+ else
+ limit = pack_size_limit - write_offset;
if (!entry->delta)
usable_delta = 0; /* no delta */
return hdrlen + datalen;
}
-static off_t write_one(struct sha1file *f,
+static int write_one(struct sha1file *f,
struct object_entry *e,
- off_t offset)
+ off_t *offset)
{
unsigned long size;
/* offset is non zero if object is written already. */
if (e->idx.offset || e->preferred_base)
- return offset;
+ return 1;
/* if we are deltified, write out base object first. */
- if (e->delta) {
- offset = write_one(f, e->delta, offset);
- if (!offset)
- return 0;
- }
+ if (e->delta && !write_one(f, e->delta, offset))
+ return 0;
- e->idx.offset = offset;
- size = write_object(f, e, offset);
+ e->idx.offset = *offset;
+ size = write_object(f, e, *offset);
if (!size) {
e->idx.offset = 0;
return 0;
written_list[nr_written++] = &e->idx;
/* make sure off_t is sufficiently large not to wrap */
- if (offset > offset + size)
+ if (*offset > *offset + size)
die("pack too large for current definition of off_t");
- return offset + size;
+ *offset += size;
+ return 1;
}
/* forward declaration for write_pack_file */
{
uint32_t i = 0, j;
struct sha1file *f;
- off_t offset, offset_one, last_obj_offset = 0;
+ off_t offset;
struct pack_header hdr;
uint32_t nr_remaining = nr_result;
time_t last_mtime = 0;
char tmpname[PATH_MAX];
int fd;
snprintf(tmpname, sizeof(tmpname),
- "%s/tmp_pack_XXXXXX", get_object_directory());
+ "%s/pack/tmp_pack_XXXXXX", get_object_directory());
fd = xmkstemp(tmpname);
pack_tmp_name = xstrdup(tmpname);
f = sha1fd(fd, pack_tmp_name);
offset = sizeof(hdr);
nr_written = 0;
for (; i < nr_objects; i++) {
- last_obj_offset = offset;
- offset_one = write_one(f, objects + i, offset);
- if (!offset_one)
+ if (!write_one(f, objects + i, &offset))
break;
- offset = offset_one;
display_progress(progress_state, written);
}
} else if (nr_written == nr_remaining) {
sha1close(f, sha1, CSUM_FSYNC);
} else {
- int fd = sha1close(f, NULL, 0);
- fixup_pack_header_footer(fd, sha1, pack_tmp_name, nr_written);
+ int fd = sha1close(f, sha1, 0);
+ fixup_pack_header_footer(fd, sha1, pack_tmp_name,
+ nr_written, sha1, offset);
close(fd);
}
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));
return 0;
}
+ if (!exclude && local && has_loose_object_nonlocal(sha1))
+ return 0;
+
for (p = packed_git; p; p = p->next) {
off_t offset = find_pack_entry_one(sha1, p);
if (offset) {
return 0;
if (local && !p->pack_local)
return 0;
+ if (ignore_packed_keep && p->pack_local && p->pack_keep)
+ return 0;
}
}
memset(array, 0, array_size);
for (;;) {
- struct object_entry *entry = *list++;
+ struct object_entry *entry;
struct unpacked *n = array + idx;
int j, max_depth, best_base = -1;
progress_unlock();
break;
}
+ entry = *list++;
(*list_size)--;
if (!entry->preferred_base) {
(*processed)++;
/*
* Compare the objects in the offset order, in order to emulate the
- * "git-rev-list --objects" output that produced the pack originally.
+ * "git rev-list --objects" output that produced the pack originally.
*/
static int ofscmp(const void *a_, const void *b_)
{
incremental = 1;
continue;
}
+ if (!strcmp("--honor-pack-keep", arg)) {
+ ignore_packed_keep = 1;
+ continue;
+ }
if (!prefixcmp(arg, "--compression=")) {
char *end;
int level = strtoul(arg+14, &end, 0);