summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Haggerty <mhagger@alum.mit.edu>2015-05-01 14:25:48 +0200
committerJunio C Hamano <gitster@pobox.com>2015-05-10 11:31:32 -0700
commite4439223700a048a5effa08ba22b6515c9270f5d (patch)
tree222a54be3fbbd752fae1d1e7a9b301c1050d0b4c
parente4f2431c7c4f3a98cd5a73eab9f000ea7242ca66 (diff)
downloadgit-e4439223700a048a5effa08ba22b6515c9270f5d.tar.gz
is_refname_available(): use dirname in first loop
In the first loop (over prefixes of refname), use dirname to keep track of the current prefix. This is not an improvement in itself, but in a moment we will start using dirname for a role where a NUL-terminated string is needed. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
-rw-r--r--refs.c43
1 files changed, 28 insertions, 15 deletions
diff --git a/refs.c b/refs.c
index b7f02a6e58..c5978a79fd 100644
--- a/refs.c
+++ b/refs.c
@@ -884,8 +884,13 @@ static int is_refname_available(const char *refname,
const char *slash;
int pos;
struct strbuf dirname = STRBUF_INIT;
+ int ret = 0;
+ strbuf_grow(&dirname, strlen(refname) + 1);
for (slash = strchr(refname, '/'); slash; slash = strchr(slash + 1, '/')) {
+ /* Expand dirname to the new prefix, not including the trailing slash: */
+ strbuf_add(&dirname, refname + dirname.len, slash - refname - dirname.len);
+
/*
* We are still at a leading dir of the refname; we are
* looking for a conflict with a leaf entry.
@@ -893,10 +898,9 @@ static int is_refname_available(const char *refname,
* If we find one, we still must make sure it is
* not in "skip".
*/
- pos = search_ref_dir(dir, refname, slash - refname);
+ pos = search_ref_dir(dir, dirname.buf, dirname.len);
if (pos >= 0) {
- struct ref_entry *entry = dir->entries[pos];
- if (skip && string_list_has_string(skip, entry->name)) {
+ if (skip && string_list_has_string(skip, dirname.buf)) {
/*
* The fact that entry is a ref whose
* name is a prefix of refname means
@@ -908,10 +912,11 @@ static int is_refname_available(const char *refname,
* is in skip), we can stop looking
* now and return true.
*/
- return 1;
+ ret = 1;
+ goto cleanup;
}
- error("'%s' exists; cannot create '%s'", entry->name, refname);
- return 0;
+ error("'%s' exists; cannot create '%s'", dirname.buf, refname);
+ goto cleanup;
}
@@ -920,9 +925,12 @@ static int is_refname_available(const char *refname,
* the next component; if we come up empty, we know
* there is nothing under this whole prefix.
*/
- pos = search_ref_dir(dir, refname, slash + 1 - refname);
- if (pos < 0)
- return 1;
+ strbuf_addch(&dirname, '/');
+ pos = search_ref_dir(dir, dirname.buf, dirname.len);
+ if (pos < 0) {
+ ret = 1;
+ goto cleanup;
+ }
dir = get_ref_dir(dir->entries[pos]);
}
@@ -931,10 +939,9 @@ static int is_refname_available(const char *refname,
* We are at the leaf of our refname; we want to
* make sure there are no directories which match it.
*/
- strbuf_addstr(&dirname, refname);
+ strbuf_addstr(&dirname, refname + dirname.len);
strbuf_addch(&dirname, '/');
pos = search_ref_dir(dir, dirname.buf, dirname.len);
- strbuf_release(&dirname);
if (pos >= 0) {
/*
@@ -948,12 +955,14 @@ static int is_refname_available(const char *refname,
dir = get_ref_dir(entry);
data.skip = skip;
sort_ref_dir(dir);
- if (!do_for_each_entry_in_dir(dir, 0, nonmatching_ref_fn, &data))
- return 1;
+ if (!do_for_each_entry_in_dir(dir, 0, nonmatching_ref_fn, &data)) {
+ ret = 1;
+ goto cleanup;
+ }
error("'%s' exists; cannot create '%s'",
data.conflicting_refname, refname);
- return 0;
+ goto cleanup;
}
/*
@@ -961,7 +970,11 @@ static int is_refname_available(const char *refname,
* node which matches it; such an entry would be the
* ref we are looking for, not a conflict.
*/
- return 1;
+ ret = 1;
+
+cleanup:
+ strbuf_release(&dirname);
+ return ret;
}
struct packed_ref_cache {