#include "commit.h"
#include "tag.h"
#include "tree.h"
+#include "progress.h"
static const char index_pack_usage[] =
"git-index-pack [-v] [-o <index-file>] [{ ---keep | --keep=<msg> }] { <pack-file> | --stdin [--fix-thin] [<pack-file>] }";
static int from_stdin;
static int verbose;
-static volatile sig_atomic_t progress_update;
-
-static void progress_interval(int signum)
-{
- progress_update = 1;
-}
-
-static void setup_progress_signal(void)
-{
- struct sigaction sa;
- struct itimerval v;
-
- memset(&sa, 0, sizeof(sa));
- sa.sa_handler = progress_interval;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = SA_RESTART;
- sigaction(SIGALRM, &sa, NULL);
-
- v.it_interval.tv_sec = 1;
- v.it_interval.tv_usec = 0;
- v.it_value = v.it_interval;
- setitimer(ITIMER_REAL, &v, NULL);
-
-}
-
-static unsigned display_progress(unsigned n, unsigned total, unsigned last_pc)
-{
- unsigned percent = n * 100 / total;
- if (percent != last_pc || progress_update) {
- fprintf(stderr, "%4u%% (%u/%u) done\r", percent, n, total);
- progress_update = 0;
- }
- return percent;
-}
+static struct progress progress;
/* We always read in 4kB chunks. */
static unsigned char input_buffer[4096];
/* Parse all objects and return the pack content SHA1 hash */
static void parse_pack_objects(unsigned char *sha1)
{
- int i, percent = -1;
+ int i;
struct delta_entry *delta = deltas;
void *data;
struct stat st;
* - remember base (SHA1 or offset) for all deltas.
*/
if (verbose)
- fprintf(stderr, "Indexing %d objects.\n", nr_objects);
+ start_progress(&progress, "Indexing %u objects...", "", nr_objects);
for (i = 0; i < nr_objects; i++) {
struct object_entry *obj = &objects[i];
data = unpack_raw_entry(obj, &delta->base);
sha1_object(data, obj->size, obj->type, obj->sha1);
free(data);
if (verbose)
- percent = display_progress(i+1, nr_objects, percent);
+ display_progress(&progress, i+1);
}
objects[i].offset = consumed_bytes;
if (verbose)
- fputc('\n', stderr);
+ stop_progress(&progress);
/* Check pack integrity */
flush();
* for some more deltas.
*/
if (verbose)
- fprintf(stderr, "Resolving %d deltas.\n", nr_deltas);
+ start_progress(&progress, "Resolving %u deltas...", "", nr_deltas);
for (i = 0; i < nr_objects; i++) {
struct object_entry *obj = &objects[i];
union delta_base base;
}
free(data);
if (verbose)
- percent = display_progress(nr_resolved_deltas,
- nr_deltas, percent);
+ display_progress(&progress, nr_resolved_deltas);
}
- if (verbose && nr_resolved_deltas == nr_deltas)
- fputc('\n', stderr);
}
static int write_compressed(int fd, void *in, unsigned int size, uint32_t *obj_crc)
static void fix_unresolved_deltas(int nr_unresolved)
{
struct delta_entry **sorted_by_pos;
- int i, n = 0, percent = -1;
+ int i, n = 0;
/*
* Since many unresolved deltas may well be themselves base objects
append_obj_to_pack(d->base.sha1, data, size, type);
free(data);
if (verbose)
- percent = display_progress(nr_resolved_deltas,
- nr_deltas, percent);
+ display_progress(&progress, nr_resolved_deltas);
}
free(sorted_by_pos);
- if (verbose)
- fputc('\n', stderr);
-}
-
-static void readjust_pack_header_and_sha1(unsigned char *sha1)
-{
- struct pack_header hdr;
- SHA_CTX ctx;
- int size;
-
- /* Rewrite pack header with updated object number */
- if (lseek(output_fd, 0, SEEK_SET) != 0)
- die("cannot seek back: %s", strerror(errno));
- if (read_in_full(output_fd, &hdr, sizeof(hdr)) != sizeof(hdr))
- die("cannot read pack header back: %s", strerror(errno));
- hdr.hdr_entries = htonl(nr_objects);
- if (lseek(output_fd, 0, SEEK_SET) != 0)
- die("cannot seek back: %s", strerror(errno));
- write_or_die(output_fd, &hdr, sizeof(hdr));
- if (lseek(output_fd, 0, SEEK_SET) != 0)
- die("cannot seek back: %s", strerror(errno));
-
- /* Recompute and store the new pack's SHA1 */
- SHA1_Init(&ctx);
- do {
- unsigned char *buf[4096];
- size = xread(output_fd, buf, sizeof(buf));
- if (size < 0)
- die("cannot read pack data back: %s", strerror(errno));
- SHA1_Update(&ctx, buf, size);
- } while (size > 0);
- SHA1_Final(sha1, &ctx);
- write_or_die(output_fd, sha1, 20);
}
static uint32_t index_default_version = 1;
parse_pack_header();
objects = xmalloc((nr_objects + 1) * sizeof(struct object_entry));
deltas = xmalloc(nr_objects * sizeof(struct delta_entry));
- if (verbose)
- setup_progress_signal();
parse_pack_objects(sha1);
- if (nr_deltas != nr_resolved_deltas) {
+ if (nr_deltas == nr_resolved_deltas) {
+ if (verbose)
+ stop_progress(&progress);
+ /* Flush remaining pack final 20-byte SHA1. */
+ flush();
+ } else {
if (fix_thin_pack) {
int nr_unresolved = nr_deltas - nr_resolved_deltas;
int nr_objects_initial = nr_objects;
(nr_objects + nr_unresolved + 1)
* sizeof(*objects));
fix_unresolved_deltas(nr_unresolved);
- if (verbose)
+ if (verbose) {
+ stop_progress(&progress);
fprintf(stderr, "%d objects were added to complete this thin pack.\n",
nr_objects - nr_objects_initial);
- readjust_pack_header_and_sha1(sha1);
+ }
+ fixup_pack_header_footer(output_fd, sha1,
+ curr_pack, nr_objects);
}
if (nr_deltas != nr_resolved_deltas)
die("pack has %d unresolved deltas",
nr_deltas - nr_resolved_deltas);
- } else {
- /* Flush remaining pack final 20-byte SHA1. */
- flush();
}
free(deltas);
curr_index = write_index_file(index_name, sha1);