Thread (1 message) 1 message, 1 author, 2016-06-15

[RFC/PATCH] Detect copies harder in diff-tree.

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:41:58
Subsystem: the rest · Maintainer: Linus Torvalds

quoted
quoted
quoted
quoted
"LT" == Linus Torvalds [off-list ref] writes:
LT> That said, I don't think -C is that important.

By now, you know I won't listen ;-).

I've done preliminary --detect-copies-harder (that is to feed all
the unmodified files to diffcore when doing -C) and --use-cache
(this is to allow diffcore to avoid expanding blob when there is
a already matching file in the work tree) changes to diff-tree.

This example is from the linux-2.6 tree, with the tip of the
tree in the work tree and the cache, and looking at the commit
when include/asm-um was cleaned up (May 5th).  The first one
does not detect copies from "unmodified" files, but the latter
two do.  In this commit there isn't any copy that "harder"
version finds but ordinary one doesn't.

: siamese; time ../git.junio/git-diff-tree -r \
  -C dbc35cc73f2edd6e39d7e814dbb6eddad6294665 >/dev/null
real    0m0.010s
user    0m0.010s
sys     0m0.000s
: siamese; time ../git.junio/git-diff-tree -r --detect-copies-harder \
  -C dbc35cc73f2edd6e39d7e814dbb6eddad6294665 >/dev/null
real    0m19.938s
user    0m11.520s
sys     0m1.240s
: siamese; time ../git.junio/git-diff-tree -r \
  --detect-copies-harder --use-cache -C \
  dbc35cc73f2edd6e39d7e814dbb6eddad6294665 >/dev/null
real    0m5.858s
user    0m5.110s
sys     0m0.710s

------------
Add --detect-copies-harder and --use-cache to diff-tree.

This adds two new options to diff-tree.  Even when -C is used,
diff-tree does not normally feed "unmodified" filepair to the
diffcore, so copy detection is done only among the files that
have changed.  With --detect-copies-harder, it can also detect
copies made from an unmodified file (this behavior is the
default for diff-files and diff-cache).  When this option is
used, it is recommended to also give --use-cache, which lets
diffcore to avoid expanding blob when the work tree has the same
file unmodified.

Signed-off-by: Junio C Hamano <redacted> 
---
cd /opt/packrat/playpen/public/in-place/git/git.junio/
jit-diff
# - linus: git-rev-list: add "end" commit and "--header" flag
# + (working tree)
diff --git a/diff-tree.c b/diff-tree.c
--- a/diff-tree.c
+++ b/diff-tree.c
@@ -6,6 +6,8 @@ static int show_root_diff = 0;
 static int verbose_header = 0;
 static int ignore_merges = 1;
 static int recursive = 0;
+static int use_cache = 0;
+static int detect_copies_harder = 0;
 static int show_tree_entry_in_recursive = 0;
 static int read_stdin = 0;
 static int diff_output_format = DIFF_FORMAT_HUMAN;
@@ -108,7 +110,8 @@ static int compare_tree_entry(void *tree
 		show_file("+", tree2, size2, base);
 		return 1;
 	}
-	if (!memcmp(sha1, sha2, 20) && mode1 == mode2)
+	if (!memcmp(sha1, sha2, 20) && mode1 == mode2 &&
+	    (detect_rename != DIFF_DETECT_COPY || !detect_copies_harder))
 		return 0;
 
 	/*
@@ -549,6 +552,14 @@ int main(int argc, const char **argv)
 			read_stdin = 1;
 			continue;
 		}
+		if (!strcmp(arg, "--use-cache")) {
+			use_cache = 1;
+			continue;
+		}
+		if (!strcmp(arg, "--detect-copies-harder")) {
+			detect_copies_harder = 1;
+			continue;
+		}
 		if (!strcmp(arg, "--root")) {
 			show_root_diff = 1;
 			continue;
@@ -566,6 +577,16 @@ int main(int argc, const char **argv)
 			pathlens[i] = strlen(paths[i]);
 	}
 
+	if (detect_rename && use_cache && !active_cache) {
+		/* read-cache does not die even when it fails
+		 * so it is safe for us to do this here.  Also
+		 * it does not smudge active_cache or active_nr
+		 * when it fails, so we do not have to worry about
+		 * cleaning it up oufselves either.
+		 */
+		read_cache();
+	}
+
 	switch (nr_sha1) {
 	case 0:
 		if (!read_stdin)
Compilation finished at Wed May 25 19:59:09
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help