Merge branch 'ph/use-delete-refs'
When removing many branches and tags, the code used to do so one ref at a time. There is another API it can use to delete multiple refs, and it makes quite a lot of performance difference when the refs are packed. * ph/use-delete-refs: use delete_refs when deleting tags or branches
This commit is contained in:
commit
f6ef8baba2
@ -202,6 +202,9 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
|
|||||||
int remote_branch = 0;
|
int remote_branch = 0;
|
||||||
struct strbuf bname = STRBUF_INIT;
|
struct strbuf bname = STRBUF_INIT;
|
||||||
unsigned allowed_interpret;
|
unsigned allowed_interpret;
|
||||||
|
struct string_list refs_to_delete = STRING_LIST_INIT_DUP;
|
||||||
|
struct string_list_item *item;
|
||||||
|
int branch_name_pos;
|
||||||
|
|
||||||
switch (kinds) {
|
switch (kinds) {
|
||||||
case FILTER_REFS_REMOTES:
|
case FILTER_REFS_REMOTES:
|
||||||
@ -219,6 +222,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
|
|||||||
default:
|
default:
|
||||||
die(_("cannot use -a with -d"));
|
die(_("cannot use -a with -d"));
|
||||||
}
|
}
|
||||||
|
branch_name_pos = strcspn(fmt, "%");
|
||||||
|
|
||||||
if (!force) {
|
if (!force) {
|
||||||
head_rev = lookup_commit_reference(the_repository, &head_oid);
|
head_rev = lookup_commit_reference(the_repository, &head_oid);
|
||||||
@ -265,30 +269,35 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
|
|||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (delete_ref(NULL, name, is_null_oid(&oid) ? NULL : &oid,
|
item = string_list_append(&refs_to_delete, name);
|
||||||
REF_NO_DEREF)) {
|
item->util = xstrdup((flags & REF_ISBROKEN) ? "broken"
|
||||||
error(remote_branch
|
: (flags & REF_ISSYMREF) ? target
|
||||||
? _("Error deleting remote-tracking branch '%s'")
|
: find_unique_abbrev(&oid, DEFAULT_ABBREV));
|
||||||
: _("Error deleting branch '%s'"),
|
|
||||||
bname.buf);
|
|
||||||
ret = 1;
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
if (!quiet) {
|
|
||||||
printf(remote_branch
|
|
||||||
? _("Deleted remote-tracking branch %s (was %s).\n")
|
|
||||||
: _("Deleted branch %s (was %s).\n"),
|
|
||||||
bname.buf,
|
|
||||||
(flags & REF_ISBROKEN) ? "broken"
|
|
||||||
: (flags & REF_ISSYMREF) ? target
|
|
||||||
: find_unique_abbrev(&oid, DEFAULT_ABBREV));
|
|
||||||
}
|
|
||||||
delete_branch_config(bname.buf);
|
|
||||||
|
|
||||||
next:
|
next:
|
||||||
free(target);
|
free(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (delete_refs(NULL, &refs_to_delete, REF_NO_DEREF))
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
for_each_string_list_item(item, &refs_to_delete) {
|
||||||
|
char *describe_ref = item->util;
|
||||||
|
char *name = item->string;
|
||||||
|
if (!ref_exists(name)) {
|
||||||
|
char *refname = name + branch_name_pos;
|
||||||
|
if (!quiet)
|
||||||
|
printf(remote_branch
|
||||||
|
? _("Deleted remote-tracking branch %s (was %s).\n")
|
||||||
|
: _("Deleted branch %s (was %s).\n"),
|
||||||
|
name + branch_name_pos, describe_ref);
|
||||||
|
|
||||||
|
delete_branch_config(refname);
|
||||||
|
}
|
||||||
|
free(describe_ref);
|
||||||
|
}
|
||||||
|
string_list_clear(&refs_to_delete, 0);
|
||||||
|
|
||||||
free(name);
|
free(name);
|
||||||
strbuf_release(&bname);
|
strbuf_release(&bname);
|
||||||
|
|
||||||
|
@ -72,10 +72,10 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting,
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef int (*each_tag_name_fn)(const char *name, const char *ref,
|
typedef int (*each_tag_name_fn)(const char *name, const char *ref,
|
||||||
const struct object_id *oid, const void *cb_data);
|
const struct object_id *oid, void *cb_data);
|
||||||
|
|
||||||
static int for_each_tag_name(const char **argv, each_tag_name_fn fn,
|
static int for_each_tag_name(const char **argv, each_tag_name_fn fn,
|
||||||
const void *cb_data)
|
void *cb_data)
|
||||||
{
|
{
|
||||||
const char **p;
|
const char **p;
|
||||||
struct strbuf ref = STRBUF_INIT;
|
struct strbuf ref = STRBUF_INIT;
|
||||||
@ -97,18 +97,42 @@ static int for_each_tag_name(const char **argv, each_tag_name_fn fn,
|
|||||||
return had_error;
|
return had_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int delete_tag(const char *name, const char *ref,
|
static int collect_tags(const char *name, const char *ref,
|
||||||
const struct object_id *oid, const void *cb_data)
|
const struct object_id *oid, void *cb_data)
|
||||||
{
|
{
|
||||||
if (delete_ref(NULL, ref, oid, 0))
|
struct string_list *ref_list = cb_data;
|
||||||
return 1;
|
|
||||||
printf(_("Deleted tag '%s' (was %s)\n"), name,
|
string_list_append(ref_list, ref);
|
||||||
find_unique_abbrev(oid, DEFAULT_ABBREV));
|
ref_list->items[ref_list->nr - 1].util = oiddup(oid);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int delete_tags(const char **argv)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
struct string_list refs_to_delete = STRING_LIST_INIT_DUP;
|
||||||
|
struct string_list_item *item;
|
||||||
|
|
||||||
|
result = for_each_tag_name(argv, collect_tags, (void *)&refs_to_delete);
|
||||||
|
if (delete_refs(NULL, &refs_to_delete, REF_NO_DEREF))
|
||||||
|
result = 1;
|
||||||
|
|
||||||
|
for_each_string_list_item(item, &refs_to_delete) {
|
||||||
|
const char *name = item->string;
|
||||||
|
struct object_id *oid = item->util;
|
||||||
|
if (!ref_exists(name))
|
||||||
|
printf(_("Deleted tag '%s' (was %s)\n"),
|
||||||
|
item->string + 10,
|
||||||
|
find_unique_abbrev(oid, DEFAULT_ABBREV));
|
||||||
|
|
||||||
|
free(oid);
|
||||||
|
}
|
||||||
|
string_list_clear(&refs_to_delete, 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static int verify_tag(const char *name, const char *ref,
|
static int verify_tag(const char *name, const char *ref,
|
||||||
const struct object_id *oid, const void *cb_data)
|
const struct object_id *oid, void *cb_data)
|
||||||
{
|
{
|
||||||
int flags;
|
int flags;
|
||||||
const struct ref_format *format = cb_data;
|
const struct ref_format *format = cb_data;
|
||||||
@ -512,7 +536,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
|
|||||||
if (filter.reachable_from || filter.unreachable_from)
|
if (filter.reachable_from || filter.unreachable_from)
|
||||||
die(_("--merged and --no-merged options are only allowed in list mode"));
|
die(_("--merged and --no-merged options are only allowed in list mode"));
|
||||||
if (cmdmode == 'd')
|
if (cmdmode == 'd')
|
||||||
return for_each_tag_name(argv, delete_tag, NULL);
|
return delete_tags(argv);
|
||||||
if (cmdmode == 'v') {
|
if (cmdmode == 'v') {
|
||||||
if (format.format && verify_ref_format(&format))
|
if (format.format && verify_ref_format(&format))
|
||||||
usage_with_options(git_tag_usage, options);
|
usage_with_options(git_tag_usage, options);
|
||||||
|
Loading…
Reference in New Issue
Block a user