Merge branch 'jl/remote-rm-prune'
"git remote rm" and "git remote prune" can involve removing many refs at once, which is not a very efficient thing to do when very many refs exist in the packed-refs file. * jl/remote-rm-prune: remote prune: optimize "dangling symref" check/warning remote: repack packed-refs once when deleting multiple refs remote rm: delete remote configuration as the last
This commit is contained in:
commit
474df928b1
@ -749,15 +749,23 @@ static int mv(int argc, const char **argv)
|
|||||||
|
|
||||||
static int remove_branches(struct string_list *branches)
|
static int remove_branches(struct string_list *branches)
|
||||||
{
|
{
|
||||||
|
const char **branch_names;
|
||||||
int i, result = 0;
|
int i, result = 0;
|
||||||
|
|
||||||
|
branch_names = xmalloc(branches->nr * sizeof(*branch_names));
|
||||||
|
for (i = 0; i < branches->nr; i++)
|
||||||
|
branch_names[i] = branches->items[i].string;
|
||||||
|
result |= repack_without_refs(branch_names, branches->nr);
|
||||||
|
free(branch_names);
|
||||||
|
|
||||||
for (i = 0; i < branches->nr; i++) {
|
for (i = 0; i < branches->nr; i++) {
|
||||||
struct string_list_item *item = branches->items + i;
|
struct string_list_item *item = branches->items + i;
|
||||||
const char *refname = item->string;
|
const char *refname = item->string;
|
||||||
unsigned char *sha1 = item->util;
|
|
||||||
|
|
||||||
if (delete_ref(refname, sha1, 0))
|
if (delete_ref(refname, NULL, 0))
|
||||||
result |= error(_("Could not remove branch %s"), refname);
|
result |= error(_("Could not remove branch %s"), refname);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -789,10 +797,6 @@ static int rm(int argc, const char **argv)
|
|||||||
known_remotes.to_delete = remote;
|
known_remotes.to_delete = remote;
|
||||||
for_each_remote(add_known_remote, &known_remotes);
|
for_each_remote(add_known_remote, &known_remotes);
|
||||||
|
|
||||||
strbuf_addf(&buf, "remote.%s", remote->name);
|
|
||||||
if (git_config_rename_section(buf.buf, NULL) < 1)
|
|
||||||
return error(_("Could not remove config section '%s'"), buf.buf);
|
|
||||||
|
|
||||||
read_branches();
|
read_branches();
|
||||||
for (i = 0; i < branch_list.nr; i++) {
|
for (i = 0; i < branch_list.nr; i++) {
|
||||||
struct string_list_item *item = branch_list.items + i;
|
struct string_list_item *item = branch_list.items + i;
|
||||||
@ -837,6 +841,12 @@ static int rm(int argc, const char **argv)
|
|||||||
}
|
}
|
||||||
string_list_clear(&skipped, 0);
|
string_list_clear(&skipped, 0);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
strbuf_addf(&buf, "remote.%s", remote->name);
|
||||||
|
if (git_config_rename_section(buf.buf, NULL) < 1)
|
||||||
|
return error(_("Could not remove config section '%s'"), buf.buf);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1303,6 +1313,8 @@ 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 *dangling_msg = dry_run
|
const char *dangling_msg = dry_run
|
||||||
? _(" %s will become dangling!")
|
? _(" %s will become dangling!")
|
||||||
: _(" %s has become dangling!");
|
: _(" %s has become dangling!");
|
||||||
@ -1316,11 +1328,20 @@ static int prune_remote(const char *remote, int dry_run)
|
|||||||
states.remote->url_nr
|
states.remote->url_nr
|
||||||
? states.remote->url[0]
|
? states.remote->url[0]
|
||||||
: _("(no URL)"));
|
: _("(no URL)"));
|
||||||
|
|
||||||
|
delete_refs = xmalloc(states.stale.nr * sizeof(*delete_refs));
|
||||||
|
for (i = 0; i < states.stale.nr; i++)
|
||||||
|
delete_refs[i] = states.stale.items[i].util;
|
||||||
|
if (!dry_run)
|
||||||
|
result |= repack_without_refs(delete_refs, states.stale.nr);
|
||||||
|
free(delete_refs);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
@ -1330,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;
|
||||||
}
|
}
|
||||||
|
21
refs.c
21
refs.c
@ -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
|
|||||||
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)
|
|||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
@ -2427,7 +2444,7 @@ static int curate_packed_ref_fn(struct ref_entry *entry, void *cb_data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int repack_without_refs(const char **refnames, int n)
|
int repack_without_refs(const char **refnames, int n)
|
||||||
{
|
{
|
||||||
struct ref_dir *packed;
|
struct ref_dir *packed;
|
||||||
struct string_list refs_to_delete = STRING_LIST_INIT_DUP;
|
struct string_list refs_to_delete = STRING_LIST_INIT_DUP;
|
||||||
|
3
refs.h
3
refs.h
@ -77,6 +77,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
|
||||||
@ -120,6 +121,8 @@ extern void rollback_packed_refs(void);
|
|||||||
*/
|
*/
|
||||||
int pack_refs(unsigned int flags);
|
int pack_refs(unsigned int flags);
|
||||||
|
|
||||||
|
extern int repack_without_refs(const char **refnames, int n);
|
||||||
|
|
||||||
extern int ref_exists(const char *);
|
extern int ref_exists(const char *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user