Git development
 help / color / mirror / Atom feed
* [PATCH v2 04/18] setup: stop using `the_repository` in `prefix_path()`
From: Patrick Steinhardt @ 2026-05-18  9:30 UTC (permalink / raw)
  To: git; +Cc: Karthik Nayak, Elijah Newren, Junio C Hamano, Tian Yuchen
In-Reply-To: <20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im>

Stop using `the_repository` in `prefix_path()` and instead accept the
repository as a parameter. The injection of `the_repository` is thus
bumped one level higher, where callers now pass it in explicitly.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 builtin/blame.c            |  2 +-
 builtin/check-attr.c       |  2 +-
 builtin/checkout-index.c   |  4 ++--
 builtin/mv.c               |  5 +++--
 builtin/sparse-checkout.c  |  3 ++-
 builtin/update-index.c     |  6 +++---
 line-log.c                 |  2 +-
 object-name.c              |  2 +-
 pathspec.c                 |  2 +-
 setup.c                    | 15 ++++++++-------
 setup.h                    |  4 ++--
 t/helper/test-path-utils.c |  2 +-
 12 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/builtin/blame.c b/builtin/blame.c
index f3a11eff44..ffbd3ce5c5 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -708,7 +708,7 @@ static unsigned parse_score(const char *arg)
 
 static char *add_prefix(const char *prefix, const char *path)
 {
-	return prefix_path(prefix, prefix ? strlen(prefix) : 0, path);
+	return prefix_path(the_repository, prefix, prefix ? strlen(prefix) : 0, path);
 }
 
 static int git_blame_config(const char *var, const char *value,
diff --git a/builtin/check-attr.c b/builtin/check-attr.c
index 51ed48ce43..04b86e42ae 100644
--- a/builtin/check-attr.c
+++ b/builtin/check-attr.c
@@ -67,7 +67,7 @@ static void check_attr(const char *prefix, struct attr_check *check,
 
 {
 	char *full_path =
-		prefix_path(prefix, prefix ? strlen(prefix) : 0, file);
+		prefix_path(the_repository, prefix, prefix ? strlen(prefix) : 0, file);
 
 	if (collect_all) {
 		git_all_attrs(the_repository->index, full_path, check);
diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c
index 188128aebd..311b94ff31 100644
--- a/builtin/checkout-index.c
+++ b/builtin/checkout-index.c
@@ -303,7 +303,7 @@ int cmd_checkout_index(int argc,
 			die("git checkout-index: don't mix '--all' and explicit filenames");
 		if (read_from_stdin)
 			die("git checkout-index: don't mix '--stdin' and explicit filenames");
-		p = prefix_path(prefix, prefix_length, arg);
+		p = prefix_path(repo, prefix, prefix_length, arg);
 		err |= checkout_file(repo->index, p, prefix);
 		free(p);
 	}
@@ -325,7 +325,7 @@ int cmd_checkout_index(int argc,
 					die("line is badly quoted");
 				strbuf_swap(&buf, &unquoted);
 			}
-			p = prefix_path(prefix, prefix_length, buf.buf);
+			p = prefix_path(repo, prefix, prefix_length, buf.buf);
 			err |= checkout_file(repo->index, p, prefix);
 			free(p);
 		}
diff --git a/builtin/mv.c b/builtin/mv.c
index 2215d34e31..948b330639 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -71,7 +71,7 @@ static void internal_prefix_pathspec(struct strvec *out,
 
 		trimmed = xmemdupz(pathspec[i], to_copy);
 		maybe_basename = (flags & DUP_BASENAME) ? basename(trimmed) : trimmed;
-		prefixed_path = prefix_path(prefix, prefixlen, maybe_basename);
+		prefixed_path = prefix_path(the_repository, prefix, prefixlen, maybe_basename);
 		strvec_push(out, prefixed_path);
 
 		free(prefixed_path);
@@ -394,7 +394,8 @@ int cmd_mv(int argc,
 			for (j = 0; j < last - first; j++) {
 				const struct cache_entry *ce = the_repository->index->cache[first + j];
 				const char *path = ce->name;
-				char *prefixed_path = prefix_path(dst_with_slash, dst_with_slash_len, path + length + 1);
+				char *prefixed_path = prefix_path(the_repository, dst_with_slash,
+								  dst_with_slash_len, path + length + 1);
 
 				strvec_push(&sources, path);
 				strvec_push(&destinations, prefixed_path);
diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c
index f4aa405da9..2af50fb2f9 100644
--- a/builtin/sparse-checkout.c
+++ b/builtin/sparse-checkout.c
@@ -735,7 +735,8 @@ static void sanitize_paths(struct repository *repo,
 		int prefix_len = strlen(prefix);
 
 		for (i = 0; i < args->nr; i++) {
-			char *prefixed_path = prefix_path(prefix, prefix_len, args->v[i]);
+			char *prefixed_path = prefix_path(the_repository, prefix,
+							  prefix_len, args->v[i]);
 			strvec_replace(args, i, prefixed_path);
 			free(prefixed_path);
 		}
diff --git a/builtin/update-index.c b/builtin/update-index.c
index 8a5907767b..7434112b8e 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -655,7 +655,7 @@ static int do_unresolve(int ac, const char **av,
 
 	for (i = 1; i < ac; i++) {
 		const char *arg = av[i];
-		char *p = prefix_path(prefix, prefix_length, arg);
+		char *p = prefix_path(the_repository, prefix, prefix_length, arg);
 		err |= unresolve_one(p);
 		free(p);
 	}
@@ -1158,7 +1158,7 @@ int cmd_update_index(int argc,
 			}
 
 			setup_work_tree();
-			p = prefix_path(prefix, prefix_length, path);
+			p = prefix_path(the_repository, prefix, prefix_length, path);
 			update_one(p);
 			if (set_executable_bit)
 				chmod_path(set_executable_bit, p);
@@ -1208,7 +1208,7 @@ int cmd_update_index(int argc,
 					die("line is badly quoted");
 				strbuf_swap(&buf, &unquoted);
 			}
-			p = prefix_path(prefix, prefix_length, buf.buf);
+			p = prefix_path(the_repository, prefix, prefix_length, buf.buf);
 			update_one(p);
 			if (set_executable_bit)
 				chmod_path(set_executable_bit, p);
diff --git a/line-log.c b/line-log.c
index 858a899cd2..346c60c554 100644
--- a/line-log.c
+++ b/line-log.c
@@ -589,7 +589,7 @@ parse_lines(struct repository *r, struct commit *commit,
 		range_part = xstrndup(item->string, name_part - item->string);
 		name_part++;
 
-		full_name = prefix_path(prefix, prefix ? strlen(prefix) : 0,
+		full_name = prefix_path(r, prefix, prefix ? strlen(prefix) : 0,
 					name_part);
 
 		spec = alloc_filespec(full_name);
diff --git a/object-name.c b/object-name.c
index 37a9ce8e87..9ac86f19c7 100644
--- a/object-name.c
+++ b/object-name.c
@@ -1707,7 +1707,7 @@ static char *resolve_relative_path(struct repository *r, const char *rel)
 		die(_("relative path syntax can't be used outside working tree"));
 
 	/* die() inside prefix_path() if resolved path is outside worktree */
-	return prefix_path(startup_info->prefix,
+	return prefix_path(the_repository, startup_info->prefix,
 			   startup_info->prefix ? strlen(startup_info->prefix) : 0,
 			   rel);
 }
diff --git a/pathspec.c b/pathspec.c
index 5993c4afa0..f78b22709c 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -486,7 +486,7 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags,
 		match = xstrdup(copyfrom);
 		prefixlen = 0;
 	} else {
-		match = prefix_path_gently(prefix, prefixlen,
+		match = prefix_path_gently(the_repository, prefix, prefixlen,
 					   &prefixlen, copyfrom);
 		if (!match) {
 			const char *hint_path;
diff --git a/setup.c b/setup.c
index 041e08b98d..adad6ceec0 100644
--- a/setup.c
+++ b/setup.c
@@ -117,7 +117,8 @@ static int abspath_part_inside_repo(struct repository *repo, char *path)
  *  ../../sub1/sub2/foo -> sub1/sub2/foo (but no remaining prefix)
  *  `pwd`/../bar -> sub1/bar       (no remaining prefix)
  */
-char *prefix_path_gently(const char *prefix, int len,
+char *prefix_path_gently(struct repository *repo,
+			 const char *prefix, int len,
 			 int *remaining_prefix, const char *path)
 {
 	const char *orig = path;
@@ -130,7 +131,7 @@ char *prefix_path_gently(const char *prefix, int len,
 			free(sanitized);
 			return NULL;
 		}
-		if (abspath_part_inside_repo(the_repository, sanitized)) {
+		if (abspath_part_inside_repo(repo, sanitized)) {
 			free(sanitized);
 			return NULL;
 		}
@@ -146,13 +147,13 @@ char *prefix_path_gently(const char *prefix, int len,
 	return sanitized;
 }
 
-char *prefix_path(const char *prefix, int len, const char *path)
+char *prefix_path(struct repository *repo, const char *prefix, int len, const char *path)
 {
-	char *r = prefix_path_gently(prefix, len, NULL, path);
+	char *r = prefix_path_gently(repo, prefix, len, NULL, path);
 	if (!r) {
-		const char *hint_path = repo_get_work_tree(the_repository);
+		const char *hint_path = repo_get_work_tree(repo);
 		if (!hint_path)
-			hint_path = repo_get_git_dir(the_repository);
+			hint_path = repo_get_git_dir(repo);
 		die(_("'%s' is outside repository at '%s'"), path,
 		    absolute_path(hint_path));
 	}
@@ -162,7 +163,7 @@ char *prefix_path(const char *prefix, int len, const char *path)
 int path_inside_repo(const char *prefix, const char *path)
 {
 	int len = prefix ? strlen(prefix) : 0;
-	char *r = prefix_path_gently(prefix, len, NULL, path);
+	char *r = prefix_path_gently(the_repository, prefix, len, NULL, path);
 	if (r) {
 		free(r);
 		return 1;
diff --git a/setup.h b/setup.h
index 71d3f91883..24034572b1 100644
--- a/setup.h
+++ b/setup.h
@@ -138,8 +138,8 @@ const char *enter_repo(const char *path, unsigned flags);
 
 const char *setup_git_directory_gently(int *);
 const char *setup_git_directory(void);
-char *prefix_path(const char *prefix, int len, const char *path);
-char *prefix_path_gently(const char *prefix, int len, int *remaining, const char *path);
+char *prefix_path(struct repository *repo, const char *prefix, int len, const char *path);
+char *prefix_path_gently(struct repository *repo, const char *prefix, int len, int *remaining, const char *path);
 
 int check_filename(const char *prefix, const char *name);
 void verify_filename(const char *prefix,
diff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c
index 874542ec34..163fdeefb0 100644
--- a/t/helper/test-path-utils.c
+++ b/t/helper/test-path-utils.c
@@ -379,7 +379,7 @@ int cmd__path_utils(int argc, const char **argv)
 		int nongit_ok;
 		setup_git_directory_gently(&nongit_ok);
 		while (argc > 3) {
-			char *pfx = prefix_path(prefix, prefix_len, argv[3]);
+			char *pfx = prefix_path(the_repository, prefix, prefix_len, argv[3]);
 
 			puts(pfx);
 			free(pfx);

-- 
2.54.0.771.g3ed373ac14.dirty


^ permalink raw reply related

* [PATCH v2 03/18] setup: stop using `the_repository` in `is_inside_git_dir()`
From: Patrick Steinhardt @ 2026-05-18  9:30 UTC (permalink / raw)
  To: git; +Cc: Karthik Nayak, Elijah Newren, Junio C Hamano, Tian Yuchen
In-Reply-To: <20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im>

Similar as with the preceding commit, `is_inside_git_dir()` determines
whether the current working directory is located inside the gitdir of
`the_repository`. Perform the same refactoring by dropping the caching
mechanism and injecting the repository that shall be checked.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 builtin/rev-parse.c |  2 +-
 setup.c             | 14 ++++++--------
 setup.h             |  2 +-
 3 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 52709ca69b..2fcd6851d1 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -1063,7 +1063,7 @@ int cmd_rev_parse(int argc,
 				continue;
 			}
 			if (!strcmp(arg, "--is-inside-git-dir")) {
-				printf("%s\n", is_inside_git_dir() ? "true"
+				printf("%s\n", is_inside_git_dir(the_repository) ? "true"
 						: "false");
 				continue;
 			}
diff --git a/setup.c b/setup.c
index b316d9aaa8..041e08b98d 100644
--- a/setup.c
+++ b/setup.c
@@ -26,7 +26,6 @@
 #include "trace2.h"
 #include "worktree.h"
 
-static int inside_git_dir = -1;
 static int work_tree_config_is_bogus;
 enum allowed_bare_repo {
 	ALLOWED_BARE_REPO_EXPLICIT = 0,
@@ -298,7 +297,7 @@ void verify_filename(const char *prefix,
  */
 void verify_non_filename(const char *prefix, const char *arg)
 {
-	if (!is_inside_work_tree(the_repository) || is_inside_git_dir())
+	if (!is_inside_work_tree(the_repository) || is_inside_git_dir(the_repository))
 		return;
 	if (*arg == '-')
 		return; /* flag */
@@ -469,11 +468,12 @@ int is_nonbare_repository_dir(struct strbuf *path)
 	return ret;
 }
 
-int is_inside_git_dir(void)
+int is_inside_git_dir(struct repository *repo)
 {
-	if (inside_git_dir < 0)
-		inside_git_dir = is_inside_dir(repo_get_git_dir(the_repository));
-	return inside_git_dir;
+	struct strbuf buf = STRBUF_INIT;
+	int ret = is_inside_dir(strbuf_realpath(&buf, repo_get_git_dir(repo), 1));
+	strbuf_release(&buf);
+	return ret;
 }
 
 int is_inside_work_tree(struct repository *repo)
@@ -1256,7 +1256,6 @@ static const char *setup_discovered_git_dir(struct repository *repo,
 	set_git_work_tree(".");
 	if (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))
 		set_git_dir(repo, gitdir, 0);
-	inside_git_dir = 0;
 	if (offset >= cwd->len)
 		return NULL;
 
@@ -1291,7 +1290,6 @@ static const char *setup_bare_git_dir(struct repository *repo,
 		return setup_explicit_git_dir(repo, gitdir, cwd, repo_fmt, nongit_ok);
 	}
 
-	inside_git_dir = 1;
 	if (offset != cwd->len) {
 		if (chdir(cwd->buf))
 			die_errno(_("cannot come back to cwd"));
diff --git a/setup.h b/setup.h
index 7c0aa75319..71d3f91883 100644
--- a/setup.h
+++ b/setup.h
@@ -4,7 +4,7 @@
 #include "refs.h"
 #include "string-list.h"
 
-int is_inside_git_dir(void);
+int is_inside_git_dir(struct repository *repo);
 int is_inside_work_tree(struct repository *repo);
 int get_common_dir_noenv(struct strbuf *sb, const char *gitdir);
 int get_common_dir(struct strbuf *sb, const char *gitdir);

-- 
2.54.0.771.g3ed373ac14.dirty


^ permalink raw reply related

* [PATCH v2 02/18] setup: stop using `the_repository` in `is_inside_worktree()`
From: Patrick Steinhardt @ 2026-05-18  9:30 UTC (permalink / raw)
  To: git; +Cc: Karthik Nayak, Elijah Newren, Junio C Hamano, Tian Yuchen
In-Reply-To: <20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im>

The function `is_inside_worktree()` verifies whether or not the current
working directory is located inside the worktree of `the_repository`.
This is done by taking the worktree path and verifying that it's a
prefix of the current working directory.

This information is cached so that we don't have to re-do this change
multiple times. Furthermore, we proactively set the value in multiple
locations so that we don't even have to perform the check when we have
discovered the repository.

While we could simply move the caching variable into the repository, the
current layout doesn't really feel sensible in the first place:

  - It can easily lead to false positives or negatives if at any point
    in time we may switch the current working directory.

  - We don't call the function in a hot loop, and neither is it overly
    expensive to compute.

Drop the caching infrastructure and instead compute the property ad-hoc
via an injected repository.

Note that there is one small gotcha: we sometimes may end up with
relative directory paths, and if so `is_inside_dir()` might fail. This
wasn't an issue before because of how we proactively set the cached
value during repository discovery. Now that we stop doing that it
becomes a problem though, but it is worked around by resolving the
repository directory via `realpath()`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 builtin/ls-files.c  |  2 +-
 builtin/rev-parse.c |  4 ++--
 object-name.c       |  2 +-
 setup.c             | 25 ++++++++++++++-----------
 setup.h             |  2 +-
 submodule.c         |  2 +-
 6 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index b148607f7a..09d95111b3 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -703,7 +703,7 @@ int cmd_ls_files(int argc,
 	if (dir.exclude_per_dir)
 		exc_given = 1;
 
-	if (require_work_tree && !is_inside_work_tree())
+	if (require_work_tree && !is_inside_work_tree(repo))
 		setup_work_tree();
 
 	if (recurse_submodules &&
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 218b5f34d6..52709ca69b 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -1006,7 +1006,7 @@ int cmd_rev_parse(int argc,
 			}
 			if (!strcmp(arg, "--show-cdup")) {
 				const char *pfx = prefix;
-				if (!is_inside_work_tree()) {
+				if (!is_inside_work_tree(the_repository)) {
 					const char *work_tree =
 						repo_get_work_tree(the_repository);
 					if (work_tree)
@@ -1068,7 +1068,7 @@ int cmd_rev_parse(int argc,
 				continue;
 			}
 			if (!strcmp(arg, "--is-inside-work-tree")) {
-				printf("%s\n", is_inside_work_tree() ? "true"
+				printf("%s\n", is_inside_work_tree(the_repository) ? "true"
 						: "false");
 				continue;
 			}
diff --git a/object-name.c b/object-name.c
index 21dcdc4a0e..37a9ce8e87 100644
--- a/object-name.c
+++ b/object-name.c
@@ -1703,7 +1703,7 @@ static char *resolve_relative_path(struct repository *r, const char *rel)
 	if (!starts_with(rel, "./") && !starts_with(rel, "../"))
 		return NULL;
 
-	if (r != the_repository || !is_inside_work_tree())
+	if (r != the_repository || !is_inside_work_tree(the_repository))
 		die(_("relative path syntax can't be used outside working tree"));
 
 	/* die() inside prefix_path() if resolved path is outside worktree */
diff --git a/setup.c b/setup.c
index ba2898473a..b316d9aaa8 100644
--- a/setup.c
+++ b/setup.c
@@ -27,7 +27,6 @@
 #include "worktree.h"
 
 static int inside_git_dir = -1;
-static int inside_work_tree = -1;
 static int work_tree_config_is_bogus;
 enum allowed_bare_repo {
 	ALLOWED_BARE_REPO_EXPLICIT = 0,
@@ -299,7 +298,7 @@ void verify_filename(const char *prefix,
  */
 void verify_non_filename(const char *prefix, const char *arg)
 {
-	if (!is_inside_work_tree() || is_inside_git_dir())
+	if (!is_inside_work_tree(the_repository) || is_inside_git_dir())
 		return;
 	if (*arg == '-')
 		return; /* flag */
@@ -477,11 +476,20 @@ int is_inside_git_dir(void)
 	return inside_git_dir;
 }
 
-int is_inside_work_tree(void)
+int is_inside_work_tree(struct repository *repo)
 {
-	if (inside_work_tree < 0)
-		inside_work_tree = is_inside_dir(repo_get_work_tree(the_repository));
-	return inside_work_tree;
+	struct strbuf buf = STRBUF_INIT;
+	const char *worktree;
+	int ret;
+
+	worktree = repo_get_work_tree(repo);
+	if (!worktree)
+		return 0;
+
+	ret = is_inside_dir(strbuf_realpath(&buf, worktree, 1));
+
+	strbuf_release(&buf);
+	return ret;
 }
 
 void setup_work_tree(void)
@@ -798,13 +806,10 @@ static int check_repository_format_gently(struct repository *repo,
 	if (!has_common) {
 		if (candidate->is_bare != -1) {
 			is_bare_repository_cfg = candidate->is_bare;
-			if (is_bare_repository_cfg == 1)
-				inside_work_tree = -1;
 		}
 		if (candidate->work_tree) {
 			free(git_work_tree_cfg);
 			git_work_tree_cfg = xstrdup(candidate->work_tree);
-			inside_work_tree = -1;
 		}
 	}
 
@@ -1252,7 +1257,6 @@ static const char *setup_discovered_git_dir(struct repository *repo,
 	if (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))
 		set_git_dir(repo, gitdir, 0);
 	inside_git_dir = 0;
-	inside_work_tree = 1;
 	if (offset >= cwd->len)
 		return NULL;
 
@@ -1288,7 +1292,6 @@ static const char *setup_bare_git_dir(struct repository *repo,
 	}
 
 	inside_git_dir = 1;
-	inside_work_tree = 0;
 	if (offset != cwd->len) {
 		if (chdir(cwd->buf))
 			die_errno(_("cannot come back to cwd"));
diff --git a/setup.h b/setup.h
index 80bc6e5f07..7c0aa75319 100644
--- a/setup.h
+++ b/setup.h
@@ -5,7 +5,7 @@
 #include "string-list.h"
 
 int is_inside_git_dir(void);
-int is_inside_work_tree(void);
+int is_inside_work_tree(struct repository *repo);
 int get_common_dir_noenv(struct strbuf *sb, const char *gitdir);
 int get_common_dir(struct strbuf *sb, const char *gitdir);
 
diff --git a/submodule.c b/submodule.c
index b1a0363f9d..a939ff5072 100644
--- a/submodule.c
+++ b/submodule.c
@@ -2620,7 +2620,7 @@ int get_superproject_working_tree(struct strbuf *buf)
 	int code;
 	ssize_t len;
 
-	if (!is_inside_work_tree())
+	if (!is_inside_work_tree(the_repository))
 		/*
 		 * FIXME:
 		 * We might have a superproject, but it is harder

-- 
2.54.0.771.g3ed373ac14.dirty


^ permalink raw reply related

* [PATCH v2 01/18] setup: replace use of `the_repository` in static functions
From: Patrick Steinhardt @ 2026-05-18  9:30 UTC (permalink / raw)
  To: git; +Cc: Karthik Nayak, Elijah Newren, Junio C Hamano, Tian Yuchen
In-Reply-To: <20260518-pks-setup-wo-the-repository-v2-0-6933c0f1d568@pks.im>

Replace the use of `the_repository` in "setup.c" for all static
functions. For now, we simply add `the_repository` to invocations of
these functions. This will be addressed in subsequent commits, where
we'll move up `the_repository` one more layer to callers of "setup.c".

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 setup.c | 188 ++++++++++++++++++++++++++++++++++------------------------------
 1 file changed, 100 insertions(+), 88 deletions(-)

diff --git a/setup.c b/setup.c
index 7ec4427368..ba2898473a 100644
--- a/setup.c
+++ b/setup.c
@@ -50,13 +50,13 @@ const char *tmp_original_cwd;
  * /dir/repolink/file     (repolink points to /dir/repo) -> file
  * /dir/repo              (exactly equal to work tree)   -> (empty string)
  */
-static int abspath_part_inside_repo(char *path)
+static int abspath_part_inside_repo(struct repository *repo, char *path)
 {
 	size_t len;
 	size_t wtlen;
 	char *path0;
 	int off;
-	const char *work_tree = precompose_string_if_needed(repo_get_work_tree(the_repository));
+	const char *work_tree = precompose_string_if_needed(repo_get_work_tree(repo));
 	struct strbuf realpath = STRBUF_INIT;
 
 	if (!work_tree)
@@ -132,7 +132,7 @@ char *prefix_path_gently(const char *prefix, int len,
 			free(sanitized);
 			return NULL;
 		}
-		if (abspath_part_inside_repo(sanitized)) {
+		if (abspath_part_inside_repo(the_repository, sanitized)) {
 			free(sanitized);
 			return NULL;
 		}
@@ -509,7 +509,7 @@ void setup_work_tree(void)
 	initialized = 1;
 }
 
-static void setup_original_cwd(void)
+static void setup_original_cwd(struct repository *repo)
 {
 	struct strbuf tmp = STRBUF_INIT;
 	const char *worktree = NULL;
@@ -535,9 +535,9 @@ static void setup_original_cwd(void)
 
 	/* Normalize the directory */
 	if (!strbuf_realpath(&tmp, tmp_original_cwd, 0)) {
-		trace2_data_string("setup", the_repository,
+		trace2_data_string("setup", repo,
 				   "realpath-path", tmp_original_cwd);
-		trace2_data_string("setup", the_repository,
+		trace2_data_string("setup", repo,
 				   "realpath-failure", strerror(errno));
 		free((char*)tmp_original_cwd);
 		tmp_original_cwd = NULL;
@@ -552,7 +552,7 @@ static void setup_original_cwd(void)
 	 * Get our worktree; we only protect the current working directory
 	 * if it's in the worktree.
 	 */
-	worktree = repo_get_work_tree(the_repository);
+	worktree = repo_get_work_tree(repo);
 	if (!worktree)
 		goto no_prevention_needed;
 
@@ -747,7 +747,10 @@ static int check_repo_format(const char *var, const char *value,
 	return read_worktree_config(var, value, ctx, vdata);
 }
 
-static int check_repository_format_gently(const char *gitdir, struct repository_format *candidate, int *nongit_ok)
+static int check_repository_format_gently(struct repository *repo,
+					  const char *gitdir,
+					  struct repository_format *candidate,
+					  int *nongit_ok)
 {
 	struct strbuf sb = STRBUF_INIT;
 	struct strbuf err = STRBUF_INIT;
@@ -776,7 +779,7 @@ static int check_repository_format_gently(const char *gitdir, struct repository_
 		die("%s", err.buf);
 	}
 
-	the_repository->repository_format_precious_objects = candidate->precious_objects;
+	repo->repository_format_precious_objects = candidate->precious_objects;
 
 	string_list_clear(&candidate->unknown_extensions, 0);
 	string_list_clear(&candidate->v1_only_extensions, 0);
@@ -1034,7 +1037,8 @@ const char *read_gitfile_gently(const char *path, int *return_error_code)
 	return error_code ? NULL : path;
 }
 
-static void setup_git_env_internal(const char *git_dir,
+static void setup_git_env_internal(struct repository *repo,
+				   const char *git_dir,
 				   bool skip_initializing_odb)
 {
 	char *git_replace_ref_base;
@@ -1052,7 +1056,7 @@ static void setup_git_env_internal(const char *git_dir,
 		args.disable_ref_updates = true;
 	args.skip_initializing_odb = skip_initializing_odb;
 
-	repo_set_gitdir(the_repository, git_dir, &args);
+	repo_set_gitdir(repo, git_dir, &args);
 	strvec_clear(&to_free);
 
 	if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))
@@ -1064,7 +1068,7 @@ static void setup_git_env_internal(const char *git_dir,
 
 	shallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT);
 	if (shallow_file)
-		set_alternate_shallow_file(the_repository, shallow_file, 0);
+		set_alternate_shallow_file(repo, shallow_file, 0);
 
 	if (git_env_bool(NO_LAZY_FETCH_ENVIRONMENT, 0))
 		fetch_if_missing = 0;
@@ -1072,30 +1076,31 @@ static void setup_git_env_internal(const char *git_dir,
 
 void setup_git_env(const char *git_dir)
 {
-	setup_git_env_internal(git_dir, false);
+	setup_git_env_internal(the_repository, git_dir, false);
 }
 
-static void set_git_dir_1(const char *path, bool skip_initializing_odb)
+static void set_git_dir_1(struct repository *repo, const char *path, bool skip_initializing_odb)
 {
 	xsetenv(GIT_DIR_ENVIRONMENT, path, 1);
-	setup_git_env_internal(path, skip_initializing_odb);
+	setup_git_env_internal(repo, path, skip_initializing_odb);
 }
 
 static void update_relative_gitdir(const char *name UNUSED,
 				   const char *old_cwd,
 				   const char *new_cwd,
-				   void *data UNUSED)
+				   void *data)
 {
+	struct repository *repo = data;
 	char *path = reparent_relative_path(old_cwd, new_cwd,
-					    repo_get_git_dir(the_repository));
+					    repo_get_git_dir(repo));
 	trace_printf_key(&trace_setup_key,
 			 "setup: move $GIT_DIR to '%s'",
 			 path);
-	set_git_dir_1(path, true);
+	set_git_dir_1(repo, path, true);
 	free(path);
 }
 
-static void set_git_dir(const char *path, int make_realpath)
+static void set_git_dir(struct repository *repo, const char *path, int make_realpath)
 {
 	struct strbuf realpath = STRBUF_INIT;
 
@@ -1104,14 +1109,15 @@ static void set_git_dir(const char *path, int make_realpath)
 		path = realpath.buf;
 	}
 
-	set_git_dir_1(path, false);
+	set_git_dir_1(repo, path, false);
 	if (!is_absolute_path(path))
-		chdir_notify_register(NULL, update_relative_gitdir, NULL);
+		chdir_notify_register(NULL, update_relative_gitdir, repo);
 
 	strbuf_release(&realpath);
 }
 
-static const char *setup_explicit_git_dir(const char *gitdirenv,
+static const char *setup_explicit_git_dir(struct repository *repo,
+					  const char *gitdirenv,
 					  struct strbuf *cwd,
 					  struct repository_format *repo_fmt,
 					  int *nongit_ok)
@@ -1139,7 +1145,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
 		die(_("not a git repository: '%s'"), gitdirenv);
 	}
 
-	if (check_repository_format_gently(gitdirenv, repo_fmt, nongit_ok)) {
+	if (check_repository_format_gently(repo, gitdirenv, repo_fmt, nongit_ok)) {
 		free(gitfile);
 		return NULL;
 	}
@@ -1155,7 +1161,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
 		}
 
 		/* #18, #26 */
-		set_git_dir(gitdirenv, 0);
+		set_git_dir(repo, gitdirenv, 0);
 		free(gitfile);
 		return NULL;
 	}
@@ -1177,7 +1183,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
 	}
 	else if (!git_env_bool(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, 1)) {
 		/* #16d */
-		set_git_dir(gitdirenv, 0);
+		set_git_dir(repo, gitdirenv, 0);
 		free(gitfile);
 		return NULL;
 	}
@@ -1185,18 +1191,18 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
 		set_git_work_tree(".");
 
 	/* set_git_work_tree() must have been called by now */
-	worktree = repo_get_work_tree(the_repository);
+	worktree = repo_get_work_tree(repo);
 
 	/* both repo_get_work_tree() and cwd are already normalized */
 	if (!strcmp(cwd->buf, worktree)) { /* cwd == worktree */
-		set_git_dir(gitdirenv, 0);
+		set_git_dir(repo, gitdirenv, 0);
 		free(gitfile);
 		return NULL;
 	}
 
 	offset = dir_inside_of(cwd->buf, worktree);
 	if (offset >= 0) {	/* cwd inside worktree? */
-		set_git_dir(gitdirenv, 1);
+		set_git_dir(repo, gitdirenv, 1);
 		if (chdir(worktree))
 			die_errno(_("cannot chdir to '%s'"), worktree);
 		strbuf_addch(cwd, '/');
@@ -1205,17 +1211,18 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
 	}
 
 	/* cwd outside worktree */
-	set_git_dir(gitdirenv, 0);
+	set_git_dir(repo, gitdirenv, 0);
 	free(gitfile);
 	return NULL;
 }
 
-static const char *setup_discovered_git_dir(const char *gitdir,
+static const char *setup_discovered_git_dir(struct repository *repo,
+					    const char *gitdir,
 					    struct strbuf *cwd, int offset,
 					    struct repository_format *repo_fmt,
 					    int *nongit_ok)
 {
-	if (check_repository_format_gently(gitdir, repo_fmt, nongit_ok))
+	if (check_repository_format_gently(repo, gitdir, repo_fmt, nongit_ok))
 		return NULL;
 
 	/* --work-tree is set without --git-dir; use discovered one */
@@ -1227,14 +1234,14 @@ static const char *setup_discovered_git_dir(const char *gitdir,
 			gitdir = to_free = real_pathdup(gitdir, 1);
 		if (chdir(cwd->buf))
 			die_errno(_("cannot come back to cwd"));
-		ret = setup_explicit_git_dir(gitdir, cwd, repo_fmt, nongit_ok);
+		ret = setup_explicit_git_dir(repo, gitdir, cwd, repo_fmt, nongit_ok);
 		free(to_free);
 		return ret;
 	}
 
 	/* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */
 	if (is_bare_repository_cfg > 0) {
-		set_git_dir(gitdir, (offset != cwd->len));
+		set_git_dir(repo, gitdir, (offset != cwd->len));
 		if (chdir(cwd->buf))
 			die_errno(_("cannot come back to cwd"));
 		return NULL;
@@ -1243,7 +1250,7 @@ static const char *setup_discovered_git_dir(const char *gitdir,
 	/* #0, #1, #5, #8, #9, #12, #13 */
 	set_git_work_tree(".");
 	if (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))
-		set_git_dir(gitdir, 0);
+		set_git_dir(repo, gitdir, 0);
 	inside_git_dir = 0;
 	inside_work_tree = 1;
 	if (offset >= cwd->len)
@@ -1258,13 +1265,14 @@ static const char *setup_discovered_git_dir(const char *gitdir,
 }
 
 /* #16.1, #17.1, #20.1, #21.1, #22.1 (see t1510) */
-static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,
+static const char *setup_bare_git_dir(struct repository *repo,
+				      struct strbuf *cwd, int offset,
 				      struct repository_format *repo_fmt,
 				      int *nongit_ok)
 {
 	int root_len;
 
-	if (check_repository_format_gently(".", repo_fmt, nongit_ok))
+	if (check_repository_format_gently(repo, ".", repo_fmt, nongit_ok))
 		return NULL;
 
 	setenv(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, "0", 1);
@@ -1276,7 +1284,7 @@ static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,
 		gitdir = offset == cwd->len ? "." : xmemdupz(cwd->buf, offset);
 		if (chdir(cwd->buf))
 			die_errno(_("cannot come back to cwd"));
-		return setup_explicit_git_dir(gitdir, cwd, repo_fmt, nongit_ok);
+		return setup_explicit_git_dir(repo, gitdir, cwd, repo_fmt, nongit_ok);
 	}
 
 	inside_git_dir = 1;
@@ -1286,10 +1294,10 @@ static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,
 			die_errno(_("cannot come back to cwd"));
 		root_len = offset_1st_component(cwd->buf);
 		strbuf_setlen(cwd, offset > root_len ? offset : root_len);
-		set_git_dir(cwd->buf, 0);
+		set_git_dir(repo, cwd->buf, 0);
 	}
 	else
-		set_git_dir(".", 0);
+		set_git_dir(repo, ".", 0);
 	return NULL;
 }
 
@@ -1827,7 +1835,7 @@ const char *enter_repo(const char *path, unsigned flags)
 	}
 
 	if (is_git_directory(".")) {
-		set_git_dir(".", 0);
+		set_git_dir(the_repository, ".", 0);
 		check_repository_format(NULL);
 		return path;
 	}
@@ -1891,18 +1899,18 @@ const char *setup_git_directory_gently(int *nongit_ok)
 
 	switch (setup_git_directory_gently_1(&dir, &gitdir, &report, 1)) {
 	case GIT_DIR_EXPLICIT:
-		prefix = setup_explicit_git_dir(gitdir.buf, &cwd, &repo_fmt, nongit_ok);
+		prefix = setup_explicit_git_dir(the_repository, gitdir.buf, &cwd, &repo_fmt, nongit_ok);
 		break;
 	case GIT_DIR_DISCOVERED:
 		if (dir.len < cwd.len && chdir(dir.buf))
 			die(_("cannot change to '%s'"), dir.buf);
-		prefix = setup_discovered_git_dir(gitdir.buf, &cwd, dir.len,
+		prefix = setup_discovered_git_dir(the_repository, gitdir.buf, &cwd, dir.len,
 						  &repo_fmt, nongit_ok);
 		break;
 	case GIT_DIR_BARE:
 		if (dir.len < cwd.len && chdir(dir.buf))
 			die(_("cannot change to '%s'"), dir.buf);
-		prefix = setup_bare_git_dir(&cwd, dir.len, &repo_fmt, nongit_ok);
+		prefix = setup_bare_git_dir(the_repository, &cwd, dir.len, &repo_fmt, nongit_ok);
 		break;
 	case GIT_DIR_HIT_CEILING:
 		if (!nongit_ok)
@@ -2044,7 +2052,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
 		free(payload);
 	}
 
-	setup_original_cwd();
+	setup_original_cwd(the_repository);
 
 	strbuf_release(&dir);
 	strbuf_release(&gitdir);
@@ -2110,7 +2118,7 @@ void check_repository_format(struct repository_format *fmt)
 	struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;
 	if (!fmt)
 		fmt = &repo_fmt;
-	check_repository_format_gently(repo_get_git_dir(the_repository), fmt, NULL);
+	check_repository_format_gently(the_repository, repo_get_git_dir(the_repository), fmt, NULL);
 	startup_info->have_repository = 1;
 	repo_set_hash_algo(the_repository, fmt->hash_algo);
 	repo_set_compat_hash_algo(the_repository, fmt->compat_hash_algo);
@@ -2239,7 +2247,9 @@ const char *get_template_dir(const char *option_template)
 
 #define GIT_DEFAULT_HASH_ENVIRONMENT "GIT_DEFAULT_HASH"
 
-static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,
+static void copy_templates_1(struct repository *repo,
+			     struct strbuf *path,
+			     struct strbuf *template_path,
 			     DIR *dir)
 {
 	size_t path_baselen = path->len;
@@ -2253,7 +2263,7 @@ static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,
 	 * with the way the namespace under .git/ is organized, should
 	 * be really carefully chosen.
 	 */
-	safe_create_dir(the_repository, path->buf, 1);
+	safe_create_dir(repo, path->buf, 1);
 	while ((de = readdir(dir)) != NULL) {
 		struct stat st_git, st_template;
 		int exists = 0;
@@ -2281,7 +2291,7 @@ static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,
 				die_errno(_("cannot opendir '%s'"), template_path->buf);
 			strbuf_addch(path, '/');
 			strbuf_addch(template_path, '/');
-			copy_templates_1(path, template_path, subdir);
+			copy_templates_1(repo, path, template_path, subdir);
 			closedir(subdir);
 		}
 		else if (exists)
@@ -2306,7 +2316,7 @@ static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,
 	}
 }
 
-static void copy_templates(const char *option_template)
+static void copy_templates(struct repository *repo, const char *option_template)
 {
 	const char *template_dir = get_template_dir(option_template);
 	struct strbuf path = STRBUF_INIT;
@@ -2347,9 +2357,9 @@ static void copy_templates(const char *option_template)
 		goto close_free_return;
 	}
 
-	strbuf_addstr(&path, repo_get_common_dir(the_repository));
+	strbuf_addstr(&path, repo_get_common_dir(repo));
 	strbuf_complete(&path, '/');
-	copy_templates_1(&path, &template_path, dir);
+	copy_templates_1(repo, &path, &template_path, dir);
 close_free_return:
 	closedir(dir);
 free_return:
@@ -2443,13 +2453,13 @@ void initialize_repository_version(int hash_algo,
 	strbuf_release(&repo_version);
 }
 
-static int is_reinit(void)
+static int is_reinit(struct repository *repo)
 {
 	struct strbuf buf = STRBUF_INIT;
 	char junk[2];
 	int ret;
 
-	repo_git_path_replace(the_repository, &buf, "HEAD");
+	repo_git_path_replace(repo, &buf, "HEAD");
 	ret = !access(buf.buf, R_OK) || readlink(buf.buf, junk, sizeof(junk) - 1) != -1;
 	strbuf_release(&buf);
 	return ret;
@@ -2459,7 +2469,7 @@ void create_reference_database(const char *initial_branch, int quiet)
 {
 	struct strbuf err = STRBUF_INIT;
 	char *to_free = NULL;
-	int reinit = is_reinit();
+	int reinit = is_reinit(the_repository);
 
 	if (ref_store_create_on_disk(get_main_ref_store(the_repository), 0, &err))
 		die("failed to set up refs db: %s", err.buf);
@@ -2493,7 +2503,8 @@ void create_reference_database(const char *initial_branch, int quiet)
 	free(to_free);
 }
 
-static int create_default_files(const char *template_path,
+static int create_default_files(struct repository *repo,
+				const char *template_path,
 				const char *original_git_dir,
 				const struct repository_format *fmt,
 				int init_shared_repository)
@@ -2502,7 +2513,7 @@ static int create_default_files(const char *template_path,
 	struct strbuf path = STRBUF_INIT;
 	int reinit;
 	int filemode;
-	const char *work_tree = repo_get_work_tree(the_repository);
+	const char *work_tree = repo_get_work_tree(repo);
 
 	/*
 	 * First copy the templates -- we might have the default
@@ -2513,19 +2524,19 @@ static int create_default_files(const char *template_path,
 	 * values (since we've just potentially changed what's available on
 	 * disk).
 	 */
-	copy_templates(template_path);
-	repo_config_clear(the_repository);
-	repo_settings_reset_shared_repository(the_repository);
-	repo_config(the_repository, git_default_config, NULL);
+	copy_templates(repo, template_path);
+	repo_config_clear(repo);
+	repo_settings_reset_shared_repository(repo);
+	repo_config(repo, git_default_config, NULL);
 
-	reinit = is_reinit();
+	reinit = is_reinit(repo);
 
 	/*
 	 * We must make sure command-line options continue to override any
 	 * values we might have just re-read from the config.
 	 */
 	if (init_shared_repository != -1)
-		repo_settings_set_shared_repository(the_repository,
+		repo_settings_set_shared_repository(repo,
 						    init_shared_repository);
 
 	is_bare_repository_cfg = !work_tree;
@@ -2534,14 +2545,14 @@ static int create_default_files(const char *template_path,
 	 * We would have created the above under user's umask -- under
 	 * shared-repository settings, we would need to fix them up.
 	 */
-	if (repo_settings_get_shared_repository(the_repository)) {
-		adjust_shared_perm(the_repository, repo_get_git_dir(the_repository));
+	if (repo_settings_get_shared_repository(repo)) {
+		adjust_shared_perm(repo, repo_get_git_dir(repo));
 	}
 
 	initialize_repository_version(fmt->hash_algo, fmt->ref_storage_format, reinit);
 
 	/* Check filemode trustability */
-	repo_git_path_replace(the_repository, &path, "config");
+	repo_git_path_replace(repo, &path, "config");
 	filemode = TEST_FILEMODE;
 	if (TEST_FILEMODE && !lstat(path.buf, &st1)) {
 		struct stat st2;
@@ -2552,22 +2563,22 @@ static int create_default_files(const char *template_path,
 		if (filemode && !reinit && (st1.st_mode & S_IXUSR))
 			filemode = 0;
 	}
-	repo_config_set(the_repository, "core.filemode", filemode ? "true" : "false");
+	repo_config_set(repo, "core.filemode", filemode ? "true" : "false");
 
 	if (is_bare_repository())
-		repo_config_set(the_repository, "core.bare", "true");
+		repo_config_set(repo, "core.bare", "true");
 	else {
-		repo_config_set(the_repository, "core.bare", "false");
+		repo_config_set(repo, "core.bare", "false");
 		/* allow template config file to override the default */
-		if (repo_settings_get_log_all_ref_updates(the_repository) == LOG_REFS_UNSET)
-			repo_config_set(the_repository, "core.logallrefupdates", "true");
+		if (repo_settings_get_log_all_ref_updates(repo) == LOG_REFS_UNSET)
+			repo_config_set(repo, "core.logallrefupdates", "true");
 		if (needs_work_tree_config(original_git_dir, work_tree))
-			repo_config_set(the_repository, "core.worktree", work_tree);
+			repo_config_set(repo, "core.worktree", work_tree);
 	}
 
 	if (!reinit) {
 		/* Check if symlink is supported in the work tree */
-		repo_git_path_replace(the_repository, &path, "tXXXXXX");
+		repo_git_path_replace(repo, &path, "tXXXXXX");
 		if (!close(xmkstemp(path.buf)) &&
 		    !unlink(path.buf) &&
 		    !symlink("testing", path.buf) &&
@@ -2575,12 +2586,12 @@ static int create_default_files(const char *template_path,
 		    S_ISLNK(st1.st_mode))
 			unlink(path.buf); /* good */
 		else
-			repo_config_set(the_repository, "core.symlinks", "false");
+			repo_config_set(repo, "core.symlinks", "false");
 
 		/* Check if the filesystem is case-insensitive */
-		repo_git_path_replace(the_repository, &path, "CoNfIg");
+		repo_git_path_replace(repo, &path, "CoNfIg");
 		if (!access(path.buf, F_OK))
-			repo_config_set(the_repository, "core.ignorecase", "true");
+			repo_config_set(repo, "core.ignorecase", "true");
 		probe_utf8_pathname_composition();
 	}
 
@@ -2588,23 +2599,23 @@ static int create_default_files(const char *template_path,
 	return reinit;
 }
 
-static void create_object_directory(void)
+static void create_object_directory(struct repository *repo)
 {
 	struct strbuf path = STRBUF_INIT;
 	size_t baselen;
 
-	strbuf_addstr(&path, repo_get_object_directory(the_repository));
+	strbuf_addstr(&path, repo_get_object_directory(repo));
 	baselen = path.len;
 
-	safe_create_dir(the_repository, path.buf, 1);
+	safe_create_dir(repo, path.buf, 1);
 
 	strbuf_setlen(&path, baselen);
 	strbuf_addstr(&path, "/pack");
-	safe_create_dir(the_repository, path.buf, 1);
+	safe_create_dir(repo, path.buf, 1);
 
 	strbuf_setlen(&path, baselen);
 	strbuf_addstr(&path, "/info");
-	safe_create_dir(the_repository, path.buf, 1);
+	safe_create_dir(repo, path.buf, 1);
 
 	strbuf_release(&path);
 }
@@ -2682,7 +2693,8 @@ static int read_default_format_config(const char *key, const char *value,
 	return ret;
 }
 
-static void repository_format_configure(struct repository_format *repo_fmt,
+static void repository_format_configure(struct repository *repo,
+					struct repository_format *repo_fmt,
 					int hash, enum ref_storage_format ref_format)
 {
 	struct default_format_config cfg = {
@@ -2719,7 +2731,7 @@ static void repository_format_configure(struct repository_format *repo_fmt,
 	} else if (cfg.hash != GIT_HASH_UNKNOWN) {
 		repo_fmt->hash_algo = cfg.hash;
 	}
-	repo_set_hash_algo(the_repository, repo_fmt->hash_algo);
+	repo_set_hash_algo(repo, repo_fmt->hash_algo);
 
 	env = getenv("GIT_DEFAULT_REF_FORMAT");
 	if (repo_fmt->version >= 0 &&
@@ -2758,7 +2770,7 @@ static void repository_format_configure(struct repository_format *repo_fmt,
 		free(backend);
 	}
 
-	repo_set_ref_storage_format(the_repository, repo_fmt->ref_storage_format,
+	repo_set_ref_storage_format(repo, repo_fmt->ref_storage_format,
 				    repo_fmt->ref_storage_payload);
 }
 
@@ -2782,12 +2794,12 @@ int init_db(const char *git_dir, const char *real_git_dir,
 		if (!exist_ok && !stat(real_git_dir, &st))
 			die(_("%s already exists"), real_git_dir);
 
-		set_git_dir(real_git_dir, 1);
+		set_git_dir(the_repository, real_git_dir, 1);
 		git_dir = repo_get_git_dir(the_repository);
 		separate_git_dir(git_dir, original_git_dir);
 	}
 	else {
-		set_git_dir(git_dir, 1);
+		set_git_dir(the_repository, git_dir, 1);
 		git_dir = repo_get_git_dir(the_repository);
 	}
 	startup_info->have_repository = 1;
@@ -2800,7 +2812,7 @@ int init_db(const char *git_dir, const char *real_git_dir,
 	 */
 	check_repository_format(&repo_fmt);
 
-	repository_format_configure(&repo_fmt, hash, ref_storage_format);
+	repository_format_configure(the_repository, &repo_fmt, hash, ref_storage_format);
 
 	/*
 	 * Ensure `core.hidedotfiles` is processed. This must happen after we
@@ -2811,12 +2823,12 @@ int init_db(const char *git_dir, const char *real_git_dir,
 
 	safe_create_dir(the_repository, git_dir, 0);
 
-	reinit = create_default_files(template_dir, original_git_dir,
+	reinit = create_default_files(the_repository, template_dir, original_git_dir,
 				      &repo_fmt, init_shared_repository);
 
 	if (!(flags & INIT_DB_SKIP_REFDB))
 		create_reference_database(initial_branch, flags & INIT_DB_QUIET);
-	create_object_directory();
+	create_object_directory(the_repository);
 
 	if (repo_settings_get_shared_repository(the_repository)) {
 		char buf[10];

-- 
2.54.0.771.g3ed373ac14.dirty


^ permalink raw reply related

* [PATCH v2 00/18] setup: drop uses of `the_repository`
From: Patrick Steinhardt @ 2026-05-18  9:30 UTC (permalink / raw)
  To: git; +Cc: Karthik Nayak, Elijah Newren, Junio C Hamano, Tian Yuchen
In-Reply-To: <20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im>

Hi,

I've had enough of "setup.c" and its complexities, so I finally decided
to take the bullet and start refactoring this subsystem. This here is
the first out of the following three steps:

  1. Drop all uses of `the_repository`. This doesn't yet allow us to get
     rid of `USE_THE_REPOSITORY_VARIABLE`.

  2. Convert a couple of global variables and drop
     `is_bare_repository_cfg`, which then allows us to drop
     `USE_THE_REPOSITORY_VARIABLE`.

  3. Refactor the subsystem a bit so that we stop intermixing repository
     discovery and repository initialization. This is my original
     motivation as I want to get rid of `odb_prepare_alternates()`, but
     due to the way we initialize the repository it has proven to be
     extremely tedious.

Most of the patches in this series here are rather mechanical. There's
only a handful of patches that warrant more attention:

  -  2/18: setup: stop using `the_repository` in `is_inside_worktree()`
  -  3/18: setup: stop using `the_repository` in `is_inside_git_dir()`
  -  9/18: setup: stop using `the_repository` in `setup_work_tree()`
  - 10/18: setup: stop using `the_repository` in `set_git_work_tree()`

Those patches don't only mechanical move stuff around, but also change
some logic to make it work.

Changes in v2:
  - Drop some static variables.
  - Rebase on top of origin/master at 59ff4886a5 (Merge branch
    'ps/clang-w-glibc-2.43-and-_Generic', 2026-05-13). This resolves a
    single conflict, but more importantly the rebase fixes CI.
  - Link to v1: https://patch.msgid.link/20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im

Changes in v1 (relative to the botched-up [1]):
  - Remove static `initialized` variable in `setup_work_tree()`.
  - Use enum values to initialize fields.
  - Fix up a comment.
  - Link to v1: https://lore.kernel.org/all/20260330-pks-setup-wo-the-repository-v1-0-0d2e822837aa@pks.im/

Thanks!

Patrick

[1]: <20260330-pks-setup-wo-the-repository-v1-0-0d2e822837aa@pks.im>

---
Patrick Steinhardt (18):
      setup: replace use of `the_repository` in static functions
      setup: stop using `the_repository` in `is_inside_worktree()`
      setup: stop using `the_repository` in `is_inside_git_dir()`
      setup: stop using `the_repository` in `prefix_path()`
      setup: stop using `the_repository` in `path_inside_repo()`
      setup: stop using `the_repository` in `verify_filename()`
      setup: stop using `the_repository` in `verify_non_filename()`
      setup: stop using `the_repository` in `enter_repo()`
      setup: stop using `the_repository` in `setup_work_tree()`
      setup: stop using `the_repository` in `set_git_work_tree()`
      setup: stop using `the_repository` in `setup_git_env()`
      setup: stop using `the_repository` in `setup_git_directory_gently()`
      setup: stop using `the_repository` in `setup_git_directory()`
      setup: stop using `the_repository` in `upgrade_repository_format()`
      setup: stop using `the_repository` in `check_repository_format()`
      setup: stop using `the_repository` in `initialize_repository_version()`
      setup: stop using `the_repository` in `create_reference_database()`
      setup: stop using `the_repository` in `init_db()`

 archive.c                                    |   2 +-
 blame.c                                      |   2 +-
 builtin/blame.c                              |   2 +-
 builtin/check-attr.c                         |   4 +-
 builtin/check-ref-format.c                   |   5 +-
 builtin/checkout-index.c                     |   4 +-
 builtin/checkout.c                           |   2 +-
 builtin/clone.c                              |  12 +-
 builtin/describe.c                           |   2 +-
 builtin/diff-index.c                         |   2 +-
 builtin/diff.c                               |  10 +-
 builtin/difftool.c                           |   2 +-
 builtin/grep.c                               |   8 +-
 builtin/hash-object.c                        |   4 +-
 builtin/help.c                               |   2 +-
 builtin/init-db.c                            |   8 +-
 builtin/ls-files.c                           |   4 +-
 builtin/merge-file.c                         |   2 +-
 builtin/mv.c                                 |   5 +-
 builtin/read-tree.c                          |   2 +-
 builtin/receive-pack.c                       |   2 +-
 builtin/reset.c                              |   6 +-
 builtin/rev-parse.c                          |  14 +-
 builtin/rm.c                                 |   2 +-
 builtin/sparse-checkout.c                    |  19 +-
 builtin/stripspace.c                         |   2 +-
 builtin/submodule--helper.c                  |   2 +-
 builtin/update-index.c                       |  16 +-
 builtin/upload-archive.c                     |   2 +-
 builtin/upload-pack.c                        |   2 +-
 daemon.c                                     |   4 +-
 environment.h                                |   2 -
 git.c                                        |  10 +-
 http-backend.c                               |   2 +-
 http-fetch.c                                 |   2 +-
 http-push.c                                  |   2 +-
 imap-send.c                                  |   2 +-
 line-log.c                                   |   2 +-
 list-objects-filter-options.c                |   2 +-
 object-name.c                                |   4 +-
 pathspec.c                                   |   2 +-
 refs.c                                       |   2 +-
 remote-curl.c                                |   4 +-
 repository.h                                 |   4 +-
 revision.c                                   |   6 +-
 scalar.c                                     |   4 +-
 setup.c                                      | 451 ++++++++++++++-------------
 setup.h                                      |  43 ++-
 submodule.c                                  |   2 +-
 t/helper/test-advise.c                       |   2 +-
 t/helper/test-bitmap.c                       |   2 +-
 t/helper/test-bloom.c                        |   2 +-
 t/helper/test-cache-tree.c                   |   2 +-
 t/helper/test-config.c                       |   2 +-
 t/helper/test-dump-cache-tree.c              |   2 +-
 t/helper/test-dump-fsmonitor.c               |   2 +-
 t/helper/test-dump-split-index.c             |   2 +-
 t/helper/test-dump-untracked-cache.c         |   2 +-
 t/helper/test-find-pack.c                    |   2 +-
 t/helper/test-fsmonitor-client.c             |   2 +-
 t/helper/test-lazy-init-name-hash.c          |   2 +-
 t/helper/test-match-trees.c                  |   2 +-
 t/helper/test-pack-deltas.c                  |   2 +-
 t/helper/test-pack-mtimes.c                  |   2 +-
 t/helper/test-partial-clone.c                |   4 +-
 t/helper/test-path-utils.c                   |   4 +-
 t/helper/test-path-walk.c                    |   2 +-
 t/helper/test-reach.c                        |   2 +-
 t/helper/test-read-cache.c                   |   2 +-
 t/helper/test-read-graph.c                   |   2 +-
 t/helper/test-read-midx.c                    |   2 +-
 t/helper/test-ref-store.c                    |   2 +-
 t/helper/test-revision-walking.c             |   2 +-
 t/helper/test-scrap-cache-tree.c             |   2 +-
 t/helper/test-serve-v2.c                     |   2 +-
 t/helper/test-submodule-config.c             |   2 +-
 t/helper/test-submodule-nested-repo-config.c |   2 +-
 t/helper/test-submodule.c                    |  10 +-
 t/helper/test-subprocess.c                   |   6 +-
 t/helper/test-userdiff.c                     |   2 +-
 t/helper/test-write-cache.c                  |   2 +-
 worktree.c                                   |   2 +-
 wt-status.c                                  |   2 +-
 83 files changed, 402 insertions(+), 383 deletions(-)

Range-diff versus v1:

 1:  2bdd6dfead =  1:  275a0e45a3 setup: replace use of `the_repository` in static functions
 2:  e38c29bd25 !  2:  d748d28abe setup: stop using `the_repository` in `is_inside_worktree()`
    @@ setup.c: int is_inside_git_dir(void)
     -	if (inside_work_tree < 0)
     -		inside_work_tree = is_inside_dir(repo_get_work_tree(the_repository));
     -	return inside_work_tree;
    -+	static struct strbuf buf = STRBUF_INIT;
    -+	const char *worktree = repo_get_work_tree(repo);
    ++	struct strbuf buf = STRBUF_INIT;
    ++	const char *worktree;
    ++	int ret;
    ++
    ++	worktree = repo_get_work_tree(repo);
     +	if (!worktree)
     +		return 0;
    -+	return is_inside_dir(strbuf_realpath(&buf, worktree, 1));
    ++
    ++	ret = is_inside_dir(strbuf_realpath(&buf, worktree, 1));
    ++
    ++	strbuf_release(&buf);
    ++	return ret;
      }
      
      void setup_work_tree(void)
 3:  184b1f2331 !  3:  3f1da8a163 setup: stop using `the_repository` in `is_inside_git_dir()`
    @@ setup.c: int is_nonbare_repository_dir(struct strbuf *path)
     -	if (inside_git_dir < 0)
     -		inside_git_dir = is_inside_dir(repo_get_git_dir(the_repository));
     -	return inside_git_dir;
    -+	static struct strbuf buf = STRBUF_INIT;
    -+	return is_inside_dir(strbuf_realpath(&buf, repo_get_git_dir(repo), 1));
    ++	struct strbuf buf = STRBUF_INIT;
    ++	int ret = is_inside_dir(strbuf_realpath(&buf, repo_get_git_dir(repo), 1));
    ++	strbuf_release(&buf);
    ++	return ret;
      }
      
      int is_inside_work_tree(struct repository *repo)
 4:  c178fb7f3d =  4:  59426f6dbc setup: stop using `the_repository` in `prefix_path()`
 5:  e408ba2332 =  5:  aae9034d31 setup: stop using `the_repository` in `path_inside_repo()`
 6:  b43251adcb =  6:  b8d6abd41f setup: stop using `the_repository` in `verify_filename()`
 7:  e489b6f84e !  7:  e6ecd9ea0d setup: stop using `the_repository` in `verify_non_filename()`
    @@ builtin/reset.c: static void parse_args(struct pathspec *pathspec,
      			/* Otherwise we treat this as a filename */
     
      ## revision.c ##
    -@@ revision.c: static int handle_dotdot_1(const char *arg, char *dotdot,
    +@@ revision.c: static int handle_dotdot_1(const char *a_name, const char *b_name,
    + 		return -1;
      
      	if (!cant_be_filename) {
    - 		*dotdot = '.';
    --		verify_non_filename(revs->prefix, arg);
    -+		verify_non_filename(the_repository, revs->prefix, arg);
    - 		*dotdot = '\0';
    +-		verify_non_filename(revs->prefix, full_name);
    ++		verify_non_filename(the_repository, revs->prefix, full_name);
      	}
      
    + 	a_obj = parse_object(revs->repo, &a_oid);
     @@ revision.c: static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl
      		goto out;
      	}
 8:  54192c579e =  8:  87fe43bf7c setup: stop using `the_repository` in `enter_repo()`
 9:  78ae1d0845 !  9:  897a0ac4a6 setup: stop using `the_repository` in `setup_work_tree()`
    @@ Commit message
         the repository as a parameter. The injection of `the_repository` is thus
         bumped one level higher, where callers now pass it in explicitly.
     
    -    Note that the function tracks bogus worktree configuration via a global
    -    variable. If we have bogus configuration, and if later on some caller
    -    tries to setup a worktree, then we'll die instead.
    +    Note that the function tracks two bits of information via global
    +    variables. This of course doesn't make much sense anymore now that we
    +    can set up worktrees for arbitrary repositories:
     
    -    Of course, tracking this as a global variable doesn't make sense anymore
    -    now that we can set up worktrees for arbitrary repositories. Move the
    -    variable into `struct repository` instead.
    +      - We track whether the worktree has already been initialized and, if
    +        so, we skip the call to `chdir_notify()` and setenv(3p). It does not
    +        make much sense to store this info in the repository, as we _would_
    +        want to update the environment when switching between worktrees back
    +        and forth.
    +
    +        So instead of storing this info in the repository, we drop this
    +        state entirely and live with the fact that we may execute the logic
    +        twice. It should ultimately be idempotent though and thus not be
    +        much of a problem.
    +
    +      - We track whether the worktree configuration is bogus. If so, and if
    +        later on some caller tries to setup the worktree, then we'll die
    +        instead. This is indeed information that we can move into the
    +        repository itself.
     
         Signed-off-by: Patrick Steinhardt <ps@pks.im>
     
    @@ setup.c
      	ALLOWED_BARE_REPO_EXPLICIT = 0,
      	ALLOWED_BARE_REPO_ALL,
     @@ setup.c: int is_inside_work_tree(struct repository *repo)
    - 	return is_inside_dir(strbuf_realpath(&buf, worktree, 1));
    + 	return ret;
      }
      
     -void setup_work_tree(void)
     +void setup_work_tree(struct repository *repo)
      {
      	const char *work_tree;
    - 	static int initialized = 0;
    -@@ setup.c: void setup_work_tree(void)
    - 	if (initialized)
    - 		return;
    +-	static int initialized = 0;
      
    +-	if (initialized)
    +-		return;
    +-
     -	if (work_tree_config_is_bogus)
     +	if (repo->worktree_config_is_bogus)
      		die(_("unable to set up work tree using invalid config"));
    @@ setup.c: void setup_work_tree(void)
      	if (!work_tree || chdir_notify(work_tree))
      		die(_("this operation must be run in a work tree"));
      
    +@@ setup.c: void setup_work_tree(void)
    + 	 */
    + 	if (getenv(GIT_WORK_TREE_ENVIRONMENT))
    + 		setenv(GIT_WORK_TREE_ENVIRONMENT, ".", 1);
    +-
    +-	initialized = 1;
    + }
    + 
    + static void setup_original_cwd(struct repository *repo)
     @@ setup.c: static const char *setup_explicit_git_dir(struct repository *repo,
      		if (git_work_tree_cfg) {
      			/* #22.2, #30 */
10:  f2f0c80991 ! 10:  f1ceac2491 setup: stop using `the_repository` in `set_git_work_tree()`
    @@ setup.c: const char *enter_repo(struct repository *repo, const char *path, unsig
      	}
     -	git_work_tree_initialized = 1;
     -	repo_set_worktree(the_repository, new_work_tree);
    -+	repo->worktree_initialized = 1;
    ++	repo->worktree_initialized = true;
     +	repo_set_worktree(repo, new_work_tree);
      }
      
11:  0c72972ba4 = 11:  f7de435b86 setup: stop using `the_repository` in `setup_git_env()`
12:  7a758cf4de = 12:  aea92d5f0a setup: stop using `the_repository` in `setup_git_directory_gently()`
13:  7485a9e031 = 13:  4981d7d67d setup: stop using `the_repository` in `setup_git_directory()`
14:  5397aac8e7 = 14:  046de3ad97 setup: stop using `the_repository` in `upgrade_repository_format()`
15:  f713bdb472 ! 15:  905b7dbb89 setup: stop using `the_repository` in `check_repository_format()`
    @@ setup.c: enum discovery_result discover_git_directory_reason(struct strbuf *comm
      }
      
     +/*
    -+ * Check the repository format version in the path found in repo_get_git_dir(the_repository),
    ++ * Check the repository format version in the path found in repo_get_git_dir(repo),
     + * and die if it is a version we don't understand. Generally one would
     + * set_git_dir() before calling this, and use it only for "are we in a valid
     + * repo?".
16:  0e1931e40f = 16:  bdf0a02c59 setup: stop using `the_repository` in `initialize_repository_version()`
17:  9cddc161a6 = 17:  74bd848268 setup: stop using `the_repository` in `create_reference_database()`
18:  996771094d = 18:  6fa2476a01 setup: stop using `the_repository` in `init_db()`

---
base-commit: 59ff4886a579f4bc91e976fe18590b9ae02c7a08
change-id: 20260330-pks-setup-wo-the-repository-81e51bc55b91


^ permalink raw reply

* Re: [PATCH v9 0/5] branch: prune-merged
From: Harald Nordgren @ 2026-05-18  8:14 UTC (permalink / raw)
  To: Harald Nordgren via GitGitGadget; +Cc: git, Kristoffer Haugsbakk, Johannes Sixt
In-Reply-To: <pull.2285.v9.git.git.1778700883.gitgitgadget@gmail.com>

Can I get some reviews here please? It's a bit less useless after
removing the nuclear option, but also much less of a foot-gun.

Harald

^ permalink raw reply

* Re: [PATCH v2] config: retry acquiring config.lock, configurable via core.configLockTimeout
From: Patrick Steinhardt @ 2026-05-18  8:07 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Joerg Thalheim, git, Johannes Schindelin
In-Reply-To: <xmqqzf1xbl4i.fsf@gitster.g>

On Mon, May 18, 2026 at 09:46:05AM +0900, Junio C Hamano wrote:
> Joerg Thalheim <joerg@thalheim.io> writes:
> 
> > +/*
> > + * How long to retry acquiring config.lock when another process holds
> > + * it. Default matches core.packedRefsTimeout; override via
> > + * core.configLockTimeout.
> > + */
> > +static long config_lock_timeout_ms(struct repository *r)
> > +{
> > +	static int configured;
> > +	static int timeout_ms = 1000;
> > +
> > +	if (!configured) {
> > +		repo_config_get_int(r, "core.configlocktimeout", &timeout_ms);
> > +		configured = 1;
> > +	}
> > +
> > +	return timeout_ms;
> > +}
> 
> The above design means whichever repository happens to be passed for
> the first time as "r" to this call will fix the return value from
> the function for the rest of the system, meaning that the lock timeout
> is a per-process property and the repository parameter passed to the
> function does not matter all that much.
> 
> It may make sense to admit that this is not a per-repository
> property (due to the use of local caching), have the function take
> no parameter and use the_repository to the config_get call.  That
> would make the intention more clear.
> 
> Of course the other end of the spectrum is to get rid of the
> "configured" caching here, and ask the config system to make a
> hashtable look-up every time the function is called.  That will keep
> the lock timeout per-repository, which is closer to what the current
> function signature suggests.
> 
> I dunno.  My gut feeling is that there aren't valid reasons why you
> would want to specifically set different timeout values per
> repository, so the simplicity of using the_repository (i.e. the
> primary repository instance this process deals with) sounds like a
> better way to go.

There probably is no reason to have different values per repo. But to
me the question is whether there even are any use cases where we have to
lock the config file so often in quick succession that the caching
mechanism even matters. My gut feeling says no, also because parsing the
value from the configuration is going to be drowned out by actually
writing the lockfile and renaming it into place.

So I'd rather lean towards dropping the cache and keeping the repository
parameter.

Patrick

^ permalink raw reply

* Re: [PATCH v8] checkout: extend --track with a "fetch" mode to refresh start-point
From: Harald Nordgren @ 2026-05-18  8:06 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Harald Nordgren via GitGitGadget, git, Ramsay Jones,
	D. Ben Knoble, Kristoffer Haugsbakk, Marc Branchaud, Phillip Wood
In-Reply-To: <xmqqh5odqxh2.fsf@gitster.g>

> I do not quite see the point of this extra block.  Can we do without
> it (and move the def of oid up near the beginning of the function,
> of course)?
>
> Even better, as resolve_fetch_target() already looks at "arg" and
> poked at the remote-tracking ref hierarchy, wouldn't it make more
> sense to make that helper function responsible for finding out if
> there already is a usable, albeit potentially stale, ref?

Done. Can I get another review here please?

> > @@ -1244,7 +1398,6 @@ static int git_checkout_config(const char *var, const char *value,
> >               opts->dwim_new_local_branch = git_config_bool(var, value);
> >               return 0;
> >       }
> > -
> >       if (starts_with(var, "submodule."))
> >               return git_default_submodule_config(var, value, NULL);
>
> Unrelated patch noise?

Removed.


Harald

^ permalink raw reply

* [PATCH v10] checkout: extend --track with a "fetch" mode to refresh start-point
From: Harald Nordgren via GitGitGadget @ 2026-05-18  8:04 UTC (permalink / raw)
  To: git
  Cc: Ramsay Jones, D. Ben Knoble, Kristoffer Haugsbakk, Marc Branchaud,
	Phillip Wood, Harald Nordgren, Harald Nordgren
In-Reply-To: <pull.2281.v9.git.git.1778583307774.gitgitgadget@gmail.com>

From: Harald Nordgren <haraldnordgren@gmail.com>

If you want to fork your topic branch from the very latest of the
tip of a branch your remote has, you would do:

    git fetch origin some-branch
    git checkout -b new_branch --track origin/some-branch

Extend the "--track" option of "git checkout" and allow users to
write

    git checkout -b new_branch --track=fetch origin/some-branch

to (1) fetch 'some-branch' from the remote 'origin', updating the
remote-tracking branch 'origin/some-branch', (2) arrange subsequent
'git pull' on 'new_branch' to interact with 'origin/some-branch' and
(3) fork 'new_branch' from it.

In the value of the '--track' option, 'fetch' can be combined with
the existing 'direct' (default) and 'inherit' modes via a
comma-separated list. Examples:

    git checkout -b new_branch --track=fetch,inherit some_local_branch
    git switch -c new_branch --track=fetch origin/some-branch

When "fetch" is requested and <start-point> is in <remote>/<branch>
form, run "git fetch <remote> <branch>" before resolving the ref, so
that other remote-tracking branches are left untouched. If
<start-point> is a bare remote name like "origin" (which resolves to
that remote's default branch), "git fetch <remote>" is run instead,
since the target branch is not known up front. Abort the checkout if
the fetch fails.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
---
    checkout: --track=fetch
    
    Rebased to fix merge conflict with master.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2281%2FHaraldNordgren%2Fcheckout-fetch-start-point-v10
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2281/HaraldNordgren/checkout-fetch-start-point-v10
Pull-Request: https://github.com/git/git/pull/2281

Range-diff vs v9:

 1:  021375e4cc ! 1:  a773fb6bdf checkout: extend --track with a "fetch" mode to refresh start-point
     @@ Documentation/git-checkout.adoc: of it").
       the refspec configured for the corresponding remote, and then stripping
      
       ## Documentation/git-switch.adoc ##
     -@@ Documentation/git-switch.adoc: should result in deletion of the path).
     +@@ Documentation/git-switch.adoc: variable.
       	attached to a terminal, regardless of `--quiet`.
       
       `-t`::
     @@ builtin/checkout.c
       #include "resolve-undo.h"
       #include "revision.h"
      +#include "run-command.h"
     + #include "sequencer.h"
       #include "setup.h"
       #include "strvec.h"
     - #include "submodule.h"
      @@ builtin/checkout.c: struct checkout_opts {
       	int count_checkout_paths;
       	int overlay_mode;


 Documentation/git-checkout.adoc |  13 ++-
 Documentation/git-switch.adoc   |  13 ++-
 builtin/checkout.c              | 168 +++++++++++++++++++++++++++++++-
 t/t7201-co.sh                   | 144 +++++++++++++++++++++++++++
 4 files changed, 332 insertions(+), 6 deletions(-)

diff --git a/Documentation/git-checkout.adoc b/Documentation/git-checkout.adoc
index a8b3b8c2e2..ec63434159 100644
--- a/Documentation/git-checkout.adoc
+++ b/Documentation/git-checkout.adoc
@@ -158,11 +158,22 @@ of it").
 	resets _<branch>_ to the start point instead of failing.
 
 `-t`::
-`--track[=(direct|inherit)]`::
+`--track[=(direct|inherit|fetch)[,...]]`::
 	When creating a new branch, set up "upstream" configuration. See
 	`--track` in linkgit:git-branch[1] for details. As a convenience,
 	--track without -b implies branch creation.
 +
+The argument is a comma-separated list. `direct` (the default) and
+`inherit` select the tracking mode and are mutually exclusive. Adding
+`fetch` requests that the remote be fetched before _<start-point>_ is
+resolved, so the new branch starts from a fresh tip: when
+_<start-point>_ is in _<remote>/<branch>_ form, only that branch is
+updated; when _<start-point>_ is a bare remote name (e.g. `origin`),
+only the remote's default branch is updated. If the fetch fails and the
+corresponding remote-tracking ref already exists, a warning is printed
+and the checkout proceeds from the existing tip; otherwise the checkout
+is aborted.
++
 If no `-b` option is given, the name of the new branch will be
 derived from the remote-tracking branch, by looking at the local part of
 the refspec configured for the corresponding remote, and then stripping
diff --git a/Documentation/git-switch.adoc b/Documentation/git-switch.adoc
index d6c4f229a5..b5e79435cd 100644
--- a/Documentation/git-switch.adoc
+++ b/Documentation/git-switch.adoc
@@ -155,11 +155,22 @@ variable.
 	attached to a terminal, regardless of `--quiet`.
 
 `-t`::
-`--track[ (direct|inherit)]`::
+`--track[=(direct|inherit|fetch)[,...]]`::
 	When creating a new branch, set up "upstream" configuration.
 	`-c` is implied. See `--track` in linkgit:git-branch[1] for
 	details.
 +
+The argument is a comma-separated list. `direct` (the default) and
+`inherit` select the tracking mode and are mutually exclusive. Adding
+`fetch` requests that the remote be fetched before _<start-point>_ is
+resolved, so the new branch starts from a fresh tip: when
+_<start-point>_ is in _<remote>/<branch>_ form, only that branch is
+updated; when _<start-point>_ is a bare remote name (e.g. `origin`),
+only the remote's default branch is updated. If the fetch fails and the
+corresponding remote-tracking ref already exists, a warning is printed
+and the switch proceeds from the existing tip; otherwise the switch is
+aborted.
++
 If no `-c` option is given, the name of the new branch will be derived
 from the remote-tracking branch, by looking at the local part of the
 refspec configured for the corresponding remote, and then stripping
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 1345e8574a..fc58456546 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -25,10 +25,12 @@
 #include "preload-index.h"
 #include "read-cache.h"
 #include "refs.h"
+#include "refspec.h"
 #include "remote.h"
 #include "repo-settings.h"
 #include "resolve-undo.h"
 #include "revision.h"
+#include "run-command.h"
 #include "sequencer.h"
 #include "setup.h"
 #include "strvec.h"
@@ -62,6 +64,7 @@ struct checkout_opts {
 	int count_checkout_paths;
 	int overlay_mode;
 	int dwim_new_local_branch;
+	int fetch;
 	int discard_changes;
 	int accept_ref;
 	int accept_pathspec;
@@ -115,6 +118,158 @@ struct branch_info {
 	char *checkout;
 };
 
+static int resolve_fetch_target(const char *arg, char **remote_out,
+				char **src_ref_out, char **existing_ref_out)
+{
+	const char *slash;
+	char *remote_name = NULL;
+	struct remote *remote = NULL;
+	struct refspec_item query = { 0 };
+	struct strbuf dst = STRBUF_INIT;
+	struct object_id oid;
+	const char *rest = NULL;
+	const char *head_target = NULL;
+	const char *short_target;
+
+	*remote_out = NULL;
+	*src_ref_out = NULL;
+	*existing_ref_out = NULL;
+
+	if (!arg || !*arg || *arg == '/')
+		return -1;
+
+	slash = arg + strlen(arg);
+	while (1) {
+		free(remote_name);
+		remote_name = xstrndup(arg, slash - arg);
+		remote = remote_get(remote_name);
+		if (remote && remote_is_configured(remote, 1))
+			break;
+		while (slash > arg && *--slash != '/')
+			;
+		if (slash == arg) {
+			free(remote_name);
+			return -1;
+		}
+	}
+
+	if (*slash == '/' && slash[1])
+		rest = slash + 1;
+	if (!rest) {
+		strbuf_addf(&dst, "refs/remotes/%s/HEAD", remote_name);
+		head_target = refs_resolve_ref_unsafe(get_main_ref_store(the_repository),
+						      dst.buf,
+						      RESOLVE_REF_READING |
+						      RESOLVE_REF_NO_RECURSE,
+						      &oid, NULL);
+		if (head_target) {
+			*existing_ref_out = xstrdup(dst.buf);
+			if (skip_prefix(head_target, "refs/remotes/", &short_target) &&
+			    skip_prefix(short_target, remote_name, &short_target) &&
+			    *short_target == '/')
+				rest = short_target + 1;
+		}
+		strbuf_reset(&dst);
+	}
+
+	if (rest) {
+		strbuf_addf(&dst, "refs/remotes/%s/%s", remote_name, rest);
+		query.dst = dst.buf;
+		if (!remote_find_tracking(remote, &query) && query.src) {
+			*src_ref_out = xstrdup(query.src);
+			free(query.src);
+		} else {
+			*src_ref_out = xstrdup(rest);
+		}
+		if (!*existing_ref_out) {
+			strbuf_reset(&dst);
+			strbuf_addf(&dst, "refs/remotes/%s", arg);
+			if (!refs_read_ref(get_main_ref_store(the_repository),
+					   dst.buf, &oid))
+				*existing_ref_out = xstrdup(dst.buf);
+		}
+	}
+
+	strbuf_release(&dst);
+	*remote_out = remote_name;
+	return 0;
+}
+
+static void fetch_remote_for_start_point(const char *arg)
+{
+	char *remote_name = NULL;
+	char *src_ref = NULL;
+	char *existing_ref = NULL;
+	struct child_process cmd = CHILD_PROCESS_INIT;
+
+	if (resolve_fetch_target(arg, &remote_name, &src_ref, &existing_ref))
+		return;
+
+	strvec_pushl(&cmd.args, "fetch", remote_name, NULL);
+	if (src_ref)
+		strvec_push(&cmd.args, src_ref);
+	cmd.git_cmd = 1;
+	if (run_command(&cmd)) {
+		if (existing_ref)
+			warning(_("failed to fetch start-point '%s'; "
+				  "using existing '%s'"),
+				arg, existing_ref);
+		else
+			die(_("failed to fetch start-point '%s'"), arg);
+	}
+
+	free(remote_name);
+	free(src_ref);
+	free(existing_ref);
+}
+
+static int parse_opt_checkout_track(const struct option *opt,
+				    const char *arg, int unset)
+{
+	struct checkout_opts *opts = opt->value;
+	struct string_list tokens = STRING_LIST_INIT_DUP;
+	struct string_list_item *item;
+	int saw_direct = 0, saw_inherit = 0;
+	int ret = 0;
+
+	opts->fetch = 0;
+
+	if (unset) {
+		opts->track = BRANCH_TRACK_NEVER;
+		return 0;
+	}
+
+	opts->track = BRANCH_TRACK_EXPLICIT;
+	if (!arg)
+		return 0;
+
+	string_list_split(&tokens, arg, ",", -1);
+	for_each_string_list_item(item, &tokens) {
+		if (!strcmp(item->string, "fetch")) {
+			opts->fetch = 1;
+		} else if (!strcmp(item->string, "direct")) {
+			saw_direct = 1;
+			opts->track = BRANCH_TRACK_EXPLICIT;
+		} else if (!strcmp(item->string, "inherit")) {
+			saw_inherit = 1;
+			opts->track = BRANCH_TRACK_INHERIT;
+		} else {
+			ret = error(_("option `%s' expects \"%s\", \"%s\", "
+				      "or \"%s\""),
+				    "--track", "direct", "inherit", "fetch");
+			goto out;
+		}
+	}
+
+	if (saw_direct && saw_inherit)
+		ret = error(_("option `%s' cannot combine \"%s\" and \"%s\""),
+			    "--track", "direct", "inherit");
+
+out:
+	string_list_clear(&tokens, 0);
+	return ret;
+}
+
 static void branch_info_release(struct branch_info *info)
 {
 	free(info->name);
@@ -1733,10 +1888,10 @@ static struct option *add_common_switch_branch_options(
 {
 	struct option options[] = {
 		OPT_BOOL('d', "detach", &opts->force_detach, N_("detach HEAD at named commit")),
-		OPT_CALLBACK_F('t', "track",  &opts->track, "(direct|inherit)",
+		OPT_CALLBACK_F('t', "track",  opts, "(direct|inherit|fetch)[,...]",
 			N_("set branch tracking configuration"),
 			PARSE_OPT_OPTARG,
-			parse_opt_tracking_mode),
+			parse_opt_checkout_track),
 		OPT__FORCE(&opts->force, N_("force checkout (throw away local modifications)"),
 			   PARSE_OPT_NOCOMPLETE),
 		OPT_STRING(0, "orphan", &opts->new_orphan_branch, N_("new-branch"), N_("new unborn branch")),
@@ -1941,8 +2096,13 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
 			opts->dwim_new_local_branch &&
 			opts->track == BRANCH_TRACK_UNSPECIFIED &&
 			!opts->new_branch;
-		int n = parse_branchname_arg(argc, argv, dwim_ok, which_command,
-					     &new_branch_info, opts, &rev);
+		int n;
+
+		if (opts->fetch)
+			fetch_remote_for_start_point(argv[0]);
+
+		n = parse_branchname_arg(argc, argv, dwim_ok, which_command,
+					 &new_branch_info, opts, &rev);
 		argv += n;
 		argc -= n;
 	} else if (!opts->accept_ref && opts->from_treeish) {
diff --git a/t/t7201-co.sh b/t/t7201-co.sh
index 7613b1d2a4..75b46494c0 100755
--- a/t/t7201-co.sh
+++ b/t/t7201-co.sh
@@ -870,4 +870,148 @@ test_expect_success 'tracking info copied with autoSetupMerge=inherit' '
 	test_cmp_config "" --default "" branch.main2.merge
 '
 
+test_expect_success 'setup upstream for --track=fetch tests' '
+	git checkout main &&
+	git init fetch_upstream &&
+	test_commit -C fetch_upstream u_main &&
+	git remote add fetch_upstream fetch_upstream &&
+	git fetch fetch_upstream &&
+	git -C fetch_upstream checkout -b fetch_new &&
+	test_commit -C fetch_upstream u_new
+'
+
+test_expect_success 'checkout --track=fetch -b picks up branch created upstream after clone' '
+	git checkout main &&
+	test_must_fail git rev-parse --verify refs/remotes/fetch_upstream/fetch_new &&
+	git checkout --track=fetch -b local_new fetch_upstream/fetch_new &&
+	test_cmp_rev refs/remotes/fetch_upstream/fetch_new HEAD &&
+	test_cmp_config fetch_upstream branch.local_new.remote &&
+	test_cmp_config refs/heads/fetch_new branch.local_new.merge
+'
+
+test_expect_success 'checkout --track=fetch <remote>/<branch> leaves other tracking branches untouched' '
+	git checkout main &&
+	git -C fetch_upstream checkout -b fetch_target &&
+	test_commit -C fetch_upstream u_target_pre &&
+	git -C fetch_upstream checkout -b fetch_other &&
+	test_commit -C fetch_upstream u_other_pre &&
+	git fetch fetch_upstream &&
+	other_before=$(git rev-parse refs/remotes/fetch_upstream/fetch_other) &&
+	git -C fetch_upstream checkout fetch_target &&
+	test_commit -C fetch_upstream u_target_post &&
+	git -C fetch_upstream checkout fetch_other &&
+	test_commit -C fetch_upstream u_other_post &&
+	git checkout --track=fetch -b local_target fetch_upstream/fetch_target &&
+	test_cmp_rev refs/remotes/fetch_upstream/fetch_target HEAD &&
+	test "$(git rev-parse refs/remotes/fetch_upstream/fetch_other)" = "$other_before"
+'
+
+test_expect_success 'checkout --track=fetch with bare remote name fetches only <remote>/HEAD target' '
+	git checkout main &&
+	git -C fetch_upstream checkout main &&
+	git remote set-head fetch_upstream main &&
+	git -C fetch_upstream checkout -b fetch_unrelated &&
+	test_commit -C fetch_upstream u_unrelated_pre &&
+	git fetch fetch_upstream fetch_unrelated &&
+	unrelated_before=$(git rev-parse refs/remotes/fetch_upstream/fetch_unrelated) &&
+	git -C fetch_upstream checkout main &&
+	test_commit -C fetch_upstream u_main_post &&
+	git -C fetch_upstream checkout fetch_unrelated &&
+	test_commit -C fetch_upstream u_unrelated_post &&
+	git checkout --track=fetch -b local_from_remote fetch_upstream &&
+	test_cmp_rev refs/remotes/fetch_upstream/main HEAD &&
+	test "$(git rev-parse refs/remotes/fetch_upstream/fetch_unrelated)" = "$unrelated_before"
+'
+
+test_expect_success 'checkout --track=fetch aborts and does not create branch when no existing ref' '
+	git checkout main &&
+	test_might_fail git branch -D bogus &&
+	test_must_fail git checkout --track=fetch -b bogus fetch_upstream/does_not_exist &&
+	test_must_fail git rev-parse --verify refs/heads/bogus
+'
+
+test_expect_success 'checkout --track=fetch warns and proceeds when fetch fails but ref exists' '
+	git checkout main &&
+	git -C fetch_upstream checkout -b fetch_offline &&
+	test_commit -C fetch_upstream u_offline &&
+	git fetch fetch_upstream fetch_offline &&
+	saved_url=$(git config remote.fetch_upstream.url) &&
+	test_when_finished "git config remote.fetch_upstream.url \"$saved_url\"" &&
+	git config remote.fetch_upstream.url ./does-not-exist &&
+	git checkout --track=fetch -b local_offline fetch_upstream/fetch_offline 2>err &&
+	test_grep "failed to fetch" err &&
+	test_cmp_rev refs/remotes/fetch_upstream/fetch_offline HEAD
+'
+
+test_expect_success 'checkout --track=fetch resolves through configured fetch refspec' '
+	git checkout main &&
+	git -C fetch_upstream checkout -b fetch_refspec &&
+	test_commit -C fetch_upstream u_refspec &&
+	git fetch fetch_upstream fetch_refspec &&
+	git remote add fetch_custom ./fetch_upstream &&
+	test_when_finished "git remote remove fetch_custom" &&
+	git config --replace-all remote.fetch_custom.fetch \
+		"+refs/heads/*:refs/remotes/custom-ns/*" &&
+	git fetch fetch_custom &&
+	test_commit -C fetch_upstream u_refspec_post &&
+	git checkout --track=fetch -b local_refspec custom-ns/fetch_refspec &&
+	test_cmp_rev refs/remotes/custom-ns/fetch_refspec HEAD
+'
+
+test_expect_success 'checkout --track=fetch handles hierarchical remote name' '
+	git checkout main &&
+	git -C fetch_upstream checkout -b fetch_hier &&
+	test_commit -C fetch_upstream u_hier &&
+	git remote add nested/remote ./fetch_upstream &&
+	test_when_finished "git remote remove nested/remote" &&
+	git fetch nested/remote fetch_hier &&
+	test_commit -C fetch_upstream u_hier_post &&
+	git checkout --track=fetch -b local_hier nested/remote/fetch_hier &&
+	test_cmp_rev refs/remotes/nested/remote/fetch_hier HEAD
+'
+
+test_expect_success 'checkout --track=inherit,direct is rejected' '
+	test_must_fail git checkout --track=inherit,direct -b bad fetch_upstream/fetch_new 2>err &&
+	test_grep "cannot combine" err
+'
+
+test_expect_success 'checkout --track=fetch then --track=direct drops fetch (last-one-wins)' '
+	git checkout main &&
+	git -C fetch_upstream checkout -b fetch_lastwin &&
+	test_commit -C fetch_upstream u_lastwin &&
+	test_must_fail git rev-parse --verify refs/remotes/fetch_upstream/fetch_lastwin &&
+	test_must_fail git checkout --track=fetch --track=direct \
+		-b local_lastwin fetch_upstream/fetch_lastwin &&
+	test_must_fail git rev-parse --verify refs/remotes/fetch_upstream/fetch_lastwin
+'
+
+test_expect_success 'checkout --track=fetch,inherit fetches and inherits' '
+	git checkout main &&
+	git -C fetch_upstream checkout -b fetch_inherit &&
+	test_commit -C fetch_upstream u_inherit &&
+	git fetch fetch_upstream fetch_inherit &&
+	git checkout -b base_inherit fetch_upstream/fetch_inherit &&
+	test_commit -C fetch_upstream u_inherit2 &&
+	git checkout main &&
+	git checkout --track=fetch,inherit -b local_inherit base_inherit &&
+	test_cmp_rev refs/remotes/fetch_upstream/fetch_inherit HEAD &&
+	test_cmp_config fetch_upstream branch.local_inherit.remote &&
+	test_cmp_config refs/heads/fetch_inherit branch.local_inherit.merge
+'
+
+test_expect_success 'checkout --track=bogus reports an error' '
+	git checkout main &&
+	test_must_fail git checkout --track=bogus -b bogus_branch fetch_upstream/fetch_new 2>err &&
+	test_grep "expects" err
+'
+
+test_expect_success 'switch --track=fetch -c picks up branch created upstream after clone' '
+	git checkout main &&
+	git -C fetch_upstream checkout -b fetch_switch &&
+	test_commit -C fetch_upstream u_switch &&
+	test_must_fail git rev-parse --verify refs/remotes/fetch_upstream/fetch_switch &&
+	git switch --track=fetch -c local_switch fetch_upstream/fetch_switch &&
+	test_cmp_rev refs/remotes/fetch_upstream/fetch_switch HEAD
+'
+
 test_done

base-commit: 68aca6b91299738150f71035d0033af6987fe455
-- 
gitgitgadget

^ permalink raw reply related

* Re: [PATCH 02/18] setup: stop using `the_repository` in `is_inside_worktree()`
From: Patrick Steinhardt @ 2026-05-18  7:46 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Tian Yuchen, git, Karthik Nayak, Elijah Newren
In-Reply-To: <xmqqa4txd2p5.fsf@gitster.g>

On Mon, May 18, 2026 at 08:41:10AM +0900, Junio C Hamano wrote:
> Tian Yuchen <cat@malon.dev> writes:
> 
> > On 4/20/26 16:22, Patrick Steinhardt wrote:
> >
> > I've noticed something that does not entirely convince me:
> >
> >> @@ -477,11 +476,13 @@ int is_inside_git_dir(void)
> >>  	return inside_git_dir;
> >>  }
> >>  
> >> -int is_inside_work_tree(void)
> >> +int is_inside_work_tree(struct repository *repo)
> >>  {
> >> -	if (inside_work_tree < 0)
> >> -		inside_work_tree = is_inside_dir(repo_get_work_tree(the_repository));
> >> -	return inside_work_tree;
> >> +	static struct strbuf buf = STRBUF_INIT;
> >> +	const char *worktree = repo_get_work_tree(repo);
> >> +	if (!worktree)
> >> +		return 0;
> >> +	return is_inside_dir(strbuf_realpath(&buf, worktree, 1));
> >>  }
> >> 
> >
> > Is it correct to statically allocate memory for the cache here? Could 
> > this lead
> > to memory overwriting issues in a multi-threaded environment?
> 
> I do not offhand know if other code paths that are called from this
> function are thread-safe, but yeah, this use of file-scope static is
> not a safe thing to do.

In the current status quo this is a safe conversion to do, as we still
have the assumption ingrained that this only works for a single repo.
We were using static variables before, and we're still using static
variables now.

That being said, I wouldn't mind dropping the static variable if this is
something we'd rather want to get rid of. It's a smell that I'm not
particularly happy about myself.

I'll send a revised version in a bit, thanks!

Patrick

^ permalink raw reply

* Re: [BUG] "git diff --word-diff" gives a diff while they are only space changes
From: Johannes Sixt @ 2026-05-18  7:30 UTC (permalink / raw)
  To: Michael Montalbo; +Cc: vincent, git, Junio C Hamano
In-Reply-To: <CAC2QwmKORPnsmV4SM_CnmhrbF+X754ae-n9m1fgjvVsL9d-wzg@mail.gmail.com>

Am 18.05.26 um 05:30 schrieb Michael Montalbo:
> On Thu, May 14, 2026 at 12:37 AM Junio C Hamano <gitster@pobox.com> wrote:
>>
>> Michael Montalbo <mmontalbo@gmail.com> writes:
>>
>>> @@ -457,6 +457,11 @@ endif::git-diff[]
>>>  +
>>>  Note that despite the name of the first mode, color is used to
>>>  highlight the changed parts in all modes if enabled.
>>> ++
>>> +Word diff works by finding word-level changes within each hunk of
>>> +the line-level diff.  The line-level alignment determines which
>>> +changed lines are compared to each other, which can affect the
>>> +word-level output.
>>
>> The added text may not say anything wrong, but I am not sure how it
>> helps the end user to know the way machinery works internally.
>>
> 
> I see what you mean. Maybe the doc should focus more on calling out
> the user-facing implication:
> 
>   `--word-diff` finds word-level changes within each hunk of the
>   line-level diff, so changes that only affect whitespace may still
>   appear in the output.
I don't know what this paragraph is trying to explain. I don't see how
this would explain Vincent's observed word-diff.

The thing is, "word-diff" is such a descriptive name for the operation
that it is difficult to find a description that is even better. The
manual page doesn't even give it a try. It defers to --word-diff-regex
right away, which then only talks about low-level details and doesn't
attempt to give a higher-level description what a word-diff is.

I don't think you can summarize the algorithm in a single sentence. But
then I have to ask: why write it down anyway? How does it help the
reader? Only so that they are able to derive an explanation for a
particular observed output? Would it have saved Vincent to write a bug
report?

If we document the algorithm in such detail, we cast it in stone. I
wouldn't want to paint ourselves into that corner.

-- Hannes


^ permalink raw reply

* Re: [BUG] "git diff --word-diff" gives a diff while they are only space changes
From: Michael Montalbo @ 2026-05-18  3:30 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: vincent, git, j6t
In-Reply-To: <xmqq8q9migqk.fsf@gitster.g>

On Thu, May 14, 2026 at 12:37 AM Junio C Hamano <gitster@pobox.com> wrote:
>
> Michael Montalbo <mmontalbo@gmail.com> writes:
>
> > @@ -457,6 +457,11 @@ endif::git-diff[]
> >  +
> >  Note that despite the name of the first mode, color is used to
> >  highlight the changed parts in all modes if enabled.
> > ++
> > +Word diff works by finding word-level changes within each hunk of
> > +the line-level diff.  The line-level alignment determines which
> > +changed lines are compared to each other, which can affect the
> > +word-level output.
>
> The added text may not say anything wrong, but I am not sure how it
> helps the end user to know the way machinery works internally.
>

I see what you mean. Maybe the doc should focus more on calling out
the user-facing implication:

  `--word-diff` finds word-level changes within each hunk of the
  line-level diff, so changes that only affect whitespace may still
  appear in the output.

I've intentionally omitted a whitespace workaround recommendation for
now given the ongoing discussion in the thread.

^ permalink raw reply

* [PATCH] fixup! approxidate: use deferred mday adjustments for "specials"
From: Tuomas Ahola @ 2026-05-18  2:40 UTC (permalink / raw)
  To: git; +Cc: Jeff King, Junio C Hamano, Tuomas Ahola
In-Reply-To: <20260516151540.9611-5-taahol@utu.fi>

Oops, let's reorder these lines.

Signed-off-by: Tuomas Ahola <taahol@utu.fi>
---
 t/t0006-date.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/t/t0006-date.sh b/t/t0006-date.sh
index b187b1bfc4..63e5628e05 100755
--- a/t/t0006-date.sh
+++ b/t/t0006-date.sh
@@ -212,9 +212,9 @@ check_approxidate 'noon today' '2009-08-30 12:00:00'
 check_approxidate 'today at noon' '2009-08-30 12:00:00' '-12 hours'
 check_approxidate 'noon today' '2009-09-01 12:00:00' '+36 hours'
 check_approxidate 'noon yesterday' '2009-08-29 12:00:00'
+check_approxidate 'noon yesterday' '2009-08-29 12:00:00' '-12 hours'
 check_approxidate 'last Friday at noon' '2009-08-28 12:00:00'
 check_approxidate 'last Friday at noon' '2009-08-28 12:00:00' '-12 hours'
-check_approxidate 'noon yesterday' '2009-08-29 12:00:00' '-12 hours'
 check_approxidate 'tea last saturday' '2009-08-29 17:00:00'
 check_approxidate 'tea last saturday' '2009-08-29 17:00:00' '-12 hours'
 check_approxidate 'January 5th noon pm' '2009-01-05 12:00:00'

base-commit: 94f057755b7941b321fd11fec1b2e3ca5313a4e0
prerequisite-patch-id: 699b43ba1ff3235d54fa068f4c9b5ab5aa58eacc
prerequisite-patch-id: 2ab5ce03bce8b2953b418fe884f45fbd4a629337
prerequisite-patch-id: 52e3b766b9c6f148f09682b898bf5244b22ae0ba
prerequisite-patch-id: 1cd0e7498368f7c3b1833f12d56fefe732dd0413
-- 
2.30.2


^ permalink raw reply related

* Re: [PATCH 1/5] doc: convert git-bisect to synopsis style
From: Junio C Hamano @ 2026-05-18  2:10 UTC (permalink / raw)
  To: Jean-Noël Avila via GitGitGadget; +Cc: git, Jean-Noël Avila
In-Reply-To: <xmqq4ik5d0le.fsf@gitster.g>

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

>> +[synopsis]
>>  ------------------------------------------------
>>  $ git bisect reset <commit>
>>  ------------------------------------------------
>
> and
>
>> +[synopsis]
>>  ------------------------------------------------
>>  git bisect old [<rev>]
>>  ------------------------------------------------
>
> were a bit surprising and confusing.  They are not exactly command
> syntax definitions (which is the SYNOPSIS section is about), but
> examples of usage.  The one with '$' command line prompt feels
> particularly confusing, as the prompt is not something that the
> end-user gives, unlike what we write in the synopsis section.
>
> Other than that, this is quite exciting.

Well, my local test with asciidoctor did not barf, but it seems that
the documentation pipeline run in GitHub Actions CI is unhappy.

https://github.com/git/git/actions/runs/26008649802/job/76444895183#step:4:4846

I do not know what the differences among the three environments
(counting your development environment---only one of which fails)
are offhand.


^ permalink raw reply

* What's cooking in git.git (May 2026, #04)
From: Junio C Hamano @ 2026-05-18  1:32 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).

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']

* en/backfill-fixes-and-edges (2026-04-15) 3 commits
  (merged to 'next' on 2026-05-11 at baccbdf26d)
 + backfill: default to grabbing edge blobs too
 + backfill: document acceptance of revision-range in more standard manner
 + backfill: reject rev-list arguments that do not make sense
 (this branch is used by ds/path-walk-filters.)

 The 'git backfill' command now rejects revision-limiting options that
 are incompatible with its operation, uses standard documentation for
 revision ranges, and includes blobs from boundary commits by default
 to improve performance of subsequent operations.
 cf. <6e95b82a-19e3-460e-86f7-f899c2df261d@gmail.com>
 source: <pull.2088.git.1776297482.gitgitgadget@gmail.com>


* en/ort-cached-rename-with-trivial-resolution (2026-04-20) 1 commit
  (merged to 'next' on 2026-05-11 at 9fe24668d9)
 + merge-ort: handle cached rename & trivial resolution interaction better

 "ort" merge backend improvements.
 source: <pull.2095.git.1776724214171.gitgitgadget@gmail.com>


* hn/git-checkout-m-with-stash (2026-04-28) 5 commits
  (merged to 'next' on 2026-05-11 at 46adae5e5d)
 + checkout -m: autostash when switching branches
 + checkout: rollback lock on early returns in merge_working_tree
 + sequencer: teach autostash apply to take optional conflict marker labels
 + sequencer: allow create_autostash to run silently
 + stash: add --label-ours, --label-theirs, --label-base for apply

 "git checkout -m another-branch" was invented to deal with local
 changes to paths that are different between the current and the new
 branch, but it gave only one chance to resolve conflicts.  The command
 was taught to create a stash to save the local changes.
 source: <pull.2234.v16.git.git.1777401552.gitgitgadget@gmail.com>


* mf/format-patch-cover-letter-format-docfix (2026-04-22) 1 commit
  (merged to 'next' on 2026-05-11 at 3cca9cc117)
 + Fix docs for format.commitListFormat

 Docfix.
 source: <576d29f15e016889e02c253713656cd8cbf1f04c.1776894255.git.mroik@delayed.space>


* ps/clang-w-glibc-2.43-and-_Generic (2026-05-10) 1 commit
  (merged to 'next' on 2026-05-12 at fca23344f2)
 + build: tolerate use of _Generic from glibc 2.43 with Clang

 Headers from glibc 2.43 when used with clang does not allow
 disabling C11 language features, causing build failures..
 source: <xmqqqzniset2.fsf@gitster.g>


* pw/rename-to-get-current-worktree (2026-05-01) 1 commit
  (merged to 'next' on 2026-05-11 at 36ca1d49e2)
 + worktree: rename get_worktree_from_repository()

 Code clean-up.
 source: <bd48396137f8d1352d11b3bd2dca2848f24a347d.1777648798.git.phillip.wood@dunelm.org.uk>


* rs/grep-column-only-match-fix (2026-04-24) 1 commit
  (merged to 'next' on 2026-05-11 at a0d87e3104)
 + grep: fix --column --only-match for 2nd and later matches

 "git grep" update.
 source: <9bd69678-f04b-41d2-ad74-a386820d34c8@web.de>


* ss/t7004-unhide-git-failures (2026-04-20) 3 commits
  (merged to 'next' on 2026-05-11 at 9ee9feacb7)
 + t7004: avoid subshells to capture git exit codes
 + t7004: dynamically grab expected state in tests
 + t7004: drop hardcoded tag count for state verification

 Test clean-up.
 cf. <aecNc-BNwaqFlg5c@pks.im>
 source: <20260421053334.5414-1-r.siddharth.shrimali@gmail.com>

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

* hn/status-pull-advice-qualified (2026-05-13) 1 commit
 - remote: qualify "git pull" advice for non-upstream branches

 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>".

 Comments?
 source: <pull.2301.v2.git.git.1778665812261.gitgitgadget@gmail.com>


* jk/dumb-http-alternate-fix (2026-05-12) 1 commit
  (merged to 'next' on 2026-05-17 at c1a51214fb)
 + http: handle absolute-path alternates from server root

 The HTTP walker misinterpreted the alternates file that gives an
 absolute path when the server URL does not have the final slash
 (i.e., "https://example.com" not "https://example.com/").

 Will merge to 'master'.
 source: <20260512162619.GA69813@coredump.intra.peff.net>


* jk/pretty-no-strbuf-presizing (2026-05-12) 1 commit
  (merged to 'next' on 2026-05-17 at ee684c614f)
 + pretty: drop strbuf pre-sizing from add_rfc2047()

 Remove ineffective strbuf presizing that would have computed an
 allocation that would not have fit in the available memory anyway,
 or too small due to integer wraparound to cause immediate automatic
 growing.

 Will merge to 'master'.
 source: <20260512162022.GA69669@coredump.intra.peff.net>


* kk/merge-octopus-optim (2026-05-11) 1 commit
 - merge: use repo_in_merge_bases for octopus up-to-date check

 The logic to determine that branches in an octopus merge are
 independent has been optimized.

 Comments?
 source: <pull.2110.git.1778566286543.gitgitgadget@gmail.com>


* rs/strbuf-add-uint (2026-05-12) 4 commits
 - ls-tree: use strbuf_add_uint()
 - ls-files: use strbuf_add_uint()
 - cat-file: use strbuf_add_uint()
 - strbuf: add strbuf_add_uint()

 Adding a decimal integer with strbuf_addf("%u") appears commonly;
 they have been optimized by using a custom formatter.

 Comments?
 source: <20260512115603.80780-1-l.s.r@web.de>


* ta/approxidate-noon-fix (2026-05-16) 4 commits
 - approxidate: use deferred mday adjustments for "specials"
 - approxidate: make "specials" respect fixed day-of-month
 - t0006: add support for approxidate test date adjustment
 - approxidate: make "today" wrap to midnight

 "Friday noon" asked in the morning on Sunday was parsed to be one
 day before the specified time, which has been corrected.

 Comments?
 source: <20260516151540.9611-1-taahol@utu.fi>


* mm/doc-word-diff (2026-05-13) 1 commit
 - doc: clarify that --word-diff operates on line-level hunks

 The documentation for "--word-diff" has been extended with a bit of
 implementation detail of where these different words come from.

 Comments?
 source: <pull.2113.git.1778686956622.gitgitgadget@gmail.com>


* rs/strbuf-add-oid-hex (2026-05-13) 1 commit
 - hex: add and use strbuf_add_oid_hex()

 Formatting object name in full hexadecimal form has been optimized
 by using a new strbuf_add_oid_hex() helper function.

 Comments?
 source: <183aa0fd-d455-4ec9-9c42-d511fac8b3e4@web.de>


* kk/limit-list-optim (2026-05-14) 1 commit
 - revision: use priority queue in limit_list()

 The limit_list() function that is one of the core part of the
 revision traversal infrastructure has been optimized by replacing
 its use of linear list with priority queue.

 Will merge to 'next'.
 source: <pull.2114.git.1778777491939.gitgitgadget@gmail.com>


* ed/check-connected-close-err-fd (2026-05-16) 1 commit
 - Merge branch 'ed/check-connected-close-err-fd-2.53' into ed/check-connected-close-err-fd
 (this branch uses ed/check-connected-close-err-fd-2.53.)

 File descriptor leak fix.

 Will merge to 'next'?
 (this branch uses ed/check-connected-close-err-fd-2.53.)


* ed/check-connected-close-err-fd-2.53 (2026-05-14) 1 commit
 - connected: close err_fd in promisor fast-path
 (this branch is used by ed/check-connected-close-err-fd.)

 File descriptor leak fix (for 2.54 maintenance track).

 Will be merged together with ed/check-connected-close-err-fd topic.
 source: <pull.2303.git.git.1778827194448.gitgitgadget@gmail.com>


* jk/apply-leakfix (2026-05-15) 1 commit
 - apply: plug leak on "patch too large" error

 Leakfix.

 Will merge to 'next'.
 source: <20260516021622.GA744303@coredump.intra.peff.net>


* jk/commit-sign-overflow-fix (2026-05-15) 1 commit
 - commit: handle large commit messages in utf8 verification

 Leakfix.

 Will merge to 'next'.
 source: <20260516022310.GB744303@coredump.intra.peff.net>


* kk/tips-reachable-from-bases-optim (2026-05-16) 2 commits
 - t6600: add tests for duplicate tips in tips_reachable_from_bases()
 - commit-reach: use object flags for tips_reachable_from_bases()

 Revision traversal optimization.

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


* pb/doc-diff-format-updates (2026-05-15) 3 commits
 - diff-format.adoc: mode and hash are 0* for unmerged paths from index only
 - diff-format.adoc: 'git diff-files' prints two lines for unmerged files
 - diff-format.adoc: remove mention of diff-tree specific output

 Doc updates.

 Will merge to 'next'.
 source: <pull.2304.git.git.1778860091.gitgitgadget@gmail.com>


* ps/t3903-cover-stash-include-untracked (2026-05-16) 1 commit
 - stash: add coverage for show --include-untracked

 Test coverage has been added to "git stash --include-untracked".

 Will merge to 'next'.
 source: <20260516183347.4323-2-pushkarkumarsingh1970@gmail.com>


* rs/trailer-fold-optim (2026-05-15) 1 commit
 - trailer: change strbuf in-place in unfold_value()

 Code simplification.

 Will merge to 'next'.
 source: <816be07e-2cd6-48fe-ae93-57fa0f2543ed@web.de>


* rs/use-builtin-add-overflow-explicitly-on-clang (2026-05-14) 2 commits
 - use __builtin_add_overflow() in st_add() with Clang
 - strbuf: use st_add3() in strbuf_grow()

 Micro optimization of codepaths that compute allocation sizes carefully.

 What's the status of this topic?
 source: <0ded6062-f66a-4713-af24-d1b5aa654823@web.de>
 source: <c6e9b337-c4fc-4cbd-ac32-e8d3814749b0@web.de>


* tc/generate-configlist-fix-for-older-ninja (2026-05-15) 1 commit
 - generate-configlist: collapse depfile for older Ninja

 Build update.

 Will merge to 'next'?
 source: <20260515-toon-fix-almalinux8-v3-1-b545a0647f0f@iotcl.com>


* hn/config-typo-advice (2026-05-16) 1 commit
 - config: suggest the correct form when key contains "=" in set context

 "git config foo.bar=baz" is not likely to be a request to read the
 value of such a variable with '=' in its name; rather it is plausible
 that the user meant "git config set foo.bar baz".  Give advice when
 giving an error message.

 Comments?
 source: <pull.2302.v2.git.git.1778935976330.gitgitgadget@gmail.com>


* ja/doc-synopsis-style-again (2026-05-17) 5 commits
 - doc: convert git-imap-send synopsis and options to new style
 - doc: convert git-apply synopsis and options to new style
 - doc: convert git-am synopsis and options to new style
 - doc: convert git-grep synopsis and options to new style
 - doc: convert git-bisect to synopsis style

 A batch of documentation pages has been updated to use the modern
 synopsis style.

 Comments?
 source: <pull.2117.git.1779049615.gitgitgadget@gmail.com>


* kn/refs-fsck-skip-lock-files (2026-05-17) 1 commit
 - refs/files: skip lock files during consistency checks

 The consistency checks for the files reference backend have been updated
 to skip lock files earlier, avoiding unnecessary parsing of
 intermediate files.

 Will merge to 'next'.
 source: <20260517-refs-fsck-skip-lock-files-v3-1-b24dfd673c7e@gmail.com>


* 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.

 Comments?
 cf. <xmqqzf1xbl4i.fsf@gitster.g>
 source: <20260517132111.1014901-1-joerg@thalheim.io>

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

* sp/shallow-deepen-on-non-shallow-repo-fix (2026-05-11) 1 commit
  (merged to 'next' on 2026-05-15 at 67dd491aae)
 + shallow: fix relative deepen on non-shallow repositories

 "git fetch --deepen=<n>" in a full clone truncated the history to <n>
 commits deep, which has been corrected to be a no-op instead.

 Will merge to 'master'.
 source: <20260511192044.169557-1-samo_pogacnik@t-2.net>


* ag/sequencer-remove-unused-struct-member (2026-05-11) 1 commit
  (merged to 'next' on 2026-05-17 at 8553437ae1)
 + sequencer: remove todo_add_branch_context.commit

 Code clean-up.

 Will merge to 'master'.
 cf. <agLKVn6RF4UBYd_8@pks.im>
 source: <pull.2111.git.1778502113485.gitgitgadget@gmail.com>


* ps/maintenance-daemonize-lockfix (2026-05-13) 2 commits
 - run-command: honor "gc.auto" for auto-maintenance
 - builtin/maintenance: fix locking with "--detach"

 "git maintenance" that goes background did not use the lockfile to
 prevent multiple maintenance processes from running at the same
 time, which has been corrected..

 Comments?
 source: <20260513-pks-maintenance-fix-lock-with-detach-v3-0-f27a1ac82891@pks.im>


* js/mingw-no-nedmalloc (2026-05-08) 3 commits
  (merged to 'next' on 2026-05-13 at 2116a6bcc9)
 + mingw: remove the vendored compat/nedmalloc/ subtree
 + mingw: drop the build-system plumbing for nedmalloc
 + mingw: stop using nedmalloc

 Stop using unmaintained custom allocator in Windows build which was
 the last user of the code.

 Will merge to 'master'.
 source: <pull.2104.v3.git.1778244661.gitgitgadget@gmail.com>


* sj/submodule-update-clone-config-fix (2026-05-09) 1 commit
  (merged to 'next' on 2026-05-12 at 5a0094838a)
 + submodule-config: fix reading submodule.fetchJobs

 The configuration variable submodule.fetchJobs was not read correctly,
 which has been corrected.

 Will merge to 'master'.
 source: <pull.2287.v4.git.git.1778385022964.gitgitgadget@gmail.com>


* aw/validate-proxy-url-scheme (2026-05-05) 1 commit
  (merged to 'next' on 2026-05-15 at da9c1b71d7)
 + http: reject unsupported proxy URL schemes

 Misspelt proxy URL (e.g., httt://...) did not trigger any warning
 or failure, which has been corrected.

 Will merge to 'master'.
 source: <20260505091941.1825-2-aminnimaj@gmail.com>


* hn/branch-prune-merged (2026-05-13) 5 commits
 - branch: add --all-remotes flag
 - branch: add branch.<name>.pruneMerged opt-out
 - branch: add --prune-merged <remote>
 - branch: let delete_branches warn instead of error on bulk refusal
 - branch: add --forked <remote>

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

 Comments?
 source: <pull.2285.v9.git.git.1778700883.gitgitgadget@gmail.com>


* kh/doc-restore-double-underscores-fix (2026-05-05) 1 commit
  (merged to 'next' on 2026-05-12 at 2e8fc7cdac)
 + doc: restore: remove double underscore

 Doc update.

 Will merge to 'master'.
 source: <double_underscore.670@msgid.xyz>


* mm/diff-U-takes-no-negative-values (2026-05-12) 4 commits
  (merged to 'next' on 2026-05-17 at d81439a049)
 + parse-options: clarify what "negated" means for PARSE_OPT_NONEG
 + xdiff: guard against negative context lengths
 + diff: reject negative values for -U/--unified
 + diff: reject negative values for --inter-hunk-context

 The command line parser for "git diff" learned a few options take
 only non-negative integers.

 Will merge to 'master'.
 source: <pull.2105.v2.git.1778609423.gitgitgadget@gmail.com>


* mm/git-url-parse (2026-05-01) 8 commits
  (merged to 'next' on 2026-05-15 at 416deceeeb)
 + t9904: add tests for the new url-parse builtin
 + doc: describe the url-parse builtin
 + builtin: create url-parse command
 + urlmatch: define url_parse function
 + url: return URL_SCHEME_UNKNOWN instead of dying
 + url: move scheme detection to URL header/source
 + url: move url_is_local_not_ssh to url.h
 + connect: rename enum protocol to url_scheme

 The internal URL parsing logic has been made accessible via a new
 subcommand "git url-parse".

 Will merge to 'master'.
 cf. <xmqqjyt9p9pk.fsf@gitster.g>
 cf. <20260512085734.GA26769@tb-raspi4>
 source: <pull.1715.v3.git.git.1777699722.gitgitgadget@gmail.com>


* kh/doc-commit-graph (2026-05-07) 1 commit
  (merged to 'next' on 2026-05-12 at b9cafeb32d)
 + doc: add caveat about turning off commit-graph

 Ramifications of turning off commit-graph has been documented a bit
 more clearly.

 Will merge to 'master'.
 source: <V3_caveat_commit-graph.6b6@msgid.xyz>


* dk/doc-exclude-is-shared-per-repo (2026-05-12) 1 commit
  (merged to 'next' on 2026-05-17 at ddc761aec6)
 + ignore: note info/exclude lives in GIT_COMMON_DIR, not GIT_DIR

 Document the fact that .git/info/exclude is shared across worktrees
 linked to the same repository.

 Will merge to 'master'.
 cf. <bea48414-217b-4860-9279-fe94e3687c28@gmail.com>
 source: <ec97ad3f054e90b675f099a36a81a23bb4b2a0ed.1778620784.git.ben.knoble+github@gmail.com>


* kk/paint-down-to-common-optim (2026-05-11) 2 commits
  (merged to 'next' on 2026-05-17 at 2e39c767e5)
 + commit-reach: early exit paint_down_to_common for single merge-base
 + commit-reach: introduce merge_base_flags enum

 "git merge-base" optimization.

 Will merge to 'master'.
 source: <pull.2109.v4.git.1778504352.gitgitgadget@gmail.com>


* st/daemon-sockaddr-fixes (2026-05-14) 3 commits
 - daemon: guard NULL REMOTE_PORT in execute() logging
 - daemon: fix IPv6 address truncation in ip2str()
 - daemon: fix IPv6 address corruption in lookup_hostname()

 Correct use of sockaddr API in "git daemon".

 Waiting for response(s) to review comment(s).
 cf. <agGLRC1ziF5F8Okh@pks.im>
 source: <pull.2300.git.git.1778773592.gitgitgadget@gmail.com>


* ag/rebase-update-refs-limit-to-branches (2026-05-10) 1 commit
  (merged to 'next' on 2026-05-12 at 5222da09bb)
 + rebase: ignore non-branch update-refs

 "git rebase --update-refs", when used with an rebase.instructionFormat
 with "%d" (describe) in it, tried to update local branch HEAD by
 mistake, which has been corrected.

 Will merge to 'master'.
 source: <20260510224111.64467-2-mail@abhinavg.net>


* jc/ci-enable-expensive (2026-05-10) 2 commits
  (merged to 'next' on 2026-05-15 at d258bb5e55)
 + ci: enable EXPENSIVE for contributor builds
 + Merge branch 'js/objects-larger-than-4gb-on-windows' into jc/ci-enable-expensive
 (this branch uses js/objects-larger-than-4gb-on-windows.)

 Enable expensive tests to catch topics that may cause breakages on
 integration branches closer to their origin in the contributor PR
 builds.

 Will merge to 'master'.
 source: <xmqqjyta9630.fsf@gitster.g>


* rs/sideband-clear-line-before-print (2026-05-10) 1 commit
  (merged to 'next' on 2026-05-12 at 83880f8ce6)
 + sideband: clear full line when printing remote messages

 Tweak the way how sideband messages from remote are printed while
 we talk with a remote repository to avoid tickling terminal
 emulator glitches.

 Will merge to 'master'.
 source: <9826dabf-c9a6-4397-8ae6-a24f9c507f1b@web.de>


* jh/alias-i18n-fixes (2026-04-24) 1 commit
  (merged to 'next' on 2026-05-13 at c7cd30d414)
 + alias: restore support for simple dotted aliases

 Further update to the i18n alias support to avoid regressions.

 Will merge to 'master'.
 source: <20260424161707.1514255-1-jonatan@jontes.page>


* kn/refs-generic-helpers (2026-05-04) 9 commits
  (merged to 'next' on 2026-05-15 at 62cb4e0ce2)
 + refs: use peeled tag values in reference backends
 + refs: add peeled object ID to the `ref_update` struct
 + refs: move object parsing to the generic layer
 + update-ref: handle rejections while adding updates
 + update-ref: move `print_rejected_refs()` up
 + refs: return `ref_transaction_error` from `ref_transaction_update()`
 + refs: extract out reflog config to generic layer
 + refs: introduce `ref_store_init_options`
 + refs: remove unused typedef 'ref_transaction_commit_fn'

 Refactor service routines in the ref subsystem backends.

 Will merge to 'master'.
 cf. <afmFmGo_Sg33Rv6V@pks.im>
 cf. <87o6isqq4q.fsf@toon--20250203-5JQV3.mail-host-address-is-not-set>
 source: <20260504-refs-move-to-generic-layer-v4-0-936ac2f0b1a3@gmail.com>


* ob/more-repo-config-values (2026-04-23) 8 commits
 - env: move "warn_on_object_refname_ambiguity" into `struct repo_config_values`
 - env: move "sparse_expect_files_outside_of_patterns" into `repo_config_values`
 - env: move "core_sparse_checkout_cone" into `struct repo_config_values`
 - environment: move "precomposed_unicode" into `struct repo_config_values`
 - environment: move "pack_compression_level" into `struct repo_config_values`
 - environment: move `zlib_compression_level` into `struct repo_config_values`
 - environment: move "check_stat" into `struct repo_config_values`
 - environment: move "trust_ctime" into `struct repo_config_values`

 Expecting a reroll.
 cf. <CAD=f0L8-_3sDGGkCzF4WA0xmUtaY_qiz__3zq5AemLgwTsqvsg@mail.gmail.com>
 cf. <xmqqlddqu013.fsf@gitster.g>
 source: <20260423165432.143598-1-belkid98@gmail.com>


* ps/history-fixup (2026-04-26) 3 commits
  (merged to 'next' on 2026-05-13 at e6154b6272)
 + builtin/history: introduce "fixup" subcommand
 + builtin/history: generalize function to commit trees
 + replay: allow callers to control what happens with empty commits

 "git history" learned "fixup" command.

 Will merge to 'master'.
 cf. <xmqq33zxp4aq.fsf@gitster.g>
 source: <20260427-b4-pks-history-fixup-v3-0-cb908f06264b@pks.im>


* sb/unpack-index-pack-buffer-resize (2026-04-28) 1 commit
  (merged to 'next' on 2026-05-13 at 2edd54bcfe)
 + index-pack, unpack-objects: increase input buffer from 4 KiB to 128 KiB

 Use a larger buffer size in the code paths to ingest pack stream.

 Will merge to 'master'.
 cf. <xmqqy0hpnpkb.fsf@gitster.g>
 source: <pull.2282.v4.git.git.1777387660841.gitgitgadget@gmail.com>


* bc/sign-commit-with-custom-encoding (2026-04-27) 2 commits
  (merged to 'next' on 2026-05-13 at e82a4966c0)
 + commit: sign commit after mutating buffer
 + commit: name UTF-8 function appropriately

 Signing commit with custom encoding was passing the data to be
 signed at a wrong stage in the pipeline, which has been corrected.

 Will merge to 'master'.
 cf. <xmqqtssdnpf7.fsf@gitster.g>
 source: <20260427221834.1824543-1-sandals@crustytoothpaste.net>


* cc/promisor-auto-config-url-more (2026-04-27) 9 commits
 - 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'
 - Merge branch 'cc/promisor-auto-config-url' into cc/promisor-auto-config-url-more

 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.

 Waiting for response(s) to review comment(s).
 cf. <875x4yoys5.fsf@toon--20250203-5JQV3.mail-host-address-is-not-set>
 source: <20260427124108.3524129-1-christian.couder@gmail.com>


* js/objects-larger-than-4gb-on-windows (2026-05-08) 11 commits
  (merged to 'next' on 2026-05-13 at 843d2ac470)
 + ci: run expensive tests on push builds to integration branches
 + t5608: mark >4GB tests as EXPENSIVE
 + test-tool synthesize: add precomputed SHA-256 pack for 4 GiB + 1
 + test-tool synthesize: precompute pack for 4 GiB + 1
 + test-tool synthesize: use the unsafe hash for speed
 + t5608: add regression test for >4GB object clone
 + test-tool: add a helper to synthesize large packfiles
 + delta, packfile: use size_t for delta header sizes
 + odb, packfile: use size_t for streaming object sizes
 + git-zlib: handle data streams larger than 4GB
 + index-pack, unpack-objects: use size_t for object size
 (this branch is used by jc/ci-enable-expensive.)

 Update code paths that assumed "unsigned long" was long enough for
 "size_t".

 Will merge to 'master'.
 source: <pull.2102.v3.git.1778228209.gitgitgadget@gmail.com>


* kh/doc-log-decorate-list (2026-04-27) 2 commits
  (merged to 'next' on 2026-05-15 at f740311a37)
 + doc: log: use the same delimiter in description list
 + doc: log: fix --decorate description list

 Doc update.

 Will merge to 'master'.
 cf. <xmqqpl31np0l.fsf@gitster.g>
 source: <CV_doc_log_--decorate_list.626@msgid.xyz>


* za/t2000-modernise-more (2026-04-29) 1 commit
  (merged to 'next' on 2026-05-15 at 3b524d0ba5)
 + t2000: consolidate second scenario into a single test block

 Test update.

 Will merge to 'master'.
 cf. <xmqqfr3xnofn.fsf@gitster.g>
 source: <20260429103607.406339-1-zakariyahali100@gmail.com>


* hn/checkout-track-fetch (2026-05-11) 1 commit
 - checkout: extend --track with a "fetch" mode to refresh start-point

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

 Comments?
 cf. <xmqqh5odqxh2.fsf@gitster.g>
 source: <pull.2281.v8.git.git.1778507225500.gitgitgadget@gmail.com>


* mf/revision-max-count-oldest (2026-05-15) 1 commit
 - revision.c: implement --max-count-oldest

 "git rev-list" (and "git log" family of commands) learned a new "--max-count-oldest"
 that picks oldest N commits in the range instead of the usual newest.

 Will merge to 'next'?
 source: <463cc8e2764edb7de3d379f615f5cfbd0919bfa3.1778887662.git.mroik@delayed.space>


* mm/line-log-cleanup (2026-04-27) 3 commits
 - line-log: allow non-patch diff formats with -L
 - line-log: integrate -L output with the standard log-tree pipeline
 - revision: move -L setup before output_format-to-diff derivation

 Code clean-up.

 Comments?
 cf. <xmqqfr3xp98b.fsf@gitster.g>
 source: <pull.2094.git.1777349126.gitgitgadget@gmail.com>


* ds/path-walk-filters (2026-05-13) 14 commits
 - path-walk: support `combine` filter
 - path-walk: support `object:type` filter
 - path-walk: support `tree:0` filter
 - t6601: tag otherwise-unreachable trees
 - pack-objects: support sparse:oid filter with path-walk
 - path-walk: add pl_sparse_trees to control tree pruning
 - path-walk: support blob size limit filter
 - backfill: die on incompatible filter options
 - path-walk: support blobless filter
 - path-walk: always emit directly-requested objects
 - t/perf: add pack-objects filter and path-walk benchmark
 - pack-objects: pass --objects with --path-walk
 - t5620: make test work with path-walk var
 - Merge branch 'en/backfill-fixes-and-edges' into ds/path-walk-filters

 The "git pack-objects --path-walk" traversal has been integrated
 with several object filters, including blobless and sparse filters.

 Comments?
 source: <pull.2101.v4.git.1778707135.gitgitgadget@gmail.com>


* en/ort-harden-against-corrupt-trees (2026-04-20) 5 commits
 - 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.

 Needs review.
 source: <pull.2096.git.1776731171.gitgitgadget@gmail.com>


* sg/t6112-unwanted-tilde-expansion-fix (2026-04-21) 1 commit
  (merged to 'next' on 2026-05-12 at ad2d08eb44)
 + t6112: avoid tilde expansion

 Test fix.

 Will merge to 'master'.
 source: <20260421192132.51172-1-szeder.dev@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.

 Needs review.
 source: <cover.1777648598.git.phillip.wood@dunelm.org.uk>


* tb/pseudo-merge-bugfixes (2026-05-11) 9 commits
 - pack-bitmap: prevent pattern leak on pseudo-merge re-assignment
 - Documentation: fix broken `sampleRate` in gitpacking(7)
 - pack-bitmap: reject pseudo-merge "sampleRate" of 0
 - pack-bitmap: parse commits in `find_pseudo_merge_group_for_ref()`
 - pack-bitmap: fix pseudo-merge lookup for shared commits
 - pack-bitmap: fix inverted binary search in `pseudo_merge_at()`
 - pack-bitmap-write: sort pseudo-merge commit lookup table in pack order
 - t5333: demonstrate various pseudo-merge bugs
 - t/helper: add 'test-tool bitmap write' subcommand

 Fixes many bugs in pseudo-merge code.

 Will merge to 'next'.
 source: <cover.1778546804.git.me@ttaylorr.com>


* ds/fetch-negotiation-options (2026-05-14) 8 commits
 - send-pack: pass negotiation config in push
 - remote: add remote.*.negotiationInclude config
 - fetch: add --negotiation-include option for negotiation
 - negotiator: add have_sent() interface
 - remote: add remote.*.negotiationRestrict config
 - transport: rename negotiation_tips
 - fetch: add --negotiation-restrict option
 - t5516: fix test order flakiness

 The negotiation tip options in "git fetch" have been reworked to
 allow requiring certain refs to be sent as "have" lines, and to
 restrict negotiation to a specific set of refs.

 Comments?
 source: <pull.2085.v4.git.1778762495.gitgitgadget@gmail.com>


* mc/http-emptyauth-negotiate-fix (2026-04-30) 4 commits
  (merged to 'next' on 2026-05-12 at 843ae82cd0)
 + doc: clarify http.emptyAuth values
  (merged to 'next' on 2026-04-20 at 6539524ca2)
 + t5563: add tests for http.emptyAuth with Negotiate
 + http: attempt Negotiate auth in http.emptyAuth=auto mode
 + http: extract http_reauth_prepare() from retry paths

 The 'http.emptyAuth=auto' configuration now correctly attempts
 Negotiate authentication before falling back to manual credentials.
 This allows seamless Kerberos ticket-based authentication without
 requiring users to explicitly set 'http.emptyAuth=true'.

 Will merge to 'master'.
 source: <e0f236767f81ea60f90749d1bc00ab78081efd0e.1777546472.git.gitgitgadget@gmail.com>
 source: <pull.2087.git.1776331259.gitgitgadget@gmail.com>


* en/batch-prefetch (2026-05-14) 4 commits
 - grep: prefetch necessary blobs
 - builtin/log: prefetch necessary blobs for `git cherry`
 - patch-ids.h: add missing trailing parenthesis in documentation comment
 - promisor-remote: document caller filtering contract

 In a lazy clone, "git cherry" and "git grep" often fetch necessary
 blob objects one by one from promisor remotes.  It has been corrected
 to collect necessary object names and fetch them in bulk to gain
 reasonable performance.

 Comments?
 source: <pull.2089.v3.git.1778775928.gitgitgadget@gmail.com>


* en/diffstat-utf8-truncation-fix (2026-04-20) 1 commit
  (merged to 'next' on 2026-05-13 at adf801eb1d)
 + diff: fix out-of-bounds reads and NULL deref in diffstat UTF-8 truncation

 The computation to shorten the filenames shown in diffstat measured
 width of individual UTF-8 characters to add up, but forgot to take
 into account error cases (e.g., an invalid UTF-8 sequence, or a
 control character).

 Will merge to 'master'.
 source: <pull.2093.v3.git.1776699778177.gitgitgadget@gmail.com>


* ps/odb-in-memory (2026-04-10) 18 commits
 - t/unit-tests: add tests for the in-memory object source
 - odb: generic in-memory source
 - odb/source-inmemory: stub out remaining functions
 - odb/source-inmemory: implement `freshen_object()` callback
 - odb/source-inmemory: implement `count_objects()` callback
 - odb/source-inmemory: implement `find_abbrev_len()` callback
 - odb/source-inmemory: implement `for_each_object()` callback
 - odb/source-inmemory: convert to use oidtree
 - oidtree: add ability to store data
 - cbtree: allow using arbitrary wrapper structures for nodes
 - odb/source-inmemory: implement `write_object_stream()` callback
 - odb/source-inmemory: implement `write_object()` callback
 - odb/source-inmemory: implement `read_object_stream()` callback
 - odb/source-inmemory: implement `read_object_info()` callback
 - odb: fix unnecessary call to `find_cached_object()`
 - odb/source-inmemory: implement `free()` callback
 - odb: introduce "in-memory" source
 - Merge branch 'jt/odb-transaction-write' into ps/odb-in-memory
 (this branch uses jt/odb-transaction-write.)

 Add a new odb "in-memory" source that is meant to only hold
 tentative objects (like the virtual blob object that represents the
 working tree file used by "git blame").

 Need to wait for the base topic.
 source: <20260410-b4-pks-odb-source-inmemory-v3-0-22fd0fad58fe@pks.im>


* js/adjust-tests-to-explicitly-access-bare-repo (2026-04-26) 8 commits
  (merged to 'next' on 2026-05-13 at 48695e1cb0)
 + safe.bareRepository: default to "explicit" with WITH_BREAKING_CHANGES
 + status tests: filter `.gitconfig` from status output
 + ls-files tests: filter `.gitconfig` from `--others` output
 + t5601: restore `.gitconfig` after includeIf test
 + t1305: use `--git-dir=.` for bare repo in include cycle test
 + t1300: remove global config settings injected by test-lib.sh
 + t7900: do not let `$HOME/.gitconfig` interfere with XDG tests
 + test-lib: allow bare repository access when breaking changes are enabled

 Some tests assume that bare repository accesses are by default
 allowed; rewrite some of them to avoid the assumption, rewrite
 others to explicitly set safe.bareRepository to allow them.

 Will merge to 'master'.
 source: <pull.2098.v2.git.1777214316.gitgitgadget@gmail.com>


* cl/conditional-config-on-worktree-path (2026-05-13) 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.

 Will merge to 'next'?
 cf. <2989eb07-2933-4b5a-9e5c-33ef9b805528@gmail.com>
 source: <20260513-includeif-worktree-v4-0-f8e6212d1fba@black-desk.cn>


* ps/shift-root-in-graph (2026-04-27) 1 commit
 - graph: add indentation for commits preceded by a parentless commit

 In a history with more than one root commit, "git log --graph
 --oneline" stuffed an unrelated commit immediately below a root
 commit, which has been corrected by making the spot below a root
 unavailable.

 Waiting for response(s) to review comment(s).
 cf. <20260513230216.GA1378627@coredump.intra.peff.net>
 source: <20260427102838.44867-2-pabloosabaterr@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.

 Needs review.
 cf. <xmqqse7xm8av.fsf@gitster.g>
 source: <cover.1776384902.git.lorenzo.pegorari2002@gmail.com>


* th/promisor-quiet-per-repo (2026-04-06) 1 commit
 - promisor-remote: fix promisor.quiet to use the correct repository

 The "promisor.quiet" configuration variable was not used from
 relevant submodules when commands like "grep --recurse-submodules"
 triggered a lazy fetch, which has been corrected.

 Comments?
 source: <20260406183041.783800-1-vikingtc4@gmail.com>


* jt/odb-transaction-write (2026-05-14) 7 commits
 - odb/transaction: make `write_object_stream()` pluggable
 - object-file: generalize packfile writes to use odb_write_stream
 - object-file: avoid fd seekback by checking object size upfront
 - object-file: remove flags from transaction packfile writes
 - odb: update `struct odb_write_stream` read() callback
 - odb/transaction: use pluggable `begin_transaction()`
 - odb: split `struct odb_transaction` into separate header
 (this branch is used by ps/odb-in-memory.)

 ODB transaction interface is being reworked to explicitly handle
 object writes.

 Will merge to 'next'?
 source: <20260514183740.1505171-1-jltobler@gmail.com>


* sa/cat-file-batch-mailmap-switch (2026-04-15) 1 commit
 - cat-file: add mailmap subcommand to --batch-command

 "git cat-file --batch" learns an in-line command "mailmap"
 that lets the user toggle use of mailmap.

 Will merge to 'next'?
 source: <20260416033250.4327-2-siddharthasthana31@gmail.com>


* tb/incremental-midx-part-3.3 (2026-04-29) 16 commits
 - repack: allow `--write-midx=incremental` without `--geometric`
 - repack: introduce `--write-midx=incremental`
 - repack: implement incremental MIDX repacking
 - packfile: ensure `close_pack_revindex()` frees in-memory revindex
 - builtin/repack.c: convert `--write-midx` to an `OPT_CALLBACK`
 - repack-geometry: prepare for incremental MIDX repacking
 - repack-midx: extract `repack_fill_midx_stdin_packs()`
 - repack-midx: factor out `repack_prepare_midx_command()`
 - midx: expose `midx_layer_contains_pack()`
 - repack: track the ODB source via existing_packs
 - midx: support custom `--base` for incremental MIDX writes
 - midx: introduce `--no-write-chain-file` for incremental MIDX writes
 - midx: use `strvec` for `keep_hashes`
 - midx: build `keep_hashes` array in order
 - midx: use `strset` for retained MIDX files
 - midx-write: handle noop writes when converting incremental chains

 The repacking code has been refactored and compaction of MIDX layers
 have been implemented, and incremental strategy that does not require
 all-into-one repacking has been introduced.

 Waiting for response(s) to review comment(s).
 cf. <agTw579yuy4iHoMq@szeder.dev>
 cf. <20260513230825.GA1378716@coredump.intra.peff.net>
 source: <cover.1777507303.git.me@ttaylorr.com>


* jd/unpack-trees-wo-the-repository (2026-03-31) 2 commits
 - unpack-trees: use repository from index instead of global
 - unpack-trees: use repository from index instead of global

 A handful of inappropriate uses of the_repository have been
 rewritten to use the right repository structure instance in the
 unpack-trees.c codepath.

 Comments?
 source: <pull.2258.v2.git.git.1774971267.gitgitgadget@gmail.com>


* ps/setup-wo-the-repository (2026-04-20) 18 commits
 - setup: stop using `the_repository` in `init_db()`
 - setup: stop using `the_repository` in `create_reference_database()`
 - setup: stop using `the_repository` in `initialize_repository_version()`
 - setup: stop using `the_repository` in `check_repository_format()`
 - setup: stop using `the_repository` in `upgrade_repository_format()`
 - setup: stop using `the_repository` in `setup_git_directory()`
 - setup: stop using `the_repository` in `setup_git_directory_gently()`
 - setup: stop using `the_repository` in `setup_git_env()`
 - setup: stop using `the_repository` in `set_git_work_tree()`
 - setup: stop using `the_repository` in `setup_work_tree()`
 - setup: stop using `the_repository` in `enter_repo()`
 - setup: stop using `the_repository` in `verify_non_filename()`
 - setup: stop using `the_repository` in `verify_filename()`
 - setup: stop using `the_repository` in `path_inside_repo()`
 - setup: stop using `the_repository` in `prefix_path()`
 - setup: stop using `the_repository` in `is_inside_git_dir()`
 - setup: stop using `the_repository` in `is_inside_worktree()`
 - setup: replace use of `the_repository` in static functions

 Many uses of the_repository has been updated to use a more
 appropriate struct repository instance in setup.c codepath.

 Needs review.
 source: <20260420-pks-setup-wo-the-repository-v1-0-f4a81c4988e8@pks.im>


* kh/doc-trailers (2026-04-13) 9 commits
 - doc: interpret-trailers: document comment line treatment
 - doc: interpret-trailers: commit to “trailer block” term
 - 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.

 Needs review.
 cf. <xmqq1pfivfa3.fsf@gitster.g>
 source: <V2_CV_doc_int-tr_key_format.613@msgid.xyz>


* ps/graph-lane-limit (2026-03-27) 3 commits
 - graph: add truncation mark to capped lanes
 - graph: add --graph-lane-limit option
 - graph: limit the graph width to a hard-coded max

 The graph output from commands like "git log --graph" can now be
 limited to a specified number of lanes, preventing overly wide output
 in repositories with many branches.

 Will merge to 'next'?
 cf. <bdff0a5d-b738-4053-9b72-08eba88156de@kdbg.org>
 source: <20260328001113.1275291-1-pabloosabaterr@gmail.com>


* jr/bisect-custom-terms-in-output (2026-05-14) 3 commits
 - rev-parse: use selected alternate terms to look up refs
 - bisect: print bisect terms in single quotes
 - bisect: use selected alternate terms in status output

 "git bisect" now uses the selected terms (e.g., old/new) more
 consistently in its output.

 Will merge to 'next'?
 source: <20260514-bisect-terms-v4-0-b3e3cf1b06ce@schlaraffenlan.de>


* ua/push-remote-group (2026-05-03) 3 commits
 - push: support pushing to a remote group
 - remote: move remote group resolution to remote.c
 - remote: fix sign-compare warnings in push_cas_option

 "git push" learned to take a "remote group" name to push to, which
 causes pushes to multiple places, just like "git fetch" would do.

 Waiting for response(s) to review comment(s).
 cf. <d6566004-f803-4824-b050-f086b6d6d76c@app.fastmail.com>
 source: <20260503153402.1333220-1-usmanakinyemi202@gmail.com>


* kh/name-rev-custom-format (2026-05-11) 5 commits
  (merged to 'next' on 2026-05-12 at c944d6131e)
 + format-rev: introduce builtin for on-demand pretty formatting
 + name-rev: make dedicated --annotate-stdin --name-only test
 + name-rev: factor code for sharing with a new command
 + name-rev: run clang-format before factoring code
 + name-rev: wrap both blocks in braces

 A new builtin "git format-rev" is introduced for pretty formatting
 one revision expression per line or commit object names found in
 running text.

 Will merge to 'master'.
 source: <V5_CV_format-rev.6c9@msgid.xyz>


* 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. <xmqqcxz2tzpr.fsf@gitster.g>
 source: <SY0P300MB0801677A2A1E0FD38D06A841CE2A2@SY0P300MB0801.AUSP300.PROD.OUTLOOK.COM>


* 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.

 On hold to help the base topic with wider exposure.
 (this branch uses jc/neuter-sideband-fixup.)
 source: <20260305233452.3727126-8-gitster@pobox.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.

 Comments?
 source: <20260305-cs-subtree-split-recursion-v2-0-7266be870ba9@howdoi.land>


* pt/fsmonitor-linux (2026-04-15) 13 commits
 - fsmonitor: convert shown khash to strset in do_handle_client
 - fsmonitor: add tests for Linux
 - fsmonitor: add timeout to daemon stop command
 - fsmonitor: close inherited file descriptors and detach in daemon
 - run-command: add close_fd_above_stderr option
 - fsmonitor: implement filesystem change listener for Linux
 - fsmonitor: rename fsm-settings-darwin.c to fsm-settings-unix.c
 - fsmonitor: rename fsm-ipc-darwin.c to fsm-ipc-unix.c
 - fsmonitor: use pthread_cond_timedwait for cookie wait
 - compat/win32: add pthread_cond_timedwait
 - fsmonitor: fix hashmap memory leak in fsmonitor_run_daemon
 - fsmonitor: fix khash memory leak in do_handle_client
 - t9210, t9211: disable GIT_TEST_SPLIT_INDEX for scalar clone tests

 The fsmonitor daemon has been implemented for Linux.

 Will merge to 'next'?
 cf. <xmqqa4u5nnxq.fsf@gitster.g>
 source: <pull.2147.v15.git.git.1776259657.gitgitgadget@gmail.com>


* pw/xdiff-shrink-memory-consumption (2026-05-04) 5 commits
  (merged to 'next' on 2026-05-15 at 7a867909d2)
 + xdiff: reduce the size of array
 + xprepare: simplify error handling
 + xdiff: cleanup xdl_clean_mmatch()
 + xdiff: reduce size of action arrays
 + Merge branch 'en/xdiff-cleanup-3' into pw/xdiff-shrink-memory-consumption
 (this branch uses en/xdiff-cleanup-3.)

 Shrink wasted memory in Myers diff that does not account for common
 prefix and suffix removal.

 Will merge to 'master'.
 source: <cover.1777903579.git.phillip.wood@dunelm.org.uk>


* en/xdiff-cleanup-3 (2026-04-29) 6 commits
  (merged to 'next' on 2026-05-12 at e4e72e0f34)
 + xdiff/xdl_cleanup_records: make execution of action easier to follow
 + xdiff/xdl_cleanup_records: make setting action easier to follow
 + xdiff/xdl_cleanup_records: make limits more clear
 + xdiff/xdl_cleanup_records: use unambiguous types
 + xdiff: use unambiguous types in xdl_bogo_sqrt()
 + xdiff/xdl_cleanup_records: delete local recs pointer
 (this branch is used by pw/xdiff-shrink-memory-consumption.)

 Preparation of the xdiff/ codebase to work with Rust.

 Will merge to 'master'.
 source: <pull.2156.v6.git.git.1777500495.gitgitgadget@gmail.com>

^ permalink raw reply

* Re: [PATCH v2] config: retry acquiring config.lock, configurable via core.configLockTimeout
From: Junio C Hamano @ 2026-05-18  0:46 UTC (permalink / raw)
  To: Joerg Thalheim; +Cc: git, Patrick Steinhardt, Johannes Schindelin
In-Reply-To: <20260517132111.1014901-1-joerg@thalheim.io>

Joerg Thalheim <joerg@thalheim.io> writes:

> +/*
> + * How long to retry acquiring config.lock when another process holds
> + * it. Default matches core.packedRefsTimeout; override via
> + * core.configLockTimeout.
> + */
> +static long config_lock_timeout_ms(struct repository *r)
> +{
> +	static int configured;
> +	static int timeout_ms = 1000;
> +
> +	if (!configured) {
> +		repo_config_get_int(r, "core.configlocktimeout", &timeout_ms);
> +		configured = 1;
> +	}
> +
> +	return timeout_ms;
> +}

The above design means whichever repository happens to be passed for
the first time as "r" to this call will fix the return value from
the function for the rest of the system, meaning that the lock timeout
is a per-process property and the repository parameter passed to the
function does not matter all that much.

It may make sense to admit that this is not a per-repository
property (due to the use of local caching), have the function take
no parameter and use the_repository to the config_get call.  That
would make the intention more clear.

Of course the other end of the spectrum is to get rid of the
"configured" caching here, and ask the config system to make a
hashtable look-up every time the function is called.  That will keep
the lock timeout per-repository, which is closer to what the current
function signature suggests.

I dunno.  My gut feeling is that there aren't valid reasons why you
would want to specifically set different timeout values per
repository, so the simplicity of using the_repository (i.e. the
primary repository instance this process deals with) sounds like a
better way to go.

Thanks.

^ permalink raw reply

* Re: [PATCH 1/5] doc: convert git-bisect to synopsis style
From: Junio C Hamano @ 2026-05-18  0:26 UTC (permalink / raw)
  To: Jean-Noël Avila via GitGitGadget; +Cc: git, Jean-Noël Avila
In-Reply-To: <dca7f192f1e5cdfb57682feace0a4b3a10204376.1779049615.git.gitgitgadget@gmail.com>

"Jean-Noël Avila via GitGitGadget" <gitgitgadget@gmail.com> writes:

> From: =?UTF-8?q?Jean-No=C3=ABl=20Avila?= <jn.avila@free.fr>
>
> Convert Documentation/git-bisect.adoc to the modern synopsis style.
>
> - Replace [verse] with [synopsis] in the SYNOPSIS block

This was expected.

> - Remove single quotes around command names in the synopsis
> - Use backticks for inline commands, options, refs, and special values
> - Apply [synopsis] attribute to in-body command-form code blocks

This is very much unexpected.  I think everybody thought [synopsis]
was invented to be used for the SYNOPSIS section at the beginning of
each manual page, and ...

>  SYNOPSIS
>  --------
> -[verse]
> -'git bisect' start [--term-(bad|new)=<term-new> --term-(good|old)=<term-old>]
> -		   [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]
> ...
> -'git bisect' help
> +[synopsis]
> +git bisect start [--term-(bad|new)=<term-new> --term-(good|old)=<term-old>]
> +		 [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]
> ...
> +git bisect help

... a change like this is very much expected and understandable, but
new appearances of [synonsis] in places like:

> +[synopsis]
>  ------------------------------------------------
>  $ git bisect reset <commit>
>  ------------------------------------------------

and

> +[synopsis]
>  ------------------------------------------------
>  git bisect old [<rev>]
>  ------------------------------------------------

were a bit surprising and confusing.  They are not exactly command
syntax definitions (which is the SYNOPSIS section is about), but
examples of usage.  The one with '$' command line prompt feels
particularly confusing, as the prompt is not something that the
end-user gives, unlike what we write in the synopsis section.

Other than that, this is quite exciting.


^ permalink raw reply

* Re: [PATCH 02/18] setup: stop using `the_repository` in `is_inside_worktree()`
From: Junio C Hamano @ 2026-05-17 23:41 UTC (permalink / raw)
  To: Tian Yuchen; +Cc: Patrick Steinhardt, git, Karthik Nayak, Elijah Newren
In-Reply-To: <4d9604e2-036b-485e-aa93-53c35d539bed@malon.dev>

Tian Yuchen <cat@malon.dev> writes:

> On 4/20/26 16:22, Patrick Steinhardt wrote:
>
> I've noticed something that does not entirely convince me:
>
>> @@ -477,11 +476,13 @@ int is_inside_git_dir(void)
>>  	return inside_git_dir;
>>  }
>>  
>> -int is_inside_work_tree(void)
>> +int is_inside_work_tree(struct repository *repo)
>>  {
>> -	if (inside_work_tree < 0)
>> -		inside_work_tree = is_inside_dir(repo_get_work_tree(the_repository));
>> -	return inside_work_tree;
>> +	static struct strbuf buf = STRBUF_INIT;
>> +	const char *worktree = repo_get_work_tree(repo);
>> +	if (!worktree)
>> +		return 0;
>> +	return is_inside_dir(strbuf_realpath(&buf, worktree, 1));
>>  }
>> 
>
> Is it correct to statically allocate memory for the cache here? Could 
> this lead
> to memory overwriting issues in a multi-threaded environment?

I do not offhand know if other code paths that are called from this
function are thread-safe, but yeah, this use of file-scope static is
not a safe thing to do.

^ permalink raw reply

* Re: [PATCH] revision: use priority queue in limit_list()
From: Junio C Hamano @ 2026-05-17 23:31 UTC (permalink / raw)
  To: Kristofer Karlsson
  Cc: Derrick Stolee, Jeff King, Kristofer Karlsson via GitGitGadget,
	git
In-Reply-To: <CAL71e4MxhcZqxPVEe38Shuqt7h5dxLDGi66hN2cFXnmg-POKWA@mail.gmail.com>

Kristofer Karlsson <krka@spotify.com> writes:

> I don't want to pollute this patch with that change - should I start a
> separate thread for it or just revisit this later?
> (Perhaps I have too many optimization patches in flux already)

Thanks for a great news.  I agree that it is a good idea to find a
good stopping point and make improvements step-wise, and the patch
posted for limit_list() is probably such a good stopping point.

If we do not see further comments on the current patch, let's merge
it to 'next', cook it for the standard 7 calendar days or so before
merging it down to 'master'.  Further optimizations can be made on
top of the updated 'master' branch as new and separate topics.

^ permalink raw reply

* [PATCH 5/5] doc: convert git-imap-send synopsis and options to new style
From: Jean-Noël Avila via GitGitGadget @ 2026-05-17 20:26 UTC (permalink / raw)
  To: git; +Cc: Jean-Noël Avila, Jean-Noël Avila
In-Reply-To: <pull.2117.git.1779049615.gitgitgadget@gmail.com>

From: =?UTF-8?q?Jean-No=C3=ABl=20Avila?= <jn.avila@free.fr>

Convert git-imap-send from [verse]/single-quote style to the modern
synopsis-block style:

- Replace [verse] with [synopsis] in SYNOPSIS block
- Backtick-quote all OPTIONS terms
- Backtick-quote all config keys in config/imap.adoc
- Backtick-quote bare config key references in prose

Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
---
 Documentation/config/imap.adoc   | 30 +++++++++++++++---------------
 Documentation/git-imap-send.adoc | 24 ++++++++++++------------
 2 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/Documentation/config/imap.adoc b/Documentation/config/imap.adoc
index 4682a6bd03..cb8f5e2700 100644
--- a/Documentation/config/imap.adoc
+++ b/Documentation/config/imap.adoc
@@ -1,44 +1,44 @@
-imap.folder::
+`imap.folder`::
 	The folder to drop the mails into, which is typically the Drafts
 	folder. For example: `INBOX.Drafts`, `INBOX/Drafts` or
 	`[Gmail]/Drafts`. The IMAP folder to interact with MUST be specified;
 	the value of this configuration variable is used as the fallback
 	default value when the `--folder` option is not given.
 
-imap.tunnel::
+`imap.tunnel`::
 	Command used to set up a tunnel to the IMAP server through which
 	commands will be piped instead of using a direct network connection
-	to the server. Required when imap.host is not set.
+	to the server. Required when `imap.host` is not set.
 
-imap.host::
+`imap.host`::
 	A URL identifying the server. Use an `imap://` prefix for non-secure
 	connections and an `imaps://` prefix for secure connections.
-	Ignored when imap.tunnel is set, but required otherwise.
+	Ignored when `imap.tunnel` is set, but required otherwise.
 
-imap.user::
+`imap.user`::
 	The username to use when logging in to the server.
 
-imap.pass::
+`imap.pass`::
 	The password to use when logging in to the server.
 
-imap.port::
+`imap.port`::
 	An integer port number to connect to on the server.
-	Defaults to 143 for imap:// hosts and 993 for imaps:// hosts.
-	Ignored when imap.tunnel is set.
+	Defaults to 143 for `imap://` hosts and 993 for `imaps://` hosts.
+	Ignored when `imap.tunnel` is set.
 
-imap.sslverify::
+`imap.sslverify`::
 	A boolean to enable/disable verification of the server certificate
 	used by the SSL/TLS connection. Default is `true`. Ignored when
-	imap.tunnel is set.
+	`imap.tunnel` is set.
 
-imap.preformattedHTML::
+`imap.preformattedHTML`::
 	A boolean to enable/disable the use of html encoding when sending
-	a patch.  An html encoded patch will be bracketed with <pre>
+	a patch.  An html encoded patch will be bracketed with `<pre>`
 	and have a content type of text/html.  Ironically, enabling this
 	option causes Thunderbird to send the patch as a plain/text,
 	format=fixed email.  Default is `false`.
 
-imap.authMethod::
+`imap.authMethod`::
 	Specify the authentication method for authenticating with the IMAP server.
 	If Git was built with the NO_CURL option, or if your curl version is older
 	than 7.34.0, or if you're running git-imap-send with the `--no-curl`
diff --git a/Documentation/git-imap-send.adoc b/Documentation/git-imap-send.adoc
index 278e5ccd36..538b91afc0 100644
--- a/Documentation/git-imap-send.adoc
+++ b/Documentation/git-imap-send.adoc
@@ -8,9 +8,9 @@ git-imap-send - Send a collection of patches from stdin to an IMAP folder
 
 SYNOPSIS
 --------
-[verse]
-'git imap-send' [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>]
-'git imap-send' --list
+[synopsis]
+git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>]
+git imap-send --list
 
 
 DESCRIPTION
@@ -32,30 +32,30 @@ $ git format-patch --signoff --stdout --attach origin | git imap-send
 OPTIONS
 -------
 
--v::
---verbose::
+`-v`::
+`--verbose`::
 	Be verbose.
 
--q::
---quiet::
+`-q`::
+`--quiet`::
 	Be quiet.
 
--f <folder>::
---folder=<folder>::
+`-f <folder>`::
+`--folder=<folder>`::
 	Specify the folder in which the emails have to saved.
 	For example: `--folder=[Gmail]/Drafts` or `-f INBOX/Drafts`.
 
---curl::
+`--curl`::
 	Use libcurl to communicate with the IMAP server, unless tunneling
 	into it.  Ignored if Git was built without the USE_CURL_FOR_IMAP_SEND
 	option set.
 
---no-curl::
+`--no-curl`::
 	Talk to the IMAP server using git's own IMAP routines instead of
 	using libcurl.  Ignored if Git was built with the NO_OPENSSL option
 	set.
 
---list::
+`--list`::
 	Run the IMAP LIST command to output a list of all the folders present.
 
 CONFIGURATION
-- 
gitgitgadget

^ permalink raw reply related

* [PATCH 4/5] doc: convert git-apply synopsis and options to new style
From: Jean-Noël Avila via GitGitGadget @ 2026-05-17 20:26 UTC (permalink / raw)
  To: git; +Cc: Jean-Noël Avila, Jean-Noël Avila
In-Reply-To: <pull.2117.git.1779049615.gitgitgadget@gmail.com>

From: =?UTF-8?q?Jean-No=C3=ABl=20Avila?= <jn.avila@free.fr>

Convert git-apply from [verse]/single-quote style to the modern
synopsis-block style:

- Replace [verse] with [synopsis] in SYNOPSIS block
- Backtick-quote all OPTIONS terms and config keys in config/apply.adoc
- Convert single-quoted inline commands ('git apply', 'diff', etc.)
- Wrap standalone placeholders in underscores (<n>, <root>, <action>)
- Backtick-quote `*.rej` and GNU `patch` tool references

Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
---
 Documentation/config/apply.adoc |  17 +++--
 Documentation/git-apply.adoc    | 125 ++++++++++++++++----------------
 2 files changed, 74 insertions(+), 68 deletions(-)

diff --git a/Documentation/config/apply.adoc b/Documentation/config/apply.adoc
index f9908e210a..36fcea6291 100644
--- a/Documentation/config/apply.adoc
+++ b/Documentation/config/apply.adoc
@@ -1,11 +1,16 @@
-apply.ignoreWhitespace::
-	When set to 'change', tells 'git apply' to ignore changes in
+`apply.ignoreWhitespace`::
+	When set to `change`, tells `git apply` to ignore changes in
 	whitespace, in the same way as the `--ignore-space-change`
 	option.
-	When set to one of: no, none, never, false, it tells 'git apply' to
+	When set to one of: `no`, `none`, `never`, `false`, it tells `git apply` to
 	respect all whitespace differences.
+ifndef::git-apply[]
 	See linkgit:git-apply[1].
+endif::git-apply[]
 
-apply.whitespace::
-	Tells 'git apply' how to handle whitespace, in the same way
-	as the `--whitespace` option. See linkgit:git-apply[1].
+`apply.whitespace`::
+	Tells `git apply` how to handle whitespace, in the same way
+	as the `--whitespace` option.
+ifndef::git-apply[]
+	See linkgit:git-apply[1].
+endif::git-apply[]
diff --git a/Documentation/git-apply.adoc b/Documentation/git-apply.adoc
index 6c71ee69da..3f22dac1ce 100644
--- a/Documentation/git-apply.adoc
+++ b/Documentation/git-apply.adoc
@@ -8,8 +8,8 @@ git-apply - Apply a patch to files and/or to the index
 
 SYNOPSIS
 --------
-[verse]
-'git apply' [--stat] [--numstat] [--summary] [--check]
+[synopsis]
+git apply [--stat] [--numstat] [--summary] [--check]
 	  [--index | --intent-to-add] [--3way] [--ours | --theirs | --union]
 	  [--apply] [--no-add] [--build-fake-ancestor=<file>] [-R | --reverse]
 	  [--allow-binary-replacement | --binary] [--reject] [-z]
@@ -35,33 +35,33 @@ linkgit:git-format-patch[1] and/or received by email.
 
 OPTIONS
 -------
-<patch>...::
-	The files to read the patch from.  '-' can be used to read
+`<patch>...`::
+	The files to read the patch from.  `-` can be used to read
 	from the standard input.
 
---stat::
+`--stat`::
 	Instead of applying the patch, output diffstat for the
 	input.  Turns off "apply".
 
---numstat::
+`--numstat`::
 	Similar to `--stat`, but shows the number of added and
 	deleted lines in decimal notation and the pathname without
 	abbreviation, to make it more machine friendly.  For
 	binary files, outputs two `-` instead of saying
 	`0 0`.  Turns off "apply".
 
---summary::
+`--summary`::
 	Instead of applying the patch, output a condensed
 	summary of information obtained from git diff extended
 	headers, such as creations, renames, and mode changes.
 	Turns off "apply".
 
---check::
+`--check`::
 	Instead of applying the patch, see if the patch is
 	applicable to the current working tree and/or the index
 	file and detects errors.  Turns off "apply".
 
---index::
+`--index`::
 	Apply the patch to both the index and the working tree (or
 	merely check that it would apply cleanly to both if `--check` is
 	in effect). Note that `--index` expects index entries and
@@ -70,13 +70,13 @@ OPTIONS
 	raise an error if they are not, even if the patch would apply
 	cleanly to both the index and the working tree in isolation.
 
---cached::
+`--cached`::
 	Apply the patch to just the index, without touching the working
 	tree. If `--check` is in effect, merely check that it would
 	apply cleanly to the index entry.
 
--N::
---intent-to-add::
+`-N`::
+`--intent-to-add`::
 	When applying the patch only to the working tree, mark new
 	files to be added to the index later (see `--intent-to-add`
 	option in linkgit:git-add[1]). This option is ignored if
@@ -84,8 +84,8 @@ OPTIONS
 	repository. Note that `--index` could be implied by other options
 	such as `--3way`.
 
--3::
---3way::
+`-3`::
+`--3way`::
 	Attempt 3-way merge if the patch records the identity of blobs it is supposed
 	to apply to and we have those blobs available locally, possibly leaving the
 	conflict markers in the files in the working tree for the user to
@@ -94,14 +94,14 @@ OPTIONS
 	When used with the `--cached` option, any conflicts are left at higher stages
 	in the cache.
 
---ours::
---theirs::
---union::
+`--ours`::
+`--theirs`::
+`--union`::
 	Instead of leaving conflicts in the file, resolve conflicts favouring
-	our (or their or both) side of the lines. Requires --3way.
+	our (or their or both) side of the lines. Requires `--3way`.
 
---build-fake-ancestor=<file>::
-	Newer 'git diff' output has embedded 'index information'
+`--build-fake-ancestor=<file>`::
+	Newer `git diff` output has embedded 'index information'
 	for each blob to help identify the original version that
 	the patch applies to.  When this flag is given, and if
 	the original versions of the blobs are available locally,
@@ -110,18 +110,18 @@ OPTIONS
 When a pure mode change is encountered (which has no index information),
 the information is read from the current index instead.
 
--R::
---reverse::
+`-R`::
+`--reverse`::
 	Apply the patch in reverse.
 
---reject::
-	For atomicity, 'git apply' by default fails the whole patch and
+`--reject`::
+	For atomicity, `git apply` by default fails the whole patch and
 	does not touch the working tree when some of the hunks
 	do not apply.  This option makes it apply
 	the parts of the patch that are applicable, and leave the
-	rejected hunks in corresponding *.rej files.
+	rejected hunks in corresponding `*.rej` files.
 
--z::
+`-z`::
 	When `--numstat` has been given, do not munge pathnames,
 	but use a NUL-terminated machine-readable format.
 +
@@ -129,20 +129,20 @@ Without this option, pathnames with "unusual" characters are quoted as
 explained for the configuration variable `core.quotePath` (see
 linkgit:git-config[1]).
 
--p<n>::
-	Remove <n> leading path components (separated by slashes) from
+`-p<n>`::
+	Remove _<n>_ leading path components (separated by slashes) from
 	traditional diff paths. E.g., with `-p2`, a patch against
 	`a/dir/file` will be applied directly to `file`. The default is
 	1.
 
--C<n>::
-	Ensure at least <n> lines of surrounding context match before
+`-C<n>`::
+	Ensure at least _<n>_ lines of surrounding context match before
 	and after each change.  When fewer lines of surrounding
 	context exist they all must match.  By default no context is
 	ever ignored.
 
---unidiff-zero::
-	By default, 'git apply' expects that the patch being
+`--unidiff-zero`::
+	By default, `git apply` expects that the patch being
 	applied is a unified diff with at least one line of context.
 	This provides good safety measures, but breaks down when
 	applying a diff generated with `--unified=0`. To bypass these
@@ -151,34 +151,34 @@ linkgit:git-config[1]).
 Note, for the reasons stated above, the usage of context-free patches is
 discouraged.
 
---apply::
+`--apply`::
 	If you use any of the options marked "Turns off
-	'apply'" above, 'git apply' reads and outputs the
+	'apply'" above, `git apply` reads and outputs the
 	requested information without actually applying the
 	patch.  Give this flag after those flags to also apply
 	the patch.
 
---no-add::
+`--no-add`::
 	When applying a patch, ignore additions made by the
 	patch.  This can be used to extract the common part between
-	two files by first running 'diff' on them and applying
+	two files by first running `diff` on them and applying
 	the result with this option, which would apply the
 	deletion part but not the addition part.
 
---allow-binary-replacement::
---binary::
+`--allow-binary-replacement`::
+`--binary`::
 	Historically we did not allow binary patch application
 	without an explicit permission from the user, and this
 	flag was the way to do so.  Currently, we always allow binary
 	patch application, so this is a no-op.
 
---exclude=<path-pattern>::
-	Don't apply changes to files matching the given path pattern. This can
+`--exclude=<path-pattern>`::
+	Don't apply changes to files matching _<path-pattern>_. This can
 	be useful when importing patchsets, where you want to exclude certain
 	files or directories.
 
---include=<path-pattern>::
-	Apply changes to files matching the given path pattern. This can
+`--include=<path-pattern>`::
+	Apply changes to files matching the _<path-pattern>_. This can
 	be useful when importing patchsets, where you want to include certain
 	files or directories.
 +
@@ -188,15 +188,15 @@ patch to each path is used.  A patch to a path that does not match any
 include/exclude pattern is used by default if there is no include pattern
 on the command line, and ignored if there is any include pattern.
 
---ignore-space-change::
---ignore-whitespace::
+`--ignore-space-change`::
+`--ignore-whitespace`::
 	When applying a patch, ignore changes in whitespace in context
 	lines if necessary.
 	Context lines will preserve their whitespace, and they will not
 	undergo whitespace fixing regardless of the value of the
 	`--whitespace` option. New lines will still be fixed, though.
 
---whitespace=<action>::
+`--whitespace=<action>`::
 	When applying a patch, detect a new or modified line that has
 	whitespace errors.  What are considered whitespace errors is
 	controlled by `core.whitespace` configuration.  By default,
@@ -209,7 +209,7 @@ By default, the command outputs warning messages but applies the patch.
 When `git-apply` is used for statistics and not applying a
 patch, it defaults to `nowarn`.
 +
-You can use different `<action>` values to control this
+You can use different _<action>_ values to control this
 behavior:
 +
 * `nowarn` turns off the trailing whitespace warning.
@@ -223,48 +223,48 @@ behavior:
   to apply the patch.
 * `error-all` is similar to `error` but shows all errors.
 
---inaccurate-eof::
-	Under certain circumstances, some versions of 'diff' do not correctly
+`--inaccurate-eof`::
+	Under certain circumstances, some versions of `diff` do not correctly
 	detect a missing new-line at the end of the file. As a result, patches
-	created by such 'diff' programs do not record incomplete lines
+	created by such `diff` programs do not record incomplete lines
 	correctly. This option adds support for applying such patches by
 	working around this bug.
 
--v::
---verbose::
+`-v`::
+`--verbose`::
 	Report progress to stderr. By default, only a message about the
 	current patch being applied will be printed. This option will cause
 	additional information to be reported.
 
--q::
---quiet::
+`-q`::
+`--quiet`::
 	Suppress stderr output. Messages about patch status and progress
 	will not be printed.
 
---recount::
+`--recount`::
 	Do not trust the line counts in the hunk headers, but infer them
 	by inspecting the patch (e.g. after editing the patch without
 	adjusting the hunk headers appropriately).
 
---directory=<root>::
-	Prepend <root> to all filenames.  If a "-p" argument was also passed,
+`--directory=<root>`::
+	Prepend _<root>_ to all filenames.  If a `-p` argument was also passed,
 	it is applied before prepending the new root.
 +
 For example, a patch that talks about updating `a/git-gui.sh` to `b/git-gui.sh`
 can be applied to the file in the working tree `modules/git-gui/git-gui.sh` by
 running `git apply --directory=modules/git-gui`.
 
---unsafe-paths::
+`--unsafe-paths`::
 	By default, a patch that affects outside the working area
 	(either a Git controlled working tree, or the current working
-	directory when "git apply" is used as a replacement of GNU
-	patch) is rejected as a mistake (or a mischief).
+	directory when `git apply` is used as a replacement of GNU
+	`patch`) is rejected as a mistake (or a mischief).
 +
-When `git apply` is used as a "better GNU patch", the user can pass
+When `git apply` is used as a "better GNU `patch`", the user can pass
 the `--unsafe-paths` option to override this safety check.  This option
 has no effect when `--index` or `--cached` is in use.
 
---allow-empty::
+`--allow-empty`::
 	Don't return an error for patches containing no diff. This includes
 	empty patches and patches with commit text only.
 
@@ -273,11 +273,12 @@ CONFIGURATION
 
 include::includes/cmd-config-section-all.adoc[]
 
+:git-apply: 1
 include::config/apply.adoc[]
 
 SUBMODULES
 ----------
-If the patch contains any changes to submodules then 'git apply'
+If the patch contains any changes to submodules then `git apply`
 treats these changes as follows.
 
 If `--index` is specified (explicitly or implicitly), then the submodule
-- 
gitgitgadget


^ permalink raw reply related

* [PATCH 3/5] doc: convert git-am synopsis and options to new style
From: Jean-Noël Avila via GitGitGadget @ 2026-05-17 20:26 UTC (permalink / raw)
  To: git; +Cc: Jean-Noël Avila, Jean-Noël Avila
In-Reply-To: <pull.2117.git.1779049615.gitgitgadget@gmail.com>

From: =?UTF-8?q?Jean-No=C3=ABl=20Avila?= <jn.avila@free.fr>

Convert git-am from [verse]/single-quote style to the modern
synopsis-block style:

- Replace [verse] with [synopsis] in SYNOPSIS block
- Backtick-quote all OPTIONS terms
- Convert inline man page refs
- Convert inline command refs
- Convert prose placeholders:

Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
---
 Documentation/config/am.adoc                  |   6 +-
 Documentation/format-patch-caveats.adoc       |   2 +-
 .../format-patch-end-of-commit-message.adoc   |   4 +-
 Documentation/git-am.adoc                     | 132 +++++++++---------
 4 files changed, 72 insertions(+), 72 deletions(-)

diff --git a/Documentation/config/am.adoc b/Documentation/config/am.adoc
index e9561e12d7..250e6b5047 100644
--- a/Documentation/config/am.adoc
+++ b/Documentation/config/am.adoc
@@ -1,11 +1,11 @@
-am.keepcr::
+`am.keepcr`::
 	If true, linkgit:git-am[1] will call linkgit:git-mailsplit[1]
 	for patches in mbox format with parameter `--keep-cr`. In this
 	case linkgit:git-mailsplit[1] will
 	not remove `\r` from lines ending with `\r\n`. Can be overridden
 	by giving `--no-keep-cr` from the command line.
 
-am.threeWay::
+`am.threeWay`::
 	By default, linkgit:git-am[1] will fail if the patch does not
 	apply cleanly. When set to true, this setting tells
 	linkgit:git-am[1] to fall back on 3-way merge if the patch
@@ -13,7 +13,7 @@ am.threeWay::
 	have those blobs available locally (equivalent to giving the
 	`--3way` option from the command line). Defaults to `false`.
 
-am.messageId::
+`am.messageId`::
 	Add a `Message-ID` trailer based on the email header to the
 	commit when using linkgit:git-am[1] (see
 	linkgit:git-interpret-trailers[1]). See also the `--message-id`
diff --git a/Documentation/format-patch-caveats.adoc b/Documentation/format-patch-caveats.adoc
index 807a65b885..133e4757e7 100644
--- a/Documentation/format-patch-caveats.adoc
+++ b/Documentation/format-patch-caveats.adoc
@@ -28,6 +28,6 @@ repositories. This goes to show that this behavior does not only impact
 email workflows.
 
 Given these limitations, one might be tempted to use a general-purpose
-utility like patch(1) instead. However, patch(1) will not only look for
+utility like `patch`(1) instead. However, `patch`(1) will not only look for
 unindented diffs (like linkgit:git-am[1]) but will try to apply indented
 diffs as well.
diff --git a/Documentation/format-patch-end-of-commit-message.adoc b/Documentation/format-patch-end-of-commit-message.adoc
index ec1ef79f5e..a1a624d2ac 100644
--- a/Documentation/format-patch-end-of-commit-message.adoc
+++ b/Documentation/format-patch-end-of-commit-message.adoc
@@ -1,8 +1,8 @@
 Any line that is of the form:
 
 * three-dashes and end-of-line, or
-* a line that begins with "diff -", or
-* a line that begins with "Index: "
+* a line that begins with `diff -`, or
+* a line that begins with `Index: `
 
 is taken as the beginning of a patch, and the commit log message
 is terminated before the first occurrence of such a line.
diff --git a/Documentation/git-am.adoc b/Documentation/git-am.adoc
index ac65852918..28adf4cf65 100644
--- a/Documentation/git-am.adoc
+++ b/Documentation/git-am.adoc
@@ -8,17 +8,17 @@ git-am - Apply a series of patches from a mailbox
 
 SYNOPSIS
 --------
-[verse]
-'git am' [--signoff] [--keep] [--[no-]keep-cr] [--[no-]utf8] [--[no-]verify]
+[synopsis]
+git am [--signoff] [--keep] [--[no-]keep-cr] [--[no-]utf8] [--[no-]verify]
 	 [--[no-]3way] [--interactive] [--committer-date-is-author-date]
 	 [--ignore-date] [--ignore-space-change | --ignore-whitespace]
 	 [--whitespace=<action>] [-C<n>] [-p<n>] [--directory=<dir>]
 	 [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet]
-	 [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>]
+	 [--[no-]scissors] [-S[<key-id>]] [--patch-format=<format>]
 	 [--quoted-cr=<action>]
 	 [--empty=(stop|drop|keep)]
 	 [(<mbox> | <Maildir>)...]
-'git am' (--continue | --skip | --abort | --quit | --retry | --show-current-patch[=(diff|raw)] | --allow-empty)
+git am (--continue | --skip | --abort | --quit | --retry | --show-current-patch[=(diff|raw)] | --allow-empty)
 
 DESCRIPTION
 -----------
@@ -30,45 +30,45 @@ history without merges.
 
 OPTIONS
 -------
-(<mbox>|<Maildir>)...::
+`(<mbox>|<Maildir>)...`::
 	The list of mailbox files to read patches from. If you do not
 	supply this argument, the command reads from the standard input.
 	If you supply directories, they will be treated as Maildirs.
 
--s::
---signoff::
+`-s`::
+`--signoff`::
 	Add a `Signed-off-by` trailer to the commit message (see
 	linkgit:git-interpret-trailers[1]), using the committer identity
 	of yourself.  See the signoff option in linkgit:git-commit[1]
 	for more information.
 
--k::
---keep::
+`-k`::
+`--keep`::
 	Pass `-k` flag to linkgit:git-mailinfo[1].
 
---keep-non-patch::
+`--keep-non-patch`::
 	Pass `-b` flag to linkgit:git-mailinfo[1].
 
---keep-cr::
---no-keep-cr::
+`--keep-cr`::
+`--no-keep-cr`::
 	With `--keep-cr`, call linkgit:git-mailsplit[1]
 	with the same option, to prevent it from stripping CR at the end of
 	lines. `am.keepcr` configuration variable can be used to specify the
 	default behaviour.  `--no-keep-cr` is useful to override `am.keepcr`.
 
--c::
---scissors::
+`-c`::
+`--scissors`::
 	Remove everything in body before a scissors line (see
 	linkgit:git-mailinfo[1]). Can be activated by default using
 	the `mailinfo.scissors` configuration variable.
 
---no-scissors::
+`--no-scissors`::
 	Ignore scissors lines (see linkgit:git-mailinfo[1]).
 
---quoted-cr=<action>::
+`--quoted-cr=<action>`::
 	This flag will be passed down to linkgit:git-mailinfo[1].
 
---empty=(drop|keep|stop)::
+`--empty=(drop|keep|stop)`::
 	How to handle an e-mail message lacking a patch:
 +
 --
@@ -82,23 +82,23 @@ OPTIONS
 	session. This is the default behavior.
 --
 
--m::
---message-id::
+`-m`::
+`--message-id`::
 	Pass the `-m` flag to linkgit:git-mailinfo[1],
 	so that the `Message-ID` header is added to the commit message.
 	The `am.messageid` configuration variable can be used to specify
 	the default behaviour.
 
---no-message-id::
+`--no-message-id`::
 	Do not add the Message-ID header to the commit message.
 	`--no-message-id` is useful to override `am.messageid`.
 
--q::
---quiet::
+`-q`::
+`--quiet`::
 	Be quiet. Only print error messages.
 
--u::
---utf8::
+`-u`::
+`--utf8`::
 	Pass `-u` flag to linkgit:git-mailinfo[1].
 	The proposed commit log message taken from the e-mail
 	is re-coded into UTF-8 encoding (configuration variable
@@ -108,57 +108,57 @@ OPTIONS
 This was optional in prior versions of git, but now it is the
 default.   You can use `--no-utf8` to override this.
 
---no-utf8::
+`--no-utf8`::
 	Pass `-n` flag to linkgit:git-mailinfo[1].
 
--3::
---3way::
---no-3way::
+`-3`::
+`--3way`::
+`--no-3way`::
 	When the patch does not apply cleanly, fall back on
 	3-way merge if the patch records the identity of blobs
 	it is supposed to apply to and we have those blobs
 	available locally. `--no-3way` can be used to override
-	am.threeWay configuration variable. For more information,
-	see am.threeWay in linkgit:git-config[1].
+	`am.threeWay` configuration variable. For more information,
+	see `am.threeWay` in linkgit:git-config[1].
 
 include::rerere-options.adoc[]
 
---ignore-space-change::
---ignore-whitespace::
---whitespace=<action>::
--C<n>::
--p<n>::
---directory=<dir>::
---exclude=<path>::
---include=<path>::
---reject::
+`--ignore-space-change`::
+`--ignore-whitespace`::
+`--whitespace=<action>`::
+`-C<n>`::
+`-p<n>`::
+`--directory=<dir>`::
+`--exclude=<path>`::
+`--include=<path>`::
+`--reject`::
 	These flags are passed to the linkgit:git-apply[1] program that
 	applies the patch.
 +
-Valid <action> for the `--whitespace` option are:
+Valid _<action>_ for the `--whitespace` option are:
 `nowarn`, `warn`, `fix`, `error`, and `error-all`.
 
---patch-format::
+`--patch-format`::
 	By default the command will try to detect the patch format
 	automatically. This option allows the user to bypass the automatic
 	detection and specify the patch format that the patch(es) should be
 	interpreted as. Valid formats are mbox, mboxrd,
 	stgit, stgit-series, and hg.
 
--i::
---interactive::
+`-i`::
+`--interactive`::
 	Run interactively.
 
---verify::
--n::
---no-verify::
+`--verify`::
+`-n`::
+`--no-verify`::
 	Run the `pre-applypatch` and `applypatch-msg` hooks. This is the
 	default. Skip these hooks with `-n` or `--no-verify`. See also
 	linkgit:githooks[5].
 +
 Note that `post-applypatch` cannot be skipped.
 
---committer-date-is-author-date::
+`--committer-date-is-author-date`::
 	By default the command records the date from the e-mail
 	message as the commit author date, and uses the time of
 	commit creation as the committer date. This allows the
@@ -172,29 +172,29 @@ committer date when applying commits on top of a base which commit is
 older (in terms of the commit date) than the oldest patch you are
 applying.
 
---ignore-date::
+`--ignore-date`::
 	By default the command records the date from the e-mail
 	message as the commit author date, and uses the time of
 	commit creation as the committer date. This allows the
 	user to lie about the author date by using the same
 	value as the committer date.
 
---skip::
+`--skip`::
 	Skip the current patch.  This is only meaningful when
 	restarting an aborted patch.
 
--S[<keyid>]::
---gpg-sign[=<keyid>]::
---no-gpg-sign::
-	GPG-sign commits. The `keyid` argument is optional and
+`-S[<key-id>]`::
+`--gpg-sign[=<key-id>]`::
+`--no-gpg-sign`::
+	GPG-sign commits. The _<key-id>_ is optional and
 	defaults to the committer identity; if specified, it must be
 	stuck to the option without a space. `--no-gpg-sign` is useful to
 	countermand both `commit.gpgSign` configuration variable, and
 	earlier `--gpg-sign`.
 
---continue::
--r::
---resolved::
+`--continue`::
+`-r`::
+`--resolved`::
 	After a patch failure (e.g. attempting to apply
 	conflicting patch), the user has applied it by hand and
 	the index file stores the result of the application.
@@ -202,36 +202,36 @@ applying.
 	extracted from the e-mail message and the current index
 	file, and continue.
 
---resolvemsg=<msg>::
-	When a patch failure occurs, <msg> will be printed
+`--resolvemsg=<msg>`::
+	When a patch failure occurs, _<msg>_ will be printed
 	to the screen before exiting.  This overrides the
 	standard message informing you to use `--continue`
 	or `--skip` to handle the failure.  This is solely
 	for internal use between linkgit:git-rebase[1] and
 	linkgit:git-am[1].
 
---abort::
+`--abort`::
 	Restore the original branch and abort the patching operation.
 	Revert the contents of files involved in the am operation to their
 	pre-am state.
 
---quit::
-	Abort the patching operation but keep HEAD and the index
+`--quit`::
+	Abort the patching operation but keep `HEAD` and the index
 	untouched.
 
---retry::
+`--retry`::
 	Try to apply the last conflicting patch again. This is generally
 	only useful for passing extra options to the retry attempt
 	(e.g., `--3way`), since otherwise you'll just see the same
 	failure again.
 
---show-current-patch[=(diff|raw)]::
+`--show-current-patch[=(diff|raw)]`::
 	Show the message at which linkgit:git-am[1] has stopped due to
 	conflicts.  If `raw` is specified, show the raw contents of
 	the e-mail message; if `diff`, show the diff portion only.
 	Defaults to `raw`.
 
---allow-empty::
+`--allow-empty`::
 	After a patch failure on an input e-mail message lacking a patch,
 	create an empty commit with the contents of the e-mail message
 	as its log message.
@@ -278,11 +278,11 @@ operation is finished, so if you decide to start over from scratch,
 run `git am --abort` before running the command with mailbox
 names.
 
-Before any patches are applied, ORIG_HEAD is set to the tip of the
+Before any patches are applied, `ORIG_HEAD` is set to the tip of the
 current branch.  This is useful if you have problems with multiple
 commits, like running linkgit:git-am[1] on the wrong branch or an error
 in the commits that is more easily fixed by changing the mailbox (e.g.
-errors in the "From:" lines).
+errors in the `From:` lines).
 
 [[caveats]]
 CAVEATS
-- 
gitgitgadget


^ permalink raw reply related

* [PATCH 2/5] doc: convert git-grep synopsis and options to new style
From: Jean-Noël Avila via GitGitGadget @ 2026-05-17 20:26 UTC (permalink / raw)
  To: git; +Cc: Jean-Noël Avila, Jean-Noël Avila
In-Reply-To: <pull.2117.git.1779049615.gitgitgadget@gmail.com>

From: =?UTF-8?q?Jean-No=C3=ABl=20Avila?= <jn.avila@free.fr>

Convert git-grep.adoc from [verse]/single-quote style to the modern
synopsis-block style:

- Replace [verse] with [synopsis] in SYNOPSIS block
- Change 'git grep' to git grep (no single quotes)
- Backtick-quote all OPTIONS terms
- Convert inline man page refs: grep(1) -> `grep`(1)
- Convert inline command refs: 'git diff' -> `git diff`
- Convert prose placeholders: <file> -> _<file>_

Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
---
 Documentation/config/grep.adoc |  36 +++---
 Documentation/git-grep.adoc    | 196 ++++++++++++++++-----------------
 2 files changed, 116 insertions(+), 116 deletions(-)

diff --git a/Documentation/config/grep.adoc b/Documentation/config/grep.adoc
index 10041f27b0..83d4b76dd3 100644
--- a/Documentation/config/grep.adoc
+++ b/Documentation/config/grep.adoc
@@ -1,28 +1,28 @@
-grep.lineNumber::
-	If set to true, enable `-n` option by default.
+`grep.lineNumber`::
+	If set to `true`, enable `-n` option by default.
 
-grep.column::
-	If set to true, enable the `--column` option by default.
+`grep.column`::
+	If set to `true`, enable the `--column` option by default.
 
-grep.patternType::
-	Set the default matching behavior. Using a value of 'basic', 'extended',
-	'fixed', or 'perl' will enable the `--basic-regexp`, `--extended-regexp`,
+`grep.patternType`::
+	Set the default matching behavior. Using a value of `basic`, `extended`,
+	`fixed`, or `perl` will enable the `--basic-regexp`, `--extended-regexp`,
 	`--fixed-strings`, or `--perl-regexp` option accordingly, while the
-	value 'default' will use the `grep.extendedRegexp` option to choose
-	between 'basic' and 'extended'.
+	value `default` will use the `grep.extendedRegexp` option to choose
+	between `basic` and `extended`.
 
-grep.extendedRegexp::
-	If set to true, enable `--extended-regexp` option by default. This
+`grep.extendedRegexp`::
+	If set to `true`, enable `--extended-regexp` option by default. This
 	option is ignored when the `grep.patternType` option is set to a value
-	other than 'default'.
+	other than `default`.
 
-grep.threads::
+`grep.threads`::
 	Number of grep worker threads to use. If unset (or set to 0), Git will
 	use as many threads as the number of logical cores available.
 
-grep.fullName::
-	If set to true, enable `--full-name` option by default.
+`grep.fullName`::
+	If set to `true`, enable `--full-name` option by default.
 
-grep.fallbackToNoIndex::
-	If set to true, fall back to `git grep --no-index` if `git grep`
-	is executed outside of a git repository.  Defaults to false.
+`grep.fallbackToNoIndex`::
+	If set to `true`, fall back to `git grep --no-index` if `git grep`
+	is executed outside of a git repository.  Defaults to `false`.
diff --git a/Documentation/git-grep.adoc b/Documentation/git-grep.adoc
index a548585d4c..19b3ade16d 100644
--- a/Documentation/git-grep.adoc
+++ b/Documentation/git-grep.adoc
@@ -8,8 +8,8 @@ git-grep - Print lines matching a pattern
 
 SYNOPSIS
 --------
-[verse]
-'git grep' [-a | --text] [-I] [--textconv] [-i | --ignore-case] [-w | --word-regexp]
+[synopsis]
+git grep [-a | --text] [-I] [--textconv] [-i | --ignore-case] [-w | --word-regexp]
 	   [-v | --invert-match] [-h|-H] [--full-name]
 	   [-E | --extended-regexp] [-G | --basic-regexp]
 	   [-P | --perl-regexp]
@@ -41,139 +41,139 @@ characters.  An empty string as search expression matches all lines.
 
 OPTIONS
 -------
---cached::
+`--cached`::
 	Instead of searching tracked files in the working tree, search
 	blobs registered in the index file.
 
---untracked::
+`--untracked`::
 	In addition to searching in the tracked files in the working
 	tree, search also in untracked files.
 
---no-index::
+`--no-index`::
 	Search files in the current directory that is not managed by Git,
 	or by ignoring that the current directory is managed by Git.  This
-	is rather similar to running the regular `grep(1)` utility with its
+	is rather similar to running the regular `grep`(1) utility with its
 	`-r` option specified, but with some additional benefits, such as
-	using pathspec patterns to limit paths;  see the 'pathspec' entry
+	using pathspec patterns to limit paths;  see the `pathspec` entry
 	in linkgit:gitglossary[7] for more information.
 +
 This option cannot be used together with `--cached` or `--untracked`.
 See also `grep.fallbackToNoIndex` in 'CONFIGURATION' below.
 
---no-exclude-standard::
+`--no-exclude-standard`::
 	Also search in ignored files by not honoring the `.gitignore`
 	mechanism. Only useful with `--untracked`.
 
---exclude-standard::
+`--exclude-standard`::
 	Do not pay attention to ignored files specified via the `.gitignore`
 	mechanism.  Only useful when searching files in the current directory
 	with `--no-index`.
 
---recurse-submodules::
+`--recurse-submodules`::
 	Recursively search in each submodule that is active and
 	checked out in the repository.  When used in combination with the
 	_<tree>_ option the prefix of all submodule output will be the name of
 	the parent project's _<tree>_ object.  This option cannot be used together
 	with `--untracked`, and it has no effect if `--no-index` is specified.
 
--a::
---text::
+`-a`::
+`--text`::
 	Process binary files as if they were text.
 
---textconv::
+`--textconv`::
 	Honor textconv filter settings.
 
---no-textconv::
+`--no-textconv`::
 	Do not honor textconv filter settings.
 	This is the default.
 
--i::
---ignore-case::
+`-i`::
+`--ignore-case`::
 	Ignore case differences between the patterns and the
 	files.
 
--I::
+`-I`::
 	Don't match the pattern in binary files.
 
---max-depth <depth>::
-	For each <pathspec> given on command line, descend at most <depth>
+`--max-depth <depth>`::
+	For each _<pathspec>_ given on command line, descend at most _<depth>_
 	levels of directories. A value of -1 means no limit.
-	This option is ignored if <pathspec> contains active wildcards.
+	This option is ignored if _<pathspec>_ contains active wildcards.
 	In other words if "a*" matches a directory named "a*",
-	"*" is matched literally so --max-depth is still effective.
+	"*" is matched literally so `--max-depth` is still effective.
 
--r::
---recursive::
+`-r`::
+`--recursive`::
 	Same as `--max-depth=-1`; this is the default.
 
---no-recursive::
+`--no-recursive`::
 	Same as `--max-depth=0`.
 
--w::
---word-regexp::
+`-w`::
+`--word-regexp`::
 	Match the pattern only at word boundary (either begin at the
 	beginning of a line, or preceded by a non-word character; end at
 	the end of a line or followed by a non-word character).
 
--v::
---invert-match::
+`-v`::
+`--invert-match`::
 	Select non-matching lines.
 
--h::
--H::
+`-h`::
+`-H`::
 	By default, the command shows the filename for each
 	match.  `-h` option is used to suppress this output.
 	`-H` is there for completeness and does not do anything
 	except it overrides `-h` given earlier on the command
 	line.
 
---full-name::
+`--full-name`::
 	When run from a subdirectory, the command usually
 	outputs paths relative to the current directory.  This
 	option forces paths to be output relative to the project
 	top directory.
 
--E::
---extended-regexp::
--G::
---basic-regexp::
+`-E`::
+`--extended-regexp`::
+`-G`::
+`--basic-regexp`::
 	Use POSIX extended/basic regexp for patterns.  Default
 	is to use basic regexp.
 
--P::
---perl-regexp::
+`-P`::
+`--perl-regexp`::
 	Use Perl-compatible regular expressions for patterns.
 +
 Support for these types of regular expressions is an optional
 compile-time dependency. If Git wasn't compiled with support for them
 providing this option will cause it to die.
 
--F::
---fixed-strings::
+`-F`::
+`--fixed-strings`::
 	Use fixed strings for patterns (don't interpret pattern
 	as a regex).
 
--n::
---line-number::
+`-n`::
+`--line-number`::
 	Prefix the line number to matching lines.
 
---column::
+`--column`::
 	Prefix the 1-indexed byte-offset of the first match from the start of the
 	matching line.
 
--l::
---files-with-matches::
---name-only::
--L::
---files-without-match::
+`-l`::
+`--files-with-matches`::
+`--name-only`::
+`-L`::
+`--files-without-match`::
 	Instead of showing every matched line, show only the
 	names of files that contain (or do not contain) matches.
-	For better compatibility with 'git diff', `--name-only` is a
+	For better compatibility with `git diff`, `--name-only` is a
 	synonym for `--files-with-matches`.
 
--O[<pager>]::
---open-files-in-pager[=<pager>]::
-	Open the matching files in the pager (not the output of 'grep').
+`-O[<pager>]`::
+`--open-files-in-pager[=<pager>]`::
+	Open the matching files in the pager (not the output of `grep`).
 	If the pager happens to be "less" or "vi", and the user
 	specified only one pattern, the first file is positioned at
 	the first match automatically. The `pager` argument is
@@ -181,65 +181,65 @@ providing this option will cause it to die.
 	without a space. If `pager` is unspecified, the default pager
 	will be used (see `core.pager` in linkgit:git-config[1]).
 
--z::
---null::
+`-z`::
+`--null`::
 	Use \0 as the delimiter for pathnames in the output, and print
 	them verbatim. Without this option, pathnames with "unusual"
 	characters are quoted as explained for the configuration
 	variable `core.quotePath` (see linkgit:git-config[1]).
 
--o::
---only-matching::
+`-o`::
+`--only-matching`::
 	Print only the matched (non-empty) parts of a matching line, with each such
 	part on a separate output line.
 
--c::
---count::
+`-c`::
+`--count`::
 	Instead of showing every matched line, show the number of
 	lines that match.
 
---color[=<when>]::
+`--color[=<when>]`::
 	Show colored matches.
-	The value must be always (the default), never, or auto.
+	The value must be `always` (the default), `never`, or `auto`.
 
---no-color::
+`--no-color`::
 	Turn off match highlighting, even when the configuration file
 	gives the default to color output.
 	Same as `--color=never`.
 
---break::
+`--break`::
 	Print an empty line between matches from different files.
 
---heading::
+`--heading`::
 	Show the filename above the matches in that file instead of
 	at the start of each shown line.
 
--p::
---show-function::
+`-p`::
+`--show-function`::
 	Show the preceding line that contains the function name of
 	the match, unless the matching line is a function name itself.
 	The name is determined in the same way as `git diff` works out
 	patch hunk headers (see 'Defining a custom hunk-header' in
 	linkgit:gitattributes[5]).
 
--<num>::
--C <num>::
---context <num>::
-	Show <num> leading and trailing lines, and place a line
+`-<num>`::
+`-C <num>`::
+`--context <num>`::
+	Show _<num>_ leading and trailing lines, and place a line
 	containing `--` between contiguous groups of matches.
 
--A <num>::
---after-context <num>::
-	Show <num> trailing lines, and place a line containing
+`-A <num>`::
+`--after-context <num>`::
+	Show _<num>_ trailing lines, and place a line containing
 	`--` between contiguous groups of matches.
 
--B <num>::
---before-context <num>::
-	Show <num> leading lines, and place a line containing
+`-B <num>`::
+`--before-context <num>`::
+	Show _<num>_ leading lines, and place a line containing
 	`--` between contiguous groups of matches.
 
--W::
---function-context::
+`-W`::
+`--function-context`::
 	Show the surrounding text from the previous line containing a
 	function name up to the one before the next function name,
 	effectively showing the whole function in which the match was
@@ -247,22 +247,22 @@ providing this option will cause it to die.
 	`git diff` works out patch hunk headers (see 'Defining a
 	custom hunk-header' in linkgit:gitattributes[5]).
 
--m <num>::
---max-count <num>::
+`-m <num>`::
+`--max-count <num>`::
 	Limit the amount of matches per file. When using the `-v` or
 	`--invert-match` option, the search stops after the specified
 	number of non-matches. A value of -1 will return unlimited
 	results (the default). A value of 0 will exit immediately with
 	a non-zero status.
 
---threads <num>::
-	Number of `grep` worker threads to use.  See 'NOTES ON THREADS'
+`--threads <num>`::
+	Number of `grep` worker threads to use.  See `NOTES ON THREADS`
 	and `grep.threads` in 'CONFIGURATION' for more information.
 
--f <file>::
-	Read patterns from <file>, one per line.
+`-f <file>`::
+	Read patterns from _<file>_, one per line.
 +
-Passing the pattern via <file> allows for providing a search pattern
+Passing the pattern via _<file>_ allows for providing a search pattern
 containing a \0.
 +
 Not all pattern types support patterns containing \0. Git will error
@@ -279,44 +279,44 @@ In future versions we may learn to support patterns containing \0 for
 more search backends, until then we'll die when the pattern type in
 question doesn't support them.
 
--e::
+`-e`::
 	The next parameter is the pattern. This option has to be
 	used for patterns starting with `-` and should be used in
 	scripts passing user input to grep.  Multiple patterns are
-	combined by 'or'.
+	combined by `or`.
 
---and::
---or::
---not::
-( ... )::
+`--and`::
+`--or`::
+`--not`::
+`( ... )`::
 	Specify how multiple patterns are combined using Boolean
 	expressions.  `--or` is the default operator.  `--and` has
 	higher precedence than `--or`.  `-e` has to be used for all
 	patterns.
 
---all-match::
+`--all-match`::
 	When giving multiple pattern expressions combined with `--or`,
 	this flag is specified to limit the match to files that
 	have lines to match all of them.
 
--q::
---quiet::
+`-q`::
+`--quiet`::
 	Do not output matched lines; instead, exit with status 0 when
 	there is a match and with non-zero status when there isn't.
 
-<tree>...::
+`<tree>...`::
 	Instead of searching tracked files in the working tree, search
 	blobs in the given trees.
 
-\--::
+`--`::
 	Signals the end of options; the rest of the parameters
-	are <pathspec> limiters.
+	are _<pathspec>_ limiters.
 
-<pathspec>...::
+`<pathspec>...`::
 	If given, limit the search to paths matching at least one pattern.
-	Both leading paths match and glob(7) patterns are supported.
+	Both leading paths match and `glob`(7) patterns are supported.
 +
-For more details about the <pathspec> syntax, see the 'pathspec' entry
+For more details about the _<pathspec>_ syntax, see the `pathspec` entry
 in linkgit:gitglossary[7].
 
 EXAMPLES
-- 
gitgitgadget


^ permalink raw reply related

* [PATCH 1/5] doc: convert git-bisect to synopsis style
From: Jean-Noël Avila via GitGitGadget @ 2026-05-17 20:26 UTC (permalink / raw)
  To: git; +Cc: Jean-Noël Avila, Jean-Noël Avila
In-Reply-To: <pull.2117.git.1779049615.gitgitgadget@gmail.com>

From: =?UTF-8?q?Jean-No=C3=ABl=20Avila?= <jn.avila@free.fr>

Convert Documentation/git-bisect.adoc to the modern synopsis style.

- Replace [verse] with [synopsis] in the SYNOPSIS block
- Remove single quotes around command names in the synopsis
- Use backticks for inline commands, options, refs, and special values
- Apply [synopsis] attribute to in-body command-form code blocks
- Format OPTIONS entries with backtick-quoted terms and direct
- Add synopsis-style formatting to listing blocks
- Format man page references as `command`(N)

Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
---
 Documentation/asciidoc.conf.in |  6 +++
 Documentation/git-bisect.adoc  | 80 ++++++++++++++++++----------------
 2 files changed, 48 insertions(+), 38 deletions(-)

diff --git a/Documentation/asciidoc.conf.in b/Documentation/asciidoc.conf.in
index 31b883a72c..93c63b284a 100644
--- a/Documentation/asciidoc.conf.in
+++ b/Documentation/asciidoc.conf.in
@@ -84,6 +84,9 @@ ifdef::doctype-manpage[]
 [blockdef-open]
 synopsis-style=template="verseparagraph",filter="sed 's!&#8230;\\(\\]\\|$\\)!<phrase>\\0</phrase>!g;s!\\([\\[ |()]\\|^\\|\\]\\|&gt;\\)\\([-=a-zA-Z0-9:+@,\\/_^\\$.\\\\\\*]\\+\\|&#8230;\\)!\\1<literal>\\2</literal>!g;s!&lt;[-a-zA-Z0-9.]\\+&gt;!<emphasis>\\0</emphasis>!g'"
 
+[blockdef-listing]
+synopsis-style=template="verseparagraph",filter="sed 's!&#8230;\\(\\]\\|$\\)!<phrase>\\0</phrase>!g;s!\\([\\[ |()]\\|^\\|\\]\\|&gt;\\)\\([-=a-zA-Z0-9:+@,\\/_^\\$.\\\\\\*]\\+\\|&#8230;\\)!\\1<literal>\\2</literal>!g;s!&lt;[-a-zA-Z0-9.]\\+&gt;!<emphasis>\\0</emphasis>!g'"
+
 [paradef-default]
 synopsis-style=template="verseparagraph",filter="sed 's!&#8230;\\(\\]\\|$\\)!<phrase>\\0</phrase>!g;s!\\([\\[ |()]\\|^\\|\\]\\|&gt;\\)\\([-=a-zA-Z0-9:+@,\\/_^\\$.\\\\\\*]\\+\\|&#8230;\\)!\\1<literal>\\2</literal>!g;s!&lt;[-a-zA-Z0-9.]\\+&gt;!<emphasis>\\0</emphasis>!g'"
 endif::doctype-manpage[]
@@ -93,6 +96,9 @@ ifdef::backend-xhtml11[]
 [blockdef-open]
 synopsis-style=template="verseparagraph",filter="sed 's!&#8230;\\(\\]\\|$\\)!<span>\\0</span>!g;s!\\([\\[ |()]\\|^\\|\\]\\|&gt;\\)\\([-=a-zA-Z0-9:+@,\\/_^\\$.\\\\\\*]\\+\\|&#8230;\\)!\\1<code>\\2</code>!g;s!&lt;[-a-zA-Z0-9.]\\+&gt;!<em>\\0</em>!g'"
 
+[blockdef-listing]
+synopsis-style=template="verseparagraph",filter="sed 's!&#8230;\\(\\]\\|$\\)!<span>\\0</span>!g;s!\\([\\[ |()]\\|^\\|\\]\\|&gt;\\)\\([-=a-zA-Z0-9:+@,\\/_^\\$.\\\\\\*]\\+\\|&#8230;\\)!\\1<code>\\2</code>!g;s!&lt;[-a-zA-Z0-9.]\\+&gt;!<em>\\0</em>!g'"
+
 [paradef-default]
 synopsis-style=template="verseparagraph",filter="sed 's!&#8230;\\(\\]\\|$\\)!<span>\\0</span>!g;s!\\([\\[ |()]\\|^\\|\\]\\|&gt;\\)\\([-=a-zA-Z0-9:+@,\\/_^\\$.\\\\\\*]\\+\\|&#8230;\\)!\\1<code>\\2</code>!g;s!&lt;[-a-zA-Z0-9.]\\+&gt;!<em>\\0</em>!g'"
 endif::backend-xhtml11[]
diff --git a/Documentation/git-bisect.adoc b/Documentation/git-bisect.adoc
index b0078dda0e..9a3b7b3cdb 100644
--- a/Documentation/git-bisect.adoc
+++ b/Documentation/git-bisect.adoc
@@ -8,20 +8,20 @@ git-bisect - Use binary search to find the commit that introduced a bug
 
 SYNOPSIS
 --------
-[verse]
-'git bisect' start [--term-(bad|new)=<term-new> --term-(good|old)=<term-old>]
-		   [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]
-'git bisect' (bad|new|<term-new>) [<rev>]
-'git bisect' (good|old|<term-old>) [<rev>...]
-'git bisect' terms [--term-(good|old) | --term-(bad|new)]
-'git bisect' skip [(<rev>|<range>)...]
-'git bisect' next
-'git bisect' reset [<commit>]
-'git bisect' (visualize|view)
-'git bisect' replay <logfile>
-'git bisect' log
-'git bisect' run <cmd> [<arg>...]
-'git bisect' help
+[synopsis]
+git bisect start [--term-(bad|new)=<term-new> --term-(good|old)=<term-old>]
+		 [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]
+git bisect (bad|new|<term-new>) [<rev>]
+git bisect (good|old|<term-old>) [<rev>...]
+git bisect terms [--term-(good|old) | --term-(bad|new)]
+git bisect skip [(<rev>|<range>)...]
+git bisect next
+git bisect reset [<commit>]
+git bisect (visualize|view)
+git bisect replay <logfile>
+git bisect log
+git bisect run <cmd> [<arg>...]
+git bisect help
 
 DESCRIPTION
 -----------
@@ -94,7 +94,7 @@ Bisect reset
 ~~~~~~~~~~~~
 
 After a bisect session, to clean up the bisection state and return to
-the original HEAD, issue the following command:
+the original `HEAD`, issue the following command:
 
 ------------------------------------------------
 $ git bisect reset
@@ -107,6 +107,7 @@ that, as it cleans up the old bisection state.)
 With an optional argument, you can return to a different commit
 instead:
 
+[synopsis]
 ------------------------------------------------
 $ git bisect reset <commit>
 ------------------------------------------------
@@ -143,12 +144,14 @@ To use "old" and "new" instead of "good" and bad, you must run `git
 bisect start` without commits as argument and then run the following
 commands to add the commits:
 
+[synopsis]
 ------------------------------------------------
 git bisect old [<rev>]
 ------------------------------------------------
 
 to indicate that a commit was before the sought change, or
 
+[synopsis]
 ------------------------------------------------
 git bisect new [<rev>...]
 ------------------------------------------------
@@ -157,6 +160,7 @@ to indicate that it was after.
 
 To get a reminder of the currently used terms, use
 
+[synopsis]
 ------------------------------------------------
 git bisect terms
 ------------------------------------------------
@@ -171,6 +175,7 @@ If you would like to use your own terms instead of "bad"/"good" or
 subcommands like `reset`, `start`, ...) by starting the
 bisection using
 
+[synopsis]
 ------------------------------------------------
 git bisect start --term-old <term-old> --term-new <term-new>
 ------------------------------------------------
@@ -194,7 +199,7 @@ of `git bisect good` and `git bisect bad` to mark commits.
 Bisect visualize/view
 ~~~~~~~~~~~~~~~~~~~~~
 
-To see the currently remaining suspects in 'gitk', issue the following
+To see the currently remaining suspects in `gitk`, issue the following
 command during the bisection process (the subcommand `view` can be used
 as an alternative to `visualize`):
 
@@ -203,12 +208,13 @@ $ git bisect visualize
 ------------
 
 Git detects a graphical environment through various environment variables:
-`DISPLAY`, which is set in X Window System environments on Unix systems.
-`SESSIONNAME`, which is set under Cygwin in interactive desktop sessions.
-`MSYSTEM`, which is set under Msys2 and Git for Windows.
-`SECURITYSESSIONID`, which may be set on macOS in interactive desktop sessions.
 
-If none of these environment variables is set, 'git log' is used instead.
+`DISPLAY`:: which is set in X Window System environments on Unix systems.
+`SESSIONNAME`:: which is set under Cygwin in interactive desktop sessions.
+`MSYSTEM`:: which is set under Msys2 and Git for Windows.
+`SECURITYSESSIONID`:: which may be set on macOS in interactive desktop sessions.
+
+If none of these environment variables is set, `git log` is used instead.
 You can also give command-line options such as `-p` and `--stat`.
 
 ------------
@@ -342,8 +348,8 @@ code between 1 and 127 (inclusive), except 125, if the current source
 code is bad/new.
 
 Any other exit code will abort the bisect process. It should be noted
-that a program that terminates via `exit(-1)` leaves $? = 255, (see the
-exit(3) manual page), as the value is chopped with `& 0377`.
+that a program that terminates via `exit(-1)` leaves `$?` = 255, (see the
+`exit`(3) manual page), as the value is chopped with `& 0377`.
 
 The special exit code 125 should be used when the current source code
 cannot be tested. If the script exits with this code, the current
@@ -355,12 +361,12 @@ details do not matter, as they are normal errors in the script, as far as
 `bisect run` is concerned).
 
 You may often find that during a bisect session you want to have
-temporary modifications (e.g. s/#define DEBUG 0/#define DEBUG 1/ in a
+temporary modifications (e.g. `s/#define DEBUG 0/#define DEBUG 1/` in a
 header file, or "revision that does not have this commit needs this
 patch applied to work around another problem this bisection is not
 interested in") applied to the revision being tested.
 
-To cope with such a situation, after the inner 'git bisect' finds the
+To cope with such a situation, after the inner `git bisect` finds the
 next revision to test, the script can apply the patch
 before compiling, run the real test, and afterwards decide if the
 revision (possibly with the needed patch) passed the test and then
@@ -370,20 +376,18 @@ determine the eventual outcome of the bisect session.
 
 OPTIONS
 -------
---no-checkout::
-+
-Do not checkout the new working tree at each iteration of the bisection
-process. Instead just update the reference named `BISECT_HEAD` to make
-it point to the commit that should be tested.
+`--no-checkout`::
+	Do not checkout the new working tree at each iteration of the bisection
+	process. Instead just update the reference named `BISECT_HEAD` to make
+	it point to the commit that should be tested.
 +
 This option may be useful when the test you would perform in each step
 does not require a checked out tree.
 +
 If the repository is bare, `--no-checkout` is assumed.
 
---first-parent::
-+
-Follow only the first parent commit upon seeing a merge commit.
+`--first-parent`::
+	Follow only the first parent commit upon seeing a merge commit.
 +
 In detecting regressions introduced through the merging of a branch, the merge
 commit will be identified as introduction of the bug and its ancestors will be
@@ -395,7 +399,7 @@ branch contained broken or non-buildable commits, but the merge itself was OK.
 EXAMPLES
 --------
 
-* Automatically bisect a broken build between v1.2 and HEAD:
+* Automatically bisect a broken build between v1.2 and `HEAD`:
 +
 ------------
 $ git bisect start HEAD v1.2 --      # HEAD is bad, v1.2 is good
@@ -403,7 +407,7 @@ $ git bisect run make                # "make" builds the app
 $ git bisect reset                   # quit the bisect session
 ------------
 
-* Automatically bisect a test failure between origin and HEAD:
+* Automatically bisect a test failure between origin and `HEAD`:
 +
 ------------
 $ git bisect start HEAD origin --    # HEAD is bad, origin is good
@@ -430,7 +434,7 @@ and `exit 1` otherwise.
 +
 It is safer if both `test.sh` and `check_test_case.sh` are
 outside the repository to prevent interactions between the bisect,
-make and test processes and the scripts.
+`make` and test processes and the scripts.
 
 * Automatically bisect with temporary modifications (hot-fix):
 +
@@ -491,9 +495,9 @@ $ git bisect run sh -c '
 $ git bisect reset                   # quit the bisect session
 ------------
 +
-In this case, when 'git bisect run' finishes, bisect/bad will refer to a commit that
+In this case, when `git bisect run` finishes, `bisect/bad` will refer to a commit that
 has at least one parent whose reachable graph is fully traversable in the sense
-required by 'git pack objects'.
+required by `git pack-objects`.
 
 * Look for a fix instead of a regression in the code
 +
-- 
gitgitgadget


^ permalink raw reply related

* [PATCH 0/5] doc: convert another batch of files to synopsis style
From: Jean-Noël Avila via GitGitGadget @ 2026-05-17 20:26 UTC (permalink / raw)
  To: git; +Cc: Jean-Noël Avila

This time, 4 new conversions:

 * git-grep
 * git-am
 * git-apply
 * git-imap-send

This batch was an opportunity to test AI-helped conversion.

Jean-Noël Avila (5):
  doc: convert git-bisect to synopsis style
  doc: convert git-grep synopsis and options to new style
  doc: convert git-am synopsis and options to new style
  doc: convert git-apply synopsis and options to new style
  doc: convert git-imap-send synopsis and options to new style

 Documentation/asciidoc.conf.in                |   6 +
 Documentation/config/am.adoc                  |   6 +-
 Documentation/config/apply.adoc               |  17 +-
 Documentation/config/grep.adoc                |  36 ++--
 Documentation/config/imap.adoc                |  30 +--
 Documentation/format-patch-caveats.adoc       |   2 +-
 .../format-patch-end-of-commit-message.adoc   |   4 +-
 Documentation/git-am.adoc                     | 132 ++++++------
 Documentation/git-apply.adoc                  | 125 +++++------
 Documentation/git-bisect.adoc                 |  80 +++----
 Documentation/git-grep.adoc                   | 196 +++++++++---------
 Documentation/git-imap-send.adoc              |  24 +--
 12 files changed, 337 insertions(+), 321 deletions(-)


base-commit: 59ff4886a579f4bc91e976fe18590b9ae02c7a08
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2117%2Fjnavila%2Fbisect-synopsis-style-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2117/jnavila/bisect-synopsis-style-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/2117
-- 
gitgitgadget

^ permalink raw reply


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