git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 6/7] diffcore-rename: allow to say "rename this blob to that blob"

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Jan 20, 2016, 11:06 UTC
Message-ID
<1453287968-26000-7-git-send-email-pclouds@gmail.com>
In-Reply-To
<1453287968-26000-1-git-send-email-pclouds@gmail.com>

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@gmail.com>
---
 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
Previous: Nguyễn Thái Ngọc DuyNext: Nguyễn Thái Ngọc Duy
Message 16 of 20 in “Diff rename, manual correction, round 2”
  1. 0/7 Diff rename, manual correction, round 2Nguyễn Thái Ngọc Duy, Jan 20, 2016
  2. 1/7 diff-no-index: do not take a redundant prefix argumentNguyễn Thái Ngọc Duy, Jan 20, 2016
  3. 2/7 diff.c: take "prefix" argument in diff_opt_parse()Nguyễn Thái Ngọc Duy, Jan 20, 2016
  4. Junio C HamanoJan 20, 2016
  5. Jeff KingJan 20, 2016
  6. Junio C HamanoJan 20, 2016
  7. Duy NguyenJan 21, 2016
  8. Junio C HamanoJan 21, 2016
  9. 3/7 diff: add --rename-fileNguyễn Thái Ngọc Duy, Jan 20, 2016
  10. Junio C HamanoJan 20, 2016
  11. Junio C HamanoJan 20, 2016
  12. 4/7 log: add --rename-notes to correct renames per commitNguyễn Thái Ngọc Duy, Jan 20, 2016
  13. Junio C HamanoJan 20, 2016
  14. Duy NguyenJan 22, 2016
  15. 5/7 merge: add --rename-fileNguyễn Thái Ngọc Duy, Jan 20, 2016
  16. 6/7 diffcore-rename: allow to say "rename this blob to that blob"Nguyễn Thái Ngọc Duy, Jan 20, 2016
  17. 7/7 merge: add --rename-notesNguyễn Thái Ngọc Duy, Jan 20, 2016
  18. Junio C HamanoJan 21, 2016
  19. Duy NguyenJan 22, 2016
  20. Junio C HamanoJan 22, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.