This will be needed for git-merge, where we do a diff between two trees far away. We need to translate paths to blobs so that merge can stll use it. This patch has another potential use: to reduce processing at rename detection. We can cache the rename output in a big file with these "blob to blob" lines. The next diff will be fast because we only need to compare SHA-1 instead of doing deltas. The naive find_manual_renames() will have to be rewritten to dealwith large cache file though. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- diffcore-rename.c | 40 ++++++++++++++++++++++++++++++++++++++++ t/t4001-diff-rename.sh | 25 +++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/diffcore-rename.c b/diffcore-rename.c index 79beec8..a06c06a 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -358,6 +358,38 @@ static int find_exact_renames(struct diff_options *options) return renames; } +static int manual_rename_blob(const char *src, int srclen, + const char *dst, int dstlen) +{ + struct object_id oid; + int src_index, dst_index; + + if (srclen != GIT_SHA1_HEXSZ || get_oid_hex(src, &oid)) + return 0; + + for (src_index = 0; src_index < rename_src_nr; src_index++) { + const unsigned char *sha1 = rename_src[src_index].p->one->sha1; + if (hashcmp(oid.hash, sha1)) + break; + } + if (src_index == rename_src_nr) + return 0; + + if (dstlen != GIT_SHA1_HEXSZ || get_oid_hex(dst, &oid)) + return 0; + + for (dst_index = 0; dst_index < rename_dst_nr; dst_index++) { + const unsigned char *sha1 = rename_dst[dst_index].two->sha1; + if (hashcmp(oid.hash, sha1)) + break; + } + if (dst_index == rename_dst_nr) + return 0; + + record_rename_pair(dst_index, src_index, MAX_SCORE); + return 1; +} + static int manual_rename(const char *src, int srclen, const char *dst, int dstlen) { @@ -406,6 +438,14 @@ static int find_manual_renames(struct diff_options *options) continue; dst = arrow + strlen(" => "); + + if (skip_prefix(src, "blob ", &src)) { + renames += + manual_rename_blob(src, arrow - src, + dst, line_end - dst); + continue; + } + renames += manual_rename(src, arrow - src, dst, line_end - dst); } diff --git a/t/t4001-diff-rename.sh b/t/t4001-diff-rename.sh index 21d9378..4d5c667 100755 --- a/t/t4001-diff-rename.sh +++ b/t/t4001-diff-rename.sh @@ -189,6 +189,31 @@ test_expect_success 'manual rename correction' ' ) ' +test_expect_success 'manual rename correction with blobs' ' + ( + cd correct-rename && + git diff -M --summary HEAD^ | grep rename >actual && + cat >expected <<-\EOF && + rename old-one => new-one (100%) + rename old-two => new-two (100%) + EOF + test_cmp expected actual && + + ONE=`echo one | git hash-object --stdin` && + TWO=`echo two | git hash-object --stdin` && + cat >correction <<-EOF && + blob $ONE => $TWO + blob $TWO => $ONE + EOF + git diff -M --rename-file=correction --summary HEAD^ | grep rename >actual && + cat >expected <<-\EOF && + rename old-two => new-one (100%) + rename old-one => new-two (100%) + EOF + test_cmp expected actual + ) +' + test_expect_success 'rename correction from notes' ' ( cd correct-rename && -- 2.7.0.125.g9eec362 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html