{"thread":{"id":"60463","subject":"[PATCH] diff: implement config.diff.renames=copies-harder","startedAt":"2023-11-03T11:25:07Z","lastAt":"2024-03-11T21:42:45Z","messageCount":9,"participants":["Sam James via GitGitGadget","Elijah Newren","Junio C Hamano","Sam James"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"484387","messageId":"pull.1606.git.1699010701704.gitgitgadget@gmail.com","threadId":"60463","inReplyTo":null,"subject":"[PATCH] diff: implement config.diff.renames=copies-harder","fromName":"Sam James via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2023-11-03T11:25:01Z","receivedAt":"2023-11-03T11:25:07Z","isPatch":true,"sender":{"key":"sam@gentoo.org","avatar":"https://avatars.githubusercontent.com/u/11667869?v=4"},"body":"From: Sam James <sam@gentoo.org>\n\nThis patch adds a config value for 'diff.renames' called 'copies-harder'\nwhich make it so '-C -C' is in effect always passed for 'git log -p',\n'git diff', etc.\n\nThis allows specifying that 'git log -p', 'git diff', etc should always act\nas if '-C --find-copies-harder' was passed.\n\nI've found this especially useful for certain types of repository (like\nGentoo's ebuild repositories) because files are often copies of a previous\nversion.\n\nSigned-off-by: Sam James <sam@gentoo.org>\n---\n    diff: implement config.diff.renames=copies-harder\n    \n    This patch adds a config value for 'diff.renames' called 'copies-harder'\n    which make it so '-C -C' is in effect always passed for 'git log -p',\n    'git diff', etc.\n    \n    This allows specifying that 'git log -p', 'git diff', etc should always\n    act as if '-C --find-copies-harder' was passed.\n    \n    I've found this especially useful for certain types of repository (like\n    Gentoo's ebuild repositories) because files are often copies of a\n    previous version.\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-1606%2Fthesamesam%2Fconfig-copies-harder-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1606/thesamesam/config-copies-harder-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/1606\n\n Documentation/config/diff.txt   |  3 ++-\n Documentation/config/status.txt |  3 ++-\n diff.c                          | 12 +++++++++---\n diff.h                          |  1 +\n diffcore-rename.c               |  4 ++--\n merge-ort.c                     |  2 +-\n merge-recursive.c               |  2 +-\n 7 files changed, 18 insertions(+), 9 deletions(-)\n\ndiff --git a/Documentation/config/diff.txt b/Documentation/config/diff.txt\nindex bd5ae0c3378..d2ff3c62d41 100644\n--- a/Documentation/config/diff.txt\n+++ b/Documentation/config/diff.txt\n@@ -131,7 +131,8 @@ diff.renames::\n \tWhether and how Git detects renames.  If set to \"false\",\n \trename detection is disabled. If set to \"true\", basic rename\n \tdetection is enabled.  If set to \"copies\" or \"copy\", Git will\n-\tdetect copies, as well.  Defaults to true.  Note that this\n+\tdetect copies, as well.  If set to \"copies-harder\", Git will try harder\n+\tto detect copies.  Defaults to true.  Note that this\n \taffects only 'git diff' Porcelain like linkgit:git-diff[1] and\n \tlinkgit:git-log[1], and not lower level commands such as\n \tlinkgit:git-diff-files[1].\ndiff --git a/Documentation/config/status.txt b/Documentation/config/status.txt\nindex 2ff8237f8fc..7ca7a4becd7 100644\n--- a/Documentation/config/status.txt\n+++ b/Documentation/config/status.txt\n@@ -33,7 +33,8 @@ status.renames::\n \tWhether and how Git detects renames in linkgit:git-status[1] and\n \tlinkgit:git-commit[1] .  If set to \"false\", rename detection is\n \tdisabled. If set to \"true\", basic rename detection is enabled.\n-\tIf set to \"copies\" or \"copy\", Git will detect copies, as well.\n+\tIf set to \"copies\" or \"copy\", Git will detect copies, as well.  If\n+\tset to \"copies-harder\", Git will try harder to detect copies.\n \tDefaults to the value of diff.renames.\n \n status.showStash::\ndiff --git a/diff.c b/diff.c\nindex 2c602df10a3..0ca906611f5 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -206,8 +206,11 @@ int git_config_rename(const char *var, const char *value)\n {\n \tif (!value)\n \t\treturn DIFF_DETECT_RENAME;\n+\tif (!strcasecmp(value, \"copies-harder\"))\n+\t\treturn DIFF_DETECT_COPY_HARDER;\n \tif (!strcasecmp(value, \"copies\") || !strcasecmp(value, \"copy\"))\n-\t\treturn  DIFF_DETECT_COPY;\n+\t\treturn DIFF_DETECT_COPY;\n+\n \treturn git_config_bool(var,value) ? DIFF_DETECT_RENAME : 0;\n }\n \n@@ -4832,8 +4835,11 @@ void diff_setup_done(struct diff_options *options)\n \telse\n \t\toptions->flags.diff_from_contents = 0;\n \n-\tif (options->flags.find_copies_harder)\n+\t/* Just fold this in as it makes the patch-to-git smaller */\n+\tif (options->flags.find_copies_harder || options->detect_rename == DIFF_DETECT_COPY_HARDER) {\n+\t\toptions->flags.find_copies_harder = 1;\n \t\toptions->detect_rename = DIFF_DETECT_COPY;\n+\t}\n \n \tif (!options->flags.relative_name)\n \t\toptions->prefix = NULL;\n@@ -5264,7 +5270,7 @@ static int diff_opt_find_copies(const struct option *opt,\n \tif (*arg != 0)\n \t\treturn error(_(\"invalid argument to %s\"), opt->long_name);\n \n-\tif (options->detect_rename == DIFF_DETECT_COPY)\n+\tif (options->detect_rename == DIFF_DETECT_COPY || options->detect_rename == DIFF_DETECT_COPY_HARDER)\n \t\toptions->flags.find_copies_harder = 1;\n \telse\n \t\toptions->detect_rename = DIFF_DETECT_COPY;\ndiff --git a/diff.h b/diff.h\nindex 66bd8aeb293..b29e5b777f8 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -555,6 +555,7 @@ int git_config_rename(const char *var, const char *value);\n \n #define DIFF_DETECT_RENAME\t1\n #define DIFF_DETECT_COPY\t2\n+#define DIFF_DETECT_COPY_HARDER 3\n \n #define DIFF_PICKAXE_ALL\t1\n #define DIFF_PICKAXE_REGEX\t2\ndiff --git a/diffcore-rename.c b/diffcore-rename.c\nindex 5a6e2bcac71..856291d66f2 100644\n--- a/diffcore-rename.c\n+++ b/diffcore-rename.c\n@@ -299,7 +299,7 @@ static int find_identical_files(struct hashmap *srcs,\n \t\t}\n \t\t/* Give higher scores to sources that haven't been used already */\n \t\tscore = !source->rename_used;\n-\t\tif (source->rename_used && options->detect_rename != DIFF_DETECT_COPY)\n+\t\tif (source->rename_used && options->detect_rename != DIFF_DETECT_COPY && options->detect_rename != DIFF_DETECT_COPY_HARDER)\n \t\t\tcontinue;\n \t\tscore += basename_same(source, target);\n \t\tif (score > best_score) {\n@@ -1405,7 +1405,7 @@ void diffcore_rename_extended(struct diff_options *options,\n \ttrace2_region_enter(\"diff\", \"setup\", options->repo);\n \tinfo.setup = 0;\n \tassert(!dir_rename_count || strmap_empty(dir_rename_count));\n-\twant_copies = (detect_rename == DIFF_DETECT_COPY);\n+\twant_copies = (detect_rename == DIFF_DETECT_COPY || detect_rename == DIFF_DETECT_COPY_HARDER);\n \tif (dirs_removed && (break_idx || want_copies))\n \t\tBUG(\"dirs_removed incompatible with break/copy detection\");\n \tif (break_idx && relevant_sources)\ndiff --git a/merge-ort.c b/merge-ort.c\nindex 6491070d965..77498354652 100644\n--- a/merge-ort.c\n+++ b/merge-ort.c\n@@ -4782,7 +4782,7 @@ static void merge_start(struct merge_options *opt, struct merge_result *result)\n \t * sanity check them anyway.\n \t */\n \tassert(opt->detect_renames >= -1 &&\n-\t       opt->detect_renames <= DIFF_DETECT_COPY);\n+\t       opt->detect_renames <= DIFF_DETECT_COPY_HARDER);\n \tassert(opt->verbosity >= 0 && opt->verbosity <= 5);\n \tassert(opt->buffer_output <= 2);\n \tassert(opt->obuf.len == 0);\ndiff --git a/merge-recursive.c b/merge-recursive.c\nindex e3beb0801b1..d52dd536606 100644\n--- a/merge-recursive.c\n+++ b/merge-recursive.c\n@@ -3708,7 +3708,7 @@ static int merge_start(struct merge_options *opt, struct tree *head)\n \tassert(opt->branch1 && opt->branch2);\n \n \tassert(opt->detect_renames >= -1 &&\n-\t       opt->detect_renames <= DIFF_DETECT_COPY);\n+\t       opt->detect_renames <= DIFF_DETECT_COPY_HARDER);\n \tassert(opt->detect_directory_renames >= MERGE_DIRECTORY_RENAMES_NONE &&\n \t       opt->detect_directory_renames <= MERGE_DIRECTORY_RENAMES_TRUE);\n \tassert(opt->rename_limit >= -1);\n\nbase-commit: 692be87cbba55e8488f805d236f2ad50483bd7d5\n-- \ngitgitgadget\n"},{"id":"484502","messageId":"CABPp-BEuvjduS4JiORJybKtoPWvJd+BbbR_JAvZdj4Px_v8H4A@mail.gmail.com","threadId":"60463","inReplyTo":"pull.1606.git.1699010701704.gitgitgadget@gmail.com","subject":"Re: [PATCH] diff: implement config.diff.renames=copies-harder","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2023-11-07T02:45:20Z","receivedAt":"2023-11-07T02:45:38Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"Hi,\n\nOn Fri, Nov 3, 2023 at 4:25 AM Sam James via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> From: Sam James <sam@gentoo.org>\n>\n> This patch adds a config value for 'diff.renames' called 'copies-harder'\n> which make it so '-C -C' is in effect always passed for 'git log -p',\n> 'git diff', etc.\n>\n> This allows specifying that 'git log -p', 'git diff', etc should always act\n> as if '-C --find-copies-harder' was passed.\n>\n> I've found this especially useful for certain types of repository (like\n> Gentoo's ebuild repositories) because files are often copies of a previous\n> version.\n\nThese must be very small repositories?  --find-copies-harder is really\nexpensive...\n\nBut, if you are willing to pay the price, the idea of making this a\nconfiguration item makes sense.\n\n> Signed-off-by: Sam James <sam@gentoo.org>\n> ---\n>     diff: implement config.diff.renames=copies-harder\n>\n>     This patch adds a config value for 'diff.renames' called 'copies-harder'\n>     which make it so '-C -C' is in effect always passed for 'git log -p',\n>     'git diff', etc.\n>\n>     This allows specifying that 'git log -p', 'git diff', etc should always\n>     act as if '-C --find-copies-harder' was passed.\n>\n>     I've found this especially useful for certain types of repository (like\n>     Gentoo's ebuild repositories) because files are often copies of a\n>     previous version.\n>\n> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1606%2Fthesamesam%2Fconfig-copies-harder-v1\n> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1606/thesamesam/config-copies-harder-v1\n> Pull-Request: https://github.com/gitgitgadget/git/pull/1606\n>\n>  Documentation/config/diff.txt   |  3 ++-\n>  Documentation/config/status.txt |  3 ++-\n>  diff.c                          | 12 +++++++++---\n>  diff.h                          |  1 +\n>  diffcore-rename.c               |  4 ++--\n>  merge-ort.c                     |  2 +-\n>  merge-recursive.c               |  2 +-\n>  7 files changed, 18 insertions(+), 9 deletions(-)\n>\n> diff --git a/Documentation/config/diff.txt b/Documentation/config/diff.txt\n> index bd5ae0c3378..d2ff3c62d41 100644\n> --- a/Documentation/config/diff.txt\n> +++ b/Documentation/config/diff.txt\n> @@ -131,7 +131,8 @@ diff.renames::\n>         Whether and how Git detects renames.  If set to \"false\",\n>         rename detection is disabled. If set to \"true\", basic rename\n>         detection is enabled.  If set to \"copies\" or \"copy\", Git will\n> -       detect copies, as well.  Defaults to true.  Note that this\n> +       detect copies, as well.  If set to \"copies-harder\", Git will try harder\n> +       to detect copies.  Defaults to true.  Note that this\n\n\"try harder to detect copies\" feels like an unhelpful explanation.  I\nunderstand that a lengthy explanation (like the one found under the\n`--find-copies-harder` option in git-diff) may not be wanted here\nsince we are trying to describe things succinctly, but could we at\nleast reference the `--find-copies-harder` option so that people know\nwhere to go to get a more detailed explanation?\n\n>         affects only 'git diff' Porcelain like linkgit:git-diff[1] and\n>         linkgit:git-log[1], and not lower level commands such as\n>         linkgit:git-diff-files[1].\n> diff --git a/Documentation/config/status.txt b/Documentation/config/status.txt\n> index 2ff8237f8fc..7ca7a4becd7 100644\n> --- a/Documentation/config/status.txt\n> +++ b/Documentation/config/status.txt\n> @@ -33,7 +33,8 @@ status.renames::\n>         Whether and how Git detects renames in linkgit:git-status[1] and\n>         linkgit:git-commit[1] .  If set to \"false\", rename detection is\n>         disabled. If set to \"true\", basic rename detection is enabled.\n> -       If set to \"copies\" or \"copy\", Git will detect copies, as well.\n> +       If set to \"copies\" or \"copy\", Git will detect copies, as well.  If\n> +       set to \"copies-harder\", Git will try harder to detect copies.\n\nSame here.\n\n>         Defaults to the value of diff.renames.\n>\n>  status.showStash::\n> diff --git a/diff.c b/diff.c\n> index 2c602df10a3..0ca906611f5 100644\n> --- a/diff.c\n> +++ b/diff.c\n> @@ -206,8 +206,11 @@ int git_config_rename(const char *var, const char *value)\n>  {\n>         if (!value)\n>                 return DIFF_DETECT_RENAME;\n> +       if (!strcasecmp(value, \"copies-harder\"))\n> +               return DIFF_DETECT_COPY_HARDER;\n>         if (!strcasecmp(value, \"copies\") || !strcasecmp(value, \"copy\"))\n> -               return  DIFF_DETECT_COPY;\n> +               return DIFF_DETECT_COPY;\n> +\n\nAs per CodingGuidelines:\n\"\"\"\n - Fixing style violations while working on a real change as a\n   preparatory clean-up step is good, but otherwise avoid useless code\n   churn for the sake of conforming to the style.\n\"\"\"\nSo, the fixing of extra space and the extra blank line should be\nplaced in a separate patch.\n\n>         return git_config_bool(var,value) ? DIFF_DETECT_RENAME : 0;\n>  }\n>\n> @@ -4832,8 +4835,11 @@ void diff_setup_done(struct diff_options *options)\n>         else\n>                 options->flags.diff_from_contents = 0;\n>\n> -       if (options->flags.find_copies_harder)\n> +       /* Just fold this in as it makes the patch-to-git smaller */\n> +       if (options->flags.find_copies_harder || options->detect_rename == DIFF_DETECT_COPY_HARDER) {\n\nAs per CodingGuidelines, this line is too long and should be split\nacross two lines at the `||`.\n\n> +               options->flags.find_copies_harder = 1;\n>                 options->detect_rename = DIFF_DETECT_COPY;\n> +       }\n>\n>         if (!options->flags.relative_name)\n>                 options->prefix = NULL;\n> @@ -5264,7 +5270,7 @@ static int diff_opt_find_copies(const struct option *opt,\n>         if (*arg != 0)\n>                 return error(_(\"invalid argument to %s\"), opt->long_name);\n>\n> -       if (options->detect_rename == DIFF_DETECT_COPY)\n> +       if (options->detect_rename == DIFF_DETECT_COPY || options->detect_rename == DIFF_DETECT_COPY_HARDER)\n\nAlso too long.\n\n>                 options->flags.find_copies_harder = 1;\n>         else\n>                 options->detect_rename = DIFF_DETECT_COPY;\n> diff --git a/diff.h b/diff.h\n> index 66bd8aeb293..b29e5b777f8 100644\n> --- a/diff.h\n> +++ b/diff.h\n> @@ -555,6 +555,7 @@ int git_config_rename(const char *var, const char *value);\n>\n>  #define DIFF_DETECT_RENAME     1\n>  #define DIFF_DETECT_COPY       2\n> +#define DIFF_DETECT_COPY_HARDER 3\n>\n>  #define DIFF_PICKAXE_ALL       1\n>  #define DIFF_PICKAXE_REGEX     2\n> diff --git a/diffcore-rename.c b/diffcore-rename.c\n> index 5a6e2bcac71..856291d66f2 100644\n> --- a/diffcore-rename.c\n> +++ b/diffcore-rename.c\n> @@ -299,7 +299,7 @@ static int find_identical_files(struct hashmap *srcs,\n>                 }\n>                 /* Give higher scores to sources that haven't been used already */\n>                 score = !source->rename_used;\n> -               if (source->rename_used && options->detect_rename != DIFF_DETECT_COPY)\n> +               if (source->rename_used && options->detect_rename != DIFF_DETECT_COPY && options->detect_rename != DIFF_DETECT_COPY_HARDER)\n\nThis line should also be split.\n\n>                         continue;\n>                 score += basename_same(source, target);\n>                 if (score > best_score) {\n> @@ -1405,7 +1405,7 @@ void diffcore_rename_extended(struct diff_options *options,\n>         trace2_region_enter(\"diff\", \"setup\", options->repo);\n>         info.setup = 0;\n>         assert(!dir_rename_count || strmap_empty(dir_rename_count));\n> -       want_copies = (detect_rename == DIFF_DETECT_COPY);\n> +       want_copies = (detect_rename == DIFF_DETECT_COPY || detect_rename == DIFF_DETECT_COPY_HARDER);\n\nand so should this one.\n\n>         if (dirs_removed && (break_idx || want_copies))\n>                 BUG(\"dirs_removed incompatible with break/copy detection\");\n>         if (break_idx && relevant_sources)\n> diff --git a/merge-ort.c b/merge-ort.c\n> index 6491070d965..77498354652 100644\n> --- a/merge-ort.c\n> +++ b/merge-ort.c\n> @@ -4782,7 +4782,7 @@ static void merge_start(struct merge_options *opt, struct merge_result *result)\n>          * sanity check them anyway.\n>          */\n>         assert(opt->detect_renames >= -1 &&\n> -              opt->detect_renames <= DIFF_DETECT_COPY);\n> +              opt->detect_renames <= DIFF_DETECT_COPY_HARDER);\n>         assert(opt->verbosity >= 0 && opt->verbosity <= 5);\n>         assert(opt->buffer_output <= 2);\n>         assert(opt->obuf.len == 0);\n> diff --git a/merge-recursive.c b/merge-recursive.c\n> index e3beb0801b1..d52dd536606 100644\n> --- a/merge-recursive.c\n> +++ b/merge-recursive.c\n> @@ -3708,7 +3708,7 @@ static int merge_start(struct merge_options *opt, struct tree *head)\n>         assert(opt->branch1 && opt->branch2);\n>\n>         assert(opt->detect_renames >= -1 &&\n> -              opt->detect_renames <= DIFF_DETECT_COPY);\n> +              opt->detect_renames <= DIFF_DETECT_COPY_HARDER);\n>         assert(opt->detect_directory_renames >= MERGE_DIRECTORY_RENAMES_NONE &&\n>                opt->detect_directory_renames <= MERGE_DIRECTORY_RENAMES_TRUE);\n>         assert(opt->rename_limit >= -1);\n>\n> base-commit: 692be87cbba55e8488f805d236f2ad50483bd7d5\n> --\n> gitgitgadget\n\nThe overall patch makes sense and looks good, modulo some minor\nstylistic things that need cleaning up.\n"},{"id":"484505","messageId":"xmqq7cmu9s29.fsf@gitster.g","threadId":"60463","inReplyTo":"CABPp-BEuvjduS4JiORJybKtoPWvJd+BbbR_JAvZdj4Px_v8H4A@mail.gmail.com","subject":"Re: [PATCH] diff: implement config.diff.renames=copies-harder","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-11-07T03:10:38Z","receivedAt":"2023-11-07T03:10:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n> On Fri, Nov 3, 2023 at 4:25 AM Sam James via GitGitGadget\n> <gitgitgadget@gmail.com> wrote:\n>>\n>> From: Sam James <sam@gentoo.org>\n>>\n>> This patch adds a config value for 'diff.renames' called 'copies-harder'\n>> which make it so '-C -C' is in effect always passed for 'git log -p',\n>> 'git diff', etc.\n>>\n>> This allows specifying that 'git log -p', 'git diff', etc should always act\n>> as if '-C --find-copies-harder' was passed.\n>>\n>> I've found this especially useful for certain types of repository (like\n>> Gentoo's ebuild repositories) because files are often copies of a previous\n>> version.\n>\n> These must be very small repositories?  --find-copies-harder is really\n> expensive...\n\nTrue.  \"often copies of a previous version\" means that it is a\ndirectory that has a collection of subdirectories, one for each\nversion?  In a source tree managed in a version control system,\nfiles are often rewritten in place from the previous version,\nso I am puzzled by that justification.\n\nIt is, in the proposed log message of our commits, a bit unusual to\nsee \"This patch does X\" and \"I do Y\", by the way, which made my\nreading hiccup a bit, but perhaps it is just me?\n\n>> diff --git a/Documentation/config/diff.txt b/Documentation/config/diff.txt\n>> index bd5ae0c3378..d2ff3c62d41 100644\n>> --- a/Documentation/config/diff.txt\n>> +++ b/Documentation/config/diff.txt\n>> @@ -131,7 +131,8 @@ diff.renames::\n>>         Whether and how Git detects renames.  If set to \"false\",\n>>         rename detection is disabled. If set to \"true\", basic rename\n>>         detection is enabled.  If set to \"copies\" or \"copy\", Git will\n>> -       detect copies, as well.  Defaults to true.  Note that this\n>> +       detect copies, as well.  If set to \"copies-harder\", Git will try harder\n>> +       to detect copies.  Defaults to true.  Note that this\n>\n> \"try harder to detect copies\" feels like an unhelpful explanation.\n\nYup.  \"will spend extra cycles to find more copies\", perhaps?\n"},{"id":"484532","messageId":"CABPp-BF9iUkF+g_w7wLATFTmjfJ3f1hsBr+zXxNZEcq-XiNOWg@mail.gmail.com","threadId":"60463","inReplyTo":"xmqq7cmu9s29.fsf@gitster.g","subject":"Re: [PATCH] diff: implement config.diff.renames=copies-harder","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2023-11-07T17:19:48Z","receivedAt":"2023-11-07T17:20:03Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Mon, Nov 6, 2023 at 7:10 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Elijah Newren <newren@gmail.com> writes:\n>\n> > On Fri, Nov 3, 2023 at 4:25 AM Sam James via GitGitGadget\n> > <gitgitgadget@gmail.com> wrote:\n> >>\n> >> From: Sam James <sam@gentoo.org>\n> >>\n> >> This patch adds a config value for 'diff.renames' called 'copies-harder'\n> >> which make it so '-C -C' is in effect always passed for 'git log -p',\n> >> 'git diff', etc.\n> >>\n> >> This allows specifying that 'git log -p', 'git diff', etc should always act\n> >> as if '-C --find-copies-harder' was passed.\n> >>\n> >> I've found this especially useful for certain types of repository (like\n> >> Gentoo's ebuild repositories) because files are often copies of a previous\n> >> version.\n> >\n> > These must be very small repositories?  --find-copies-harder is really\n> > expensive...\n>\n> True.  \"often copies of a previous version\" means that it is a\n> directory that has a collection of subdirectories, one for each\n> version?  In a source tree managed in a version control system,\n> files are often rewritten in place from the previous version,\n> so I am puzzled by that justification.\n>\n> It is, in the proposed log message of our commits, a bit unusual to\n> see \"This patch does X\" and \"I do Y\", by the way, which made my\n> reading hiccup a bit, but perhaps it is just me?\n\nI think I read Sam's description a bit differently than you.  My\nassumption was they'd have files with names like the following in the\nsame directory:\n   gcc-13.x.build.recipe\n   gcc-12.x.build.recipe\n   gcc-11.x.build.recipe\n   gcc-10.x.build.recipe\n\nAnd that gcc-13.x.build.recipe was started as a copy of\ngcc-12.x.build.recipe (which was started as a copy of\ngcc-11.x.build.recipe, etc.).  They keep all versions because they\nwant users to be able to build and install multiple gcc versions.\n\nI could be completely off, but that's what I was imagining from the description.\n\n> >> diff --git a/Documentation/config/diff.txt b/Documentation/config/diff.txt\n> >> index bd5ae0c3378..d2ff3c62d41 100644\n> >> --- a/Documentation/config/diff.txt\n> >> +++ b/Documentation/config/diff.txt\n> >> @@ -131,7 +131,8 @@ diff.renames::\n> >>         Whether and how Git detects renames.  If set to \"false\",\n> >>         rename detection is disabled. If set to \"true\", basic rename\n> >>         detection is enabled.  If set to \"copies\" or \"copy\", Git will\n> >> -       detect copies, as well.  Defaults to true.  Note that this\n> >> +       detect copies, as well.  If set to \"copies-harder\", Git will try harder\n> >> +       to detect copies.  Defaults to true.  Note that this\n> >\n> > \"try harder to detect copies\" feels like an unhelpful explanation.\n>\n> Yup.  \"will spend extra cycles to find more copies\", perhaps?\n\nI find that marginally better; but I still don't think it answers the\nuser's question of why they should pick one option or the other.  The\nwording for the `--find-copies-harder` does explain when it's useful:\n\n        For performance reasons, by default, `-C` option finds copies only\n        if the original file of the copy was modified in the same\n        changeset.  This flag makes the command\n        inspect unmodified files as candidates for the source of\n        copy.  This is a very expensive operation for large\n        projects, so use it with caution.\n\nWe probably don't want to copy all three of those sentences here, but\nI think we need to make sure users can find them, thus my suggestion\nto reference the `--find-copies-harder` option to git-diff so that\naffected users can get the info they need to choose.\n"},{"id":"484549","messageId":"xmqqttpx828i.fsf@gitster.g","threadId":"60463","inReplyTo":"CABPp-BF9iUkF+g_w7wLATFTmjfJ3f1hsBr+zXxNZEcq-XiNOWg@mail.gmail.com","subject":"Re: [PATCH] diff: implement config.diff.renames=copies-harder","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-11-08T01:26:05Z","receivedAt":"2023-11-08T01:26:12Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n>> True.  \"often copies of a previous version\" means that it is a\n>> directory that has a collection of subdirectories, one for each\n>> version?  In a source tree managed in a version control system,\n>> files are often rewritten in place from the previous version,\n>> so I am puzzled by that justification.\n>>\n>> It is, in the proposed log message of our commits, a bit unusual to\n>> see \"This patch does X\" and \"I do Y\", by the way, which made my\n>> reading hiccup a bit, but perhaps it is just me?\n>\n> I think I read Sam's description a bit differently than you.  My\n> assumption was they'd have files with names like the following in the\n> same directory:\n>    gcc-13.x.build.recipe\n>    gcc-12.x.build.recipe\n>    gcc-11.x.build.recipe\n>    gcc-10.x.build.recipe\n>\n> And that gcc-13.x.build.recipe was started as a copy of\n> gcc-12.x.build.recipe (which was started as a copy of\n> gcc-11.x.build.recipe, etc.).  They keep all versions because they\n> want users to be able to build and install multiple gcc versions.\n\nOK, \"previous version\" is within the context of \"variants of gcc\",\nand to us, there is no distinction among them (we do not care which\nones are older than the others---we need to keep track of them all).\n\nWhich makes sense.  OK.\n\n> I find that marginally better; but I still don't think it answers the\n> user's question of why they should pick one option or the other.  The\n> wording for the `--find-copies-harder` does explain when it's useful:\n>\n>         For performance reasons, by default, `-C` option finds copies only\n>         if the original file of the copy was modified in the same\n>         changeset.  This flag makes the command\n>         inspect unmodified files as candidates for the source of\n>         copy.  This is a very expensive operation for large\n>         projects, so use it with caution.\n>\n> We probably don't want to copy all three of those sentences here, but\n> I think we need to make sure users can find them, thus my suggestion\n> to reference the `--find-copies-harder` option to git-diff so that\n> affected users can get the info they need to choose.\n\n\"in addition to paths that are different, will look for more copies\neven in unmodified paths\" then?\n"},{"id":"484556","messageId":"CABPp-BEgxKn3QvJQ+6L3Z1RN1im=c3dfApLRCrQqum_Yim44Gw@mail.gmail.com","threadId":"60463","inReplyTo":"xmqqttpx828i.fsf@gitster.g","subject":"Re: [PATCH] diff: implement config.diff.renames=copies-harder","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2023-11-08T03:30:09Z","receivedAt":"2023-11-08T03:30:24Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Tue, Nov 7, 2023 at 5:26 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Elijah Newren <newren@gmail.com> writes:\n>\n> > I find that marginally better; but I still don't think it answers the\n> > user's question of why they should pick one option or the other.  The\n> > wording for the `--find-copies-harder` does explain when it's useful:\n> >\n> >         For performance reasons, by default, `-C` option finds copies only\n> >         if the original file of the copy was modified in the same\n> >         changeset.  This flag makes the command\n> >         inspect unmodified files as candidates for the source of\n> >         copy.  This is a very expensive operation for large\n> >         projects, so use it with caution.\n> >\n> > We probably don't want to copy all three of those sentences here, but\n> > I think we need to make sure users can find them, thus my suggestion\n> > to reference the `--find-copies-harder` option to git-diff so that\n> > affected users can get the info they need to choose.\n>\n> \"in addition to paths that are different, will look for more copies\n> even in unmodified paths\" then?\n\nThat's much better.  I still slightly prefer referencing\n`--find-copies-harder` so that there's a link between \"copies-harder\"\nand `--find-copies-harder`; but this version would also be fine.\n"},{"id":"484557","messageId":"xmqqv8ac7utk.fsf@gitster.g","threadId":"60463","inReplyTo":"CABPp-BEgxKn3QvJQ+6L3Z1RN1im=c3dfApLRCrQqum_Yim44Gw@mail.gmail.com","subject":"Re: [PATCH] diff: implement config.diff.renames=copies-harder","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-11-08T04:06:15Z","receivedAt":"2023-11-08T04:06:21Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n>> > We probably don't want to copy all three of those sentences here, but\n>> > I think we need to make sure users can find them, thus my suggestion\n>> > to reference the `--find-copies-harder` option to git-diff so that\n>> > affected users can get the info they need to choose.\n>>\n>> \"in addition to paths that are different, will look for more copies\n>> even in unmodified paths\" then?\n>\n> That's much better.  I still slightly prefer referencing\n> `--find-copies-harder` so that there's a link between \"copies-harder\"\n> and `--find-copies-harder`; but this version would also be fine.\n\nOh, I didn't mean \"use this rewrite and do not make any external\nreference\".  More like \"external reference is a good idea and\nnecessary to help motivated readers, but we should give enough\ninformation inline, and I think this level of details would be\nsufficient\".\n\nThanks.\n"},{"id":"484558","messageId":"CABPp-BHqJ0o85H7nBbPJ0b4kXvWF7TMCrTzpxhWfSHSrfGf7dQ@mail.gmail.com","threadId":"60463","inReplyTo":"xmqqv8ac7utk.fsf@gitster.g","subject":"Re: [PATCH] diff: implement config.diff.renames=copies-harder","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2023-11-08T04:38:36Z","receivedAt":"2023-11-08T04:38:51Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Tue, Nov 7, 2023 at 8:06 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> Elijah Newren <newren@gmail.com> writes:\n>\n> >> > We probably don't want to copy all three of those sentences here, but\n> >> > I think we need to make sure users can find them, thus my suggestion\n> >> > to reference the `--find-copies-harder` option to git-diff so that\n> >> > affected users can get the info they need to choose.\n> >>\n> >> \"in addition to paths that are different, will look for more copies\n> >> even in unmodified paths\" then?\n> >\n> > That's much better.  I still slightly prefer referencing\n> > `--find-copies-harder` so that there's a link between \"copies-harder\"\n> > and `--find-copies-harder`; but this version would also be fine.\n>\n> Oh, I didn't mean \"use this rewrite and do not make any external\n> reference\".  More like \"external reference is a good idea and\n> necessary to help motivated readers, but we should give enough\n> information inline, and I think this level of details would be\n> sufficient\".\n\nAh, gotcha.  Yeah, this sounds good.\n"},{"id":"490404","messageId":"87frwwmomn.fsf@gentoo.org","threadId":"60463","inReplyTo":"pull.1606.git.1699010701704.gitgitgadget@gmail.com","subject":"Re: [PATCH] diff: implement config.diff.renames=copies-harder","fromName":"Sam James","fromEmail":"sam@gentoo.org","sentAt":"2024-03-11T21:42:40Z","receivedAt":"2024-03-11T21:42:45Z","isPatch":true,"sender":{"key":"sam@gentoo.org","avatar":"https://avatars.githubusercontent.com/u/11667869?v=4"},"body":"\"Sam James via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Sam James <sam@gentoo.org>\n>\n> This patch adds a config value for 'diff.renames' called 'copies-harder'\n> which make it so '-C -C' is in effect always passed for 'git log -p',\n> 'git diff', etc.\n>\n> This allows specifying that 'git log -p', 'git diff', etc should always act\n> as if '-C --find-copies-harder' was passed.\n>\n> I've found this especially useful for certain types of repository (like\n> Gentoo's ebuild repositories) because files are often copies of a previous\n> version.\n>\n> Signed-off-by: Sam James <sam@gentoo.org>\n> ---\n>     diff: implement config.diff.renames=copies-harder\n>     \n>     This patch adds a config value for 'diff.renames' called 'copies-harder'\n>     which make it so '-C -C' is in effect always passed for 'git log -p',\n>     'git diff', etc.\n>     \n>     This allows specifying that 'git log -p', 'git diff', etc should always\n>     act as if '-C --find-copies-harder' was passed.\n>     \n>     I've found this especially useful for certain types of repository (like\n>     Gentoo's ebuild repositories) because files are often copies of a\n>     previous version.\n>\n> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1606%2Fthesamesam%2Fconfig-copies-harder-v1\n> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1606/thesamesam/config-copies-harder-v1\n> Pull-Request: https://github.com/gitgitgadget/git/pull/1606\n>\n\nv2: https://lore.kernel.org/git/20231226202102.3392518-1-sam@gentoo.org/\nv3: https://lore.kernel.org/git/20240311213928.1872437-1-sam@gentoo.org/\n"}]}