add merge.renamelimit config option
authorJeff King <peff@peff.net>
Wed, 30 Apr 2008 17:23:55 +0000 (13:23 -0400)
committerJunio C Hamano <gitster@pobox.com>
Sat, 3 May 2008 20:39:51 +0000 (13:39 -0700)
The point of rename limiting is to bound the amount of time
we spend figuring out inexact renames. Currently we use a
single value, diff.renamelimit, for all situations. However,
it is probably the case that a user is willing to spend more
time finding renames during a merge than they are while
looking at git-log.

This patch provides a way of setting those values separately
(though for backwards compatibility, merge still falls back
on the diff renamelimit).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/merge-config.txt
builtin-merge-recursive.c
t/t6032-merge-large-rename.sh [new file with mode: 0755]
index 9719311b42f1beadeca752888dbd12a05ce511f8..48ce747cf4dad592d642735856eb156e93d6cf30 100644 (file)
@@ -6,6 +6,11 @@ merge.log::
        Whether to include summaries of merged commits in newly created
        merge commit messages. False by default.
 
        Whether to include summaries of merged commits in newly created
        merge commit messages. False by default.
 
+merge.renameLimit::
+       The number of files to consider when performing rename detection
+       during a merge; if not specified, defaults to the value of
+       diff.renameLimit.
+
 merge.tool::
        Controls which merge resolution program is used by
        linkgit:git-mergetool[1].  Valid built-in values are: "kdiff3",
 merge.tool::
        Controls which merge resolution program is used by
        linkgit:git-mergetool[1].  Valid built-in values are: "kdiff3",
index 910c0d20e7ba1128c705a49bfd9966212c5420b2..1293e3d342de89b6a8fe81c54a1abd16418acba8 100644 (file)
@@ -92,7 +92,8 @@ static struct path_list current_directory_set = {NULL, 0, 0, 1};
 
 static int call_depth = 0;
 static int verbosity = 2;
 
 static int call_depth = 0;
 static int verbosity = 2;
-static int rename_limit = -1;
+static int diff_rename_limit = -1;
+static int merge_rename_limit = -1;
 static int buffer_output = 1;
 static struct strbuf obuf = STRBUF_INIT;
 
 static int buffer_output = 1;
 static struct strbuf obuf = STRBUF_INIT;
 
@@ -361,7 +362,9 @@ static struct path_list *get_renames(struct tree *tree,
        diff_setup(&opts);
        DIFF_OPT_SET(&opts, RECURSIVE);
        opts.detect_rename = DIFF_DETECT_RENAME;
        diff_setup(&opts);
        DIFF_OPT_SET(&opts, RECURSIVE);
        opts.detect_rename = DIFF_DETECT_RENAME;
-       opts.rename_limit = rename_limit;
+       opts.rename_limit = merge_rename_limit >= 0 ? merge_rename_limit :
+                           diff_rename_limit >= 0 ? diff_rename_limit :
+                           100;
        opts.output_format = DIFF_FORMAT_NO_OUTPUT;
        if (diff_setup_done(&opts) < 0)
                die("diff setup failed");
        opts.output_format = DIFF_FORMAT_NO_OUTPUT;
        if (diff_setup_done(&opts) < 0)
                die("diff setup failed");
@@ -1343,7 +1346,11 @@ static int merge_config(const char *var, const char *value)
                return 0;
        }
        if (!strcasecmp(var, "diff.renamelimit")) {
                return 0;
        }
        if (!strcasecmp(var, "diff.renamelimit")) {
-               rename_limit = git_config_int(var, value);
+               diff_rename_limit = git_config_int(var, value);
+               return 0;
+       }
+       if (!strcasecmp(var, "merge.renamelimit")) {
+               merge_rename_limit = git_config_int(var, value);
                return 0;
        }
        return git_default_config(var, value);
                return 0;
        }
        return git_default_config(var, value);
diff --git a/t/t6032-merge-large-rename.sh b/t/t6032-merge-large-rename.sh
new file mode 100755 (executable)
index 0000000..eac5eba
--- /dev/null
@@ -0,0 +1,73 @@
+#!/bin/sh
+
+test_description='merging with large rename matrix'
+. ./test-lib.sh
+
+count() {
+       i=1
+       while test $i -le $1; do
+               echo $i
+               i=$(($i + 1))
+       done
+}
+
+test_expect_success 'setup (initial)' '
+       touch file &&
+       git add . &&
+       git commit -m initial &&
+       git tag initial
+'
+
+make_text() {
+       echo $1: $2
+       for i in `count 20`; do
+               echo $1: $i
+       done
+       echo $1: $3
+}
+
+test_rename() {
+       test_expect_success "rename ($1, $2)" '
+       n='$1'
+       expect='$2'
+       git checkout -f master &&
+       git branch -D test$n || true &&
+       git reset --hard initial &&
+       for i in $(count $n); do
+               make_text $i initial initial >$i
+       done &&
+       git add . &&
+       git commit -m add=$n &&
+       for i in $(count $n); do
+               make_text $i changed initial >$i
+       done &&
+       git commit -a -m change=$n &&
+       git checkout -b test$n HEAD^ &&
+       for i in $(count $n); do
+               git rm $i
+               make_text $i initial changed >$i.moved
+       done &&
+       git add . &&
+       git commit -m change+rename=$n &&
+       case "$expect" in
+               ok) git merge master ;;
+                *) test_must_fail git merge master ;;
+       esac
+       '
+}
+
+test_rename 5 ok
+
+test_expect_success 'set diff.renamelimit to 4' '
+       git config diff.renamelimit 4
+'
+test_rename 4 ok
+test_rename 5 fail
+
+test_expect_success 'set merge.renamelimit to 5' '
+       git config merge.renamelimit 5
+'
+test_rename 5 ok
+test_rename 6 fail
+
+test_done