threads / patch / 23549

patchMake git log --follow support --find-copies-harder.

Subject: [PATCH] Make git log --follow support --find-copies-harder.

## tl;dr

4 messages between Apr 21, 2010 and Apr 22, 2010. Diffs are folded; open one to read it.

replies: 3people: 2as markdown or json

Bo Yang· Apr 21, 2010, 14:37 UTC · lore

'git log --follow --find-copies-harder <path>' don't track copies from unmodified files, and this patch fix it.

Signed-off-by: Bo Yang <struggleyb.nku@gmail.com>
---
 t/t4205-log-follow-harder-copies.sh |   56 +++++++++++++++++++++++++++++++++++
 tree-diff.c                         |    2 +
 2 files changed, 58 insertions(+), 0 deletions(-)
 create mode 100755 t/t4205-log-follow-harder-copies.sh
Show changes to 2 files +58 −0

t/t4205-log-follow-harder-copies.sh, tree-diff.c

diff --git a/t/t4205-log-follow-harder-copies.sh b/t/t4205-log-follow-harder-copies.sh
new file mode 100755
index 0000000..11e85f4
--- /dev/null
+++ b/t/t4205-log-follow-harder-copies.sh
@@ -0,0 +1,56 @@
+#!/bin/sh
+#
+# Copyright (c) 2010 Bo Yang
+#
+
+test_description='Test --follow with --find-copies-harder in git log.
+
+'
+. ./test-lib.sh
+. "$TEST_DIRECTORY"/diff-lib.sh
+
+echo >path0 'Line 1
+Line 2
+Line 3
+'
+
+test_expect_success \
+    'add a file path0 and commit.' \
+    'git add path0 &&
+     git commit -m "Add path0"'
+
+echo >path0 'New line 1
+New line 2
+New line 3
+'
+test_expect_success \
+    'Change path0.' \
+    'git add path0 &&
+     git commit -m "Change path0"'
+
+cat <path0 >path1
+test_expect_success \
+    'copy path0 to path1.' \
+    'git add path1 &&
+     git commit -m "Copy path1 from path0"'
+
+test_expect_success \
+    'find the copy path0 -> path1 harder' \
+    'git log --follow --find-copies-harder --name-status --pretty="format:%s"  path1 > current'
+
+cat >expected <<\EOF
+Copy path1 from path0
+C100	path0	path1
+
+Change path0
+M	path0
+
+Add path0
+A	path0
+EOF
+
+test_expect_success \
+    'validate the output.' \
+    'compare_diff_patch current expected'
+
+test_done
diff --git a/tree-diff.c b/tree-diff.c
index fe9f52c..0dea53e 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -346,6 +346,8 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co
 
 	diff_setup(&diff_opts);
 	DIFF_OPT_SET(&diff_opts, RECURSIVE);
+	if (DIFF_OPT_TST(opt, FIND_COPIES_HARDER))
+		DIFF_OPT_SET(&diff_opts, FIND_COPIES_HARDER);
 	diff_opts.detect_rename = DIFF_DETECT_RENAME;
 	diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
 	diff_opts.single_follow = opt->paths[0];
-- 
1.7.0.2.273.gc2413.dirty
Junio C Hamano· Apr 21, 2010, 16:56 UTC · re: Bo Yang · lore

Re: [PATCH] Make git log --follow support --find-copies-harder.

Bo Yang <struggleyb.nku@gmail.com> writes:
> 'git log --follow --find-copies-harder <path>' don't track copies
> from unmodified files, and this patch fix it.

What does the command do when given a single -C instead of --f-c-h, with or without your patch? What should it do?

Because try_to_follow_renames() is supposed to be a rare-event (it only happens when a path we have been following disappears), I am having this feeling that it would make more sense to do this change unconditionally.

Two possible outcomes that this patch allows the users to have by giving them a choice to give (or not to give) --f-c-h are:

 (1) the path is judged to be new in a commit and traversal finishes
     there; or 
 (2) the path is found to be a copy from another path from one of the
     parents and traversal continues.

But I think using --follow is a sure sign of the user wanting the latter and never the former, no?

Bo Yang· Apr 22, 2010, 02:27 UTC · re: Junio C Hamano · lore

Re: [PATCH] Make git log --follow support --find-copies-harder.

On Thu, Apr 22, 2010 at 12:56 AM, Junio C Hamano <gitster@pobox.com> wrote:
> What does the command do when given a single -C instead of --f-c-h, with
> or without your patch?  What should it do?

I have found that two days ago, all '-M/-C/-C -C' with some <path> specified will fail. byang@byang-laptop:~/git/git$ git diff --name-status -M maint master builtin/add.c A builtin/add.c

byang@byang-laptop:~/git/git$ git log -M -C -C --name-status --pretty=oneline t/t4013/diff.show_--first-parent_master 2bf6587349e31b582dae47954b1a334052230e28 show --first-parent/-m: do not default to --cc A t/t4013/diff.show_--first-parent_master

without <path>
byang@byang-laptop:~/git/git$ git diff --name-status -M  maint master
| grep  'builtin/add.c'
R100	builtin-add.c	builtin/add.c

byang@byang-laptop:~/git/git$ git log -M -C -C --name-status --pretty=oneline | grep -- 't/t4013/diff.show_--first-parent_master' C050 t/t4013/diff.show_master t/t4013/diff.show_--first-parent_master

Both of above files are copied/renamed.
This because in diff_tree,
              if (opt->nr_paths) {
                        skip_uninteresting(t1, base, baselen, opt);
                        skip_uninteresting(t2, base, baselen, opt);
                }

And this give no chance for later rename/copy detection. I have been trying to figure out a patch for this, but the logic is complex and it will take more time...

Show 15 quoted lines
> Because try_to_follow_renames() is supposed to be a rare-event (it only
> happens when a path we have been following disappears), I am having this
> feeling that it would make more sense to do this change unconditionally.
>
> Two possible outcomes that this patch allows the users to have by giving
> them a choice to give (or not to give) --f-c-h are:
>
>  (1) the path is judged to be new in a commit and traversal finishes
>     there; or
>
>  (2) the path is found to be a copy from another path from one of the
>     parents and traversal continues.
>
> But I think using --follow is a sure sign of the user wanting the latter
> and never the former, no?
Hmm, that makes sense. So, --follow always means --f-c-h.

Regards! Bo

Junio C Hamano· Apr 22, 2010, 05:54 UTC · re: Bo Yang · lore

Re: [PATCH] Make git log --follow support --find-copies-harder.

Bo Yang <struggleyb.nku@gmail.com> writes:
Show 8 quoted lines
> This because in diff_tree,
>
>               if (opt->nr_paths) {
>                         skip_uninteresting(t1, base, baselen, opt);
>                         skip_uninteresting(t2, base, baselen, opt);
>                 }
>
> And this give no chance for later rename/copy detection.

That is rather an old news. This thread may help to avoid rehashing the same issues:

    http://thread.gmane.org/gmane.comp.version-control.git/10225/focus=10259

← back to recent threads