提交 e6bea66d 编写于 作者: J Jens Lindström 提交者: Junio C Hamano

remote prune: optimize "dangling symref" check/warning

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: NJens Lindström <jl@opera.com>
Signed-off-by: NJunio C Hamano <gitster@pobox.com>
上级 c9e768bb
...@@ -1313,6 +1313,7 @@ static int prune_remote(const char *remote, int dry_run) ...@@ -1313,6 +1313,7 @@ static int prune_remote(const char *remote, int dry_run)
{ {
int result = 0, i; int result = 0, i;
struct ref_states states; struct ref_states states;
struct string_list delete_refs_list = STRING_LIST_INIT_NODUP;
const char **delete_refs; const char **delete_refs;
const char *dangling_msg = dry_run const char *dangling_msg = dry_run
? _(" %s will become dangling!") ? _(" %s will become dangling!")
...@@ -1339,6 +1340,8 @@ static int prune_remote(const char *remote, int dry_run) ...@@ -1339,6 +1340,8 @@ static int prune_remote(const char *remote, int dry_run)
for (i = 0; i < states.stale.nr; i++) { for (i = 0; i < states.stale.nr; i++) {
const char *refname = states.stale.items[i].util; const char *refname = states.stale.items[i].util;
string_list_insert(&delete_refs_list, refname);
if (!dry_run) if (!dry_run)
result |= delete_ref(refname, NULL, 0); result |= delete_ref(refname, NULL, 0);
...@@ -1348,9 +1351,11 @@ static int prune_remote(const char *remote, int dry_run) ...@@ -1348,9 +1351,11 @@ static int prune_remote(const char *remote, int dry_run)
else else
printf_ln(_(" * [pruned] %s"), printf_ln(_(" * [pruned] %s"),
abbrev_ref(refname, "refs/remotes/")); abbrev_ref(refname, "refs/remotes/"));
warn_dangling_symref(stdout, dangling_msg, refname);
} }
warn_dangling_symrefs(stdout, dangling_msg, &delete_refs_list);
string_list_clear(&delete_refs_list, 0);
free_remote_ref_states(&states); free_remote_ref_states(&states);
return result; return result;
} }
......
...@@ -1611,6 +1611,7 @@ int peel_ref(const char *refname, unsigned char *sha1) ...@@ -1611,6 +1611,7 @@ int peel_ref(const char *refname, unsigned char *sha1)
struct warn_if_dangling_data { struct warn_if_dangling_data {
FILE *fp; FILE *fp;
const char *refname; const char *refname;
const struct string_list *refnames;
const char *msg_fmt; const char *msg_fmt;
}; };
...@@ -1625,8 +1626,12 @@ static int warn_if_dangling_symref(const char *refname, const unsigned char *sha ...@@ -1625,8 +1626,12 @@ static int warn_if_dangling_symref(const char *refname, const unsigned char *sha
return 0; return 0;
resolves_to = resolve_ref_unsafe(refname, junk, 0, NULL); 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; return 0;
}
fprintf(d->fp, d->msg_fmt, refname); fprintf(d->fp, d->msg_fmt, refname);
fputc('\n', d->fp); fputc('\n', d->fp);
...@@ -1639,6 +1644,18 @@ void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname) ...@@ -1639,6 +1644,18 @@ void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
data.fp = fp; data.fp = fp;
data.refname = refname; 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; data.msg_fmt = msg_fmt;
for_each_rawref(warn_if_dangling_symref, &data); for_each_rawref(warn_if_dangling_symref, &data);
} }
......
...@@ -89,6 +89,7 @@ static inline const char *has_glob_specials(const char *pattern) ...@@ -89,6 +89,7 @@ static inline const char *has_glob_specials(const char *pattern)
extern int for_each_rawref(each_ref_fn, void *); extern int for_each_rawref(each_ref_fn, void *);
extern void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname); extern void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname);
extern void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, const struct string_list* refnames);
/* /*
* Lock the packed-refs file for writing. Flags is passed to * Lock the packed-refs file for writing. Flags is passed to
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册