Git development
 help / color / mirror / Atom feed
* [PATCH v3] SubmittingPatches: address design critiques
From: Junio C Hamano @ 2026-06-19 16:17 UTC (permalink / raw)
  To: git; +Cc: Michael Montalbo, Kristoffer Haugsbakk
In-Reply-To: <xmqqpl1oteoi.fsf@gitster.g>

Contributors sometimes fail to answer fundamental design or
viability comments from reviewers and submit subsequent rounds
without addressing them.  When design decisions are resolved on the
mailing list, the final justification should be recorded in the
commit messages.

Instruct authors to be particularly mindful of critiques regarding
high-level design or viability, to defend their choices on the list,
and to accompany new iterations with clearer explanations in the cover
letter, responses, and revised commit messages. Also instruct them to
explicitly document the resolution of these concerns in the commit
message body to keep the historical record complete.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---

 * Updated a bit after reading comments by Kichael and Kristoffer

 Documentation/SubmittingPatches | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index f042bb5aaf..a9789e5303 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -51,6 +51,21 @@ area.
   respond to them with "Reply-All" on the mailing list, while taking
   them into account while preparing an updated set of patches.
 +
+Be particularly mindful of critiques regarding the high-level design
+or viability of your proposal (e.g., questioning if the feature is
+worth implementing, or if the chosen approach is appropriate).  Defend
+your design decisions on the list first, work with reviewers and other
+members to improve the design before revising the implementation, to
+avoid wasting effort on an implementation before its design is solid.
++
+Make sure that any new version explains and justifies those design
+decisions more clearly, in the cover letter and in the revised commit
+messages.  Aim to make the reviewers say "it is now clear why we may
+want to do this with the updated version".
++
+Topics with unresolved fundamental design critiques will not be
+considered ready for merging.
++
 It is often beneficial to allow some time for reviewers to provide
 feedback before sending a new version, rather than sending an updated
 series immediately after receiving a review. This helps collect broader
@@ -323,6 +338,10 @@ The body should provide a meaningful commit message, which:
 
 . alternate solutions considered but discarded, if any.
 
+. records the resolution of design or viability concerns raised by the
+  community during the review, if any, ensuring the historical record
+  explains why the chosen approach was accepted over alternatives.
+
 [[present-tense]]
 The problem statement that describes the status quo is written in the
 present tense.  Write "The code does X when it is given input Y",
-- 
2.55.0-rc1-129-gff98d784de


^ permalink raw reply related

* [PATCH v4 0/3] environment: migrate 'trust_executable_bit' into 'repo_config_values'
From: Tian Yuchen @ 2026-06-19 16:21 UTC (permalink / raw)
  To: git; +Cc: ps, Tian Yuchen, Christian Couder, Ayush Chandekar,
	Olamide Caleb Bello
In-Reply-To: <20260612160527.167203-1-cat@malon.dev>

The 'core.filemode' (stored as 'trust_executable_bit') configuration
act as a core filesystem capability flag.

This series moves it into 'struct repo_config_values' to tie it to
the specific repository instance it was read from. Eager parsing
is maintained because this flag is heavily consulted in hot paths.

Note: 'repo_config_values()' still does not support any struct
repository other than the_repository due to how deeply these flags
are accessed. In other words, this series of patches is laying
the groundwork for the eventual elimination of the_repository.

Previous related work:
[PATCH 2/6] config: add trust_executable_bit to global config [1]
[PATCH] Refactor 'trust_executable_bit' to repository-scoped setting [2]
(This previous attempt was unsuccessful because the target location
selected was 'struct repo_settings', which our analysis indicated
was not the optimal choice. For further details, please see: [3])

Change since V3:

 - In repo_trust_executable_bit(), change repo->gitdir to using
 (repo && repo->initialized).

Thanks!

[1] https://lore.kernel.org/git/837b5360b40f992351f489a0ae05fedf49884c6e.1685716420.git.gitgitgadget@gmail.com/
[2] https://lore.kernel.org/git/20260301190017.53539-1-dronarajgyawali@gmail.com/
[3] https://lore.kernel.org/git/xmqq1pht6nyx.fsf@gitster.g/

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Ayush Chandekar <ayu.chandekar@gmail.com>
Mentored-by: Olamide Caleb Bello <belkid98@gmail.com>
Signed-off-by: Tian Yuchen <cat@malon.dev>

Tian Yuchen (3):
  read-cache: remove redundant extern declarations
  read-cache: move 'ce_mode_from_stat()' to 'read-cache.c'
  environment: move trust_executable_bit into repo_config_values

 apply.c       |  2 +-
 environment.c | 11 +++++++++--
 environment.h |  9 ++++++++-
 read-cache.c  | 21 ++++++++++++++++-----
 read-cache.h  | 23 +++++++++--------------
 5 files changed, 43 insertions(+), 23 deletions(-)

-- 
2.43.0


^ permalink raw reply

* [PATCH v4 1/3] read-cache: remove redundant extern declarations
From: Tian Yuchen @ 2026-06-19 16:21 UTC (permalink / raw)
  To: git; +Cc: ps, Tian Yuchen, Christian Couder, Ayush Chandekar,
	Olamide Caleb Bello
In-Reply-To: <20260619162105.648495-1-cat@malon.dev>

The 'read-cache.c' file already includes 'environment.h', which provides
the extern declarations for variables like 'trust_executable_bit' and
'has_symlinks'.

Remove the redundant extern declarations inside 'st_mode_from_ce()' to
clean up the code.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Ayush Chandekar <ayu.chandekar@gmail.com>
Mentored-by: Olamide Caleb Bello <belkid98@gmail.com>
Signed-off-by: Tian Yuchen <cat@malon.dev>
---
 read-cache.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/read-cache.c b/read-cache.c
index 38a04b8de3..c44e4d128f 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -204,8 +204,6 @@ void fill_stat_cache_info(struct index_state *istate, struct cache_entry *ce, st
 
 static unsigned int st_mode_from_ce(const struct cache_entry *ce)
 {
-	extern int trust_executable_bit, has_symlinks;
-
 	switch (ce->ce_mode & S_IFMT) {
 	case S_IFLNK:
 		return has_symlinks ? S_IFLNK : (S_IFREG | 0644);
-- 
2.43.0


^ permalink raw reply related

* [PATCH v4 2/3] read-cache: move 'ce_mode_from_stat()' to 'read-cache.c'
From: Tian Yuchen @ 2026-06-19 16:21 UTC (permalink / raw)
  To: git; +Cc: ps, Tian Yuchen, Christian Couder, Ayush Chandekar,
	Olamide Caleb Bello
In-Reply-To: <20260619162105.648495-1-cat@malon.dev>

The ce_mode_from_stat() function is declared as a static inline function
in 'read-cache.h'. As we want to migrate configuration variables, this
helper function will need access to corresponding repository-specific
configuration logic. Move the implementation to 'read-cache.c' to
cleanly encapsulate its dependencies.

Note that the 'extern int trust_executable_bit, has_symlinks;' line is
discarded because it's not necessary when the function lives in
"read-cache.c".

At present, this change has no visible impact, but it is crucial
for our future plans to pass in the repo context. Comment
has been added whilst we are at it.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Ayush Chandekar <ayu.chandekar@gmail.com>
Mentored-by: Olamide Caleb Bello <belkid98@gmail.com>
Signed-off-by: Tian Yuchen <cat@malon.dev>
---
 read-cache.c | 13 +++++++++++++
 read-cache.h | 23 +++++++++--------------
 2 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/read-cache.c b/read-cache.c
index c44e4d128f..54150fe756 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -202,6 +202,19 @@ void fill_stat_cache_info(struct index_state *istate, struct cache_entry *ce, st
 	}
 }
 
+unsigned int ce_mode_from_stat(const struct cache_entry *ce, unsigned int mode)
+{
+	if (!has_symlinks && S_ISREG(mode) &&
+	    ce && S_ISLNK(ce->ce_mode))
+		return ce->ce_mode;
+	if (!trust_executable_bit && S_ISREG(mode)) {
+		if (ce && S_ISREG(ce->ce_mode))
+			return ce->ce_mode;
+		return create_ce_mode(0666);
+	}
+	return create_ce_mode(mode);
+}
+
 static unsigned int st_mode_from_ce(const struct cache_entry *ce)
 {
 	switch (ce->ce_mode & S_IFMT) {
diff --git a/read-cache.h b/read-cache.h
index 043da1f1aa..9088a0724a 100644
--- a/read-cache.h
+++ b/read-cache.h
@@ -5,20 +5,15 @@
 #include "object.h"
 #include "pathspec.h"
 
-static inline unsigned int ce_mode_from_stat(const struct cache_entry *ce,
-					     unsigned int mode)
-{
-	extern int trust_executable_bit, has_symlinks;
-	if (!has_symlinks && S_ISREG(mode) &&
-	    ce && S_ISLNK(ce->ce_mode))
-		return ce->ce_mode;
-	if (!trust_executable_bit && S_ISREG(mode)) {
-		if (ce && S_ISREG(ce->ce_mode))
-			return ce->ce_mode;
-		return create_ce_mode(0666);
-	}
-	return create_ce_mode(mode);
-}
+/*
+ * Determine the appropriate index mode for a file based on its stat()
+ * information and the existing cache entry (if any).
+ *
+ * This function handles degradation for filesystems that lack
+ * symlink support or reliable executable bits.
+ */
+unsigned int ce_mode_from_stat(const struct cache_entry *ce,
+				unsigned int mode);
 
 static inline int ce_to_dtype(const struct cache_entry *ce)
 {
-- 
2.43.0


^ permalink raw reply related

* [PATCH v4 3/3] environment: move trust_executable_bit into repo_config_values
From: Tian Yuchen @ 2026-06-19 16:21 UTC (permalink / raw)
  To: git; +Cc: ps, Tian Yuchen, Christian Couder, Ayush Chandekar,
	Olamide Caleb Bello
In-Reply-To: <20260619162105.648495-1-cat@malon.dev>

Move the global 'trust_executable_bit' configuration
into the repository-specific 'repo_config_values'
struct. To ensure code readability, the getter function
'repo_trust_executable_bit()' has been introduced.

For now, associated functions access this configuration by
explicitly falling back to 'the_repository'.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Ayush Chandekar <ayu.chandekar@gmail.com>
Mentored-by: Olamide Caleb Bello <belkid98@gmail.com>
Signed-off-by: Tian Yuchen <cat@malon.dev>
---
 apply.c       |  2 +-
 environment.c | 11 +++++++++--
 environment.h |  9 ++++++++-
 read-cache.c  |  8 ++++----
 4 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/apply.c b/apply.c
index 249248d4f2..fbb907d3c0 100644
--- a/apply.c
+++ b/apply.c
@@ -3893,7 +3893,7 @@ static int check_preimage(struct apply_state *state,
 		if (*ce && !(*ce)->ce_mode)
 			BUG("ce_mode == 0 for path '%s'", old_name);
 
-		if (trust_executable_bit || !S_ISREG(st->st_mode))
+		if (repo_trust_executable_bit(the_repository) || !S_ISREG(st->st_mode))
 			st_mode = ce_mode_from_stat(*ce, st->st_mode);
 		else if (*ce)
 			st_mode = (*ce)->ce_mode;
diff --git a/environment.c b/environment.c
index fc3ed8bb1c..348053146e 100644
--- a/environment.c
+++ b/environment.c
@@ -41,7 +41,6 @@
 static int pack_compression_seen;
 static int zlib_compression_seen;
 
-int trust_executable_bit = 1;
 int trust_ctime = 1;
 int check_stat = 1;
 int has_symlinks = 1;
@@ -142,6 +141,13 @@ int is_bare_repository(void)
 	return is_bare_repository_cfg && !repo_get_work_tree(the_repository);
 }
 
+int repo_trust_executable_bit(struct repository *repo)
+{
+	return (repo && repo->initialized) ?
+		repo_config_values(repo)->trust_executable_bit :
+		1;
+}
+
 int have_git_dir(void)
 {
 	return startup_info->have_repository
@@ -305,7 +311,7 @@ int git_default_core_config(const char *var, const char *value,
 
 	/* This needs a better name */
 	if (!strcmp(var, "core.filemode")) {
-		trust_executable_bit = git_config_bool(var, value);
+		cfg->trust_executable_bit = git_config_bool(var, value);
 		return 0;
 	}
 	if (!strcmp(var, "core.trustctime")) {
@@ -720,5 +726,6 @@ void repo_config_values_init(struct repo_config_values *cfg)
 {
 	cfg->attributes_file = NULL;
 	cfg->apply_sparse_checkout = 0;
+	cfg->trust_executable_bit = 1;
 	cfg->branch_track = BRANCH_TRACK_REMOTE;
 }
diff --git a/environment.h b/environment.h
index 123a71cdc8..6607ac9408 100644
--- a/environment.h
+++ b/environment.h
@@ -91,6 +91,7 @@ struct repo_config_values {
 	/* section "core" config values */
 	char *attributes_file;
 	int apply_sparse_checkout;
+	int trust_executable_bit;
 
 	/* section "branch" config values */
 	enum branch_track branch_track;
@@ -123,6 +124,13 @@ int git_default_config(const char *, const char *,
 int git_default_core_config(const char *var, const char *value,
 			    const struct config_context *ctx, void *cb);
 
+/*
+ * Getter for the `trust_executable_bit` field of `struct repo_config_values`.
+ * It checks `repo->initialized` to prevent calling repo_config_values()`
+ * before the repository setup is fully complete or in non-git environments.
+ */
+int repo_trust_executable_bit(struct repository *repo);
+
 void repo_config_values_init(struct repo_config_values *cfg);
 
 /*
@@ -160,7 +168,6 @@ int is_bare_repository(void);
 extern char *git_work_tree_cfg;
 
 /* Environment bits from configuration mechanism */
-extern int trust_executable_bit;
 extern int trust_ctime;
 extern int check_stat;
 extern int has_symlinks;
diff --git a/read-cache.c b/read-cache.c
index 54150fe756..757249a449 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -207,7 +207,7 @@ unsigned int ce_mode_from_stat(const struct cache_entry *ce, unsigned int mode)
 	if (!has_symlinks && S_ISREG(mode) &&
 	    ce && S_ISLNK(ce->ce_mode))
 		return ce->ce_mode;
-	if (!trust_executable_bit && S_ISREG(mode)) {
+	if (!repo_trust_executable_bit(the_repository) && S_ISREG(mode)) {
 		if (ce && S_ISREG(ce->ce_mode))
 			return ce->ce_mode;
 		return create_ce_mode(0666);
@@ -221,7 +221,7 @@ static unsigned int st_mode_from_ce(const struct cache_entry *ce)
 	case S_IFLNK:
 		return has_symlinks ? S_IFLNK : (S_IFREG | 0644);
 	case S_IFREG:
-		return (ce->ce_mode & (trust_executable_bit ? 0755 : 0644)) | S_IFREG;
+		return (ce->ce_mode & (repo_trust_executable_bit(the_repository) ? 0755 : 0644)) | S_IFREG;
 	case S_IFGITLINK:
 		return S_IFDIR | 0755;
 	case S_IFDIR:
@@ -331,7 +331,7 @@ static int ce_match_stat_basic(const struct cache_entry *ce, struct stat *st)
 		/* We consider only the owner x bit to be relevant for
 		 * "mode changes"
 		 */
-		if (trust_executable_bit &&
+		if (repo_trust_executable_bit(the_repository) &&
 		    (0100 & (ce->ce_mode ^ st->st_mode)))
 			changed |= MODE_CHANGED;
 		break;
@@ -752,7 +752,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
 		ce->ce_flags |= CE_INTENT_TO_ADD;
 
 
-	if (trust_executable_bit && has_symlinks) {
+	if (repo_trust_executable_bit(the_repository) && has_symlinks) {
 		ce->ce_mode = create_ce_mode(st_mode);
 	} else {
 		/* If there is an existing entry, pick the mode bits and type
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH] help: prompt user to run corrected command on typo
From: Justin Tobler @ 2026-06-19 16:24 UTC (permalink / raw)
  To: Jishnu C K; +Cc: git, gitster
In-Reply-To: <6a34dc40.2c570c9e.381c97.203f@mx.google.com>

On 26/06/18 11:05PM, Jishnu C K wrote:
> If the consensus is that the default should remain non-interactive,
> we are happy to rework this as an improvement to the existing
> `autocorrect=prompt` mode (showing args in the prompt) with
> documentation updates to make the option more discoverable.

I'm not sure what the current consensus is here, but as it would be a
change to the existing behavior it would need its merits discussed
accordingly. Personally, I think requiring users to opt-in to
autocorrect isn't a significant barrier itself. It does require that
users know that the option is available in the first place though. So if
discoverablility of this feature is lacking and can be improved in
documentation, that certainly seems like a reasonable change. 

Regarding changing the prompt to display command arguments, I'm
relatively indifferent towards it. I'm not sure it adds a ton of value,
but maybe other folks will have a different opinion.

-Justin

^ permalink raw reply

* Re: Pinned references?
From: Junio C Hamano @ 2026-06-19 16:25 UTC (permalink / raw)
  To: Patrick Steinhardt; +Cc: Erik Östlund, git
In-Reply-To: <ajTx9vLIWK5wvTHM@pks.im>

Patrick Steinhardt <ps@pks.im> writes:

> You can already kind of do this:
>
>     $ git rev-parse v2.54.0
>     0b13e48a3a30cdfa94e8ef842e24d6045ab3d015
>
>     $ git rev-parse v2.54.0-0-g0b13e48a3
>     0b13e48a3a30cdfa94e8ef842e24d6045ab3d015
>
>     $ git rev-parse v2.54.0-0-g95e20213f
>     95e20213faefeb95df29277c58ac1980ab68f701
>
> This is described under gitrevisions(7), `<describeOutput>`. The only
> gotcha is that this format will not verify that the tag and the object
> ID actually match. But other than that it gives you the ability to have
> both the human-readable name and the machine-readable commit ID in
> there.
>
> As said, we don't verify that those two revisions actually match. So in
> the case where they don't the result is certainly going to be lots of
> confusion. It certainly is one of the more surprising syntaxes that we
> have in Git.

It is very unlikely we would change this, but it is a fun thought
experiment to imagine what would have happened if we insisted (i.e.,
verified and then died if it does not hold true) on the presence of
v2.54.0 tag and when the "hop" count is "-0-", we also insisted that
the hexadecimal part exactly matched the contents of v2.54.0 tag, or
when the "hop" count is not zero, we insisted that the hexadecimal
part names a commit that is descendant of the commit v2.54.0 names.


^ permalink raw reply

* Re: [PATCH] t4216: fix no-op test that breaks TAP output
From: Junio C Hamano @ 2026-06-19 16:29 UTC (permalink / raw)
  To: Taylor Blau; +Cc: Patrick Steinhardt, git, Todd Zullinger, Jeff King
In-Reply-To: <ajVMZpjTKiXc7TRe@nand.local>

Taylor Blau <me@ttaylorr.com> writes:

> Given this and the above, I would probably err on the side of
> designating this as 'test_lazy_prereq' or otherwise silencing the output
> of 'test_cmp' so that this does not taint the TAP output.

We can argue the merit and demerit with a good log message.  The
central issue at hand is how precious 52a9 in the script lost by
this patch is (in other words, are we checking more than "is our
char signed or unsigned?").

By the way, I do not quite get the _BY_DEFAULT in the name
SIGNED_CHAR_BY_DEFAULT.  The builder may have configured to use
signed char on a platform that can handle both and their char is by
default unsigned, and under such a condition, we would set this
prerequisite, even though the default on such a platform is
unsigned, no?

^ permalink raw reply

* Bug: Checkout in sparse mode can overwrite uncommited files
From: charmocc @ 2026-06-19 16:31 UTC (permalink / raw)
  To: git@vger.kernel.org


Hey. Today I discovered inconsistent behavior in sparse mode that may lead to data loss during initial checkout. Please have a look.

What did you do before the bug happened? (Steps to reproduce your issue)

$ git init foo
$ cd foo
$ echo 1 > file
$ git add file
$ git commit -m 'test'
$ cd ..

$ git clone --no-checkout foo bar
$ cd bar
$ echo 2 > file
$ git checkout
error: The following untracked working tree files would be overwritten by checkout:
	file
Please move or remove them before you switch branches.
Aborting
$ cat file
2
$ git sparse-checkout set
$ git checkout
warning: The following paths were already present and thus not updated despite sparse patterns:
	file

After fixing the above paths, you may want to run `git sparse-checkout reapply`.
Your branch is up to date with 'origin/master'.
$ cat file
1

What did you expect to happen? (Expected behavior)

Checkout should fail due to uncommited changes

What happened instead? (Actual behavior)

After enabling sparse mode checkout overwrites file in working directory

What's different between what you expected and what actually happened?

In normal mode checkout is aborted correctly but in sparse it overwrites data and gives misleading message

Anything else you want to add:

[System Info]
git version:
git version 2.53.0
cpu: x86_64
no commit associated with this build
sizeof-long: 8
sizeof-size_t: 8
shell-path: /bin/sh
rust: disabled
gettext: enabled
libcurl: 8.18.0
zlib: 1.3.1
SHA-1: SHA1_DC
SHA-256: SHA256_BLK
default-ref-format: files
default-hash: sha1
uname: Linux 7.0.0-22-generic #22-Ubuntu SMP PREEMPT_DYNAMIC Mon May 25 15:54:34 UTC 2026 x86_64
compiler info: gnuc: 15.2
libc info: glibc: 2.43
$SHELL (typically, interactive shell): /bin/bash


[Enabled Hooks]


^ permalink raw reply

* Re: [PATCH] help: prompt user to run corrected command on typo
From: Junio C Hamano @ 2026-06-19 16:37 UTC (permalink / raw)
  To: Jishnu C K; +Cc: Justin Tobler, git
In-Reply-To: <6a34dc40.2c570c9e.381c97.203f@mx.google.com>

Jishnu C K <jishnuck26@gmail.com> writes:

> You're right that `help.autocorrect=prompt` exists and is similar.
> Our change differs in two ways:
>
> 1. No configuration needed. The existing prompt mode requires the user

I do not particularly see it as an advantage.

> 2. The prompt includes the original arguments. `help.autocorrect=prompt`
>    shows only:
>
>      Run 'checkout' instead [y/N]?
>
>    Our prompt shows the full corrected invocation:
>
>      Did you mean 'git checkout neo'? [y/N]
>
>    This lets the user confirm exactly what will run, including their
>    original arguments, before pressing 'y'.

This may be an improvement, but is there a reason why such a change
must be done as a parallel and unrelated (re)implementation and not
as an incrementa improvement to the code that implements the
existing feature?




^ permalink raw reply

* [PATCH v4 0/1] environment: move protect_hfs and protect_ntfs into repo_config_values
From: Tian Yuchen @ 2026-06-19 16:38 UTC (permalink / raw)
  To: git; +Cc: Tian Yuchen, Christian Couder, Ayush Chandekar,
	Olamide Caleb Bello

Hi everyone,

This series continues the ongoing libification effort by moving the
global filesystem variables, 'protect_hfs' and 'protect_ntfs', into
'struct repo_config_values'.

Place them within the per-repository configuration structure
aligns with our goal of removing global states.

For reviewers familiar with previous libification efforts, Derrick Stolee
attempted to wrap this kind of filesystem-level variable using a
lazy-loaded global accessor get_int_config_global() [1].

However, as Glen Choo pointed out in his review of that series [2],
it is strongly preferred to use plain fields in a repository-scoped
struct over global lazy-loaders, provided those fields are properly
initialized during the setup process.

By moving these variables into repo_config_values and parsing
them eagerly, we successfully tie the filesystem security flags
to the specific repository instance without altering the timing
of configuration warnings or introducing new global states.

Thanks!

Change since V3:

 - In repo_protect_hfs() and repo_protect_ntfs(), change repo->gitdir to
 using (repo && repo->initialized).

[1] https://lore.kernel.org/git/a42dd9397d07b2dc4a0d7e75bfe1af2e46cad262.1685716420.git.gitgitgadget@gmail.com/
[2] https://lore.kernel.org/git/kl6lbkhpzujf.fsf@chooglen-macbookpro.roam.corp.google.com/
[3] https://lore.kernel.org/git/20260612160527.167203-1-cat@malon.dev/

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Ayush Chandekar <ayu.chandekar@gmail.com>
Mentored-by: Olamide Caleb Bello <belkid98@gmail.com>
Signed-off-by: Tian Yuchen <cat@malon.dev>

Tian Yuchen (1):
  environment: move 'protect_hfs' and 'protect_ntfs' into
    'repo_config_values'

 compat/mingw.c             |  2 +-
 environment.c              | 22 ++++++++++++++++++----
 environment.h              | 12 ++++++++++--
 read-cache.c               |  7 ++++---
 t/helper/test-path-utils.c | 24 +++++++++++++++---------
 5 files changed, 48 insertions(+), 19 deletions(-)

-- 
2.43.0


^ permalink raw reply

* [PATCH v4 1/1] environment: move 'protect_hfs' and 'protect_ntfs' into 'repo_config_values'
From: Tian Yuchen @ 2026-06-19 16:38 UTC (permalink / raw)
  To: git; +Cc: Tian Yuchen, Christian Couder, Ayush Chandekar,
	Olamide Caleb Bello
In-Reply-To: <20260619163823.652091-1-cat@malon.dev>

Move the global 'protect_hfs' and 'protect_ntfs' configurations
into the repository-specific 'repo_config_values' struct.
This will help with the elimination of 'the_repository'

To ensure code readability, the getter functions
'repo_protect_hfs()' and 'repo_protect_ntfs()'
have been introduced.

For now, associated functions access this configuration by
explicitly falling back to 'the_repository', which needs to
be addressed in the future.

Note: In 't/helper/test-path-utils.c', there is a function
'protect_ntfs_hfs_benchmark()' where these two global
variables are used as loop iterators. New local variables
have been created to replace them.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Ayush Chandekar <ayu.chandekar@gmail.com>
Mentored-by: Olamide Caleb Bello <belkid98@gmail.com>
Signed-off-by: Tian Yuchen <cat@malon.dev>
---
 compat/mingw.c             |  2 +-
 environment.c              | 22 ++++++++++++++++++----
 environment.h              | 12 ++++++++++--
 read-cache.c               |  7 ++++---
 t/helper/test-path-utils.c | 24 +++++++++++++++---------
 5 files changed, 48 insertions(+), 19 deletions(-)

diff --git a/compat/mingw.c b/compat/mingw.c
index aa7525f419..af87df77fd 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -3392,7 +3392,7 @@ int is_valid_win32_path(const char *path, int allow_literal_nul)
 	const char *p = path;
 	int preceding_space_or_period = 0, i = 0, periods = 0;
 
-	if (!protect_ntfs)
+	if (!repo_protect_ntfs(the_repository))
 		return 1;
 
 	skip_dos_drive_prefix((char **)&path);
diff --git a/environment.c b/environment.c
index fc3ed8bb1c..f34f6fc750 100644
--- a/environment.c
+++ b/environment.c
@@ -82,12 +82,10 @@ unsigned long pack_size_limit_cfg;
 #ifndef PROTECT_HFS_DEFAULT
 #define PROTECT_HFS_DEFAULT 0
 #endif
-int protect_hfs = PROTECT_HFS_DEFAULT;
 
 #ifndef PROTECT_NTFS_DEFAULT
 #define PROTECT_NTFS_DEFAULT 1
 #endif
-int protect_ntfs = PROTECT_NTFS_DEFAULT;
 
 /*
  * The character that begins a commented line in user-editable file
@@ -142,6 +140,20 @@ int is_bare_repository(void)
 	return is_bare_repository_cfg && !repo_get_work_tree(the_repository);
 }
 
+int repo_protect_ntfs(struct repository *repo)
+{
+	return (repo && repo->initialized) ?
+		repo_config_values(repo)->protect_ntfs :
+		PROTECT_NTFS_DEFAULT;
+}
+
+int repo_protect_hfs(struct repository *repo)
+{
+	return (repo && repo->initialized) ?
+		repo_config_values(repo)->protect_hfs :
+		PROTECT_HFS_DEFAULT;
+}
+
 int have_git_dir(void)
 {
 	return startup_info->have_repository
@@ -541,12 +553,12 @@ int git_default_core_config(const char *var, const char *value,
 	}
 
 	if (!strcmp(var, "core.protecthfs")) {
-		protect_hfs = git_config_bool(var, value);
+		cfg->protect_hfs = git_config_bool(var, value);
 		return 0;
 	}
 
 	if (!strcmp(var, "core.protectntfs")) {
-		protect_ntfs = git_config_bool(var, value);
+		cfg->protect_ntfs = git_config_bool(var, value);
 		return 0;
 	}
 
@@ -720,5 +732,7 @@ void repo_config_values_init(struct repo_config_values *cfg)
 {
 	cfg->attributes_file = NULL;
 	cfg->apply_sparse_checkout = 0;
+	cfg->protect_hfs = PROTECT_HFS_DEFAULT;
+	cfg->protect_ntfs = PROTECT_NTFS_DEFAULT;
 	cfg->branch_track = BRANCH_TRACK_REMOTE;
 }
diff --git a/environment.h b/environment.h
index 9eb97b3869..b1ae4a70de 100644
--- a/environment.h
+++ b/environment.h
@@ -91,6 +91,8 @@ struct repo_config_values {
 	/* section "core" config values */
 	char *attributes_file;
 	int apply_sparse_checkout;
+	int protect_hfs;
+	int protect_ntfs;
 
 	/* section "branch" config values */
 	enum branch_track branch_track;
@@ -123,6 +125,14 @@ int git_default_config(const char *, const char *,
 int git_default_core_config(const char *var, const char *value,
 			    const struct config_context *ctx, void *cb);
 
+/*
+ * Getters for the `protect_hfs` and `protect_ntfs` fields of `struct repo_config_values`.
+ * They check `repo->initialized` to prevent calling `repo_config_values()`
+ * before the repository setup is fully complete or in non-git environments.
+ */
+int repo_protect_hfs(struct repository *repo);
+int repo_protect_ntfs(struct repository *repo);
+
 void repo_config_values_init(struct repo_config_values *cfg);
 
 /*
@@ -173,8 +183,6 @@ extern int pack_compression_level;
 extern unsigned long pack_size_limit_cfg;
 
 extern int precomposed_unicode;
-extern int protect_hfs;
-extern int protect_ntfs;
 
 extern int core_sparse_checkout_cone;
 extern int sparse_expect_files_outside_of_patterns;
diff --git a/read-cache.c b/read-cache.c
index 21829102ae..2c6a60c756 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1002,7 +1002,7 @@ static enum verify_path_result verify_path_internal(const char *path,
 			return PATH_OK;
 		if (is_dir_sep(c)) {
 inside:
-			if (protect_hfs) {
+			if (repo_protect_hfs(the_repository)) {
 
 				if (is_hfs_dotgit(path))
 					return PATH_INVALID;
@@ -1011,7 +1011,7 @@ static enum verify_path_result verify_path_internal(const char *path,
 						return PATH_INVALID;
 				}
 			}
-			if (protect_ntfs) {
+			if (repo_protect_ntfs(the_repository)) {
 #if defined GIT_WINDOWS_NATIVE || defined __CYGWIN__
 				if (c == '\\')
 					return PATH_INVALID;
@@ -1035,7 +1035,8 @@ static enum verify_path_result verify_path_internal(const char *path,
 			if (c == '\0')
 				return S_ISDIR(mode) ? PATH_DIR_WITH_SEP :
 						       PATH_INVALID;
-		} else if (c == '\\' && protect_ntfs) {
+		} else if (c == '\\' &&
+			   repo_protect_ntfs(the_repository)) {
 			if (is_ntfs_dotgit(path))
 				return PATH_INVALID;
 			if (S_ISLNK(mode)) {
diff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c
index 15eb44485c..f77b3f9d70 100644
--- a/t/helper/test-path-utils.c
+++ b/t/helper/test-path-utils.c
@@ -250,6 +250,7 @@ static int protect_ntfs_hfs_benchmark(int argc, const char **argv)
 	double m[3][2], v[3][2];
 	uint64_t cumul;
 	double cumul2;
+	int ntfs, hfs;
 
 	if (argc > 1 && !strcmp(argv[1], "--with-symlink-mode")) {
 		file_mode = 0120000;
@@ -276,8 +277,13 @@ static int protect_ntfs_hfs_benchmark(int argc, const char **argv)
 			names[i][--len] = (char)(' ' + (my_random() % ('\x7f' - ' ')));
 	}
 
-	for (protect_ntfs = 0; protect_ntfs < 2; protect_ntfs++)
-		for (protect_hfs = 0; protect_hfs < 2; protect_hfs++) {
+	if (!the_repository->gitdir)
+		the_repository->gitdir = xstrdup(".git");
+
+	for (ntfs = 0; ntfs < 2; ntfs++)
+		for (hfs = 0; hfs < 2; hfs++) {
+			repo_config_values(the_repository)->protect_ntfs = ntfs;
+			repo_config_values(the_repository)->protect_hfs = hfs;
 			cumul = 0;
 			cumul2 = 0;
 			for (i = 0; i < repetitions; i++) {
@@ -285,18 +291,18 @@ static int protect_ntfs_hfs_benchmark(int argc, const char **argv)
 				for (j = 0; j < nr; j++)
 					verify_path(names[j], file_mode);
 				end = getnanotime();
-				printf("protect_ntfs = %d, protect_hfs = %d: %lfms\n", protect_ntfs, protect_hfs, (end-begin) / (double)1e6);
+				printf("protect_ntfs = %d, protect_hfs = %d: %lfms\n", ntfs, hfs, (end-begin) / (double)1e6);
 				cumul += end - begin;
 				cumul2 += (end - begin) * (end - begin);
 			}
-			m[protect_ntfs][protect_hfs] = cumul / (double)repetitions;
-			v[protect_ntfs][protect_hfs] = my_sqrt(cumul2 / (double)repetitions - m[protect_ntfs][protect_hfs] * m[protect_ntfs][protect_hfs]);
-			printf("mean: %lfms, stddev: %lfms\n", m[protect_ntfs][protect_hfs] / (double)1e6, v[protect_ntfs][protect_hfs] / (double)1e6);
+			m[ntfs][hfs] = cumul / (double)repetitions;
+			v[ntfs][hfs] = my_sqrt(cumul2 / (double)repetitions - m[ntfs][hfs] * m[ntfs][hfs]);
+			printf("mean: %lfms, stddev: %lfms\n", m[ntfs][hfs] / (double)1e6, v[ntfs][hfs] / (double)1e6);
 		}
 
-	for (protect_ntfs = 0; protect_ntfs < 2; protect_ntfs++)
-		for (protect_hfs = 0; protect_hfs < 2; protect_hfs++)
-			printf("ntfs=%d/hfs=%d: %lf%% slower\n", protect_ntfs, protect_hfs, (m[protect_ntfs][protect_hfs] - m[0][0]) * 100 / m[0][0]);
+	for (ntfs = 0; ntfs < 2; ntfs++)
+		for (hfs = 0; hfs < 2; hfs++)
+			printf("ntfs=%d/hfs=%d: %lf%% slower\n", ntfs, hfs, (m[ntfs][hfs] - m[0][0]) * 100 / m[0][0]);
 
 	return 0;
 }
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH v3 15/17] odb/source-packed: stub out remaining functions
From: Junio C Hamano @ 2026-06-19 16:40 UTC (permalink / raw)
  To: Patrick Steinhardt; +Cc: git, Karthik Nayak, Justin Tobler
In-Reply-To: <ajTRK4nBxyv3YIgs@pks.im>

Patrick Steinhardt <ps@pks.im> writes:

>> diff --git a/odb/source-packed.c b/odb/source-packed.c
>> index 42c28fba0e..decc81aa52 100644
>> --- a/odb/source-packed.c
>> +++ b/odb/source-packed.c
>> @@ -503,7 +503,7 @@ static int odb_source_packed_freshen_object(struct odb_source *source,
>>  
>>  static int odb_source_packed_write_object(struct odb_source *source UNUSED,
>>  					  const void *buf UNUSED,
>> -					  unsigned long len UNUSED,
>> +					  size_t len UNUSED,
>>  					  enum object_type type UNUSED,
>>  					  struct object_id *oid UNUSED,
>>  					  struct object_id *compat_oid UNUSED,
>
> Thanks for the heads up, the change looks obviously correct to me. I'm
> also happy to send a rebased version -- just give me a nudge and I'll do
> that.

Nah, I expect the other topic would be ready and among the first
batch to graduate post 2.55 final, so it is not too much of a hassle
to carry the merge-fix around for me.  I do not even expect I need
"refs rename" for this, as the merge order will unlikely to be
flipped ;-)

THanks.

^ permalink raw reply

* Re: Strange behavior of "git log" with file argument
From: Junio C Hamano @ 2026-06-19 17:02 UTC (permalink / raw)
  To: Vincent Lefevre; +Cc: git
In-Reply-To: <20260619154448.GA769454@qaa.vinc17.org>

Vincent Lefevre <vincent@vinc17.net> writes:

> "git log git-gui/git-gui--askyesno.sh" outputs nothing. To get logs, I
> can add the -m option. In particular, this shows 3 non-merge commits.

This is a known joy of subtree-merge hack.

You could probably do 

    $ git log -- git-gui/git-gui--askyesno.sh git-gui--askyesno.sh

The thing is, in git-gui project, git-gui--askyesno.sh script is at
the root level of its working tree, and we are subtree-merging it in
a subdirectory.  Once the history traversal realizes that a change
to the script came from git-gui history, it would need to be told
that it needs to pay attention to git-gui--askyesno.sh at the root
tree as well.

^ permalink raw reply

* [PATCH v2] help: include arguments in autocorrect=prompt message
From: Jishnu C K @ 2026-06-19 17:04 UTC (permalink / raw)
  To: git; +Cc: gitster, Justin Tobler
In-Reply-To: <ajQuqTB580gqNP8D@denethor>

v2: Reworked as an incremental improvement to the existing
autocorrect=prompt code path rather than a parallel reimplementation,
per feedback from Junio and Justin.

---
From a4e8fb6fd6dd6a501e565c7500cbf927d7cb0b42 Mon Sep 17 00:00:00 2001
From: calicomills <jishnuck26@gmail.com>
Date: Fri, 19 Jun 2026 13:01:40 +0530
Subject: [PATCH v2 v2] help: include arguments in autocorrect=prompt message

When 'help.autocorrect=prompt' is configured and the user mistypes
a git command, the prompt currently shows only the corrected command
name:

  Run 'checkout' instead [y/N]?

This leaves the user unsure whether their original arguments will be
preserved. Update the prompt to include the full corrected invocation:

  Run 'git checkout neo' instead [y/N]?

The help_unknown_cmd() signature is updated to accept the args vector
so the prompt can show the original arguments alongside the corrected
command name. Callers that do not have access to the args (e.g.
builtin/help.c) pass NULL, which is handled gracefully.

Signed-off-by: calicomills <jishnuck26@gmail.com>
---
 help.c                      | 49 +++++++++++++----------------------
 t/t9003-help-autocorrect.sh | 51 +++++--------------------------------
 2 files changed, 23 insertions(+), 77 deletions(-)

diff --git a/help.c b/help.c
index 30f32a7206..9ea4c076e1 100644
--- a/help.c
+++ b/help.c
@@ -739,7 +739,16 @@ char *help_unknown_cmd(const char *cmd, const struct strvec *args)
 		else if (cfg.autocorrect == AUTOCORRECT_PROMPT) {
 			char *answer;
 			struct strbuf msg = STRBUF_INIT;
-			strbuf_addf(&msg, _("Run '%s' instead [y/N]? "), assumed);
+			struct strbuf full_cmd = STRBUF_INIT;
+			strbuf_addstr(&full_cmd, assumed);
+			if (args) {
+				for (size_t j = 1; j < args->nr; j++) {
+					strbuf_addch(&full_cmd, ' ');
+					strbuf_addstr(&full_cmd, args->v[j]);
+				}
+			}
+			strbuf_addf(&msg, _("Run 'git %s' instead [y/N]? "), full_cmd.buf);
+			strbuf_release(&full_cmd);
 			answer = git_prompt(msg.buf, PROMPT_ECHO);
 			strbuf_release(&msg);
 			if (!(starts_with(answer, "y") ||
@@ -762,37 +771,13 @@ char *help_unknown_cmd(const char *cmd, const struct strvec *args)
 	fprintf_ln(stderr, _("git: '%s' is not a git command. See 'git --help'."), cmd);
 
 	if (SIMILAR_ENOUGH(best_similarity)) {
-		if (n == 1 && isatty(0) && isatty(2)) {
-			char *answer;
-			struct strbuf msg = STRBUF_INIT;
-			struct strbuf full_cmd = STRBUF_INIT;
-			strbuf_addstr(&full_cmd, main_cmds.names[0]->name);
-			if (args) {
-				for (size_t j = 1; j < args->nr; j++) {
-					strbuf_addch(&full_cmd, ' ');
-					strbuf_addstr(&full_cmd, args->v[j]);
-				}
-			}
-			strbuf_addf(&msg, _("\nDid you mean 'git %s'? [y/N] "),
-				    full_cmd.buf);
-			strbuf_release(&full_cmd);
-			answer = git_prompt(msg.buf, PROMPT_ECHO);
-			strbuf_release(&msg);
-			if (starts_with(answer, "y") || starts_with(answer, "Y")) {
-				char *assumed = xstrdup(main_cmds.names[0]->name);
-				cmdnames_release(&cfg.aliases);
-				cmdnames_release(&main_cmds);
-				cmdnames_release(&other_cmds);
-				return assumed;
-			}
-		} else {
-			fprintf_ln(stderr,
-				   Q_("\nThe most similar command is",
-				      "\nThe most similar commands are",
-				   n));
-			for (i = 0; i < n; i++)
-				fprintf(stderr, "\t%s\n", main_cmds.names[i]->name);
-		}
+		fprintf_ln(stderr,
+			   Q_("\nThe most similar command is",
+			      "\nThe most similar commands are",
+			   n));
+
+		for (i = 0; i < n; i++)
+			fprintf(stderr, "\t%s\n", main_cmds.names[i]->name);
 	}
 
 	exit(1);
diff --git a/t/t9003-help-autocorrect.sh b/t/t9003-help-autocorrect.sh
index 6fe2da1595..75821d63e1 100755
--- a/t/t9003-help-autocorrect.sh
+++ b/t/t9003-help-autocorrect.sh
@@ -70,57 +70,18 @@ test_expect_success 'autocorrect works in work tree created from bare repo' '
 	git -C worktree -c help.autocorrect=immediate status
 '
 
-# Default behaviour (no help.autocorrect set): when there is exactly one
-# similar command but the session is non-interactive, fall back to printing
-# the suggestion list and exiting rather than showing a prompt.
-test_expect_success 'default: single match non-interactive shows suggestion and fails' '
-	test_might_fail git config --unset help.autocorrect &&
-
-	test_must_fail git lfg 2>actual &&
-	grep "most similar command" actual &&
-	grep "lgf" actual
-'
-
-test_expect_success 'default: multiple matches non-interactive shows list and fails' '
-	test_might_fail git config --unset help.autocorrect &&
-
-	test_must_fail git com 2>actual &&
-	grep "most similar commands" actual &&
-	grep "commit" actual
-'
-
-# Interactive prompt tests require a real TTY.  On macOS the TTY prereq is
-# skipped due to IO::Pty reliability issues; these tests run on Linux CI.
-test_expect_success TTY 'default: single match interactive, answer y runs command' '
-	git config --unset help.autocorrect &&
-
-	write_script git-typotest <<-\EOF &&
-		echo typotest-ran
-	EOF
-	PATH="$PATH:." export PATH &&
-
-	# Feed "y" to /dev/tty via a wrapper that answers the prompt
-	write_script answer-prompt <<-\EOF &&
-		# Write the answer to the controlling terminal
-		printf "y\n" >/dev/tty
-		exec "$@"
-	EOF
-
-	test_terminal ./answer-prompt git typotest 2>err >out &&
-	grep "typotest-ran" out &&
-	grep "Did you mean" err
-'
-
-test_expect_success TTY 'default: single match interactive, answer n exits cleanly' '
-	git config --unset help.autocorrect &&
+# autocorrect=prompt should include the original arguments in the prompt.
+# Requires a TTY; skipped on macOS due to IO::Pty reliability issues.
+test_expect_success TTY 'autocorrect=prompt includes arguments in prompt' '
+	git config help.autocorrect prompt &&
 
 	write_script answer-prompt-no <<-\EOF &&
 		printf "n\n" >/dev/tty
 		exec "$@"
 	EOF
 
-	test_must_fail test_terminal ./answer-prompt-no git typotest 2>err &&
-	grep "Did you mean" err
+	test_must_fail test_terminal ./answer-prompt-no git lfg --oneline 2>actual &&
+	grep "lgf --oneline" actual
 '
 
 test_done
-- 
2.50.1



^ permalink raw reply related

* Re: [PATCH v4 0/1] environment: move protect_hfs and protect_ntfs into repo_config_values
From: Junio C Hamano @ 2026-06-19 17:14 UTC (permalink / raw)
  To: Tian Yuchen; +Cc: git, Christian Couder, Ayush Chandekar, Olamide Caleb Bello
In-Reply-To: <20260619163823.652091-1-cat@malon.dev>

Tian Yuchen <cat@malon.dev> writes:

> This series continues the ongoing libification effort by moving the
> global filesystem variables, 'protect_hfs' and 'protect_ntfs', into
> 'struct repo_config_values'.
> ...
> Change since V3:
>
>  - In repo_protect_hfs() and repo_protect_ntfs(), change repo->gitdir to
>  using (repo && repo->initialized).

While I think that it is a good change for consistency with other
two topics, the hfs/ntfs topic is already in 'next', so it needs to
be handled differently.  Namely, a topic in 'next' should not be
replaced, but be improved by additional patches on top.

In this particular case case, I think it would be good to have "to
match how we refrain from calling repo_config_values() on an
uninitialized instance of a repository object in other two topics
that deal with X bit and Y bit, check the repo->initialized bit
instead of the repo->gitdir member" or something like that in the
log message to explain why we are making the change, perhaps.

The patch text may look like this.

 environment.c | 4 ++--
 environment.h | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git c/environment.c w/environment.c
index 683fe1b4d3..f34f6fc750 100644
--- c/environment.c
+++ w/environment.c
@@ -142,14 +142,14 @@ int is_bare_repository(void)
 
 int repo_protect_ntfs(struct repository *repo)
 {
-	return repo->gitdir ?
+	return (repo && repo->initialized) ?
 		repo_config_values(repo)->protect_ntfs :
 		PROTECT_NTFS_DEFAULT;
 }
 
 int repo_protect_hfs(struct repository *repo)
 {
-	return repo->gitdir ?
+	return (repo && repo->initialized) ?
 		repo_config_values(repo)->protect_hfs :
 		PROTECT_HFS_DEFAULT;
 }
diff --git c/environment.h w/environment.h
index fdd9775900..b1ae4a70de 100644
--- c/environment.h
+++ w/environment.h
@@ -127,8 +127,8 @@ int git_default_core_config(const char *var, const char *value,
 
 /*
  * Getters for the `protect_hfs` and `protect_ntfs` fields of `struct repo_config_values`.
- * They check `repo->gitdir` to prevent calling repo_config_values()
- * before the configuration is loaded or in bare environments.
+ * They check `repo->initialized` to prevent calling `repo_config_values()`
+ * before the repository setup is fully complete or in non-git environments.
  */
 int repo_protect_hfs(struct repository *repo);
 int repo_protect_ntfs(struct repository *repo);


^ permalink raw reply related

* Re: [PATCH v4 0/1] environment: move protect_hfs and protect_ntfs into repo_config_values
From: Junio C Hamano @ 2026-06-19 17:25 UTC (permalink / raw)
  To: Tian Yuchen; +Cc: git, Christian Couder, Ayush Chandekar, Olamide Caleb Bello
In-Reply-To: <xmqqo6h6jvuk.fsf@gitster.g>

Junio C Hamano <gitster@pobox.com> writes:

> diff --git c/environment.h w/environment.h
> index fdd9775900..b1ae4a70de 100644
> --- c/environment.h
> +++ w/environment.h
> @@ -127,8 +127,8 @@ int git_default_core_config(const char *var, const char *value,
>  
>  /*
>   * Getters for the `protect_hfs` and `protect_ntfs` fields of `struct repo_config_values`.
> - * They check `repo->gitdir` to prevent calling repo_config_values()
> - * before the configuration is loaded or in bare environments.
> + * They check `repo->initialized` to prevent calling `repo_config_values()`
> + * before the repository setup is fully complete or in non-git environments.
>   */
>  int repo_protect_hfs(struct repository *repo);
>  int repo_protect_ntfs(struct repository *repo);

Another thing we should remember (but should *NOT* do while these
topics are still in flight) to do is to consolidate these comments
into one.  The hfs and htfs getters are covered by the same single
comment, but ignorecase and trustexecutable bit getters have their
own comments, only because they came in different topics.  We should
conslidate them into a single comment block once all of these have
landed in 'master', which may happen soon after 2.55 final gets
tagged.


^ permalink raw reply

* Re: [PATCH v2] Makefile: dedup archives in $(LIBS) so link recipes don't repeat them
From: Harald Nordgren @ 2026-06-19 20:25 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Harald Nordgren via GitGitGadget, git
In-Reply-To: <xmqqldcamtat.fsf@gitster.g>

Thanks for a good lesson about linkers!

Good idea to fix it through the same LD_MAJOR_VERSION as we did for
the __DATA,__common alignment, makes it a lot cleaner.


Harald

^ permalink raw reply

* [PATCH v3] config.mak.uname: avoid macOS dup-library warning
From: Harald Nordgren via GitGitGadget @ 2026-06-19 20:32 UTC (permalink / raw)
  To: git; +Cc: Harald Nordgren, Harald Nordgren
In-Reply-To: <pull.2314.v2.git.git.1780610623006.gitgitgadget@gmail.com>

From: Harald Nordgren <haraldnordgren@gmail.com>

Building on macOS with Xcode 15 or newer emits:

    ld: warning: ignoring duplicate libraries: 'libgit.a',
    'target/release/libgitcore.a'

Some link recipes list the same archive twice, which is harmless.
Quiet the warning instead.

Pass -Wl,-no_warn_duplicate_libraries on Xcode 15 and newer, whose
linkers added both the warning and the suppression flag (ld64-907
and dyld-1009). Earlier linkers reject the flag, so gate on the
linker version. Broaden the existing -fno-common version probe to
also match the "ld64-NNN" and "dyld-NNN" forms Xcode 15 reports.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
---
    Makefile: drop duplicate %.a from test-helper link rule
    
    Fix warning of duplicate libraries on macOS.
    
    Changes in v3:
    
     * Suppress the warning at the linker rather than dedup the archive list
     * Pass -Wl,-no_warn_duplicate_libraries in config.mak.uname, gated on
       the linker version (reuses the probe added for -fno-common), and
       broaden the regex to match all three PROJECT:{ld64,dyld,ld}-NNN forms
     * Floor of 907 and the version forms (ld64-907, dyld-1009.5) per meson:
       https://github.com/mesonbuild/meson/blob/master/mesonbuild/linkers/linkers.py

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2314%2FHaraldNordgren%2Fmakefile-test-helper-dedup-libs-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2314/HaraldNordgren/makefile-test-helper-dedup-libs-v3
Pull-Request: https://github.com/git/git/pull/2314

Range-diff vs v2:

 1:  0ef442ea05 < -:  ---------- Makefile: dedup archives in $(LIBS) so link recipes don't repeat them
 -:  ---------- > 1:  5bf560c5ad config.mak.uname: avoid macOS dup-library warning


 config.mak.uname | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/config.mak.uname b/config.mak.uname
index 8719e09f66..9ebd240378 100644
--- a/config.mak.uname
+++ b/config.mak.uname
@@ -173,8 +173,15 @@ ifeq ($(uname_S),Darwin)
 		NEEDS_GOOD_LIBICONV = UnfortunatelyYes
         endif
 
-	# Silence Xcode 16.3+ linker warning about __DATA,__common alignment.
-	LD_MAJOR_VERSION = $(shell ld -v 2>&1 | sed -n 's/.*PROJECT:ld-\([0-9]*\).*/\1/p')
+	# ld reports "PROJECT:{ld,ld64,dyld}-NNN", match any of the three.
+	LD_MAJOR_VERSION = $(shell ld -v 2>&1 | sed -n 's/.*PROJECT:[^ ]*-\([0-9][0-9]*\).*/\1/p')
+
+	# Silence the Xcode 15+ warning about archives listed more than once.
+        ifeq ($(shell test -n "$(LD_MAJOR_VERSION)" && test "$(LD_MAJOR_VERSION)" -ge 907 && echo 1),1)
+		BASIC_LDFLAGS += -Wl,-no_warn_duplicate_libraries
+        endif
+
+	# Silence the Xcode 16.3+ warning about __DATA,__common alignment.
         ifeq ($(shell test -n "$(LD_MAJOR_VERSION)" && test "$(LD_MAJOR_VERSION)" -ge 1167 && echo 1),1)
 		BASIC_CFLAGS += -fno-common
         endif

base-commit: 95e20213faefeb95df29277c58ac1980ab68f701
-- 
gitgitgadget

^ permalink raw reply related

* Re: [PATCH v3] config.mak.uname: avoid macOS dup-library warning
From: Junio C Hamano @ 2026-06-19 22:27 UTC (permalink / raw)
  To: Harald Nordgren via GitGitGadget; +Cc: git, Harald Nordgren
In-Reply-To: <pull.2314.v3.git.git.1781901127385.gitgitgadget@gmail.com>

"Harald Nordgren via GitGitGadget" <gitgitgadget@gmail.com> writes:

> From: Harald Nordgren <haraldnordgren@gmail.com>
>
> Building on macOS with Xcode 15 or newer emits:
>
>     ld: warning: ignoring duplicate libraries: 'libgit.a',
>     'target/release/libgitcore.a'
>
> Some link recipes list the same archive twice, which is harmless.
> Quiet the warning instead.
>
> Pass -Wl,-no_warn_duplicate_libraries on Xcode 15 and newer, whose
> linkers added both the warning and the suppression flag (ld64-907
> and dyld-1009). Earlier linkers reject the flag, so gate on the
> linker version. Broaden the existing -fno-common version probe to
> also match the "ld64-NNN" and "dyld-NNN" forms Xcode 15 reports.
>
> Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
> ---

Yeah, this looks like what I expected.

A few things to note.

 * Can folks with different versions of Xcode (or is 15 sufficiently
   old that practically nobody is expected to have anything older?)
   test this patch?

 * We only patch Makefile here; can folks who use meson report how
   well your build goes?

Thanks.

>  config.mak.uname | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/config.mak.uname b/config.mak.uname
> index 8719e09f66..9ebd240378 100644
> --- a/config.mak.uname
> +++ b/config.mak.uname
> @@ -173,8 +173,15 @@ ifeq ($(uname_S),Darwin)
>  		NEEDS_GOOD_LIBICONV = UnfortunatelyYes
>          endif
>  
> -	# Silence Xcode 16.3+ linker warning about __DATA,__common alignment.
> -	LD_MAJOR_VERSION = $(shell ld -v 2>&1 | sed -n 's/.*PROJECT:ld-\([0-9]*\).*/\1/p')
> +	# ld reports "PROJECT:{ld,ld64,dyld}-NNN", match any of the three.
> +	LD_MAJOR_VERSION = $(shell ld -v 2>&1 | sed -n 's/.*PROJECT:[^ ]*-\([0-9][0-9]*\).*/\1/p')
> +
> +	# Silence the Xcode 15+ warning about archives listed more than once.
> +        ifeq ($(shell test -n "$(LD_MAJOR_VERSION)" && test "$(LD_MAJOR_VERSION)" -ge 907 && echo 1),1)
> +		BASIC_LDFLAGS += -Wl,-no_warn_duplicate_libraries
> +        endif
> +
> +	# Silence the Xcode 16.3+ warning about __DATA,__common alignment.
>          ifeq ($(shell test -n "$(LD_MAJOR_VERSION)" && test "$(LD_MAJOR_VERSION)" -ge 1167 && echo 1),1)
>  		BASIC_CFLAGS += -fno-common
>          endif
>
> base-commit: 95e20213faefeb95df29277c58ac1980ab68f701

^ permalink raw reply

* Re: [PATCH v3] SubmittingPatches: address design critiques
From: Michael Montalbo @ 2026-06-19 22:40 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: code, git, Michael Montalbo

Junio C Hamano <gitster@pobox.com> writes:
> +Be particularly mindful of critiques regarding the high-level design
> +or viability of your proposal (e.g., questioning if the feature is
> +worth implementing, or if the chosen approach is appropriate).  Defend
> +your design decisions on the list first, work with reviewers and other
> +members to improve the design before revising the implementation, to
> +avoid wasting effort on an implementation before its design is solid.

Slight reflow suggestions:

  Defend your design decisions on the list first; work with reviewers and
  other members to improve the design before revising the implementation.
  This will avoid wasting effort on an implementation before its design is
  solid.

The rest looks good to me!

^ permalink raw reply

* What's cooking in git.git (Jun 2026, #07)
From: Junio C Hamano @ 2026-06-20  1:33 UTC (permalink / raw)
  To: git

Here are the topics that have been cooking in my tree.  Commits
prefixed with '+' are in 'next' (being in 'next' is a sign that a
topic is stable enough to be used and is a candidate to be in a
future release).  Commits prefixed with '-' are only in 'seen', and
aren't considered "accepted" at all and may be annotated with a URL
to a message that raises issues but they are by no means exhaustive.
A topic without enough support may be discarded after a long period
of no activity (of course they can be resubmitted when new interests
arise).

Git 2.55-rc1 has been tagged and pushed out.  There may be a few
more topics in 'next' that we may want to include in the release
that I didn't manage or I forgot (please let me know), but basically
this development cycle is over, the tree is feature-frozen, and
remaining topics in 'next' will stay in "Will cook in 'next'"
instead of "Will merge to 'master'" state.  We'd want to force
ourselves to concentrate on addressing topics that are important
fixes but still in the "Needs review" state, and of course, find any
correct any regressions relative to Git 2.54, until we are ready to
tag Git 2.55 final.

Copies of the source code to Git live in many repositories, and the
following is a list of the ones I push into or their mirrors.  Some
repositories have only a subset of branches.

With maint, master, next, seen, todo:

	git://git.kernel.org/pub/scm/git/git.git/
	git://repo.or.cz/alt-git.git/
	https://kernel.googlesource.com/pub/scm/git/git/
	https://github.com/git/git/
	https://gitlab.com/git-scm/git/

With all the integration branches and topics broken out:

	https://github.com/gitster/git/

Even though the preformatted documentation in HTML and man format
are not sources, they are published in these repositories for
convenience (replace "htmldocs" with "manpages" for the manual
pages):

	git://git.kernel.org/pub/scm/git/git-htmldocs.git/
	https://github.com/gitster/git-htmldocs.git/

Release tarballs are available at:

	https://www.kernel.org/pub/software/scm/git/

--------------------------------------------------
[Graduated to 'master']

* dl/posix-unused-warning-clang (2026-06-13) 3 commits
  (merged to 'next' on 2026-06-15 at 1d7e627c24)
 + compat/posix.h: simplify GIT_GNUC_PREREQ() comparison
 + compat/posix.h: clean up GIT_GNUC_PREREQ() and UNUSED
 + compat/posix.h: enable UNUSED warning messages for Clang

 The UNUSED macro in 'compat/posix.h' has been updated to use a
 newly introduced GIT_CLANG_PREREQ macro for compiler version
 checks, and the existing GIT_GNUC_PREREQ macro has been modernized
 to use explicit major/minor comparisons rather than bit-shifting.
 cf. <ai-8Y1r9zbWfdY8p@pks.im>
 source: <20260613122711.38662-1-dominik.loidolt@univie.ac.at>


* en/commit-graph-timestamp-fix (2026-06-13) 1 commit
  (merged to 'next' on 2026-06-16 at 13248b8196)
 + commit-graph: use timestamp_t for max parent generation accumulator

 compute_reachable_generation_numbers() in commit-graph used a 32-bit
 integer to accumulate parent generations, which is OK for generation
 number v1 (topological levels), but with generation number v2
 (adjusted committer timestamps), it truncated timestamps beyond
 2106.  Fixed by widening the accumulator to timestamp_t.
 cf. <09e50180-e165-48d8-a9d0-485283342f5c@gmail.com>
 source: <pull.2148.git.1781420271100.gitgitgadget@gmail.com>


* jc/t1400-fifo-cleanup (2026-06-10) 1 commit
  (merged to 'next' on 2026-06-15 at 7d5acd110a)
 + t1400: have fifo test clean after itself

 Test cleanup.
 cf. <aiqs5Wq2Di-6yW0D@pks.im>
 source: <xmqqo6hit6rn.fsf@gitster.g>


* js/objects-larger-than-4gb-on-windows (2026-06-18) 1 commit
  (merged to 'next' on 2026-06-18 at 99d7cf9126)
 + zlib: properly clamp to uLong

 A hotfix to an earlier attempt to update code paths that assumed
 "unsigned long" was long enough for "size_t".
 source: <pull.2153.git.1781790619424.gitgitgadget@gmail.com>


* ps/transport-helper-tsan-fix (2026-06-09) 1 commit
  (merged to 'next' on 2026-06-15 at 0857e6696f)
 + transport-helper: fix TSAN race in transfer_debug()

 The TSAN race in transfer_debug() within transport-helper.c has been
 resolved by initializing the debug flag early in
 bidirectional_transfer_loop() before spawning worker threads, allowing
 the removal of a TSAN suppression.
 cf. <20260609002833.GE358144@coredump.intra.peff.net>
 cf. <20260611083320.GI2191159@coredump.intra.peff.net>
 source: <20260609134741.4727-2-pushkarkumarsingh1970@gmail.com>


* ta/doc-config-adoc-fixes (2026-06-11) 3 commits
  (merged to 'next' on 2026-06-15 at 93340b5cf0)
 + doc: git-config: escape erroneous highlight markup
 + doc: config/sideband: fix description list delimiter
 + doc: config: terminate runaway lists

 Various AsciiDoc markup fixes in 'git config' documentation and
 related files to ensure lists and formatting are rendered correctly.
 cf. <20260612045329.GA593075@coredump.intra.peff.net>
 source: <20260611161946.12166-1-taahol@utu.fi>


* td/describe-tag-iteration (2026-06-10) 1 commit
  (merged to 'next' on 2026-06-15 at 1ae171f3b7)
 + describe: limit default ref iteration to tags

 'git describe' has been taught to pass the 'refs/tags/' prefix down to
 the ref iterator when '--all' is not requested, avoiding unnecessary
 iteration over non-tag refs.
 cf. <20260611064912.GC2191159@coredump.intra.peff.net>
 source: <20260610-describe-tag-ref-scope-v3-1-5aa63ab279f7@gmail.com>


* td/ls-files-pathspec-prefilter (2026-06-11) 1 commit
  (merged to 'next' on 2026-06-15 at 38918c4cfd)
 + ls-files: filter pathspec before lstat

 `git ls-files --modified` and `git ls-files --deleted` have been
 optimized to filter with pathspec before calling lstat() when there is
 only a single pathspec item, avoiding unnecessary filesystem access
 for entries that will not be shown.
 cf. <xmqqfr2tnfk0.fsf@gitster.g>
 source: <20260611-ls-files-pathspec-lstat-v3-1-f967e1a00c13@gmail.com>

--------------------------------------------------
[New Topics]

* jc/submittingpatches-design-critiques (2026-06-19) 1 commit
 - SubmittingPatches: address design critiques

 The documentation in SubmittingPatches has been updated to clarify how
 patch contributors should respond to design and viability critiques,
 and how the resolution of such critiques should be recorded in the
 final commit messages.

 Needs review.
 source: <xmqqik7eld2g.fsf_-_@gitster.g>


* wy/doc-clarify-review-replies (2026-06-17) 2 commits
 - doc: advise batching patch rerolls
 - doc: encourage review replies before rerolling

 Documentation on community contribution guidelines has been updated to
 encourage replying to review comments before rerolling, and to advise
 a default limit of at most one reroll per day to give reviewers across
 different time zones enough time to participate.

 Expecting a reroll.
 cf. <ajVCD51lLvHreyJB@wyuan.org>
 source: <cover.1781714757.git.wy@wyuan.org>


* ps/gitlab-ci-windows (2026-06-15) 1 commit
 - gitlab-ci: migrate Windows builds away from Chocolatey

 Wean the Windows builds in GitLab CI procedure away from
 (unfortunately unreliable) Chocolatey to install dependencies.

 Will merge to 'next'?
 cf. <ajL1677NQShTO6tD@denethor>
 source: <20260615-b4-pks-gitlab-ci-drop-chocolatey-v1-1-51a6e7d5e388@pks.im>


* ty/migrate-ignorecase (2026-06-19) 2 commits
 - config: use repo_ignore_case() to access core.ignorecase
 - environment: move ignore_case into repo_config_values

 The global configuration variable ignore_case (representing the
 core.ignorecase configuration) has been migrated into struct
 repo_config_values to tie it to a specific repository instance.

 Needs review.
 source: <20260619155152.642760-1-cat@malon.dev>


* mm/line-log-limited-ops (2026-06-18) 7 commits
 - diffcore-pickaxe: scope -G to the -L tracked range
 - diff: support --check with -L line ranges
 - line-log: support diff stat formats with -L
 - diff: extract a line-range diff helper for reuse
 - diff: emit -L hunk headers via xdiff's formatter
 - diff: simplify the line-range filter by classifying removals immediately
 - diff: rename and group the line-range filter for clarity

 "git log -L<range>:<path>" learned to limit various "diff" operations
 like --stat, --check, -G, to the specified range:path.

 Waiting for response(s) to review comment(s).
 cf. <xmqq8q8bpl03.fsf@gitster.g>
 source: <pull.2152.git.1781806593.gitgitgadget@gmail.com>


* hn/history-squash (2026-06-18) 6 commits
 - SQUASH??? avoid test_grep lint triggering on uses of raw grep
 - SQUASH??? avoid test number clash by moving 3454-h-squash to 3455
 - history: re-edit a squash with every message
 - history: add squash subcommand to fold a range
 - history: give commit_tree_ext a message template
 - history: extract helper for a commit's parent tree

 The experimental "git history" command has been taught a new
 "squash" subcommand to fold a range of commits into a single commit,
 replaying any descendants on top.

 Waiting for response(s) to review comment(s).
 cf. <ajU8T2JFJTdk1hr2@pks.im>
 source: <pull.2337.v3.git.git.1781810226.gitgitgadget@gmail.com>


* ps/t4216-tap-fix (2026-06-19) 1 commit
 - t4216: fix no-op test that breaks TAP output

 TAP output breakage fix.

 Waiting for response(s) to review comment(s).
 cf. <xmqqa4sqlchz.fsf@gitster.g>
 source: <20260619-pks-t4216-drop-unused-prereq-v1-1-2ce0d7bea088@pks.im>


* hn/macos-linker-warning (2026-06-19) 1 commit
 - config.mak.uname: avoid macOS dup-library warning

 Xcode 15 and later has a linker set to complain when the same library
 archive is listed twice on the command line.  Squelch the annoyance.

 Will merge to 'next'?
 source: <pull.2314.v3.git.git.1781901127385.gitgitgadget@gmail.com>

--------------------------------------------------
[Stalled]

* jt/config-lock-timeout (2026-05-17) 1 commit
 - config: retry acquiring config.lock, configurable via core.configLockTimeout

 Configuration file locking now retries for a short period, avoiding
 failures when multiple processes attempt to update the configuration
 simultaneously.

 Waiting for response(s) to review comment(s) for too long, stalled.
 cf. <agrIrGwSMFlKTx9x@pks.im>
 source: <20260517132111.1014901-1-joerg@thalheim.io>

--------------------------------------------------
[Cooking]

* mh/fetch-follow-remote-head-config (2026-06-19) 8 commits
 - fetch: fixup a misaligned comment
 - fetch: add configuration variable fetch.followRemoteHEAD
 - fetch: refactor do_fetch handling of followRemoteHEAD
 - fetch: return 0 on known git_fetch_config
 - fetch: rename function report_set_head
 - t5510: cleanup remote in followRemoteHEAD dangling ref test
 - doc: explain fetchRemoteHEADWarn advice
 - fetch: fixup set_head advice for warn-if-not-branch

 The `fetch.followRemoteHEAD` configuration variable has been added to
 provide a default for the per-remote `remote.<name>.followRemoteHEAD`
 setting.

 Will merge to 'next'?
 cf. <xmqqcxxp1j2t.fsf@gitster.g>
 source: <20260619094751.2996804-1-m@lfurio.us>


* ps/refs-writing-subcommands (2026-06-17) 5 commits
 - builtin/refs: add "rename" subcommand
 - builtin/refs: add "create" subcommand
 - builtin/refs: add "update" subcommand
 - builtin/refs: add "delete" subcommand
 - builtin/refs: drop `the_repository`

 The "git refs" toolbox has been extended with new "create", "delete",
 "update", and "rename" subcommands to create, delete, update, and
 rename references, respectively.

 Needs review.
 source: <20260617-pks-refs-writing-subcommands-v2-0-07f3d18336f9@pks.im>


* po/hash-object-size-t (2026-06-16) 6 commits
 - hash-object: add a >4GB/LLP64 test case using filtered input
 - hash-object: add another >4GB/LLP64 test case
 - hash-object --stdin: verify that it works with >4GB/LLP64
 - hash algorithms: use size_t for section lengths
 - object-file.c: use size_t for header lengths
 - hash-object: demonstrate a >4GB/LLP64 problem

 Support for hashing loose or packed objects larger than 4GB on Windows
 and other LLP64 platforms has been improved by converting object header
 buffers and data-handling functions from 'unsigned long' to 'size_t'.

 Will merge to 'next'.
 cf. <ajOQthRjhD3hRM9w@pks.im>
 source: <pull.2138.v2.git.1781621398.gitgitgadget@gmail.com>


* kh/submittingpatches-trailers (2026-06-18) 5 commits
 - SubmittingPatches: note that trailer order matters
 - SubmittingPatches: be consistent with trailer markup
 - SubmittingPatches: document Based-on-patch-by trailer
 - SubmittingPatches: discourage common Linux trailers
 - SubmittingPatches: encourage trailer use for substantial help

 The trailer sections in SubmittingPatches have been updated to
 encourage use of standard trailers.

 Will merge to 'next'?
 cf. <xmqq4ij0vo8f.fsf@gitster.g>
 source: <V3_CV_SubPatches_trailers.9ec@msgid.xyz>


* mv/log-follow-mergy (2026-06-14) 1 commit
 - log: improve --follow following renames for non-linear history

 "git log --follow" has been updated to handle non-linear history, in
 which the path being tracked gets renamed differently in multiple
 history lines, better.

 Needs review.
 source: <ai-aE83w02xPRlPr@collabora.com>


* wy/doc-myfirstcontribution-trim-quotes (2026-06-11) 1 commit
 - MyFirstContribution: mention trimming quoted text in replies

 The contributor guide has been updated to advise new contributors to
 trim irrelevant quoted text when replying to review comments, matching
 the existing advice given to reviewers.

 Comments?
 cf. <xmqqcxxwljue.fsf@gitster.g>
 source: <080402ff0ac8127b654dccea59a1bf643df62a5c.1781186476.git.wy@wyuan.org>


* tb/midx-incremental-custom-base (2026-06-12) 3 commits
 - midx-write: include packs above custom incremental base
 - midx: pass custom '--base' through incremental writes
 - t5334: expose shared `nth_line()` helper

 The `git multi-pack-index write --incremental` command has been
 corrected to properly honor the `--base` option. Previously, the
 custom base was ignored by the normal write path, and the pack
 exclusion logic incorrectly skipped packs from layers above the
 selected base, breaking reachability closure for bitmaps.

 Needs review.
 source: <cover.1781294771.git.me@ttaylorr.com>


* mm/test-grep-lint (2026-06-12) 6 commits
 - t: add greplint to detect bare grep assertions
 - t: convert grep assertions to test_grep
 - t: fix Lexer line count for $() inside double-quoted strings
 - t: extract chainlint's parser into shared module
 - t: fix grep assertions missing file arguments
 - t/README: document test_grep helper

 Needs review.
 source: <pull.2135.v2.git.1781323575.gitgitgadget@gmail.com>


* js/objects-larger-than-4gb-on-windows-more (2026-06-15) 7 commits
  (merged to 'next' on 2026-06-18 at 2b3ac350e6)
 + odb: use size_t for object_info.sizep and the size APIs
 + packfile,delta: drop the `cast_size_t_to_ulong()` wrappers
 + pack-objects: use size_t for in-core object sizes
 + packfile: widen unpack_entry()'s size out-parameter to size_t
 + pack-objects(check_pack_inflate()): use size_t instead of unsigned long
 + patch-delta: use size_t for sizes
 + compat/msvc: use _chsize_s for ftruncate

 Will cook in 'next'.
 cf. <ajPhBn7n1wR-sii4@pks.im>
 source: <pull.2137.v2.git.1781524349.gitgitgadget@gmail.com>


* kw/gitattributes-typofix (2026-06-15) 1 commit
  (merged to 'next' on 2026-06-17 at 14ff167ef8)
 + gitattributes: fix eol attribute for Perl scripts

 Will cook in 'next'.
 cf. <ai-5vfY8D84UhsB4@pks.im>
 source: <pull.2151.v2.git.1781510039164.gitgitgadget@gmail.com>


* rs/cat-file-default-format-optim (2026-06-14) 1 commit
  (merged to 'next' on 2026-06-17 at 43ed8b3969)
 + cat-file: speed up default format

 Will cook in 'next'.
 cf. <20260615165326.GA91269@coredump.intra.peff.net>
 source: <5a7ed929-6fe0-496c-83bd-65dee57c2241@web.de>


* js/parseopt-subcommand-autocorrection (2026-04-27) 11 commits
 - SQUASH???
 - doc: document autocorrect API
 - parseopt: add tests for subcommand autocorrection
 - parseopt: enable subcommand autocorrection for git-remote and git-notes
 - parseopt: autocorrect mistyped subcommands
 - autocorrect: provide config resolution API
 - autocorrect: rename AUTOCORRECT_SHOW to AUTOCORRECT_HINT
 - autocorrect: use mode and delay instead of magic numbers
 - help: move tty check for autocorrection to autocorrect.c
 - help: make autocorrect handling reusable
 - parseopt: extract subcommand handling from parse_options_step()

 The parse-options library learned to auto-correct misspelled
 subcommand names.

 Expecting a reroll.
 cf. <xmqq33yzd9yf.fsf@gitster.g>
 cf. <SY0P300MB0801E50FCB7EB2F45CD15208CE042@SY0P300MB0801.AUSP300.PROD.OUTLOOK.COM>
 source: <SY0P300MB0801677A2A1E0FD38D06A841CE2A2@SY0P300MB0801.AUSP300.PROD.OUTLOOK.COM>


* kk/prio-queue-get-put-fusion (2026-06-08) 2 commits
 - prio-queue: fold lazy_queue into prio_queue for automatic get+put fusion
 - prio-queue: rename .nr to .nr_ and add accessor helpers

 The lazy priority queue optimization pattern (deferring actual removal
 in prio_queue_get() to allow get+put fusion) has been folded directly
 into prio_queue itself, speeding up commit traversal workflows and
 simplifying callers.

 Needs review.
 source: <pull.2140.v4.git.1780945851.gitgitgadget@gmail.com>


* td/ref-filter-memoize-contains (2026-06-12) 3 commits
 - commit-reach: die on contains walk errors
 - ref-filter: memoize --contains with generations
 - commit-reach: reject cycles in contains walk

 'git branch --contains' and 'git for-each-ref --contains' have
 been optimized to use the memoized commit traversal previously
 used only by 'git tag --contains', significantly speeding up
 connectivity checks across many candidate refs with shared
 history.

 Needs review.
 source: <20260612-ref-filter-memoized-contains-v4-0-5ed39fd001dd@gmail.com>


* tc/replay-linearize (2026-06-16) 4 commits
 - SQUASH??? prepare for mm/test-grep-lint
 - replay: offer an option to linearize the commit topology
 - replay: add helper to put entry into mapped_commits
 - replay: refactor enum replay_mode into a bool

 git replay learns --linearize option to drop merge commits and
 linearize the replayed history, mimicking git rebase
 --no-rebase-merges.

 Needs review.
 source: <20260616-toon-git-replay-drop-merges-v3-0-153e9eb99ce1@iotcl.com>


* ps/setup-drop-global-state (2026-06-10) 8 commits
  (merged to 'next' on 2026-06-15 at d9a8b88d47)
 + treewide: drop USE_THE_REPOSITORY_VARIABLE
 + environment: stop using `the_repository` in `is_bare_repository()`
 + environment: split up concerns of `is_bare_repository_cfg`
 + builtin/init: stop modifying `is_bare_repository_cfg`
 + setup: remove global `git_work_tree_cfg` variable
 + builtin/init: simplify logic to configure worktree
 + builtin/init: stop modifying global `git_work_tree_cfg` variable
 + Merge branch 'ps/setup-centralize-odb-creation' into ps/setup-drop-global-state

 Continuation of "setup.c" refactoring to drop remaining global state
 (`git_work_tree_cfg`, `is_bare_repository_cfg`). The most notable
 outcome is that `is_bare_repository()` has been updated to no longer
 implicitly rely on `the_repository`.

 Will cook in 'next'.
 cf. <airVOrTboNDDGBak@denethor>
 cf. <87ldckyygk.fsf@emacs.iotcl.com>
 source: <20260611-b4-pks-setup-drop-global-state-v2-0-a6f7269c841d@pks.im>


* ps/refs-avoid-chdir-notify-reparent (2026-06-19) 11 commits
 - refs: drop local buffer in `refs_compute_filesystem_location()`
 - refs: fix recursing `get_main_ref_store()` with "onbranch" config
 - refs/reftable-backend: manually parse "core.sharedRepository"
 - refs: move parsing of "core.logAllRefUpdates" back into ref stores
 - repository: free main reference database
 - chdir-notify: drop unused `chdir_notify_reparent()`
 - refs: unregister reference stores from "chdir_notify"
 - setup: don't apply "GIT_REFERENCE_BACKEND" without a repository
 - setup: stop applying repository format twice
 - setup: inline `check_and_apply_repository_format()`
 - Merge branch 'ps/setup-centralize-odb-creation' into ps/refs-avoid-chdir-notify-reparent

 The reference backends have been converted to always use absolute
 paths internally. This allows dropping the calls to
 `chdir_notify_reparent()` and fixes a memory leak in how the
 reference database is constructed with an "onbranch" condition.

 Needs review.
 source: <20260619-b4-pks-refs-avoid-chdir-notify-reparent-v4-0-a6472be7acc4@pks.im>


* ps/odb-source-packed (2026-06-16) 18 commits
  (merged to 'next' on 2026-06-19 at dcf0c084e4)
 + odb/source-packed: drop pointer to "files" parent source
 + midx: refactor interfaces to work on "packed" source
 + odb/source-packed: stub out remaining functions
 + odb/source-packed: wire up `freshen_object()` callback
 + odb/source-packed: wire up `find_abbrev_len()` callback
 + odb/source-packed: wire up `count_objects()` callback
 + odb/source-packed: wire up `for_each_object()` callback
 + odb/source-packed: wire up `read_object_stream()` callback
 + odb/source-packed: wire up `read_object_info()` callback
 + packfile: use higher-level interface to implement `has_object_pack()`
 + odb/source-packed: wire up `reprepare()` callback
 + odb/source-packed: wire up `close()` callback
 + odb/source-packed: start converting to a proper `struct odb_source`
 + odb/source-packed: store pointer to "files" instead of generic source
 + packfile: move packed source into "odb/" subsystem
 + packfile: split out packfile list logic
 + packfile: rename `struct packfile_store` to `odb_source_packed`
 + Merge branch 'ps/odb-source-loose' into ps/odb-source-packed

 The packed object source has been refactored into a proper struct
 odb_source.

 Will cook in 'next'.
 cf. <ajK2QKdW-TdflfR0@denethor>
 source: <20260617-pks-odb-source-packed-v3-0-b5c7583cd795@pks.im>


* td/ref-filter-restore-prefix-iteration (2026-06-12) 1 commit
  (merged to 'next' on 2026-06-19 at a19dbb4193)
 + ref-filter: restore prefix-scoped iteration

 Commands that list branches and tags (like git branch and git tag)
 have been optimized to pass the namespace prefix when initializing
 their ref iterator, avoiding a loose-ref scaling regression in
 repositories with many unrelated loose references.

 Will cook in 'next'.
 cf. <xmqqik7fsv2m.fsf@gitster.g>
 source: <20260612-fix-git-branch-regression-v4-1-f150038c02f4@gmail.com>


* ty/move-protect-hfs-ntfs (2026-06-10) 1 commit
  (merged to 'next' on 2026-06-15 at c2a30ca954)
 + environment: move 'protect_hfs' and 'protect_ntfs' into 'repo_config_values'

 The global configuration variables protect_hfs and protect_ntfs have
 been migrated into struct repo_config_values to tie them to
 per-repository configuration state.

 Will cook in 'next'.
 cf. <CAP8UFD35Tiy1_fqpjq8P-z=ZhzR3MTiThqfCs977652umRoSEQ@mail.gmail.com>
 cf. <xmqqse6uwdnz.fsf@gitster.g>
 source: <20260610124353.149874-2-cat@malon.dev>


* ps/cat-file-remote-object-info (2026-06-19) 12 commits
 - cat-file: make remote-object-info allow-list dynamic
 - cat-file: validate remote atoms with allow_list
 - cat-file: add remote-object-info to batch-command
 - transport: add client support for object-info
 - serve: advertise object-info feature
 - fetch-pack: move fetch initialization
 - connect: refactor packet writing
 - fetch-pack: move function to connect.c
 - t1006: split test utility functions into new "lib-cat-file.sh"
 - cat-file: declare loop counter inside for()
 - git-compat-util: add strtoul_ul() with error handling
 - transport-helper: fix memory leak of helper on disconnect

 The `remote-object-info` command has been added to `git cat-file
 --batch-command`, allowing clients to request object metadata
 (currently size) from a remote server via protocol v2 without
 downloading the entire object.

 The client dynamically filters format placeholders based on
 server-advertised capabilities and safely returns empty strings for
 inapplicable or unsupported fields.

 Needs review.
 source: <20260619-ps-eric-work-rebase-v13-0-3d4c7315d2f8@gmail.com>


* ap/http-redirect-wwwauth-fix (2026-06-02) 1 commit
 - http: preserve wwwauth_headers across redirects

 When cURL follows a redirect, the WWW-Authenticate headers from the
 redirect target were lost because credential_from_url() cleared the
 credential state. This has been fixed by preserving the collected
 headers across the redirect update.

 Expecting a reroll.
 cf. <5144a29d-a53f-4446-beff-e1f549345bf9@nvidia.com>
 source: <20260602161150.1527493-1-aplattner@nvidia.com>


* ps/doc-recommend-b4 (2026-06-15) 3 commits
  (merged to 'next' on 2026-06-17 at dd9a463369)
 + b4: introduce configuration for the Git project
 + MyFirstContribution: recommend the use of b4
 + MyFirstContribution: recommend shallow threading of cover letters

 Project-specific configuration for b4 has been introduced, and the
 documentation has been updated to recommend using it as a
 streamlined method for submitting patches.

 Will cook in 'next'.
 cf. <87eci7yomp.fsf@emacs.iotcl.com>
 source: <20260615-pks-b4-v4-0-22cfca8f19c5@pks.im>


* sn/rebase-update-refs-symrefs (2026-06-03) 1 commit
 - rebase: skip branch symref aliases

 "git rebase --update-refs" has been taught to resolve local branch
 symrefs to their referents before queuing updates. This correctly
 skips aliases of the current branch and avoids duplicate updates for
 underlying real branches, fixing failures when branch aliases (like a
 default branch rename) are present.

 Waiting for response(s) to review comment(s).
 cf. <f982c386-e329-4ab0-b695-e540bcb9de3d@gmail.com>
 source: <pull.2126.v2.git.1780482436865.gitgitgadget@gmail.com>


* mm/diff-process-hunks (2026-06-14) 6 commits
 - blame: consult diff process for no-hunk detection
 - diff: bypass diff process with --no-ext-diff and in format-patch
 - diff: add long-running diff process via diff.<driver>.process
 - sub-process: separate process lifecycle from hashmap management
 - userdiff: add diff.<driver>.process config
 - xdiff: support external hunks via xpparam_t

 A new `diff.<driver>.process` configuration has been introduced to
 allow a long-running external process to act as a hunk provider to
 allows external tools to control which lines Git considers changed
 while leaving all output formatting (word diff, color, blame, etc.) to
 Git's standard pipeline.

 Expecting a reroll.
 cf. <CAC2Qwm+P=fZOtpfMPeMiSXf3Afk6OLYpTP8Br78_PRA8WNL1Wg@mail.gmail.com>
 cf. <CAC2Qwm+P=fZOtpfMPeMiSXf3Afk6OLYpTP8Br78_PRA8WNL1Wg@mail.gmail.com>
 source: <pull.2120.v4.git.1781463564.gitgitgadget@gmail.com>


* tb/pack-path-walk-bitmap-delta-islands (2026-06-15) 6 commits
 - SQUASH???
 - pack-objects: support `--delta-islands` with `--path-walk`
 - pack-objects: extract `record_tree_depth()` helper
 - pack-objects: support reachability bitmaps with `--path-walk`
 - t/perf: drop p5311's lookup-table permutation
 - Merge branch 'ds/path-walk-filters' into tb/pack-path-walk-bitmap-delta-islands

 The pack-objects command now supports using reachability bitmaps and
 delta-islands concurrently with the `--path-walk` option, allowing
 faster packaging by falling back to path-walk when bitmaps cannot
 fully satisfy the request.

 Waiting for response(s) to review comment(s).
 cf. <849c659f-efa8-430a-bfac-0c26a3ed1aaa@gmail.com>
 cf. <xmqqjyrzbjyf.fsf@gitster.g>
 cf. <7afdaf77-07f5-4d48-955d-e153d148f647@gmail.com>
 source: <cover.1780438896.git.me@ttaylorr.com>


* ty/migrate-trust-executable-bit (2026-06-19) 3 commits
 - environment: move trust_executable_bit into repo_config_values
 - read-cache: move 'ce_mode_from_stat()' to 'read-cache.c'
 - read-cache: remove redundant extern declarations

 The 'trust_executable_bit' (coming from 'core.filemode'
 configuration) has been migrated into 'repo_config_values' to tie it
 to a specific repository instance.

 Needs review.
 source: <20260619162105.648495-1-cat@malon.dev>


* kk/prio-queue-cascade-sift (2026-06-01) 1 commit
 - prio-queue: use cascade-down for faster extract-min

 prio_queue_get() has been optimized by using a cascade-down approach
 (promoting the smaller child at each level and sifting up the last
 element from the leaf vacancy), which halves the number of comparisons
 per extract-min operation in the common case.

 Expecting a reroll.
 cf. <CAL71e4Ob-B5MJ5DPY+_tzpj6nyrbQ5WutxED2T93SWJV6kJGPA@mail.gmail.com>
 cf. <CAL71e4MYNiScZjTwkApjDAjRh2LM0_SP59h5HCTywV-Pua03tw@mail.gmail.com>
 source: <pull.2132.v2.git.1780301856444.gitgitgadget@gmail.com>


* jk/repo-info-path-keys (2026-06-15) 4 commits
 - repo: add path.gitdir with absolute and relative suffix formatting
 - repo: add path.commondir with absolute and relative suffix formatting
 - rev-parse: use append_formatted_path() for path formatting
 - path: introduce append_formatted_path() for shared path formatting

 The "git repo info" command has been taught new keys to output both
 absolute and relative paths for "gitdir" and "commondir", supported by
 a new path-formatting helper extracted from "git rev-parse".

 Expecting a reroll.
 cf. <CA+rGoLfhhRNrSReeJ1grhy+2K3BSrikTCNgGpCaGqc4fFp3Lfg@mail.gmail.com>
 source: <20260616044953.184806-1-jayatheerthkulkarni2005@gmail.com>


* ps/history-drop (2026-06-15) 10 commits
 - builtin/history: implement "drop" subcommand
 - builtin/history: split handling of ref updates into two phases
 - reset: stop assuming that the caller passes in a clean index
 - reset: allow the caller to specify the current HEAD object
 - reset: introduce ability to skip updating HEAD
 - reset: introduce dry-run mode
 - reset: modernize flags passed to `reset_working_tree()`
 - reset: rename `reset_head()`
 - reset: drop `USE_THE_REPOSITORY_VARIABLE`
 - read-cache: split out function to drop unmerged entries to stage 0

 The experimental "git history" command has been taught a new "drop"
 subcommand to remove a commit and replay its descendants onto its
 parent.

 Needs review.
 source: <20260615-b4-pks-history-drop-v6-0-2e329e536d78@pks.im>


* jk/setup-gitfile-diag-fix (2026-06-16) 1 commit
  (merged to 'next' on 2026-06-18 at b63b3d1f25)
 + read_gitfile(): simplify NOT_A_REPO error message

 A regression in the error diagnosis code for invalid .git files has
 been fixed, avoiding a potential NULL-pointer crash when reporting
 that a .git file does not point to a valid repository.

 Will cook in 'next'.
 cf. <xmqqjyry4hax.fsf@gitster.g>
 source: <20260616123516.GA2301231@coredump.intra.peff.net>


* kh/doc-trailers (2026-06-10) 10 commits
 - doc: interpret-trailers: document comment line treatment
 - doc: interpret-trailers: commit to “trailer block” term
 - doc: interpret-trailers: join new-trailers again
 - doc: interpret-trailers: add key format example
 - doc: interpret-trailers: explain key format
 - doc: interpret-trailers: explain the format after the intro
 - doc: interpret-trailers: not just for commit messages
 - doc: interpret-trailers: use “metadata” in Name as well
 - doc: interpret-trailers: replace “lines” with “metadata”
 - doc: interpret-trailers: stop fixating on RFC 822

 Documentation updates.

 Expecting a reroll.
 cf. <729baf6b-53ea-4e8d-95ab-5935667e66c2@app.fastmail.com>
 source: <V3_CV_doc_int-tr_key_format.8a3@msgid.xyz>


* za/completion-hide-dotfiles (2026-05-26) 1 commit
 - completion: hide dotfiles for selected path completion

 The path completion for commands like `git rm` and `git mv`, is being
 updated to hide dotfiles by default, unless the user explicitly starts
 the path with a dot, matching standard shell-completion behavior.

 Waiting for response(s) to review comment(s).
 cf. <xmqqik7qusuc.fsf@gitster.g>
 source: <pull.2311.v2.git.git.1779808987825.gitgitgadget@gmail.com>


* ec/commit-fixup-options (2026-05-26) 2 commits
 - commit: allow -c/-C for all kinds of --fixup
 - commit: allow -m/-F for all kinds of --fixup

 The -m/-F/-c/-C options to supply commit log message from outside the
 editor are now supported for all "git commit --fixup" variations.

 Needs review.
 source: <cover.1779792311.git.erik@cervined.in>


* kh/doc-replay-config (2026-06-05) 4 commits
 - doc: replay: move “default” to the right-hand side
 - doc: replay: use a nested description list
 - doc: replay: improve config description
 - doc: link to config for git-replay(1)

 Doc update for "git replay" to actually refer to its configuration
 variables.

 Needs review.
 source: <V3_CV_doc_replay_config.780@msgid.xyz>


* hn/status-pull-advice-qualified (2026-05-21) 1 commit
  (merged to 'next' on 2026-06-15 at 898a4df940)
 + remote: qualify "git pull" advice for non-upstream compareBranches

 Advice shown by "git status" when the local branch is behind or has
 diverged from its push branch has been updated to suggest "git pull
 <remote> <branch>".

 Will cook in 'next'.
 cf. <xmqq7bo6xuok.fsf@gitster.g>
 source: <pull.2301.v4.git.git.1779372367317.gitgitgadget@gmail.com>


* hn/branch-delete-merged (2026-06-18) 7 commits
 - branch: add --dry-run for --delete-merged
 - branch: add branch.<name>.deleteMerged opt-out
 - branch: add --delete-merged <branch>
 - branch: prepare delete_branches for a bulk caller
 - branch: let delete_branches skip unmerged branches on bulk refusal
 - branch: convert delete_branches() to a flags argument
 - branch: add --forked filter for --list mode

 "git branch" command learned "--delete-merged" option to remove
 local branches that have already been merged to the remote-tracking
 branches they track.

 Waiting for response(s) to review comment(s).
 cf. <78b6dfdd-df61-4c44-96eb-b527cb26243c@gmail.com>
 cf. <f68e2a11-02a5-47b9-a01a-458eba821c37@gmail.com>
 cf. <37f2a483-c8bf-4c24-84de-c6233cc20b25@gmail.com>
 cf. <xmqq33yimsdp.fsf@gitster.g>
 source: <pull.2285.v16.git.git.1781810729.gitgitgadget@gmail.com>


* cc/promisor-auto-config-url-more (2026-05-27) 8 commits
  (merged to 'next' on 2026-06-15 at d1c99e75cc)
 + doc: promisor: improve acceptFromServer entry
 + promisor-remote: auto-configure unknown remotes
 + promisor-remote: trust known remotes matching acceptFromServerUrl
 + promisor-remote: introduce promisor.acceptFromServerUrl
 + promisor-remote: add 'local_name' to 'struct promisor_info'
 + urlmatch: add url_normalize_pattern() helper
 + urlmatch: change 'allow_globs' arg to bool
 + t5710: simplify 'mkdir X' followed by 'git -C X init'

 The handling of promisor-remote protocol capability has been
 loosened to allow the other side to add to the list of promisor
 remotes via the promisor.acceptFromServerURL configuration
 variable.

 Will cook in 'next'.
 cf. <877bo7294j.fsf@emacs.iotcl.com>
 cf. <xmqqh5naxwfc.fsf@gitster.g>
 source: <20260527140820.1438165-1-christian.couder@gmail.com>


* hn/checkout-track-fetch (2026-06-18) 2 commits
 - checkout: extend --track with a "fetch" mode to refresh start-point
 - branch: expose helpers for finding the remote owning a tracking ref

 "git checkout --track=..." learned to optionally fetch the branch
 from the remote the new branch will work with.

 Needs review.
 source: <pull.2281.v14.git.git.1781786652.gitgitgadget@gmail.com>


* en/ort-harden-against-corrupt-trees (2026-06-13) 5 commits
  (merged to 'next' on 2026-06-18 at e51bee59ca)
 + cache-tree: fix verify_cache() to catch non-adjacent D/F conflicts
 + merge-ort: abort merge when trees have duplicate entries
 + merge-ort: free diff pairs queue in clear_or_reinit_internal_opts()
 + merge-ort: drop unnecessary show_all_errors from collect_merge_info()
 + merge-ort: propagate callback errors from traverse_trees_wrapper()

 "ort" merge backend handles merging corrupt trees better by
 aborting when it should.

 Will cook in 'next'.
 cf. <xmqq5x3ldu4h.fsf@gitster.g>
 source: <pull.2096.v2.git.1781419047.gitgitgadget@gmail.com>


* pw/status-rebase-todo (2026-05-01) 2 commits
 - status: improve rebase todo list parsing
 - sequencer: factor out parsing of todo commands

 The display of the rebase todo list in "git status" has been
 improved to correctly abbreviate object IDs for more commands and
 avoid misinterpreting refs as object IDs.

 Waiting for response(s) to review comment(s).
 cf. <xmqqqzmdoya9.fsf@gitster.g>
 source: <cover.1777648598.git.phillip.wood@dunelm.org.uk>


* cl/conditional-config-on-worktree-path (2026-05-24) 2 commits
 - config: add "worktree" and "worktree/i" includeIf conditions
 - config: refactor include_by_gitdir() into include_by_path()

 The [includeIf "condition"] conditional inclusion facility for
 configuration files has learned to use the location of worktree
 in its condition.

 Waiting for response(s) to review comment(s).
 cf. <xmqq8q97et9b.fsf@gitster.g>
 source: <20260525-includeif-worktree-v5-0-1efe525d025a@black-desk.cn>


* ps/shift-root-in-graph (2026-06-13) 2 commits
 - graph: indent visual root in graph
 - lib-log-graph: move check_graph function

 "git log --graph" has been modified to visually distinguish
 parentless "root" commits (and commits that become roots due to
 history simplification) by indenting them, preventing them from
 appearing falsely related to unrelated commits rendered immediately
 above them.

 Waiting for response(s) to review comment(s).
 cf. <20260617202744.GA3465855@coredump.intra.peff.net>
 source: <20260613-ps-pre-commit-indent-v5-0-8d308efea63d@gmail.com>

--------------------------------------------------
[Discarded]

* kk/fetch-store-ref-optimization (2026-05-24) 1 commit
 . fetch: pass transport to post-fetch connectivity check

 When fetching from a transport that provides a self-contained pack,
 pass the transport pointer to the post-fetch `check_connected()` call
 to optimize connectivity check.

 Retracted.
 cf. <CAL71e4MrVqC1=AR6x0_8S=8kVqPdDkhgCZRb4etFsxTzd6s_8Q@mail.gmail.com>
 source: <pull.2123.git.1779625693328.gitgitgadget@gmail.com>


* lp/repack-propagate-promisor-debugging-info (2026-04-18) 6 commits
 . repack-promisor: add missing headers
 . t7703: test for promisor file content after geometric repack
 . t7700: test for promisor file content after repack
 . repack-promisor: preserve content of promisor files after repack
 . repack-promisor add helper to fill promisor file after repack
 . pack-write: add explanation to promisor file content

 When fetching objects into a lazily cloned repository, .promisor
 files are created with information meant to help debugging.  "git
 repack" has been taught to carry this information forward to
 packfiles that are newly created.

 Retracted.
 cf. <agx_GPfBKpkSc3Gx@lorenzo-VM>
 source: <cover.1776384902.git.lorenzo.pegorari2002@gmail.com>


* cs/subtree-split-recursion (2026-03-05) 3 commits
 . contrib/subtree: reduce recursion during split
 . contrib/subtree: functionalize split traversal
 . contrib/subtree: reduce function side-effects

 When processing large history graphs on Debian or Ubuntu, "git
 subtree" can die with a "recursion depth reached" error.

 Retracted.
 cf. <0915b5cc-5cbb-4cce-a832-147f85d4ff1f@howdoi.land>
 source: <20260305-cs-subtree-split-recursion-v2-0-7266be870ba9@howdoi.land>


* jc/neuter-sideband-post-3.0 (2026-03-05) 2 commits
 . sideband: delay sanitizing by default to Git v3.0
 . Merge branch 'jc/neuter-sideband-fixup' into jc/neuter-sideband-post-3.0

 The final step, split from earlier attempt by Dscho, to loosen the
 sideband restriction for now and tighten later at Git v3.0 boundary.

 Retracted.
 cf. <xmqqzf11oz7a.fsf@gitster.g>
 source: <20260305233452.3727126-8-gitster@pobox.com>


* kk/remove-get-reachable-subset (2026-06-11) 1 commit
 . commit-reach: remove get_reachable_subset()

 API clean-up.

 Retracted.
 cf. <CAL71e4P3Oq08xVPZ+dxQ8L5PKekPJN0RsL4pTicom1og7-1D=A@mail.gmail.com>
 source: <pull.2144.v2.git.1781178567862.gitgitgadget@gmail.com>


* ds/config-no-includes (2026-06-08) 3 commits
 . git: add --no-includes top-level option
 . config: add GIT_CONFIG_INCLUDES
 . git-config.adoc: fix paragraph break

 Two new mechanisms, the GIT_CONFIG_INCLUDES environment variable and
 the top-level --no-includes command-line option, have been introduced
 to ignore configuration include directives.

 Retracted.
 cf. <539713c4-b291-42e6-8541-a16a454518f5@gmail.com>
 source: <pull.2139.git.1780927027.gitgitgadget@gmail.com>

^ permalink raw reply

* [GSoC Patch v6 0/4] teach git repo info to handle path keys
From: K Jayatheerth @ 2026-06-20  3:16 UTC (permalink / raw)
  To: git
  Cc: jltobler, lucasseikioshiro, gitster, phillip.wood, sandals,
	kumarayushjha123, a3205153416, kristofferhaugsbakk, K Jayatheerth
In-Reply-To: <20260601151950.30686-1-jayatheerthkulkarni2005@gmail.com>

Hi!

This series teaches `git repo info` to handle `path.*`
keys, allowing scripts to reliably discover core
repository paths without resorting to `git rev-parse`.

The patches are structured as follows:

1. path: Extract the localized path-formatting logic
   out of `rev-parse` and expose it globally via
   `path.h` using clear append semantics.

2. rev-parse: Delegate the command's path-printing
   helper to the newly shared path engine, while
   leaving its existing option-parsing untouched.

3. repo: Introduce `path.commondir.absolute` and
   `path.commondir.relative` alongside a robust,
   isolated test helper.

4. repo: Introduce `path.gitdir.absolute` and
   `path.gitdir.relative` using the same standardized
   formatting rules.

Changes since v5:

* Dropped `PATH_FORMAT_DEFAULT` from the shared
  `path_format` enum in path.h. It only existed to let
  rev-parse track "no format was requested", which is a
  rev-parse-specific concern that other callers of
  `append_formatted_path()` shouldn't need to reason
  about (Phillip).

* Reverted `print_path()` in builtin/rev-parse.c to keep
  its original `format_type` and `default_type` local
  enums completely untouched (Phillip).

* As a result, patch 2 is now much smaller: it only
  touches the body of `print_path()`.

Tagging Justin Tobler, Lucas Seiki Oshiro, Junio,
Phillip Wood, brian m. carlson, and Ayush Jha.

Thanks again for the careful review!

K Jayatheerth (4):
  path: introduce append_formatted_path() for shared path formatting
  rev-parse: use append_formatted_path() for path formatting
  repo: add path.commondir with absolute and relative suffix formatting
  repo: add path.gitdir with absolute and relative suffix formatting

 Documentation/git-repo.adoc | 15 ++++++++
 builtin/repo.c              | 50 +++++++++++++++++++++++++
 builtin/rev-parse.c         | 73 +++++++++++++++----------------------
 path.c                      | 69 +++++++++++++++++++++++++++++++++++
 path.h                      | 30 +++++++++++++++
 t/t1900-repo-info.sh        | 58 +++++++++++++++++++++++++++++
 6 files changed, 251 insertions(+), 44 deletions(-)

Range-diff against v5:
1:  31bc2c96e9 ! 1:  bb8bb40030 path: introduce append_formatted_path() for shared path formatting
    @@ path.c: char *xdg_cache_home(const char *filename)
     +			   const char *prefix, enum path_format format)
     +{
     +	switch (format) {
    -+	case PATH_FORMAT_DEFAULT:
     +	case PATH_FORMAT_UNMODIFIED:
     +		strbuf_addstr(dest, path);
     +		break;
    @@ path.h: enum scld_error safe_create_leading_directories_no_share(char *path);
     + * The formatting strategy to apply when writing a path into a buffer.
     + */
     +enum path_format {
    -+	/*
    -+	 * Represents the default formatting behavior. Treated as
    -+	 * PATH_FORMAT_UNMODIFIED by append_formatted_path().
    -+	 */
    -+	PATH_FORMAT_DEFAULT,
    -+
     +	/* Output the path exactly as-is without any modifications. */
     +	PATH_FORMAT_UNMODIFIED,
     +
2:  12af24ffc3 ! 2:  0ab0e4bde3 rev-parse: use append_formatted_path() for path formatting
    @@ Metadata
      ## Commit message ##
         rev-parse: use append_formatted_path() for path formatting
     
    -    Now that path formatting logic lives in a shared helper, keeping a
    -    duplicate implementation in rev-parse is unnecessary and risks the
    -    two diverging over time.
    +    Now that the core path-formatting algorithm lives in
    +    append_formatted_path(), print_path() doesn't need to duplicate it.
     
    -    Replace the local format_type and default_type enums and the
    -    hand-rolled formatting logic with a call to append_formatted_path().
    -    Introduce PATH_FORMAT_DEFAULT as the initial value of arg_path_format
    -    so that per-path fallback behavior is resolved in print_path() rather
    -    than leaked into the shared helper.
    +    Replace the body of print_path() with a small mapping from rev-parse's
    +    existing format_type/default_type pair to the shared path_format enum,
    +    then delegate to append_formatted_path(). The two local enums, and
    +    every call site that uses them throughout cmd_rev_parse(), are left
    +    untouched.
     
         Mentored-by: Justin Tobler <jltobler@gmail.com>
         Mentored-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>
         Signed-off-by: K Jayatheerth <jayatheerthkulkarni2005@gmail.com>
     
      ## builtin/rev-parse.c ##
    -@@ builtin/rev-parse.c: static void handle_ref_opt(const char *pattern, const char *prefix)
    - 	clear_ref_exclusions(&ref_excludes);
    - }
    +@@ builtin/rev-parse.c: enum default_type {
    + 	DEFAULT_UNMODIFIED,
    + };
      
    --enum format_type {
    --	/* We would like a relative path. */
    --	FORMAT_RELATIVE,
    --	/* We would like a canonical absolute path. */
    --	FORMAT_CANONICAL,
    --	/* We would like the default behavior. */
    --	FORMAT_DEFAULT,
    --};
    --
    --enum default_type {
    --	/* Our default is a relative path. */
    --	DEFAULT_RELATIVE,
    --	/* Our default is a relative path if there's a shared root. */
    --	DEFAULT_RELATIVE_IF_SHARED,
    --	/* Our default is a canonical absolute path. */
    --	DEFAULT_CANONICAL,
    --	/* Our default is not to modify the item. */
    --	DEFAULT_UNMODIFIED,
    --};
    --
     -static void print_path(const char *path, const char *prefix, enum format_type format, enum default_type def)
     +static void print_path(const char *path, const char *prefix,
    -+		       enum path_format arg_path_format, enum path_format def_format)
    ++		       enum format_type format, enum default_type def)
      {
     -	char *cwd = NULL;
     -	/*
    @@ builtin/rev-parse.c: static void handle_ref_opt(const char *pattern, const char
     -		if (!is_absolute_path(prefix)) {
     -			strbuf_realpath_forgiving(&prefixbuf, prefix, 1);
     -			prefix = prefixbuf.buf;
    --		}
    ++	struct strbuf sb = STRBUF_INIT;
    ++	enum path_format fmt;
    ++
    ++	if (format == FORMAT_RELATIVE) {
    ++		fmt = PATH_FORMAT_RELATIVE;
    ++	} else if (format == FORMAT_CANONICAL) {
    ++		fmt = PATH_FORMAT_CANONICAL;
    ++	} else /* FORMAT_DEFAULT */ {
    ++		switch (def) {
    ++		case DEFAULT_RELATIVE:
    ++			fmt = PATH_FORMAT_RELATIVE;
    ++			break;
    ++		case DEFAULT_RELATIVE_IF_SHARED:
    ++			fmt = PATH_FORMAT_RELATIVE_IF_SHARED;
    ++			break;
    ++		case DEFAULT_CANONICAL:
    ++			fmt = PATH_FORMAT_CANONICAL;
    ++			break;
    ++		case DEFAULT_UNMODIFIED:
    ++		default:
    ++			fmt = PATH_FORMAT_UNMODIFIED;
    ++			break;
    + 		}
     -		puts(relative_path(path, prefix, &buf));
     -		strbuf_release(&buf);
     -		strbuf_release(&realbuf);
    @@ builtin/rev-parse.c: static void handle_ref_opt(const char *pattern, const char
     -		strbuf_realpath_forgiving(&buf, path, 1);
     -		puts(buf.buf);
     -		strbuf_release(&buf);
    --	}
    + 	}
     -	free(cwd);
    -+	struct strbuf sb = STRBUF_INIT;
    -+	/* If the user didn't explicitly specify a format, fallback to the path-specific default. */
    -+	enum path_format fmt = (arg_path_format != PATH_FORMAT_DEFAULT) ? arg_path_format : def_format;
     +
     +	append_formatted_path(&sb, path, prefix, fmt);
     +	puts(sb.buf);
    @@ builtin/rev-parse.c: static void handle_ref_opt(const char *pattern, const char
      }
      
      int cmd_rev_parse(int argc,
    -@@ builtin/rev-parse.c: int cmd_rev_parse(int argc,
    - 	const char *name = NULL;
    - 	struct strbuf buf = STRBUF_INIT;
    - 	int seen_end_of_options = 0;
    --	enum format_type format = FORMAT_DEFAULT;
    -+	enum path_format arg_path_format = PATH_FORMAT_DEFAULT;
    - 
    - 	show_usage_if_asked(argc, argv, builtin_rev_parse_usage);
    - 
    -@@ builtin/rev-parse.c: int cmd_rev_parse(int argc,
    - 					die(_("--git-path requires an argument"));
    - 				print_path(repo_git_path_replace(the_repository, &buf,
    - 								 "%s", argv[i + 1]), prefix,
    --						format,
    --						DEFAULT_RELATIVE_IF_SHARED);
    -+						arg_path_format,
    -+						PATH_FORMAT_RELATIVE_IF_SHARED);
    - 				i++;
    - 				continue;
    - 			}
    -@@ builtin/rev-parse.c: int cmd_rev_parse(int argc,
    - 				if (!arg)
    - 					die(_("--path-format requires an argument"));
    - 				if (!strcmp(arg, "absolute")) {
    --					format = FORMAT_CANONICAL;
    -+					arg_path_format = PATH_FORMAT_CANONICAL;
    - 				} else if (!strcmp(arg, "relative")) {
    --					format = FORMAT_RELATIVE;
    -+					arg_path_format = PATH_FORMAT_RELATIVE;
    - 				} else {
    - 					die(_("unknown argument to --path-format: %s"), arg);
    - 				}
    -@@ builtin/rev-parse.c: int cmd_rev_parse(int argc,
    - 			if (!strcmp(arg, "--show-toplevel")) {
    - 				const char *work_tree = repo_get_work_tree(the_repository);
    - 				if (work_tree)
    --					print_path(work_tree, prefix, format, DEFAULT_UNMODIFIED);
    -+					print_path(work_tree, prefix, arg_path_format, PATH_FORMAT_UNMODIFIED);
    - 				else
    - 					die(_("this operation must be run in a work tree"));
    - 				continue;
    -@@ builtin/rev-parse.c: int cmd_rev_parse(int argc,
    - 			if (!strcmp(arg, "--show-superproject-working-tree")) {
    - 				struct strbuf superproject = STRBUF_INIT;
    - 				if (get_superproject_working_tree(&superproject))
    --					print_path(superproject.buf, prefix, format, DEFAULT_UNMODIFIED);
    -+					print_path(superproject.buf, prefix, arg_path_format, PATH_FORMAT_UNMODIFIED);
    - 				strbuf_release(&superproject);
    - 				continue;
    - 			}
    -@@ builtin/rev-parse.c: int cmd_rev_parse(int argc,
    - 				const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
    - 				char *cwd;
    - 				int len;
    --				enum format_type wanted = format;
    -+				enum path_format wanted = arg_path_format;
    - 				if (arg[2] == 'g') {	/* --git-dir */
    - 					if (gitdir) {
    --						print_path(gitdir, prefix, format, DEFAULT_UNMODIFIED);
    -+						print_path(gitdir, prefix, arg_path_format, PATH_FORMAT_UNMODIFIED);
    - 						continue;
    - 					}
    - 					if (!prefix) {
    --						print_path(".git", prefix, format, DEFAULT_UNMODIFIED);
    -+						print_path(".git", prefix, arg_path_format, PATH_FORMAT_UNMODIFIED);
    - 						continue;
    - 					}
    - 				} else {		/* --absolute-git-dir */
    --					wanted = FORMAT_CANONICAL;
    -+					wanted = PATH_FORMAT_CANONICAL;
    - 					if (!gitdir && !prefix)
    - 						gitdir = ".git";
    - 					if (gitdir) {
    -@@ builtin/rev-parse.c: int cmd_rev_parse(int argc,
    - 				strbuf_reset(&buf);
    - 				strbuf_addf(&buf, "%s%s.git", cwd, len && cwd[len-1] != '/' ? "/" : "");
    - 				free(cwd);
    --				print_path(buf.buf, prefix, wanted, DEFAULT_CANONICAL);
    -+				print_path(buf.buf, prefix, wanted, PATH_FORMAT_CANONICAL);
    - 				continue;
    - 			}
    - 			if (!strcmp(arg, "--git-common-dir")) {
    --				print_path(repo_get_common_dir(the_repository), prefix, format, DEFAULT_RELATIVE_IF_SHARED);
    -+				print_path(repo_get_common_dir(the_repository), prefix, arg_path_format, PATH_FORMAT_RELATIVE_IF_SHARED);
    - 				continue;
    - 			}
    - 			if (!strcmp(arg, "--is-inside-git-dir")) {
    -@@ builtin/rev-parse.c: int cmd_rev_parse(int argc,
    - 				if (the_repository->index->split_index) {
    - 					const struct object_id *oid = &the_repository->index->split_index->base_oid;
    - 					const char *path = repo_git_path_replace(the_repository, &buf, "sharedindex.%s", oid_to_hex(oid));
    --					print_path(path, prefix, format, DEFAULT_RELATIVE);
    -+					print_path(path, prefix, arg_path_format, PATH_FORMAT_RELATIVE);
    - 				}
    - 				continue;
    - 			}
3:  7aecf1e806 = 3:  a50c75a55b repo: add path.commondir with absolute and relative suffix formatting
4:  f30010b76c = 4:  1dd22e5cd4 repo: add path.gitdir with absolute and relative suffix formatting
-- 
2.54.0


^ permalink raw reply

* [GSoC Patch v6 1/4] path: introduce append_formatted_path() for shared path formatting
From: K Jayatheerth @ 2026-06-20  3:16 UTC (permalink / raw)
  To: git
  Cc: jltobler, lucasseikioshiro, gitster, phillip.wood, sandals,
	kumarayushjha123, a3205153416, kristofferhaugsbakk, K Jayatheerth
In-Reply-To: <20260620031644.353772-1-jayatheerthkulkarni2005@gmail.com>

The path-formatting logic in builtin/rev-parse.c is tightly coupled
to that command and writes directly to stdout, making it impossible
for other builtins to reuse.

Extract the core algorithm into append_formatted_path() in path.c
and expose a path_format enum in path.h so that any builtin can
format paths consistently without duplicating logic.

Mentored-by: Justin Tobler <jltobler@gmail.com>
Mentored-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>
Signed-off-by: K Jayatheerth <jayatheerthkulkarni2005@gmail.com>
---
 path.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 path.h | 30 +++++++++++++++++++++++++
 2 files changed, 99 insertions(+)

diff --git a/path.c b/path.c
index d7e17bf174..6d8e892ada 100644
--- a/path.c
+++ b/path.c
@@ -1579,6 +1579,75 @@ char *xdg_cache_home(const char *filename)
 	return NULL;
 }
 
+void append_formatted_path(struct strbuf *dest, const char *path,
+			   const char *prefix, enum path_format format)
+{
+	switch (format) {
+	case PATH_FORMAT_UNMODIFIED:
+		strbuf_addstr(dest, path);
+		break;
+
+	case PATH_FORMAT_RELATIVE: {
+		struct strbuf relative_buf = STRBUF_INIT;
+		struct strbuf real_path = STRBUF_INIT;
+		struct strbuf real_prefix = STRBUF_INIT;
+		char *cwd = NULL;
+
+		/*
+		 * We don't ever produce a relative path if prefix is NULL,
+		 * so set the prefix to the current directory so that we can
+		 * produce a relative path whenever possible.
+		 */
+		if (!prefix)
+			prefix = cwd = xgetcwd();
+
+		if (!is_absolute_path(path)) {
+			strbuf_realpath_forgiving(&real_path, path, 1);
+			path = real_path.buf;
+		}
+		if (!is_absolute_path(prefix)) {
+			strbuf_realpath_forgiving(&real_prefix, prefix, 1);
+			prefix = real_prefix.buf;
+		}
+
+		strbuf_addstr(dest, relative_path(path, prefix, &relative_buf));
+
+		strbuf_release(&relative_buf);
+		strbuf_release(&real_path);
+		strbuf_release(&real_prefix);
+		free(cwd);
+		break;
+	}
+
+	case PATH_FORMAT_RELATIVE_IF_SHARED: {
+		struct strbuf relative_buf = STRBUF_INIT;
+
+		/*
+		 * If we're using RELATIVE_IF_SHARED mode, then we want an
+		 * absolute path unless the two share a common prefix, so don't
+		 * default the prefix to the current working directory. Doing so
+		 * would cause a relative path to always be produced if possible.
+		 */
+		strbuf_addstr(dest, relative_path(path, prefix, &relative_buf));
+		strbuf_release(&relative_buf);
+		break;
+	}
+
+	case PATH_FORMAT_CANONICAL: {
+		struct strbuf canonical_buf = STRBUF_INIT;
+
+		strbuf_realpath_forgiving(&canonical_buf, path, 1);
+		strbuf_addbuf(dest, &canonical_buf);
+
+		strbuf_release(&canonical_buf);
+		break;
+	}
+
+	default:
+		BUG("unknown path_format value %d", format);
+	}
+}
+
 REPO_GIT_PATH_FUNC(squash_msg, "SQUASH_MSG")
 REPO_GIT_PATH_FUNC(merge_msg, "MERGE_MSG")
 REPO_GIT_PATH_FUNC(merge_rr, "MERGE_RR")
diff --git a/path.h b/path.h
index 4c2958a903..4d982a2c8e 100644
--- a/path.h
+++ b/path.h
@@ -262,6 +262,36 @@ enum scld_error safe_create_leading_directories_no_share(char *path);
 int safe_create_file_with_leading_directories(struct repository *repo,
 					      const char *path);
 
+/**
+ * The formatting strategy to apply when writing a path into a buffer.
+ */
+enum path_format {
+	/* Output the path exactly as-is without any modifications. */
+	PATH_FORMAT_UNMODIFIED,
+
+	/* Output a path relative to the provided directory prefix. */
+	PATH_FORMAT_RELATIVE,
+
+	/* Output a relative path only if the path shares a root with the prefix. */
+	PATH_FORMAT_RELATIVE_IF_SHARED,
+
+	/* Output a fully resolved, absolute canonical path. */
+	PATH_FORMAT_CANONICAL
+};
+
+/**
+ * Format a path according to the specified formatting strategy and append
+ * the result to the given strbuf.
+ *
+ * `dest`   : The string buffer to append the formatted path to.
+ * `path`   : The path string that needs to be formatted.
+ * `prefix` : The directory prefix to calculate relative offsets against.
+ * Pass NULL to default to the current working directory where applicable.
+ * `format` : The formatting behavior rule to execute.
+ */
+void append_formatted_path(struct strbuf *dest, const char *path,
+			   const char *prefix, enum path_format format);
+
 # ifdef USE_THE_REPOSITORY_VARIABLE
 #  include "strbuf.h"
 #  include "repository.h"
-- 
2.54.0


^ permalink raw reply related

* [GSoC Patch v6 2/4] rev-parse: use append_formatted_path() for path formatting
From: K Jayatheerth @ 2026-06-20  3:16 UTC (permalink / raw)
  To: git
  Cc: jltobler, lucasseikioshiro, gitster, phillip.wood, sandals,
	kumarayushjha123, a3205153416, kristofferhaugsbakk, K Jayatheerth
In-Reply-To: <20260620031644.353772-1-jayatheerthkulkarni2005@gmail.com>

Now that the core path-formatting algorithm lives in
append_formatted_path(), print_path() doesn't need to duplicate it.

Replace the body of print_path() with a small mapping from rev-parse's
existing format_type/default_type pair to the shared path_format enum,
then delegate to append_formatted_path(). The two local enums, and
every call site that uses them throughout cmd_rev_parse(), are left
untouched.

Mentored-by: Justin Tobler <jltobler@gmail.com>
Mentored-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>
Signed-off-by: K Jayatheerth <jayatheerthkulkarni2005@gmail.com>
---
 builtin/rev-parse.c | 73 ++++++++++++++++++---------------------------
 1 file changed, 29 insertions(+), 44 deletions(-)

diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index bb882678fe..6de01466db 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -653,53 +653,38 @@ enum default_type {
 	DEFAULT_UNMODIFIED,
 };
 
-static void print_path(const char *path, const char *prefix, enum format_type format, enum default_type def)
+static void print_path(const char *path, const char *prefix,
+		       enum format_type format, enum default_type def)
 {
-	char *cwd = NULL;
-	/*
-	 * We don't ever produce a relative path if prefix is NULL, so set the
-	 * prefix to the current directory so that we can produce a relative
-	 * path whenever possible.  If we're using RELATIVE_IF_SHARED mode, then
-	 * we want an absolute path unless the two share a common prefix, so don't
-	 * set it in that case, since doing so causes a relative path to always
-	 * be produced if possible.
-	 */
-	if (!prefix && (format != FORMAT_DEFAULT || def != DEFAULT_RELATIVE_IF_SHARED))
-		prefix = cwd = xgetcwd();
-	if (format == FORMAT_DEFAULT && def == DEFAULT_UNMODIFIED) {
-		puts(path);
-	} else if (format == FORMAT_RELATIVE ||
-		  (format == FORMAT_DEFAULT && def == DEFAULT_RELATIVE)) {
-		/*
-		 * In order for relative_path to work as expected, we need to
-		 * make sure that both paths are absolute paths.  If we don't,
-		 * we can end up with an unexpected absolute path that the user
-		 * didn't want.
-		 */
-		struct strbuf buf = STRBUF_INIT, realbuf = STRBUF_INIT, prefixbuf = STRBUF_INIT;
-		if (!is_absolute_path(path)) {
-			strbuf_realpath_forgiving(&realbuf, path,  1);
-			path = realbuf.buf;
-		}
-		if (!is_absolute_path(prefix)) {
-			strbuf_realpath_forgiving(&prefixbuf, prefix, 1);
-			prefix = prefixbuf.buf;
+	struct strbuf sb = STRBUF_INIT;
+	enum path_format fmt;
+
+	if (format == FORMAT_RELATIVE) {
+		fmt = PATH_FORMAT_RELATIVE;
+	} else if (format == FORMAT_CANONICAL) {
+		fmt = PATH_FORMAT_CANONICAL;
+	} else /* FORMAT_DEFAULT */ {
+		switch (def) {
+		case DEFAULT_RELATIVE:
+			fmt = PATH_FORMAT_RELATIVE;
+			break;
+		case DEFAULT_RELATIVE_IF_SHARED:
+			fmt = PATH_FORMAT_RELATIVE_IF_SHARED;
+			break;
+		case DEFAULT_CANONICAL:
+			fmt = PATH_FORMAT_CANONICAL;
+			break;
+		case DEFAULT_UNMODIFIED:
+		default:
+			fmt = PATH_FORMAT_UNMODIFIED;
+			break;
 		}
-		puts(relative_path(path, prefix, &buf));
-		strbuf_release(&buf);
-		strbuf_release(&realbuf);
-		strbuf_release(&prefixbuf);
-	} else if (format == FORMAT_DEFAULT && def == DEFAULT_RELATIVE_IF_SHARED) {
-		struct strbuf buf = STRBUF_INIT;
-		puts(relative_path(path, prefix, &buf));
-		strbuf_release(&buf);
-	} else {
-		struct strbuf buf = STRBUF_INIT;
-		strbuf_realpath_forgiving(&buf, path, 1);
-		puts(buf.buf);
-		strbuf_release(&buf);
 	}
-	free(cwd);
+
+	append_formatted_path(&sb, path, prefix, fmt);
+	puts(sb.buf);
+
+	strbuf_release(&sb);
 }
 
 int cmd_rev_parse(int argc,
-- 
2.54.0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox