Skip to content

Commit 5a4d494

Browse files
mhaggergitster
authored andcommitted
names_conflict(): simplify implementation
Save a bunch of lines of code and a couple of strlen() calls. Signed-off-by: Michael Haggerty <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d66da47 commit 5a4d494

File tree

1 file changed

+37
-25
lines changed

1 file changed

+37
-25
lines changed

refs.c

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -342,41 +342,53 @@ static int do_for_each_ref_in_arrays(struct ref_array *array1,
342342
*/
343343
static int names_conflict(const char *refname1, const char *refname2)
344344
{
345-
int len1 = strlen(refname1);
346-
int len2 = strlen(refname2);
347-
int cmplen;
348-
const char *lead;
349-
350-
if (len1 < len2) {
351-
cmplen = len1;
352-
lead = refname2;
353-
} else {
354-
cmplen = len2;
355-
lead = refname1;
345+
for (; *refname1 && *refname1 == *refname2; refname1++, refname2++)
346+
;
347+
return (*refname1 == '\0' && *refname2 == '/')
348+
|| (*refname1 == '/' && *refname2 == '\0');
349+
}
350+
351+
struct name_conflict_cb {
352+
const char *refname;
353+
const char *oldrefname;
354+
const char *conflicting_refname;
355+
};
356+
357+
static int name_conflict_fn(const char *existingrefname, const unsigned char *sha1,
358+
int flags, void *cb_data)
359+
{
360+
struct name_conflict_cb *data = (struct name_conflict_cb *)cb_data;
361+
if (data->oldrefname && !strcmp(data->oldrefname, existingrefname))
362+
return 0;
363+
if (names_conflict(data->refname, existingrefname)) {
364+
data->conflicting_refname = existingrefname;
365+
return 1;
356366
}
357-
return !strncmp(refname1, refname2, cmplen) && lead[cmplen] == '/';
367+
return 0;
358368
}
359369

360370
/*
361371
* Return true iff a reference named refname could be created without
362-
* conflicting with the name of an existing reference. If oldrefname
363-
* is non-NULL, ignore potential conflicts with oldrefname (e.g.,
364-
* because oldrefname is scheduled for deletion in the same
372+
* conflicting with the name of an existing reference in array. If
373+
* oldrefname is non-NULL, ignore potential conflicts with oldrefname
374+
* (e.g., because oldrefname is scheduled for deletion in the same
365375
* operation).
366376
*/
367377
static int is_refname_available(const char *refname, const char *oldrefname,
368378
struct ref_array *array)
369379
{
370-
int i;
371-
for (i = 0; i < array->nr; i++) {
372-
struct ref_entry *entry = array->refs[i];
373-
if (oldrefname && !strcmp(oldrefname, entry->name))
374-
continue;
375-
if (names_conflict(refname, entry->name)) {
376-
error("'%s' exists; cannot create '%s'",
377-
entry->name, refname);
378-
return 0;
379-
}
380+
struct name_conflict_cb data;
381+
data.refname = refname;
382+
data.oldrefname = oldrefname;
383+
data.conflicting_refname = NULL;
384+
385+
sort_ref_array(array);
386+
if (do_for_each_ref_in_array(array, 0, "", name_conflict_fn,
387+
0, DO_FOR_EACH_INCLUDE_BROKEN,
388+
&data)) {
389+
error("'%s' exists; cannot create '%s'",
390+
data.conflicting_refname, refname);
391+
return 0;
380392
}
381393
return 1;
382394
}

0 commit comments

Comments
 (0)