summaryrefslogtreecommitdiff
path: root/builtin/fetch.c
diff options
context:
space:
mode:
authorMichael Haggerty <mhagger@alum.mit.edu>2015-06-22 16:02:59 +0200
committerJunio C Hamano <gitster@pobox.com>2015-06-22 13:17:10 -0700
commita087b432a79f85b34e8582219a0bdec73c5821f5 (patch)
treea6ff333e0564f36a893d504cf03919131e51be9a /builtin/fetch.c
parenta122366d6946ea41ac8167a88f1949416008decb (diff)
downloadgit-a087b432a79f85b34e8582219a0bdec73c5821f5.tar.gz
prune_refs(): use delete_refs()
The old version just looped over the references to delete, calling delete_ref() on each one. But that has quadratic behavior, because each call to delete_ref() might have to rewrite the packed-refs file. This can be very expensive in a repository with a large number of references. In some (admittedly extreme) repositories, we've seen cases where the ref-pruning part of fetch takes multiple tens of minutes. Instead call delete_refs(), which (aside from being less code) has the optimization that it only rewrites the packed-refs file a single time. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin/fetch.c')
-rw-r--r--builtin/fetch.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 8d5b2dba2b..34b6f5ebca 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -790,20 +790,29 @@ static int prune_refs(struct refspec *refs, int ref_count, struct ref *ref_map,
if (4 < i && !strncmp(".git", url + i - 3, 4))
url_len = i - 3;
- for (ref = stale_refs; ref; ref = ref->next) {
- if (!dry_run)
- result |= delete_ref(ref->name, NULL, 0);
- if (verbosity >= 0 && !shown_url) {
- fprintf(stderr, _("From %.*s\n"), url_len, url);
- shown_url = 1;
- }
- if (verbosity >= 0) {
+ if (!dry_run) {
+ struct string_list refnames = STRING_LIST_INIT_NODUP;
+
+ for (ref = stale_refs; ref; ref = ref->next)
+ string_list_append(&refnames, ref->name);
+
+ result = delete_refs(&refnames);
+ string_list_clear(&refnames, 0);
+ }
+
+ if (verbosity >= 0) {
+ for (ref = stale_refs; ref; ref = ref->next) {
+ if (!shown_url) {
+ fprintf(stderr, _("From %.*s\n"), url_len, url);
+ shown_url = 1;
+ }
fprintf(stderr, " x %-*s %-*s -> %s\n",
TRANSPORT_SUMMARY(_("[deleted]")),
REFCOL_WIDTH, _("(none)"), prettify_refname(ref->name));
warn_dangling_symref(stderr, dangling_msg, ref->name);
}
}
+
free(url);
free_refs(stale_refs);
return result;