summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2015-02-26 20:39:48 -0500
committerJunio C Hamano <gitster@pobox.com>2015-02-27 13:41:21 -0800
commitf98c2f7e53062a59f67914337c0b45c82393e11f (patch)
tree7236356f1c027456bb51f4f4d5be4c7c8374a84e
parent282616c72d1d08a77ca4fe1186cb708c38408d87 (diff)
downloadgit-f98c2f7e53062a59f67914337c0b45c82393e11f.tar.gz
diffcore-rename: split locate_rename_dst into two functions
This function manages the mapping of destination pathnames to filepairs, and it handles both insertion and lookup. This makes the return value a bit confusing, as we return a newly created entry (even though no caller cares), and have no room to indicate to the caller that an entry already existed. Instead, let's break this up into two distinct functions, both backed by a common binary search. The binary search will use our normal "return the index if we found something, or negative index minus one to show where it would have gone" semantics. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--diffcore-rename.c38
1 files changed, 26 insertions, 12 deletions
diff --git a/diffcore-rename.c b/diffcore-rename.c
index 749a35d2c2..0afe903de9 100644
--- a/diffcore-rename.c
+++ b/diffcore-rename.c
@@ -15,8 +15,7 @@ static struct diff_rename_dst {
} *rename_dst;
static int rename_dst_nr, rename_dst_alloc;
-static struct diff_rename_dst *locate_rename_dst(struct diff_filespec *two,
- int insert_ok)
+static int find_rename_dst(struct diff_filespec *two)
{
int first, last;
@@ -27,16 +26,33 @@ static struct diff_rename_dst *locate_rename_dst(struct diff_filespec *two,
struct diff_rename_dst *dst = &(rename_dst[next]);
int cmp = strcmp(two->path, dst->two->path);
if (!cmp)
- return dst;
+ return next;
if (cmp < 0) {
last = next;
continue;
}
first = next+1;
}
- /* not found */
- if (!insert_ok)
- return NULL;
+ return -first - 1;
+}
+
+static struct diff_rename_dst *locate_rename_dst(struct diff_filespec *two)
+{
+ int ofs = find_rename_dst(two);
+ return ofs < 0 ? NULL : &rename_dst[ofs];
+}
+
+/*
+ * Returns 0 on success, -1 if we found a duplicate.
+ */
+static int add_rename_dst(struct diff_filespec *two)
+{
+ int first = find_rename_dst(two);
+
+ if (first >= 0)
+ return -1;
+ first = -first - 1;
+
/* insert to make it at "first" */
ALLOC_GROW(rename_dst, rename_dst_nr + 1, rename_dst_alloc);
rename_dst_nr++;
@@ -46,7 +62,7 @@ static struct diff_rename_dst *locate_rename_dst(struct diff_filespec *two,
rename_dst[first].two = alloc_filespec(two->path);
fill_filespec(rename_dst[first].two, two->sha1, two->sha1_valid, two->mode);
rename_dst[first].pair = NULL;
- return &(rename_dst[first]);
+ return 0;
}
/* Table of rename/copy src files */
@@ -452,7 +468,7 @@ void diffcore_rename(struct diff_options *options)
is_empty_blob_sha1(p->two->sha1))
continue;
else
- locate_rename_dst(p->two, 1);
+ add_rename_dst(p->two);
}
else if (!DIFF_OPT_TST(options, RENAME_EMPTY) &&
is_empty_blob_sha1(p->one->sha1))
@@ -583,8 +599,7 @@ void diffcore_rename(struct diff_options *options)
* We would output this create record if it has
* not been turned into a rename/copy already.
*/
- struct diff_rename_dst *dst =
- locate_rename_dst(p->two, 0);
+ struct diff_rename_dst *dst = locate_rename_dst(p->two);
if (dst && dst->pair) {
diff_q(&outq, dst->pair);
pair_to_free = p;
@@ -614,8 +629,7 @@ void diffcore_rename(struct diff_options *options)
*/
if (DIFF_PAIR_BROKEN(p)) {
/* broken delete */
- struct diff_rename_dst *dst =
- locate_rename_dst(p->one, 0);
+ struct diff_rename_dst *dst = locate_rename_dst(p->one);
if (dst && dst->pair)
/* counterpart is now rename/copy */
pair_to_free = p;