Merge branch 'nd/prune-progress'

* nd/prune-progress:
  reachable: per-object progress
  prune: handle --progress/no-progress
  prune: show progress while marking reachable objects
This commit is contained in:
Junio C Hamano 2011-12-05 15:11:11 -08:00
commit 7b1baed3fb
5 changed files with 60 additions and 17 deletions

View File

@ -32,7 +32,7 @@ static const char *prune_expire = "2.weeks.ago";
static const char *argv_pack_refs[] = {"pack-refs", "--all", "--prune", NULL};
static const char *argv_reflog[] = {"reflog", "expire", "--all", NULL};
static const char *argv_repack[MAX_ADD] = {"repack", "-d", "-l", NULL};
static const char *argv_prune[] = {"prune", "--expire", NULL, NULL};
static const char *argv_prune[] = {"prune", "--expire", NULL, NULL, NULL};
static const char *argv_rerere[] = {"rerere", "gc", NULL};
static int gc_config(const char *var, const char *value, void *cb)
@ -243,6 +243,8 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
if (prune_expire) {
argv_prune[2] = prune_expire;
if (quiet)
argv_prune[3] = "--no-progress";
if (run_command_v_opt(argv_prune, RUN_GIT_CMD))
return error(FAILED_RUN, argv_prune[0]);
}

View File

@ -5,6 +5,7 @@
#include "builtin.h"
#include "reachable.h"
#include "parse-options.h"
#include "progress.h"
#include "dir.h"
static const char * const prune_usage[] = {
@ -14,6 +15,7 @@ static const char * const prune_usage[] = {
static int show_only;
static int verbose;
static unsigned long expire;
static int show_progress = -1;
static int prune_tmp_object(const char *path, const char *filename)
{
@ -124,9 +126,11 @@ static void remove_temporary_files(const char *path)
int cmd_prune(int argc, const char **argv, const char *prefix)
{
struct rev_info revs;
struct progress *progress = NULL;
const struct option options[] = {
OPT__DRY_RUN(&show_only, "do not remove, show only"),
OPT__VERBOSE(&verbose, "report pruned objects"),
OPT_BOOL(0, "progress", &show_progress, "show progress"),
OPT_DATE(0, "expire", &expire,
"expire objects older than <time>"),
OPT_END()
@ -152,7 +156,14 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
else
die("unrecognized argument: %s", name);
}
mark_reachable_objects(&revs, 1);
if (show_progress == -1)
show_progress = isatty(2);
if (show_progress)
progress = start_progress_delay("Checking connectivity", 0, 0, 2);
mark_reachable_objects(&revs, 1, progress);
stop_progress(&progress);
prune_object_dir(get_object_directory());
prune_packed_objects(show_only);

View File

@ -647,7 +647,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
init_revisions(&cb.revs, prefix);
if (cb.verbose)
printf("Marking reachable objects...");
mark_reachable_objects(&cb.revs, 0);
mark_reachable_objects(&cb.revs, 0, NULL);
if (cb.verbose)
putchar('\n');
}

View File

@ -7,11 +7,25 @@
#include "revision.h"
#include "reachable.h"
#include "cache-tree.h"
#include "progress.h"
struct connectivity_progress {
struct progress *progress;
unsigned long count;
};
static void update_progress(struct connectivity_progress *cp)
{
cp->count++;
if ((cp->count & 1023) == 0)
display_progress(cp->progress, cp->count);
}
static void process_blob(struct blob *blob,
struct object_array *p,
struct name_path *path,
const char *name)
const char *name,
struct connectivity_progress *cp)
{
struct object *obj = &blob->object;
@ -20,6 +34,7 @@ static void process_blob(struct blob *blob,
if (obj->flags & SEEN)
return;
obj->flags |= SEEN;
update_progress(cp);
/* Nothing to do, really .. The blob lookup was the important part */
}
@ -34,7 +49,8 @@ static void process_gitlink(const unsigned char *sha1,
static void process_tree(struct tree *tree,
struct object_array *p,
struct name_path *path,
const char *name)
const char *name,
struct connectivity_progress *cp)
{
struct object *obj = &tree->object;
struct tree_desc desc;
@ -46,6 +62,7 @@ static void process_tree(struct tree *tree,
if (obj->flags & SEEN)
return;
obj->flags |= SEEN;
update_progress(cp);
if (parse_tree(tree) < 0)
die("bad tree object %s", sha1_to_hex(obj->sha1));
add_object(obj, p, path, name);
@ -57,23 +74,25 @@ static void process_tree(struct tree *tree,
while (tree_entry(&desc, &entry)) {
if (S_ISDIR(entry.mode))
process_tree(lookup_tree(entry.sha1), p, &me, entry.path);
process_tree(lookup_tree(entry.sha1), p, &me, entry.path, cp);
else if (S_ISGITLINK(entry.mode))
process_gitlink(entry.sha1, p, &me, entry.path);
else
process_blob(lookup_blob(entry.sha1), p, &me, entry.path);
process_blob(lookup_blob(entry.sha1), p, &me, entry.path, cp);
}
free(tree->buffer);
tree->buffer = NULL;
}
static void process_tag(struct tag *tag, struct object_array *p, const char *name)
static void process_tag(struct tag *tag, struct object_array *p,
const char *name, struct connectivity_progress *cp)
{
struct object *obj = &tag->object;
if (obj->flags & SEEN)
return;
obj->flags |= SEEN;
update_progress(cp);
if (parse_tag(tag) < 0)
die("bad tag object %s", sha1_to_hex(obj->sha1));
@ -81,15 +100,18 @@ static void process_tag(struct tag *tag, struct object_array *p, const char *nam
add_object(tag->tagged, p, NULL, name);
}
static void walk_commit_list(struct rev_info *revs)
static void walk_commit_list(struct rev_info *revs,
struct connectivity_progress *cp)
{
int i;
struct commit *commit;
struct object_array objects = OBJECT_ARRAY_INIT;
/* Walk all commits, process their trees */
while ((commit = get_revision(revs)) != NULL)
process_tree(commit->tree, &objects, NULL, "");
while ((commit = get_revision(revs)) != NULL) {
process_tree(commit->tree, &objects, NULL, "", cp);
update_progress(cp);
}
/* Then walk all the pending objects, recursively processing them too */
for (i = 0; i < revs->pending.nr; i++) {
@ -97,15 +119,15 @@ static void walk_commit_list(struct rev_info *revs)
struct object *obj = pending->item;
const char *name = pending->name;
if (obj->type == OBJ_TAG) {
process_tag((struct tag *) obj, &objects, name);
process_tag((struct tag *) obj, &objects, name, cp);
continue;
}
if (obj->type == OBJ_TREE) {
process_tree((struct tree *)obj, &objects, NULL, name);
process_tree((struct tree *)obj, &objects, NULL, name, cp);
continue;
}
if (obj->type == OBJ_BLOB) {
process_blob((struct blob *)obj, &objects, NULL, name);
process_blob((struct blob *)obj, &objects, NULL, name, cp);
continue;
}
die("unknown pending object %s (%s)", sha1_to_hex(obj->sha1), name);
@ -191,8 +213,11 @@ static void add_cache_refs(struct rev_info *revs)
add_cache_tree(active_cache_tree, revs);
}
void mark_reachable_objects(struct rev_info *revs, int mark_reflog)
void mark_reachable_objects(struct rev_info *revs, int mark_reflog,
struct progress *progress)
{
struct connectivity_progress cp;
/*
* Set up revision parsing, and mark us as being interested
* in all object types, not just commits.
@ -211,11 +236,15 @@ void mark_reachable_objects(struct rev_info *revs, int mark_reflog)
if (mark_reflog)
for_each_reflog(add_one_reflog, revs);
cp.progress = progress;
cp.count = 0;
/*
* Set up the revision walk - this will move all commits
* from the pending list to the commit walking list.
*/
if (prepare_revision_walk(revs))
die("revision walk setup failed");
walk_commit_list(revs);
walk_commit_list(revs, &cp);
display_progress(cp.progress, cp.count);
}

View File

@ -1,6 +1,7 @@
#ifndef REACHEABLE_H
#define REACHEABLE_H
extern void mark_reachable_objects(struct rev_info *revs, int mark_reflog);
struct progress;
extern void mark_reachable_objects(struct rev_info *revs, int mark_reflog, struct progress *);
#endif