summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRonnie Sahlberg <sahlberg@google.com>2014-11-20 10:04:26 -0800
committerJunio C Hamano <gitster@pobox.com>2014-11-20 11:12:40 -0800
commita8739c210bda544077278de6790f4da39fe6befc (patch)
tree957ad32ad43d9a69f913385549cd220bf981676c
parente69b1ce000e6c530ac8bf06470742456277e2a36 (diff)
downloadgit-sb/simplify-repack-without-refs.tar.gz
refs.c: use a string_list for repack_without_refssb/simplify-repack-without-refs
This patch doesn't intend any functional changes. It is just a refactoring, which replaces a char** array by a string_list in the function repack_without_refs. This is easier to read and maintain as it delivers the same functionality with less lines of code and more lines of documentation. [sb: ported this patch from a larger patch series to the master branch, added documentary comments in refs.h] Signed-off-by: Ronnie Sahlberg <sahlberg@google.com> Signed-off-by: Stefan Beller <sbeller@google.com> Reviewed-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--builtin/remote.c32
-rw-r--r--refs.c38
-rw-r--r--refs.h12
3 files changed, 42 insertions, 40 deletions
diff --git a/builtin/remote.c b/builtin/remote.c
index 7f28f92a37..364350af21 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -750,16 +750,11 @@ static int mv(int argc, const char **argv)
static int remove_branches(struct string_list *branches)
{
struct strbuf err = STRBUF_INIT;
- const char **branch_names;
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;
- if (repack_without_refs(branch_names, branches->nr, &err))
+ if (repack_without_refs(branches, &err))
result |= error("%s", err.buf);
strbuf_release(&err);
- free(branch_names);
for (i = 0; i < branches->nr; i++) {
struct string_list_item *item = branches->items + i;
@@ -1316,8 +1311,8 @@ static int prune_remote(const char *remote, int dry_run)
{
int result = 0, i;
struct ref_states states;
- struct string_list delete_refs_list = STRING_LIST_INIT_NODUP;
- const char **delete_refs;
+ struct string_list delete_refs = STRING_LIST_INIT_NODUP;
+ struct string_list_item *ref;
const char *dangling_msg = dry_run
? _(" %s will become dangling!")
: _(" %s has become dangling!");
@@ -1325,6 +1320,9 @@ static int prune_remote(const char *remote, int dry_run)
memset(&states, 0, sizeof(states));
get_remote_ref_states(remote, &states, GET_REF_STATES);
+ for (i = 0; i < states.stale.nr; i++)
+ string_list_append(&delete_refs, states.stale.items[i].util);
+
if (states.stale.nr) {
printf_ln(_("Pruning %s"), remote);
printf_ln(_("URL: %s"),
@@ -1332,23 +1330,16 @@ static int prune_remote(const char *remote, int dry_run)
? states.remote->url[0]
: _("(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) {
struct strbuf err = STRBUF_INIT;
- if (repack_without_refs(delete_refs, states.stale.nr,
- &err))
+ if (repack_without_refs(&delete_refs, &err))
result |= error("%s", err.buf);
strbuf_release(&err);
}
- free(delete_refs);
}
- for (i = 0; i < states.stale.nr; i++) {
- const char *refname = states.stale.items[i].util;
-
- string_list_insert(&delete_refs_list, refname);
+ for_each_string_list_item(ref, &delete_refs) {
+ const char *refname = ref->string;
if (!dry_run)
result |= delete_ref(refname, NULL, 0);
@@ -1361,9 +1352,10 @@ static int prune_remote(const char *remote, int dry_run)
abbrev_ref(refname, "refs/remotes/"));
}
- warn_dangling_symrefs(stdout, dangling_msg, &delete_refs_list);
- string_list_clear(&delete_refs_list, 0);
+ sort_string_list(&delete_refs);
+ warn_dangling_symrefs(stdout, dangling_msg, &delete_refs);
+ string_list_clear(&delete_refs, 0);
free_remote_ref_states(&states);
return result;
}
diff --git a/refs.c b/refs.c
index 5ff457ebfc..ebcd90f90f 100644
--- a/refs.c
+++ b/refs.c
@@ -2639,23 +2639,26 @@ static int curate_packed_ref_fn(struct ref_entry *entry, void *cb_data)
return 0;
}
-int repack_without_refs(const char **refnames, int n, struct strbuf *err)
+int repack_without_refs(struct string_list *without, struct strbuf *err)
{
struct ref_dir *packed;
struct string_list refs_to_delete = STRING_LIST_INIT_DUP;
struct string_list_item *ref_to_delete;
- int i, ret, removed = 0;
+ int ret, needs_repacking = 0, removed = 0;
assert(err);
/* Look for a packed ref */
- for (i = 0; i < n; i++)
- if (get_packed_ref(refnames[i]))
+ for_each_string_list_item(ref_to_delete, without) {
+ if (get_packed_ref(ref_to_delete->string)) {
+ needs_repacking = 1;
break;
+ }
+ }
/* Avoid locking if we have nothing to do */
- if (i == n)
- return 0; /* no refname exists in packed refs */
+ if (!needs_repacking)
+ return 0;
if (lock_packed_refs(0)) {
unable_to_lock_message(git_path("packed-refs"), errno, err);
@@ -2664,8 +2667,8 @@ int repack_without_refs(const char **refnames, int n, struct strbuf *err)
packed = get_packed_refs(&ref_cache);
/* Remove refnames from the cache */
- for (i = 0; i < n; i++)
- if (remove_entry(packed, refnames[i]) != -1)
+ for_each_string_list_item(ref_to_delete, without)
+ if (remove_entry(packed, ref_to_delete->string) != -1)
removed = 1;
if (!removed) {
/*
@@ -3738,10 +3741,11 @@ static int ref_update_reject_duplicates(struct ref_update **updates, int n,
int ref_transaction_commit(struct ref_transaction *transaction,
struct strbuf *err)
{
- int ret = 0, delnum = 0, i;
- const char **delnames;
+ int ret = 0, i;
int n = transaction->nr;
struct ref_update **updates = transaction->updates;
+ struct string_list refs_to_delete = STRING_LIST_INIT_NODUP;
+ struct string_list_item *ref_to_delete;
assert(err);
@@ -3753,9 +3757,6 @@ int ref_transaction_commit(struct ref_transaction *transaction,
return 0;
}
- /* Allocate work space */
- delnames = xmalloc(sizeof(*delnames) * n);
-
/* Copy, sort, and reject duplicate refs */
qsort(updates, n, sizeof(*updates), ref_update_compare);
if (ref_update_reject_duplicates(updates, n, err)) {
@@ -3815,16 +3816,17 @@ int ref_transaction_commit(struct ref_transaction *transaction,
}
if (!(update->flags & REF_ISPRUNING))
- delnames[delnum++] = update->lock->ref_name;
+ string_list_append(&refs_to_delete,
+ update->lock->ref_name);
}
}
- if (repack_without_refs(delnames, delnum, err)) {
+ if (repack_without_refs(&refs_to_delete, err)) {
ret = TRANSACTION_GENERIC_ERROR;
goto cleanup;
}
- for (i = 0; i < delnum; i++)
- unlink_or_warn(git_path("logs/%s", delnames[i]));
+ for_each_string_list_item(ref_to_delete, &refs_to_delete)
+ unlink_or_warn(git_path("logs/%s", ref_to_delete->string));
clear_loose_ref_cache(&ref_cache);
cleanup:
@@ -3833,7 +3835,7 @@ cleanup:
for (i = 0; i < n; i++)
if (updates[i]->lock)
unlock_ref(updates[i]->lock);
- free(delnames);
+ string_list_clear(&refs_to_delete, 0);
return ret;
}
diff --git a/refs.h b/refs.h
index 2bc3556874..3562b656aa 100644
--- a/refs.h
+++ b/refs.h
@@ -163,8 +163,16 @@ extern void rollback_packed_refs(void);
*/
int pack_refs(unsigned int flags);
-extern int repack_without_refs(const char **refnames, int n,
- struct strbuf *err);
+/*
+ * Remove the refs listed in 'without' from the packed-refs file.
+ * On error, packed-refs will be unchanged, the return value is
+ * nonzero, and a message about the error is written to the 'err'
+ * strbuf.
+ *
+ * The refs in 'without' may have any order. The err buffer must
+ * not be omitted.
+ */
+extern int repack_without_refs(struct string_list *without, struct strbuf *err);
extern int ref_exists(const char *);