summaryrefslogtreecommitdiff
path: root/refs.c
diff options
context:
space:
mode:
authorJens Lindström <jl@opera.com>2014-05-23 12:30:25 +0200
committerJunio C Hamano <gitster@pobox.com>2014-05-27 12:30:47 -0700
commite6bea66db6229a0975ebba510a1d2827bf09cb7f (patch)
treeb81289073f96aae1f89492b519083c7ccb2ed44b /refs.c
parentc9e768bb77762765f739fffb5c09d0888f3de20e (diff)
downloadgit-e6bea66db6229a0975ebba510a1d2827bf09cb7f.tar.gz
remote prune: optimize "dangling symref" check/warningjl/remote-rm-prune
When 'git remote prune' was used to delete many refs in a repository with many refs, a lot of time was spent checking for (now) dangling symbolic refs pointing to the deleted ref, since warn_dangling_symref() was once per deleted ref to check all other refs in the repository. Avoid this using the new warn_dangling_symrefs() function which makes one pass over all refs and checks for all the deleted refs in one go, after they have all been deleted. Signed-off-by: Jens Lindström <jl@opera.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'refs.c')
-rw-r--r--refs.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/refs.c b/refs.c
index 262c1c26cb..59fb70087a 100644
--- a/refs.c
+++ b/refs.c
@@ -1611,6 +1611,7 @@ int peel_ref(const char *refname, unsigned char *sha1)
struct warn_if_dangling_data {
FILE *fp;
const char *refname;
+ const struct string_list *refnames;
const char *msg_fmt;
};
@@ -1625,8 +1626,12 @@ static int warn_if_dangling_symref(const char *refname, const unsigned char *sha
return 0;
resolves_to = resolve_ref_unsafe(refname, junk, 0, NULL);
- if (!resolves_to || strcmp(resolves_to, d->refname))
+ if (!resolves_to
+ || (d->refname
+ ? strcmp(resolves_to, d->refname)
+ : !string_list_has_string(d->refnames, resolves_to))) {
return 0;
+ }
fprintf(d->fp, d->msg_fmt, refname);
fputc('\n', d->fp);
@@ -1639,6 +1644,18 @@ void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
data.fp = fp;
data.refname = refname;
+ data.refnames = NULL;
+ data.msg_fmt = msg_fmt;
+ for_each_rawref(warn_if_dangling_symref, &data);
+}
+
+void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, const struct string_list *refnames)
+{
+ struct warn_if_dangling_data data;
+
+ data.fp = fp;
+ data.refname = NULL;
+ data.refnames = refnames;
data.msg_fmt = msg_fmt;
for_each_rawref(warn_if_dangling_symref, &data);
}