Merge branch 'ph/fetch-prune-optim'
"git fetch --prune" used to be O(n^2) expensive when there are many refs, which has been corrected. * ph/fetch-prune-optim: clean up interface for refs_warn_dangling_symrefs refs: remove old refs_warn_dangling_symref fetch-prune: optimize dangling-ref reporting
This commit is contained in:
@@ -1340,9 +1340,10 @@ static int prune_refs(struct display_state *display_state,
|
||||
int result = 0;
|
||||
struct ref *ref, *stale_refs = get_stale_heads(rs, ref_map);
|
||||
struct strbuf err = STRBUF_INIT;
|
||||
const char *dangling_msg = dry_run
|
||||
? _(" (%s will become dangling)")
|
||||
: _(" (%s has become dangling)");
|
||||
struct string_list refnames = STRING_LIST_INIT_NODUP;
|
||||
|
||||
for (ref = stale_refs; ref; ref = ref->next)
|
||||
string_list_append(&refnames, ref->name);
|
||||
|
||||
if (!dry_run) {
|
||||
if (transaction) {
|
||||
@@ -1353,15 +1354,9 @@ static int prune_refs(struct display_state *display_state,
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
struct string_list refnames = STRING_LIST_INIT_NODUP;
|
||||
|
||||
for (ref = stale_refs; ref; ref = ref->next)
|
||||
string_list_append(&refnames, ref->name);
|
||||
|
||||
result = refs_delete_refs(get_main_ref_store(the_repository),
|
||||
"fetch: prune", &refnames,
|
||||
0);
|
||||
string_list_clear(&refnames, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1373,12 +1368,14 @@ static int prune_refs(struct display_state *display_state,
|
||||
_("(none)"), ref->name,
|
||||
&ref->new_oid, &ref->old_oid,
|
||||
summary_width);
|
||||
refs_warn_dangling_symref(get_main_ref_store(the_repository),
|
||||
stderr, dangling_msg, ref->name);
|
||||
}
|
||||
string_list_sort(&refnames);
|
||||
refs_warn_dangling_symrefs(get_main_ref_store(the_repository),
|
||||
stderr, " ", dry_run, &refnames);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
string_list_clear(&refnames, 0);
|
||||
strbuf_release(&err);
|
||||
free_refs(stale_refs);
|
||||
return result;
|
||||
|
||||
@@ -1521,9 +1521,6 @@ static int prune_remote(const char *remote, int dry_run)
|
||||
struct ref_states states = REF_STATES_INIT;
|
||||
struct string_list refs_to_prune = STRING_LIST_INIT_NODUP;
|
||||
struct string_list_item *item;
|
||||
const char *dangling_msg = dry_run
|
||||
? _(" %s will become dangling!")
|
||||
: _(" %s has become dangling!");
|
||||
|
||||
get_remote_ref_states(remote, &states, GET_REF_STATES);
|
||||
|
||||
@@ -1555,7 +1552,7 @@ static int prune_remote(const char *remote, int dry_run)
|
||||
}
|
||||
|
||||
refs_warn_dangling_symrefs(get_main_ref_store(the_repository),
|
||||
stdout, dangling_msg, &refs_to_prune);
|
||||
stdout, " ", dry_run, &refs_to_prune);
|
||||
|
||||
string_list_clear(&refs_to_prune, 0);
|
||||
free_remote_ref_states(&states);
|
||||
|
||||
34
refs.c
34
refs.c
@@ -439,9 +439,9 @@ static int for_each_filter_refs(const char *refname, const char *referent,
|
||||
struct warn_if_dangling_data {
|
||||
struct ref_store *refs;
|
||||
FILE *fp;
|
||||
const char *refname;
|
||||
const struct string_list *refnames;
|
||||
const char *msg_fmt;
|
||||
const char *indent;
|
||||
int dry_run;
|
||||
};
|
||||
|
||||
static int warn_if_dangling_symref(const char *refname, const char *referent UNUSED,
|
||||
@@ -449,44 +449,34 @@ static int warn_if_dangling_symref(const char *refname, const char *referent UNU
|
||||
int flags, void *cb_data)
|
||||
{
|
||||
struct warn_if_dangling_data *d = cb_data;
|
||||
const char *resolves_to;
|
||||
const char *resolves_to, *msg;
|
||||
|
||||
if (!(flags & REF_ISSYMREF))
|
||||
return 0;
|
||||
|
||||
resolves_to = refs_resolve_ref_unsafe(d->refs, refname, 0, NULL, NULL);
|
||||
if (!resolves_to
|
||||
|| (d->refname
|
||||
? strcmp(resolves_to, d->refname)
|
||||
: !string_list_has_string(d->refnames, resolves_to))) {
|
||||
|| !string_list_has_string(d->refnames, resolves_to)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(d->fp, d->msg_fmt, refname);
|
||||
fputc('\n', d->fp);
|
||||
msg = d->dry_run
|
||||
? _("%s%s will become dangling after %s is deleted\n")
|
||||
: _("%s%s has become dangling after %s was deleted\n");
|
||||
fprintf(d->fp, msg, d->indent, refname, resolves_to);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void refs_warn_dangling_symref(struct ref_store *refs, FILE *fp,
|
||||
const char *msg_fmt, const char *refname)
|
||||
{
|
||||
struct warn_if_dangling_data data = {
|
||||
.refs = refs,
|
||||
.fp = fp,
|
||||
.refname = refname,
|
||||
.msg_fmt = msg_fmt,
|
||||
};
|
||||
refs_for_each_rawref(refs, warn_if_dangling_symref, &data);
|
||||
}
|
||||
|
||||
void refs_warn_dangling_symrefs(struct ref_store *refs, FILE *fp,
|
||||
const char *msg_fmt, const struct string_list *refnames)
|
||||
const char *indent, int dry_run,
|
||||
const struct string_list *refnames)
|
||||
{
|
||||
struct warn_if_dangling_data data = {
|
||||
.refs = refs,
|
||||
.fp = fp,
|
||||
.refnames = refnames,
|
||||
.msg_fmt = msg_fmt,
|
||||
.indent = indent,
|
||||
.dry_run = dry_run,
|
||||
};
|
||||
refs_for_each_rawref(refs, warn_if_dangling_symref, &data);
|
||||
}
|
||||
|
||||
5
refs.h
5
refs.h
@@ -452,10 +452,9 @@ static inline const char *has_glob_specials(const char *pattern)
|
||||
return strpbrk(pattern, "?*[");
|
||||
}
|
||||
|
||||
void refs_warn_dangling_symref(struct ref_store *refs, FILE *fp,
|
||||
const char *msg_fmt, const char *refname);
|
||||
void refs_warn_dangling_symrefs(struct ref_store *refs, FILE *fp,
|
||||
const char *msg_fmt, const struct string_list *refnames);
|
||||
const char *indent, int dry_run,
|
||||
const struct string_list *refnames);
|
||||
|
||||
/*
|
||||
* Flags for controlling behaviour of pack_refs()
|
||||
|
||||
Reference in New Issue
Block a user