From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id EBB7115802E for ; Sun, 30 Jun 2024 17:38:26 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id CE465E2A2B; Sun, 30 Jun 2024 17:38:21 +0000 (UTC) Received: from smtp.gentoo.org (woodpecker.gentoo.org [140.211.166.183]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 6CE6AE29AE for ; Sun, 30 Jun 2024 17:38:21 +0000 (UTC) From: Sam James To: gentoo-dev@lists.gentoo.org Subject: [gentoo-dev] Reviewing ebuilds with git Organization: Gentoo Date: Sun, 30 Jun 2024 18:38:15 +0100 Message-ID: <87r0cepbzs.fsf@gentoo.org> Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-dev@lists.gentoo.org Reply-to: gentoo-dev@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply MIME-Version: 1.0 Content-Type: multipart/signed; boundary="==-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Archives-Salt: e9700f35-2b6a-437e-8239-d4794db01ea1 X-Archives-Hash: f78414bf5408cc78ae35c9b3c83c82a5 --==-=-= Content-Type: multipart/mixed; boundary="=-=-=" --=-=-= Content-Type: text/plain Hi, I've mentioned this on IRC a bunch of times to people but I figure I'll mention it here in case anyone finds it useful. Our use of git doesn't lend itself well to the default mode `git diff` and friends operate in, as we create many new files rather than solely changing existing ones. git can be coerced into checking for copies (and doing so "harder" too) but there's no configuration option for this, and it's a pain to remember. You can use the attached patch for dev-vcs/git and then set: $ git config diff.renames copies-harder in gentoo.git to make `git log -p`, `git diff`, etc default to this mode. IME, it makes reviewing much easier. Be warned that it does make git log a bit slower though if the config option is enabled for a repo -- but maybe only noticeably if your repo is grafted with the pre-2015 CVS history. --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-diff-implement-config.diff.renames-copies-harder.patch Content-Transfer-Encoding: quoted-printable Content-Description: copies harder patch https://lore.kernel.org/git/20240311213928.1872437-1-sam@gentoo.org From=202b9b8903fcc3815415f0d22a4646794757fc001a Mon Sep 17 00:00:00 2001 From: Sam James Date: Fri, 16 Feb 2024 22:07:54 +0000 Subject: [PATCH 1/2] diff: implement config.diff.renames=3Dcopies-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 vers= ions 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 =2D-- Documentation/config/diff.txt | 8 +++++--- Documentation/config/status.txt | 4 +++- diff.c | 11 +++++++++-- diff.h | 1 + diffcore-rename.c | 6 ++++-- merge-ort.c | 2 +- merge-recursive.c | 2 +- 7 files changed, 24 insertions(+), 10 deletions(-) diff --git a/Documentation/config/diff.txt b/Documentation/config/diff.txt index bd5ae0c337..cdd8a74ec0 100644 =2D-- a/Documentation/config/diff.txt +++ b/Documentation/config/diff.txt @@ -131,9 +131,11 @@ diff.renames:: Whether and how Git detects renames. 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 =2D detect copies, as well. Defaults to true. Note that this =2D affects only 'git diff' Porcelain like linkgit:git-diff[1] and =2D linkgit:git-log[1], and not lower level commands such as + 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]. Defaults to true. + Note that this affects only 'git diff' Porcelain like linkgit:git-diff[1] + and linkgit:git-log[1], and not lower level commands such as linkgit:git-diff-files[1]. =20 diff.suppressBlankEmpty:: diff --git a/Documentation/config/status.txt b/Documentation/config/status.= txt index 2ff8237f8f..5236088878 100644 =2D-- a/Documentation/config/status.txt +++ b/Documentation/config/status.txt @@ -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. =2D 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]. Defaults to the value of diff.renames. =20 status.showStash:: diff --git a/diff.c b/diff.c index e50def4538..a6433dec30 100644 =2D-- a/diff.c +++ b/diff.c @@ -204,6 +204,8 @@ int git_config_rename(const char *var, const char *valu= e) { 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; @@ -4848,8 +4850,12 @@ void diff_setup_done(struct diff_options *options) else options->flags.diff_from_contents =3D 0; =20 =2D 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 =3D=3D DIFF_DETECT_COPY_HARDER) { + options->flags.find_copies_harder =3D 1; options->detect_rename =3D DIFF_DETECT_COPY; + } =20 if (!options->flags.relative_name) options->prefix =3D NULL; @@ -5280,7 +5286,8 @@ static int diff_opt_find_copies(const struct option *= opt, if (*arg !=3D 0) return error(_("invalid argument to %s"), opt->long_name); =20 =2D if (options->detect_rename =3D=3D DIFF_DETECT_COPY) + if (options->detect_rename =3D=3D DIFF_DETECT_COPY || + options->detect_rename =3D=3D DIFF_DETECT_COPY_HARDER) options->flags.find_copies_harder =3D 1; else options->detect_rename =3D DIFF_DETECT_COPY; diff --git a/diff.h b/diff.h index 66bd8aeb29..b29e5b777f 100644 =2D-- a/diff.h +++ b/diff.h @@ -555,6 +555,7 @@ int git_config_rename(const char *var, const char *valu= e); =20 #define DIFF_DETECT_RENAME 1 #define DIFF_DETECT_COPY 2 +#define DIFF_DETECT_COPY_HARDER 3 =20 #define DIFF_PICKAXE_ALL 1 #define DIFF_PICKAXE_REGEX 2 diff --git a/diffcore-rename.c b/diffcore-rename.c index 5a6e2bcac7..d54078de7d 100644 =2D-- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -299,7 +299,8 @@ static int find_identical_files(struct hashmap *srcs, } /* Give higher scores to sources that haven't been used already */ score =3D !source->rename_used; =2D if (source->rename_used && options->detect_rename !=3D DIFF_DETECT_COP= Y) + if (source->rename_used && options->detect_rename !=3D DIFF_DETECT_COPY = && + options->detect_rename !=3D DIFF_DETECT_COPY_HARDER) continue; score +=3D basename_same(source, target); if (score > best_score) { @@ -1405,7 +1406,8 @@ void diffcore_rename_extended(struct diff_options *op= tions, trace2_region_enter("diff", "setup", options->repo); info.setup =3D 0; assert(!dir_rename_count || strmap_empty(dir_rename_count)); =2D want_copies =3D (detect_rename =3D=3D DIFF_DETECT_COPY); + want_copies =3D (detect_rename =3D=3D DIFF_DETECT_COPY || + detect_rename =3D=3D 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 8617babee4..2572c6fa1b 100644 =2D-- a/merge-ort.c +++ b/merge-ort.c @@ -4784,7 +4784,7 @@ static void merge_start(struct merge_options *opt, st= ruct merge_result *result) * sanity check them anyway. */ assert(opt->detect_renames >=3D -1 && =2D opt->detect_renames <=3D DIFF_DETECT_COPY); + opt->detect_renames <=3D DIFF_DETECT_COPY_HARDER); assert(opt->verbosity >=3D 0 && opt->verbosity <=3D 5); assert(opt->buffer_output <=3D 2); assert(opt->obuf.len =3D=3D 0); diff --git a/merge-recursive.c b/merge-recursive.c index a0c3e7a2d9..f8c003a4e6 100644 =2D-- a/merge-recursive.c +++ b/merge-recursive.c @@ -3703,7 +3703,7 @@ static int merge_start(struct merge_options *opt, str= uct tree *head) assert(opt->branch1 && opt->branch2); =20 assert(opt->detect_renames >=3D -1 && =2D opt->detect_renames <=3D DIFF_DETECT_COPY); + opt->detect_renames <=3D DIFF_DETECT_COPY_HARDER); assert(opt->detect_directory_renames >=3D MERGE_DIRECTORY_RENAMES_NONE && opt->detect_directory_renames <=3D MERGE_DIRECTORY_RENAMES_TRUE); assert(opt->rename_limit >=3D -1); =2D-=20 2.43.2 --=-=-= Content-Type: text/plain thanks, sam --=-=-=-- --==-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iOUEARYKAI0WIQQlpruI3Zt2TGtVQcJzhAn1IN+RkAUCZoGYCF8UgAAAAAAuAChp c3N1ZXItZnByQG5vdGF0aW9ucy5vcGVucGdwLmZpZnRoaG9yc2VtYW4ubmV0MjVB NkJCODhERDlCNzY0QzZCNTU0MUMyNzM4NDA5RjUyMERGOTE5MA8cc2FtQGdlbnRv by5vcmcACgkQc4QJ9SDfkZB/3wD+KG7Z6o7/PbuqMSrx1/IorXLNuHRrKNtWH0iV PXEHMmQBAIoNhvV0I+Q6dTd4UAGByxG+qXx1qdV2IdoEfRyl+ykO =GF/m -----END PGP SIGNATURE----- --==-=-=--