summaryrefslogtreecommitdiff
path: root/builtin/prune.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/prune.c')
-rw-r--r--builtin/prune.c44
1 files changed, 32 insertions, 12 deletions
diff --git a/builtin/prune.c b/builtin/prune.c
index 1ec9ddd751..97613eccb5 100644
--- a/builtin/prune.c
+++ b/builtin/prune.c
@@ -31,16 +31,39 @@ static int prune_tmp_file(const char *fullpath)
return 0;
}
+static void perform_reachability_traversal(struct rev_info *revs)
+{
+ static int initialized;
+ struct progress *progress = NULL;
+
+ if (initialized)
+ return;
+
+ if (show_progress)
+ progress = start_delayed_progress(_("Checking connectivity"), 0);
+ mark_reachable_objects(revs, 1, expire, progress);
+ stop_progress(&progress);
+ initialized = 1;
+}
+
+static int is_object_reachable(const struct object_id *oid,
+ struct rev_info *revs)
+{
+ struct object *obj;
+
+ perform_reachability_traversal(revs);
+
+ obj = lookup_object(the_repository, oid->hash);
+ return obj && (obj->flags & SEEN);
+}
+
static int prune_object(const struct object_id *oid, const char *fullpath,
void *data)
{
+ struct rev_info *revs = data;
struct stat st;
- /*
- * Do we know about this object?
- * It must have been reachable
- */
- if (lookup_object(the_repository, oid->hash))
+ if (is_object_reachable(oid, revs))
return 0;
if (lstat(fullpath, &st)) {
@@ -102,7 +125,6 @@ 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;
int exclude_promisor_objects = 0;
const struct option options[] = {
OPT__DRY_RUN(&show_only, N_("do not remove, show only")),
@@ -142,17 +164,13 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
if (show_progress == -1)
show_progress = isatty(2);
- if (show_progress)
- progress = start_delayed_progress(_("Checking connectivity"), 0);
if (exclude_promisor_objects) {
fetch_if_missing = 0;
revs.exclude_promisor_objects = 1;
}
- mark_reachable_objects(&revs, 1, expire, progress);
- stop_progress(&progress);
for_each_loose_file_in_objdir(get_object_directory(), prune_object,
- prune_cruft, prune_subdir, NULL);
+ prune_cruft, prune_subdir, &revs);
prune_packed_objects(show_only ? PRUNE_PACKED_DRY_RUN : 0);
remove_temporary_files(get_object_directory());
@@ -160,8 +178,10 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
remove_temporary_files(s);
free(s);
- if (is_repository_shallow(the_repository))
+ if (is_repository_shallow(the_repository)) {
+ perform_reachability_traversal(&revs);
prune_shallow(show_only ? PRUNE_SHOW_ONLY : 0);
+ }
return 0;
}