summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: f1af60b)
raw | patch | inline | side by side (parent: f1af60b)
author | Nicolas Pitre <nico@cam.org> | |
Wed, 18 Apr 2007 18:27:45 +0000 (14:27 -0400) | ||
committer | Junio C Hamano <junkio@cox.net> | |
Mon, 23 Apr 2007 05:18:05 +0000 (22:18 -0700) |
Instead of having this code duplicated in multiple places, let's have
a common interface for progress display. If someday someone wishes to
display a cheezy progress bar instead then only one file will have to
be changed.
Note: I left merge-recursive.c out since it has a strange notion of
progress as it apparently increase the expected total number as it goes.
Someone with more intimate knowledge of what that is supposed to mean
might look at converting it to the common progress interface.
Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
a common interface for progress display. If someday someone wishes to
display a cheezy progress bar instead then only one file will have to
be changed.
Note: I left merge-recursive.c out since it has a strange notion of
progress as it apparently increase the expected total number as it goes.
Someone with more intimate knowledge of what that is supposed to mean
might look at converting it to the common progress interface.
Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Makefile | patch | blob | history | |
builtin-pack-objects.c | patch | blob | history | |
builtin-unpack-objects.c | patch | blob | history | |
index-pack.c | patch | blob | history | |
progress.c | [new file with mode: 0644] | patch | blob |
progress.h | [new file with mode: 0644] | patch | blob |
unpack-trees.c | patch | blob | history |
diff --git a/Makefile b/Makefile
index c9c2a5fb6685333895b6ab28a4ae355a6ac378bb..65bd2dbf9d8089ba8c7bf20479605ef3b02b6a49 100644 (file)
--- a/Makefile
+++ b/Makefile
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 \
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 50fc37fa0f77876fd73558eab3751653cce2a27e..d7d9996f5e3b6ce58c4dbe26d89adf6d66de6281 100644 (file)
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
#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\
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,
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) {
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);
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);
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;
}
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];
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
} while (i > 0);
if (progress)
- fputc('\n', stderr);
+ stop_progress(&progress_state);
for (i = 0; i < window; ++i) {
free_delta_index(array[i].index);
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")) {
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];
index f8219064602775346bb0d8a323339b3d077da31c..c370c7f834f69ba69d5366d47aadab3b6162b095 100644 (file)
--- a/builtin-unpack-objects.c
+++ b/builtin-unpack-objects.c
#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";
free(base);
}
-static void unpack_one(unsigned nr, unsigned total)
+static void unpack_one(unsigned nr)
{
unsigned shift;
unsigned char *pack, c;
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:
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);
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");
}
}
/* All done */
- if (!quiet)
- fprintf(stderr, "\n");
return has_errors;
}
diff --git a/index-pack.c b/index-pack.c
index 7aad261d485f209f7459362dbe5a7cf5f6a9cf42..a49d03d6de170dbffa63b55c07bf9425b704380c 100644 (file)
--- a/index-pack.c
+++ b/index-pack.c
#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;
* - 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);
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();
* 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;
}
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)
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);
}
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
--- /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
--- /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 5139481358d0838a95db3fdb62e32221eb7343b1..8a11622ccb58b192425b9300078e82760a6bce38 100644 (file)
--- a/unpack-trees.c
+++ b/unpack-trees.c
#include "tree-walk.h"
#include "cache-tree.h"
#include "unpack-trees.h"
+#include "progress.h"
#define DBRT_DEBUG 1
}
}
-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++) {
if (total) {
fprintf(stderr, "Checking files out...\n");
- setup_progress_signal();
- progress_update = 1;
+ start_progress(&progress, "", total);
}
cnt = 0;
}
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);
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)