summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--builtin-pack-objects.c83
-rw-r--r--builtin-unpack-objects.c38
-rw-r--r--index-pack.c78
-rw-r--r--progress.c68
-rw-r--r--progress.h14
-rw-r--r--unpack-trees.c54
7 files changed, 154 insertions, 185 deletions
diff --git a/Makefile b/Makefile
index c9c2a5fb66..65bd2dbf9d 100644
--- a/Makefile
+++ b/Makefile
@@ -283,7 +283,7 @@ LIB_H = \
diff.h object.h pack.h pkt-line.h quote.h refs.h list-objects.h sideband.h \
run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h \
tree-walk.h log-tree.h dir.h path-list.h unpack-trees.h builtin.h \
- utf8.h reflog-walk.h patch-ids.h attr.h decorate.h
+ utf8.h reflog-walk.h patch-ids.h attr.h decorate.h progress.h
DIFF_OBJS = \
diff.o diff-lib.o diffcore-break.o diffcore-order.o \
@@ -305,7 +305,7 @@ LIB_OBJS = \
write_or_die.o trace.o list-objects.o grep.o match-trees.o \
alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \
color.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o \
- convert.o attr.o decorate.o
+ convert.o attr.o decorate.o progress.o
BUILTIN_OBJS = \
builtin-add.o \
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 50fc37fa0f..d7d9996f5e 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -12,6 +12,7 @@
#include "diff.h"
#include "revision.h"
#include "list-objects.h"
+#include "progress.h"
static const char pack_usage[] = "\
git-pack-objects [{ -q | --progress | --all-progress }] \n\
@@ -62,10 +63,10 @@ static const char *pack_tmp_name, *idx_tmp_name;
static char tmpname[PATH_MAX];
static unsigned char pack_file_sha1[20];
static int progress = 1;
-static volatile sig_atomic_t progress_update;
static int window = 10;
static int pack_to_stdout;
static int num_preferred_base;
+static struct progress progress_state;
/*
* The object names in objects array are hashed with this hashtable,
@@ -564,7 +565,6 @@ static off_t write_pack_file(void)
struct sha1file *f;
off_t offset, last_obj_offset = 0;
struct pack_header hdr;
- unsigned last_percent = 999;
int do_progress = progress;
if (pack_to_stdout) {
@@ -580,8 +580,10 @@ static off_t write_pack_file(void)
f = sha1fd(fd, pack_tmp_name);
}
- if (do_progress)
+ if (do_progress) {
fprintf(stderr, "Writing %u objects.\n", nr_result);
+ start_progress(&progress_state, "", nr_result);
+ }
hdr.hdr_signature = htonl(PACK_SIGNATURE);
hdr.hdr_version = htonl(PACK_VERSION);
@@ -593,18 +595,11 @@ static off_t write_pack_file(void)
for (i = 0; i < nr_objects; i++) {
last_obj_offset = offset;
offset = write_one(f, objects + i, offset);
- if (do_progress) {
- unsigned percent = written * 100 / nr_result;
- if (progress_update || percent != last_percent) {
- fprintf(stderr, "%4u%% (%u/%u) done\r",
- percent, written, nr_result);
- progress_update = 0;
- last_percent = percent;
- }
- }
+ if (do_progress)
+ display_progress(&progress_state, written);
}
if (do_progress)
- fputc('\n', stderr);
+ stop_progress(&progress_state);
done:
if (written != nr_result)
die("wrote %u objects while expecting %u", written, nr_result);
@@ -865,10 +860,8 @@ static int add_object_entry(const unsigned char *sha1, enum object_type type,
else
object_ix[-1 - ix] = nr_objects;
- if (progress_update) {
- fprintf(stderr, "Counting objects...%u\r", nr_objects);
- progress_update = 0;
- }
+ if (progress)
+ display_progress(&progress_state, nr_objects);
return 1;
}
@@ -1390,15 +1383,16 @@ static void find_deltas(struct object_entry **list, int window, int depth)
uint32_t i = nr_objects, idx = 0, processed = 0;
unsigned int array_size = window * sizeof(struct unpacked);
struct unpacked *array;
- unsigned last_percent = 999;
int max_depth;
if (!nr_objects)
return;
array = xmalloc(array_size);
memset(array, 0, array_size);
- if (progress)
+ if (progress) {
fprintf(stderr, "Deltifying %u objects.\n", nr_result);
+ start_progress(&progress_state, "", nr_result);
+ }
do {
struct object_entry *entry = list[--i];
@@ -1408,15 +1402,8 @@ static void find_deltas(struct object_entry **list, int window, int depth)
if (!entry->preferred_base)
processed++;
- if (progress) {
- unsigned percent = processed * 100 / nr_result;
- if (percent != last_percent || progress_update) {
- fprintf(stderr, "%4u%% (%u/%u) done\r",
- percent, processed, nr_result);
- progress_update = 0;
- last_percent = percent;
- }
- }
+ if (progress)
+ display_progress(&progress_state, processed);
if (entry->delta)
/* This happens if we decided to reuse existing
@@ -1471,7 +1458,7 @@ static void find_deltas(struct object_entry **list, int window, int depth)
} while (i > 0);
if (progress)
- fputc('\n', stderr);
+ stop_progress(&progress_state);
for (i = 0; i < window; ++i) {
free_delta_index(array[i].index);
@@ -1498,28 +1485,6 @@ static void prepare_pack(int window, int depth)
free(delta_list);
}
-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 int git_pack_config(const char *k, const char *v)
{
if(!strcmp(k, "pack.window")) {
@@ -1759,31 +1724,25 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
if (progress) {
fprintf(stderr, "Generating pack...\n");
- setup_progress_signal();
+ start_progress(&progress_state, "Counting objects: ", 0);
}
-
if (!use_internal_rev_list)
read_object_list_from_stdin();
else {
rp_av[rp_ac] = NULL;
get_object_list(rp_ac, rp_av);
}
-
- if (progress)
+ if (progress) {
+ stop_progress(&progress_state);
fprintf(stderr, "Done counting %u objects.\n", nr_objects);
+ }
+
if (non_empty && !nr_result)
return 0;
if (progress && (nr_objects != nr_result))
fprintf(stderr, "Result has %u objects.\n", nr_result);
if (nr_result)
prepare_pack(window, depth);
- if (progress == 1 && pack_to_stdout) {
- /* the other end usually displays progress itself */
- struct itimerval v = {{0,},};
- setitimer(ITIMER_REAL, &v, NULL);
- signal(SIGALRM, SIG_IGN );
- progress_update = 0;
- }
last_obj_offset = write_pack_file();
if (!pack_to_stdout) {
unsigned char object_list_sha1[20];
diff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c
index f821906460..c370c7f834 100644
--- a/builtin-unpack-objects.c
+++ b/builtin-unpack-objects.c
@@ -7,6 +7,7 @@
#include "commit.h"
#include "tag.h"
#include "tree.h"
+#include "progress.h"
static int dry_run, quiet, recover, has_errors;
static const char unpack_usage[] = "git-unpack-objects [-n] [-q] [-r] < pack-file";
@@ -264,7 +265,7 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
free(base);
}
-static void unpack_one(unsigned nr, unsigned total)
+static void unpack_one(unsigned nr)
{
unsigned shift;
unsigned char *pack, c;
@@ -286,20 +287,7 @@ static void unpack_one(unsigned nr, unsigned total)
size += (c & 0x7f) << shift;
shift += 7;
}
- if (!quiet) {
- static unsigned long last_sec;
- static unsigned last_percent;
- struct timeval now;
- unsigned percentage = ((nr+1) * 100) / total;
-
- gettimeofday(&now, NULL);
- if (percentage != last_percent || now.tv_sec != last_sec) {
- last_sec = now.tv_sec;
- last_percent = percentage;
- fprintf(stderr, "%4u%% (%u/%u) done\r",
- percentage, (nr+1), total);
- }
- }
+
switch (type) {
case OBJ_COMMIT:
case OBJ_TREE:
@@ -323,6 +311,7 @@ static void unpack_one(unsigned nr, unsigned total)
static void unpack_all(void)
{
int i;
+ struct progress progress;
struct pack_header *hdr = fill(sizeof(struct pack_header));
unsigned nr_objects = ntohl(hdr->hdr_entries);
@@ -330,12 +319,21 @@ static void unpack_all(void)
die("bad pack file");
if (!pack_version_ok(hdr->hdr_version))
die("unknown pack file version %d", ntohl(hdr->hdr_version));
- fprintf(stderr, "Unpacking %d objects\n", nr_objects);
+ use(sizeof(struct pack_header));
+ if (!quiet) {
+ fprintf(stderr, "Unpacking %d objects\n", nr_objects);
+ start_progress(&progress, "", nr_objects);
+ }
obj_list = xmalloc(nr_objects * sizeof(*obj_list));
- use(sizeof(struct pack_header));
- for (i = 0; i < nr_objects; i++)
- unpack_one(i, nr_objects);
+ for (i = 0; i < nr_objects; i++) {
+ unpack_one(i);
+ if (!quiet)
+ display_progress(&progress, i + 1);
+ }
+ if (!quiet)
+ stop_progress(&progress);
+
if (delta_list)
die("unresolved deltas left after unpacking");
}
@@ -404,7 +402,5 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix)
}
/* All done */
- if (!quiet)
- fprintf(stderr, "\n");
return has_errors;
}
diff --git a/index-pack.c b/index-pack.c
index 7aad261d48..a49d03d6de 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -6,6 +6,7 @@
#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>] }";
@@ -47,40 +48,7 @@ static int nr_resolved_deltas;
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];
@@ -428,7 +396,7 @@ static int compare_delta_entry(const void *a, const void *b)
/* 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;
@@ -439,8 +407,10 @@ static void parse_pack_objects(unsigned char *sha1)
* - calculate SHA1 of all non-delta objects;
* - remember base (SHA1 or offset) for all deltas.
*/
- if (verbose)
+ if (verbose) {
fprintf(stderr, "Indexing %d objects.\n", nr_objects);
+ start_progress(&progress, "", nr_objects);
+ }
for (i = 0; i < nr_objects; i++) {
struct object_entry *obj = &objects[i];
data = unpack_raw_entry(obj, &delta->base);
@@ -453,11 +423,11 @@ static void parse_pack_objects(unsigned char *sha1)
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();
@@ -488,8 +458,10 @@ static void parse_pack_objects(unsigned char *sha1)
* recursively checking if the resulting object is used as a base
* for some more deltas.
*/
- if (verbose)
+ if (verbose) {
fprintf(stderr, "Resolving %d deltas.\n", nr_deltas);
+ start_progress(&progress, "", nr_deltas);
+ }
for (i = 0; i < nr_objects; i++) {
struct object_entry *obj = &objects[i];
union delta_base base;
@@ -521,11 +493,8 @@ static void parse_pack_objects(unsigned char *sha1)
}
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)
@@ -587,7 +556,7 @@ static int delta_pos_compare(const void *_a, const void *_b)
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
@@ -632,12 +601,9 @@ static void fix_unresolved_deltas(int nr_unresolved)
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)
@@ -980,10 +946,13 @@ int main(int argc, char **argv)
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;
@@ -993,17 +962,16 @@ int main(int argc, char **argv)
(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);
}
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);
diff --git a/progress.c b/progress.c
new file mode 100644
index 0000000000..702e116066
--- /dev/null
+++ b/progress.c
@@ -0,0 +1,68 @@
+#include "git-compat-util.h"
+#include "progress.h"
+
+static volatile sig_atomic_t progress_update;
+
+static void progress_interval(int signum)
+{
+ progress_update = 1;
+}
+
+static void set_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 void clear_progress_signal(void)
+{
+ struct itimerval v = {{0,},};
+ setitimer(ITIMER_REAL, &v, NULL);
+ signal(SIGALRM, SIG_IGN);
+ progress_update = 0;
+}
+
+int display_progress(struct progress *progress, unsigned n)
+{
+ if (progress->total) {
+ unsigned percent = n * 100 / progress->total;
+ if (percent != progress->last_percent || progress_update) {
+ progress->last_percent = percent;
+ fprintf(stderr, "%s%4u%% (%u/%u) done\r",
+ progress->msg, percent, n, progress->total);
+ progress_update = 0;
+ return 1;
+ }
+ } else if (progress_update) {
+ fprintf(stderr, "%s%u\r", progress->msg, n);
+ progress_update = 0;
+ return 1;
+ }
+ return 0;
+}
+
+void start_progress(struct progress *progress, const char *msg, unsigned total)
+{
+ progress->msg = msg;
+ progress->total = total;
+ progress->last_percent = -1;
+ set_progress_signal();
+}
+
+void stop_progress(struct progress *progress)
+{
+ clear_progress_signal();
+ if (progress->total)
+ fputc('\n', stderr);
+}
diff --git a/progress.h b/progress.h
new file mode 100644
index 0000000000..5fa4948117
--- /dev/null
+++ b/progress.h
@@ -0,0 +1,14 @@
+#ifndef __progress_h__
+#define __progress_h__
+
+struct progress {
+ const char *msg;
+ unsigned total;
+ unsigned last_percent;
+};
+
+int display_progress(struct progress *progress, unsigned n);
+void start_progress(struct progress *progress, const char *msg, unsigned total);
+void stop_progress(struct progress *progress);
+
+#endif
diff --git a/unpack-trees.c b/unpack-trees.c
index 5139481358..8a11622ccb 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -4,6 +4,7 @@
#include "tree-walk.h"
#include "cache-tree.h"
#include "unpack-trees.h"
+#include "progress.h"
#define DBRT_DEBUG 1
@@ -288,36 +289,13 @@ static void unlink_entry(char *name)
}
}
-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 struct checkout state;
static void check_updates(struct cache_entry **src, int nr,
struct unpack_trees_options *o)
{
unsigned short mask = htons(CE_UPDATE);
- unsigned last_percent = 200, cnt = 0, total = 0;
+ unsigned cnt = 0, total = 0;
+ struct progress progress;
if (o->update && o->verbose_update) {
for (total = cnt = 0; cnt < nr; cnt++) {
@@ -332,8 +310,7 @@ static void check_updates(struct cache_entry **src, int nr,
if (total) {
fprintf(stderr, "Checking files out...\n");
- setup_progress_signal();
- progress_update = 1;
+ start_progress(&progress, "", total);
}
cnt = 0;
}
@@ -341,20 +318,9 @@ static void check_updates(struct cache_entry **src, int nr,
while (nr--) {
struct cache_entry *ce = *src++;
- if (total) {
- if (!ce->ce_mode || ce->ce_flags & mask) {
- unsigned percent;
- cnt++;
- percent = (cnt * 100) / total;
- if (percent != last_percent ||
- progress_update) {
- fprintf(stderr, "%4u%% (%u/%u) done\r",
- percent, cnt, total);
- last_percent = percent;
- progress_update = 0;
- }
- }
- }
+ if (total)
+ if (!ce->ce_mode || ce->ce_flags & mask)
+ display_progress(&progress, ++cnt);
if (!ce->ce_mode) {
if (o->update)
unlink_entry(ce->name);
@@ -366,10 +332,8 @@ static void check_updates(struct cache_entry **src, int nr,
checkout_entry(ce, &state, NULL);
}
}
- if (total) {
- signal(SIGALRM, SIG_IGN);
- fputc('\n', stderr);
- }
+ if (total)
+ stop_progress(&progress);;
}
int unpack_trees(struct object_list *trees, struct unpack_trees_options *o)