Skip to content

Commit

Permalink
Merge branch 'np/progress'
Browse files Browse the repository at this point in the history
* np/progress:
  Show total transferred as part of throughput progress
  make sure throughput display gets updated even if progress doesn't move
  return the prune-packed progress display to the inner loop
  add throughput display to git-push
  add some copyright notice to the progress display code
  add throughput display to index-pack
  add throughput to progress display
  relax usage of the progress API
  make struct progress an opaque type
  prune-packed: don't call display_progress() for every file
  Stop displaying "Pack pack-$ID created." during git-gc
  Teach prune-packed to use the standard progress meter
  Change 'Deltifying objects' to 'Compressing objects'
  fix for more minor memory leaks
  fix const issues with some functions
  pack-objects.c: fix some global variable abuse and memory leaks
  pack-objects: no delta possible with only one object in the list
  cope with multiple line breaks within sideband progress messages
  more compact progress display
  • Loading branch information
Junio C Hamano committed Nov 2, 2007
2 parents 7240bfe + 81f6654 commit 265ae18
Show file tree
Hide file tree
Showing 13 changed files with 276 additions and 138 deletions.
65 changes: 27 additions & 38 deletions builtin-pack-objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ static int no_reuse_delta, no_reuse_object, keep_unreachable;
static int local;
static int incremental;
static int allow_ofs_delta;
static const char *pack_tmp_name, *idx_tmp_name;
static char tmpname[PATH_MAX];
static const char *base_name;
static int progress = 1;
static int window = 10;
Expand All @@ -75,7 +73,7 @@ static int depth = 50;
static int delta_search_threads = 1;
static int pack_to_stdout;
static int num_preferred_base;
static struct progress progress_state;
static struct progress *progress_state;
static int pack_compression_level = Z_DEFAULT_COMPRESSION;
static int pack_compression_seen;

Expand Down Expand Up @@ -587,12 +585,6 @@ static off_t write_one(struct sha1file *f,
return offset + size;
}

static int open_object_dir_tmp(const char *path)
{
snprintf(tmpname, sizeof(tmpname), "%s/%s", get_object_directory(), path);
return xmkstemp(tmpname);
}

/* forward declaration for write_pack_file */
static int adjust_perm(const char *path, mode_t mode);

Expand All @@ -606,16 +598,21 @@ static void write_pack_file(void)
uint32_t nr_remaining = nr_result;

if (do_progress)
start_progress(&progress_state, "Writing %u objects...", "", nr_result);
progress_state = start_progress("Writing objects", nr_result);
written_list = xmalloc(nr_objects * sizeof(struct object_entry *));

do {
unsigned char sha1[20];
char *pack_tmp_name = NULL;

if (pack_to_stdout) {
f = sha1fd(1, "<stdout>");
f = sha1fd_throughput(1, "<stdout>", progress_state);
} else {
int fd = open_object_dir_tmp("tmp_pack_XXXXXX");
char tmpname[PATH_MAX];
int fd;
snprintf(tmpname, sizeof(tmpname),
"%s/tmp_pack_XXXXXX", get_object_directory());
fd = xmkstemp(tmpname);
pack_tmp_name = xstrdup(tmpname);
f = sha1fd(fd, pack_tmp_name);
}
Expand All @@ -632,8 +629,7 @@ static void write_pack_file(void)
if (!offset_one)
break;
offset = offset_one;
if (do_progress)
display_progress(&progress_state, written);
display_progress(progress_state, written);
}

/*
Expand All @@ -643,19 +639,21 @@ static void write_pack_file(void)
if (pack_to_stdout || nr_written == nr_remaining) {
sha1close(f, sha1, 1);
} else {
sha1close(f, sha1, 0);
fixup_pack_header_footer(f->fd, sha1, pack_tmp_name, nr_written);
close(f->fd);
int fd = sha1close(f, NULL, 0);
fixup_pack_header_footer(fd, sha1, pack_tmp_name, nr_written);
close(fd);
}

if (!pack_to_stdout) {
mode_t mode = umask(0);
char *idx_tmp_name, tmpname[PATH_MAX];

umask(mode);
mode = 0444 & ~mode;

idx_tmp_name = write_idx_file(NULL,
(struct pack_idx_entry **) written_list, nr_written, sha1);
(struct pack_idx_entry **) written_list,
nr_written, sha1);
snprintf(tmpname, sizeof(tmpname), "%s-%s.pack",
base_name, sha1_to_hex(sha1));
if (adjust_perm(pack_tmp_name, mode))
Expand All @@ -672,6 +670,8 @@ static void write_pack_file(void)
if (rename(idx_tmp_name, tmpname))
die("unable to rename temporary index file: %s",
strerror(errno));
free(idx_tmp_name);
free(pack_tmp_name);
puts(sha1_to_hex(sha1));
}

Expand All @@ -683,8 +683,7 @@ static void write_pack_file(void)
} while (nr_remaining && i < nr_objects);

free(written_list);
if (do_progress)
stop_progress(&progress_state);
stop_progress(&progress_state);
if (written != nr_result)
die("wrote %u objects while expecting %u", written, nr_result);
/*
Expand Down Expand Up @@ -852,8 +851,7 @@ static int add_object_entry(const unsigned char *sha1, enum object_type type,
else
object_ix[-1 - ix] = nr_objects;

if (progress)
display_progress(&progress_state, nr_objects);
display_progress(progress_state, nr_objects);

if (name && no_try_delta(name))
entry->no_try_delta = 1;
Expand Down Expand Up @@ -1516,8 +1514,7 @@ static void find_deltas(struct object_entry **list, unsigned list_size,

progress_lock();
(*processed)++;
if (progress)
display_progress(&progress_state, *processed);
display_progress(progress_state, *processed);
progress_unlock();

/*
Expand Down Expand Up @@ -1714,16 +1711,14 @@ static void prepare_pack(int window, int depth)
delta_list[n++] = entry;
}

if (nr_deltas) {
if (nr_deltas && n > 1) {
unsigned nr_done = 0;
if (progress)
start_progress(&progress_state,
"Deltifying %u objects...", "",
nr_deltas);
progress_state = start_progress("Compressing objects",
nr_deltas);
qsort(delta_list, n, sizeof(*delta_list), type_size_sort);
ll_find_deltas(delta_list, n, window+1, depth, &nr_done);
if (progress)
stop_progress(&progress_state);
stop_progress(&progress_state);
if (nr_done != nr_deltas)
die("inconsistency with delta count");
}
Expand Down Expand Up @@ -2135,23 +2130,17 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
prepare_packed_git();

if (progress)
start_progress(&progress_state, "Generating pack...",
"Counting objects: ", 0);
progress_state = start_progress("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) {
stop_progress(&progress_state);
fprintf(stderr, "Done counting %u objects.\n", nr_objects);
}
stop_progress(&progress_state);

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);
write_pack_file();
Expand Down
14 changes: 9 additions & 5 deletions builtin-prune-packed.c
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
#include "builtin.h"
#include "cache.h"
#include "progress.h"

static const char prune_packed_usage[] =
"git-prune-packed [-n] [-q]";

#define DRY_RUN 01
#define VERBOSE 02

static struct progress *progress;

static void prune_dir(int i, DIR *dir, char *pathname, int len, int opts)
{
struct dirent *de;
Expand All @@ -27,6 +30,7 @@ static void prune_dir(int i, DIR *dir, char *pathname, int len, int opts)
printf("rm -f %s\n", pathname);
else if (unlink(pathname) < 0)
error("unable to unlink %s", pathname);
display_progress(progress, i + 1);
}
pathname[len] = 0;
rmdir(pathname);
Expand All @@ -39,6 +43,10 @@ void prune_packed_objects(int opts)
const char *dir = get_object_directory();
int len = strlen(dir);

if (opts == VERBOSE)
progress = start_progress_delay("Removing duplicate objects",
256, 95, 2);

if (len > PATH_MAX - 42)
die("impossible object directory");
memcpy(pathname, dir, len);
Expand All @@ -49,16 +57,12 @@ void prune_packed_objects(int opts)

sprintf(pathname + len, "%02x/", i);
d = opendir(pathname);
if (opts == VERBOSE && (d || i == 255))
fprintf(stderr, "Removing unused objects %d%%...\015",
((i+1) * 100) / 256);
if (!d)
continue;
prune_dir(i, d, pathname, len + 3, opts);
closedir(d);
}
if (opts == VERBOSE)
fprintf(stderr, "\nDone.\n");
stop_progress(&progress);
}

int cmd_prune_packed(int argc, const char **argv, const char *prefix)
Expand Down
10 changes: 4 additions & 6 deletions builtin-unpack-objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ static void unpack_one(unsigned nr)
static void unpack_all(void)
{
int i;
struct progress progress;
struct progress *progress = NULL;
struct pack_header *hdr = fill(sizeof(struct pack_header));
unsigned nr_objects = ntohl(hdr->hdr_entries);

Expand All @@ -322,15 +322,13 @@ static void unpack_all(void)
use(sizeof(struct pack_header));

if (!quiet)
start_progress(&progress, "Unpacking %u objects...", "", nr_objects);
progress = start_progress("Unpacking objects", nr_objects);
obj_list = xmalloc(nr_objects * sizeof(*obj_list));
for (i = 0; i < nr_objects; i++) {
unpack_one(i);
if (!quiet)
display_progress(&progress, i + 1);
display_progress(progress, i + 1);
}
if (!quiet)
stop_progress(&progress);
stop_progress(&progress);

if (delta_list)
die("unresolved deltas left after unpacking");
Expand Down
31 changes: 22 additions & 9 deletions csum-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* able to verify hasn't been messed with afterwards.
*/
#include "cache.h"
#include "progress.h"
#include "csum-file.h"

static void sha1flush(struct sha1file *f, unsigned int count)
Expand All @@ -17,6 +18,7 @@ static void sha1flush(struct sha1file *f, unsigned int count)
for (;;) {
int ret = xwrite(f->fd, buf, count);
if (ret > 0) {
display_throughput(f->tp, ret);
buf = (char *) buf + ret;
count -= ret;
if (count)
Expand All @@ -31,22 +33,27 @@ static void sha1flush(struct sha1file *f, unsigned int count)

int sha1close(struct sha1file *f, unsigned char *result, int final)
{
int fd;
unsigned offset = f->offset;
if (offset) {
SHA1_Update(&f->ctx, f->buffer, offset);
sha1flush(f, offset);
f->offset = 0;
}
if (!final)
return 0; /* only want to flush (no checksum write, no close) */
SHA1_Final(f->buffer, &f->ctx);
if (result)
hashcpy(result, f->buffer);
sha1flush(f, 20);
if (close(f->fd))
die("%s: sha1 file error on close (%s)", f->name, strerror(errno));
if (final) {
/* write checksum and close fd */
SHA1_Final(f->buffer, &f->ctx);
if (result)
hashcpy(result, f->buffer);
sha1flush(f, 20);
if (close(f->fd))
die("%s: sha1 file error on close (%s)",
f->name, strerror(errno));
fd = 0;
} else
fd = f->fd;
free(f);
return 0;
return fd;
}

int sha1write(struct sha1file *f, void *buf, unsigned int count)
Expand Down Expand Up @@ -74,6 +81,11 @@ int sha1write(struct sha1file *f, void *buf, unsigned int count)
}

struct sha1file *sha1fd(int fd, const char *name)
{
return sha1fd_throughput(fd, name, NULL);
}

struct sha1file *sha1fd_throughput(int fd, const char *name, struct progress *tp)
{
struct sha1file *f;
unsigned len;
Expand All @@ -89,6 +101,7 @@ struct sha1file *sha1fd(int fd, const char *name)
f->fd = fd;
f->error = 0;
f->offset = 0;
f->tp = tp;
f->do_crc = 0;
SHA1_Init(&f->ctx);
return f;
Expand Down
4 changes: 4 additions & 0 deletions csum-file.h
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
#ifndef CSUM_FILE_H
#define CSUM_FILE_H

struct progress;

/* A SHA1-protected file */
struct sha1file {
int fd, error;
unsigned int offset, namelen;
SHA_CTX ctx;
struct progress *tp;
char name[PATH_MAX];
int do_crc;
uint32_t crc32;
unsigned char buffer[8192];
};

extern struct sha1file *sha1fd(int fd, const char *name);
extern struct sha1file *sha1fd_throughput(int fd, const char *name, struct progress *tp);
extern int sha1close(struct sha1file *, unsigned char *, int);
extern int sha1write(struct sha1file *, void *, unsigned int);
extern void crc32_begin(struct sha1file *);
Expand Down
3 changes: 0 additions & 3 deletions git-repack.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,6 @@ for name in $names ; do
fullbases="$fullbases pack-$name"
chmod a-w "$PACKTMP-$name.pack"
chmod a-w "$PACKTMP-$name.idx"
if test "$quiet" != '-q'; then
echo "Pack pack-$name created."
fi
mkdir -p "$PACKDIR" || exit

for sfx in pack idx
Expand Down
Loading

0 comments on commit 265ae18

Please sign in to comment.