зеркало из https://github.com/microsoft/git.git
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>
This commit is contained in:
Родитель
a122366d69
Коммит
a087b432a7
|
@ -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;
|
||||
|
||||
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 (!dry_run)
|
||||
result |= delete_ref(ref->name, NULL, 0);
|
||||
if (verbosity >= 0 && !shown_url) {
|
||||
if (!shown_url) {
|
||||
fprintf(stderr, _("From %.*s\n"), url_len, url);
|
||||
shown_url = 1;
|
||||
}
|
||||
if (verbosity >= 0) {
|
||||
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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче