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:
commit
7b1baed3fb
@ -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]);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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');
|
||||
}
|
||||
|
55
reachable.c
55
reachable.c
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user