summaryrefslogtreecommitdiff
path: root/dev-vcs/git/files/git-2.49.0-diff-implement-config.diff.renames-copies-harder.patch
diff options
context:
space:
mode:
authorSam James <sam@gentoo.org>2025-03-28 19:44:25 +0000
committerSam James <sam@gentoo.org>2025-03-28 19:47:55 +0000
commit8b1595184775bdd47164e3df4859756684dcb2ba (patch)
treef9cf2eafd10422c66f9371ef062ec62cb82068e9 /dev-vcs/git/files/git-2.49.0-diff-implement-config.diff.renames-copies-harder.patch
parentcca6ecd44446ed3c0bb8258eee614dbbc89989f3 (diff)
downloadgentoo-8b1595184775bdd47164e3df4859756684dcb2ba.tar.gz
gentoo-8b1595184775bdd47164e3df4859756684dcb2ba.tar.bz2
gentoo-8b1595184775bdd47164e3df4859756684dcb2ba.zip
dev-vcs/git: add copies-harder patch
I wasn't planning on adding this to dev-vcs/git, but after polling a few times on IRC in #gentoo-dev, it seems people want it. It was rejected upstream (after several revisions; we hope it'll be accepted in future) because they don't see the value in having a config option for this, but when working in a repo like ::gentoo, it's natural to want it as a default. It seems okay to patch it in downstream unconditionally given you have to actively opt-in to *using* it by adding the relevant config option - this was also the opinion of others which helped persuade me to do this. The docs added by the patch also mention that it's patched in and not upstream. Details are within the patch itself, but quoting some of it: > diff: implement config.diff.renames=copies-harder > > This patch adds a config value for 'diff.renames' called 'copies-harder' > which make it so '-C -C' is in effect always passed for 'git log -p', > 'git diff', etc. > > This allows specifying that 'git log -p', 'git diff', etc should always act > as if '-C --find-copies-harder' was passed. (I also ended up having to manually distribute rebased versions of this patch on new releases, so it's better all-round to do this, I think). Signed-off-by: Sam James <sam@gentoo.org>
Diffstat (limited to 'dev-vcs/git/files/git-2.49.0-diff-implement-config.diff.renames-copies-harder.patch')
-rw-r--r--dev-vcs/git/files/git-2.49.0-diff-implement-config.diff.renames-copies-harder.patch160
1 files changed, 160 insertions, 0 deletions
diff --git a/dev-vcs/git/files/git-2.49.0-diff-implement-config.diff.renames-copies-harder.patch b/dev-vcs/git/files/git-2.49.0-diff-implement-config.diff.renames-copies-harder.patch
new file mode 100644
index 000000000000..27159f71ffa2
--- /dev/null
+++ b/dev-vcs/git/files/git-2.49.0-diff-implement-config.diff.renames-copies-harder.patch
@@ -0,0 +1,160 @@
+https://lore.kernel.org/git/20240311213928.1872437-1-sam@gentoo.org/
+
+From dd8ed5e247032dc94f9b92aaa8be987154f58c27 Mon Sep 17 00:00:00 2001
+Message-ID: <dd8ed5e247032dc94f9b92aaa8be987154f58c27.1741976834.git.sam@gentoo.org>
+From: Sam James <sam@gentoo.org>
+Date: Fri, 16 Feb 2024 22:07:54 +0000
+Subject: [PATCH 1/2] diff: implement config.diff.renames=copies-harder
+
+This patch adds a config value for 'diff.renames' called 'copies-harder'
+which make it so '-C -C' is in effect always passed for 'git log -p',
+'git diff', etc.
+
+This allows specifying that 'git log -p', 'git diff', etc should always act
+as if '-C --find-copies-harder' was passed.
+
+It has proven this especially useful for certain types of repository (like
+Gentoo's ebuild repositories) because files are often copies of a previous
+version:
+
+Suppose a directory 'sys-devel/gcc' contains recipes for building
+GCC, with one file for each supported upstream branch:
+ gcc-13.x.build.recipe
+ gcc-12.x.build.recipe
+ gcc-11.x.build.recipe
+ gcc-10.x.build.recipe
+
+gcc-13.x.build.recipe was started as a copy of gcc-12.x.build.recipe
+(which was started as a copy of gcc-11.x.build.recipe, etc.). Previous versions
+are kept around to support parallel installation of multiple versions.
+
+Being able to easily observe the diff relative to other recipes within the
+directory has been a quality of life improvement for such repo layouts.
+
+Signed-off-by: Sam James <sam@gentoo.org>
+---
+ Documentation/config/status.adoc | 4 +++-
+ diff.c | 11 +++++++++--
+ diff.h | 1 +
+ diffcore-rename.c | 6 ++++--
+ merge-ort.c | 2 +-
+ merge-recursive.c | 2 +-
+ 7 files changed, 22 insertions(+), 10 deletions(-)
+
+diff --git a/Documentation/config/status.adoc b/Documentation/config/status.adoc
+index 8caf90f51c..e15add32a3 100644
+--- a/Documentation/config/status.adoc
++++ b/Documentation/config/status.adoc
+@@ -33,7 +33,9 @@ status.renames::
+ Whether and how Git detects renames in linkgit:git-status[1] and
+ linkgit:git-commit[1] . If set to "false", rename detection is
+ disabled. If set to "true", basic rename detection is enabled.
+- If set to "copies" or "copy", Git will detect copies, as well.
++ If set to "copies" or "copy", Git will detect copies, as well. If set
++ to "copies-harder", Git will spend extra cycles to find more copies even
++ in unmodified paths, see '--find-copies-harder' in linkgit:git-diff[1] (Gentoo patch).
+ Defaults to the value of diff.renames.
+
+ status.showStash::
+diff --git a/diff.c b/diff.c
+index c89c15d98e..743a504f6f 100644
+--- a/diff.c
++++ b/diff.c
+@@ -212,6 +212,8 @@ int git_config_rename(const char *var, const char *value)
+ {
+ if (!value)
+ return DIFF_DETECT_RENAME;
++ if (!strcasecmp(value, "copies-harder"))
++ return DIFF_DETECT_COPY_HARDER;
+ if (!strcasecmp(value, "copies") || !strcasecmp(value, "copy"))
+ return DIFF_DETECT_COPY;
+ return git_config_bool(var,value) ? DIFF_DETECT_RENAME : 0;
+@@ -4900,8 +4902,12 @@ void diff_setup_done(struct diff_options *options)
+ else
+ options->flags.diff_from_contents = 0;
+
+- if (options->flags.find_copies_harder)
++ /* Just fold this in as it makes the patch-to-git smaller */
++ if (options->flags.find_copies_harder ||
++ options->detect_rename == DIFF_DETECT_COPY_HARDER) {
++ options->flags.find_copies_harder = 1;
+ options->detect_rename = DIFF_DETECT_COPY;
++ }
+
+ if (!options->flags.relative_name)
+ options->prefix = NULL;
+@@ -5340,7 +5346,8 @@ static int diff_opt_find_copies(const struct option *opt,
+ if (*arg != 0)
+ return error(_("invalid argument to %s"), opt->long_name);
+
+- if (options->detect_rename == DIFF_DETECT_COPY)
++ if (options->detect_rename == DIFF_DETECT_COPY ||
++ options->detect_rename == DIFF_DETECT_COPY_HARDER)
+ options->flags.find_copies_harder = 1;
+ else
+ options->detect_rename = DIFF_DETECT_COPY;
+diff --git a/diff.h b/diff.h
+index ff0348e4a9..08cb6f587c 100644
+--- a/diff.h
++++ b/diff.h
+@@ -561,6 +561,7 @@ int git_config_rename(const char *var, const char *value);
+
+ #define DIFF_DETECT_RENAME 1
+ #define DIFF_DETECT_COPY 2
++#define DIFF_DETECT_COPY_HARDER 3
+
+ #define DIFF_PICKAXE_ALL 1
+ #define DIFF_PICKAXE_REGEX 2
+diff --git a/diffcore-rename.c b/diffcore-rename.c
+index 91b77993c7..1219882f0d 100644
+--- a/diffcore-rename.c
++++ b/diffcore-rename.c
+@@ -302,7 +302,8 @@ static int find_identical_files(struct hashmap *srcs,
+ }
+ /* Give higher scores to sources that haven't been used already */
+ score = !source->rename_used;
+- if (source->rename_used && options->detect_rename != DIFF_DETECT_COPY)
++ if (source->rename_used && options->detect_rename != DIFF_DETECT_COPY &&
++ options->detect_rename != DIFF_DETECT_COPY_HARDER)
+ continue;
+ score += basename_same(source, target);
+ if (score > best_score) {
+@@ -1407,7 +1408,8 @@ void diffcore_rename_extended(struct diff_options *options,
+ trace2_region_enter("diff", "setup", options->repo);
+ info.setup = 0;
+ assert(!dir_rename_count || strmap_empty(dir_rename_count));
+- want_copies = (detect_rename == DIFF_DETECT_COPY);
++ want_copies = (detect_rename == DIFF_DETECT_COPY ||
++ detect_rename == DIFF_DETECT_COPY_HARDER);
+ if (dirs_removed && (break_idx || want_copies))
+ BUG("dirs_removed incompatible with break/copy detection");
+ if (break_idx && relevant_sources)
+diff --git a/merge-ort.c b/merge-ort.c
+index 46e78c3ffa..94699789bd 100644
+--- a/merge-ort.c
++++ b/merge-ort.c
+@@ -4921,7 +4921,7 @@ static void merge_start(struct merge_options *opt, struct merge_result *result)
+ * sanity check them anyway.
+ */
+ assert(opt->detect_renames >= -1 &&
+- opt->detect_renames <= DIFF_DETECT_COPY);
++ opt->detect_renames <= DIFF_DETECT_COPY_HARDER);
+ assert(opt->verbosity >= 0 && opt->verbosity <= 5);
+ assert(opt->buffer_output <= 2);
+ assert(opt->obuf.len == 0);
+diff --git a/merge-recursive.c b/merge-recursive.c
+index 884ccf99a5..b979d43b85 100644
+--- a/merge-recursive.c
++++ b/merge-recursive.c
+@@ -3771,7 +3771,7 @@ static int merge_start(struct merge_options *opt, struct tree *head)
+ assert(opt->branch1 && opt->branch2);
+
+ assert(opt->detect_renames >= -1 &&
+- opt->detect_renames <= DIFF_DETECT_COPY);
++ opt->detect_renames <= DIFF_DETECT_COPY_HARDER);
+ assert(opt->detect_directory_renames >= MERGE_DIRECTORY_RENAMES_NONE &&
+ opt->detect_directory_renames <= MERGE_DIRECTORY_RENAMES_TRUE);
+ assert(opt->rename_limit >= -1);
+--
+2.48.1
+