public inbox for git@vger.kernel.org 
 help / color / mirror / Atom feed
From: Adrian Ratiu <adrian.ratiu@collabora•com>
To: git@vger•kernel.org
Cc: Emily Shaffer <emilyshaffer@google•com>,
	Rodrigo Damazio Bovendorp <rdamazio@google•com>,
	Jeff King <peff@peff•net>, Junio C Hamano <gitster@pobox•com>,
	Aaron Schrab <aaron@schrab•com>,
	Jonathan Nieder <jrnieder@gmail•com>,
	Patrick Steinhardt <ps@pks•im>,
	Josh Steadmon <steadmon@google•com>,
	Ben Knoble <ben.knoble@gmail•com>,
	Phillip Wood <phillip.wood123@gmail•com>,
	Adrian Ratiu <adrian.ratiu@collabora•com>
Subject: [PATCH v4 0/4] Encode submodule gitdir names to avoid conflicts
Date: Fri,  7 Nov 2025 17:05:43 +0200	[thread overview]
Message-ID: <20251107150547.3272180-1-adrian.ratiu@collabora.com> (raw)
In-Reply-To: <20250816213642.3517822-1-adrian.ratiu@collabora.com>

Hello everyone,

For those new to this series, we are adding an extension to encode submodule
gitdir paths to avoid filesystem conflicts.

v4 continues with the simplifications started in v3, based on reviewer feedback
(many thanks to everyone, especially to Junio and Patrick).

The biggest design change in v4 is that config submodule.<name>.gitdir becomes
mandatory when extensions.submoduleEncoding is enabled, so instead of being just
an optional override like in previous iterations, in v4 it's the centerpiece of
design, the single point of truth from which submodule gitdir paths are located.

This allows users to not care about the specific encoding being used and also
allows git to improveme the encoding implementation over time: everyone just gets
the submodule gitdirs from the config after the extension is enabled.

Another important change is that we do not encode everything by default when the
extension is enabled: submodule_name_to_gitdir() validates multiple candidates
and picks the best one and encoding only when required.

As always this is based on latest master branch, I've merged into next/seen for
any conflicts, pushed to GitHub [1] and ran the CI with all tests passing [2].

I also added a rangediff between v3 and v4, which might help some reviewers,
though it's rather big because we changed the config/encoding design like I
mentioned above so it might be easier to give it a full review.

Changes between v3 -> v4:
* Replaced bmwill@google•com -> bwilliams.eng@gmail•com (Kristoffer)
* Made the gitdir config the authoritative source of truth for all submodule
  git dirs when the extension is enabled (Junio, Patrick)
* Replaced the "encode everything by default" design with a stepwise/retry
  validation in submodule_name_to_gitdir() to pick the best canditate (Junio)
* Moved is_rfc3986_unreserved() to url.[ch] instead of strbuf (Junio)
* Fixed a parallel job execution bug I introduced with the extension in v3 (Adrian)
* Improved lib-verify-submodule-gitdir-path.sh to handle relative/abs paths (Adrian)
* Fixed submodule.<name>.gitdir documentation vs code mismatch (Junio)
* Defined the config together with the extension by squashing commits (Patrick)
* Removed the A -> _a, B -> _b custom encoding in favor of a simplified percent
  encodin which is only done when case-folding to allow uppercase chars (Junio)
* Dropped patch with pathconf wrapper, as it's not required for basic encoding,
  it can be added back if we implement sharding (Junio, Peff, Patrick)
* Used repo_config_get_string_tmp to avoid a char* free call (Patrick)
* Added comment to document is_rfc3986_unreserved() (Patrick)
* Fixed heredoc body indentation (Patrick)
* Fixed trivial doc markup conflict with upstream commit (Adrian)
* Reworded multiple commits for clarity (Junio)

Please let me know if you have any questions or other feedback.

Thank you,
Adrian

[1] https://github.com/10ne1/git/tree/dev/aratiu/encoding-v4
[2] https://github.com/10ne1/git/actions/runs/19170390360

Range-diff against v3:
1:  b2e317a8f6 ! 1:  7d34507692 submodule--helper: use submodule_name_to_gitdir in add_submodule
    @@ Commit message
         submodule--helper: use submodule_name_to_gitdir in add_submodule
     
         While testing submodule gitdir path encoding, I noticed submodule--helper
    -    is still using a hardcoded name-based path leading to test failures, so
    -    convert it to the common helper function introduced by commit ce125d431a
    -    (submodule: extract path to submodule gitdir func, 2021-09-15)  and used
    -    in other locations across the source tree.
    +    is still using a hardcoded modules gitdir path leading to test failures.
    +
    +    Call the submodule_name_to_gitdir() helper instead, which was invented
    +    exactly for this purpose and is already used by all the other locations
    +    which work on gitdirs.
    +
    +    Also narrow the scope of the submod_gitdir_path variable which is not
    +    used anymore in the updated "else" branch.
     
         Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora•com>
     
2:  17838ad13f < -:  ---------- submodule: add gitdir path config override
3:  4fc7020f26 < -:  ---------- strbuf: bring back is_rfc3986_unreserved
-:  ---------- > 2:  1e609bdd1a builtin/credential-store: move is_rfc3986_unreserved to url.[ch]
4:  dc6d5069ff ! 3:  c51fd58669 submodule: encode gitdir paths to avoid conflicts
    @@ Metadata
     Author: Adrian Ratiu <adrian.ratiu@collabora•com>
     
      ## Commit message ##
    -    submodule: encode gitdir paths to avoid conflicts
    +    submodule: add extension to encode gitdir paths
     
    -    This adds a new submoduleEncoding extension which encodes gitdir names
    -    to avoid collisions due to nested gitdirs or case insensitive filesystems.
    +    Add a submoduleEncoding extension which fixes filesystem collisions by
    +    encoding gitdir paths. At a high level, this implements a mechanism to
    +    encode -> validate -> retry until a working gitdir path is found.
     
    -    A custom encoding can become unnecessarily complex, while url-encoding is
    -    relatively well-known, however it needs some extending to support case
    -    insensitive filesystems, hence why A is encoded as _a, B as _b and so on.
    +    Credit goes to Junio for coming up with this design: encoding is only
    +    applied when necessary, e.g. uppercase characters are encoded only on
    +    case-folding filesystems and only if a real conflict is detected.
     
    -    Unfortunately encoding A -> _a (...) is not enough to fix the reserved
    -    Windows file names (e.g. COM1) because worktrees still use names like COM1
    -    even if the gitdirs paths are encoded, so future work is needed to fully
    -    address Windows reserved names.
    +    To make this work, we rely on the submodule.<name>.gitdir config as the
    +    single source of truth for gitidir paths: the config is always set when
    +    the extension is enabled. Users who care about gitdir paths are expected
    +    to get/set the config and not the underlying encoding implementation.
     
    -    For now url-encoding is the only option, however in the future we may
    -    add alternatives (other encodings, hashes or even hash_name).
    +    This commit adds the basic encoding logic which addresses nested gitdirs.
    +    The next commit fixes case-folding, the next commit fixes names longer
    +    than NAME_MAX. The idea is the encoding can be improved over time in a
    +    way which is transparent to users.
     
    +    Suggested-by: Junio C Hamano <gitster@pobox•com>
         Suggested-by: Phillip Wood <phillip.wood123@gmail•com>
         Suggested-by: Patrick Steinhardt <ps@pks•im>
    +    Based-on-patch-by: Brandon Williams <bwilliams.eng@gmail•com>
         Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora•com>
     
      ## Documentation/config/extensions.adoc ##
    -@@ Documentation/config/extensions.adoc: relativeWorktrees::
    +@@ Documentation/config/extensions.adoc: relativeWorktrees:::
      	repaired with either the `--relative-paths` option or with the
      	`worktree.useRelativePaths` config set to `true`.
      
    -+submoduleEncoding::
    ++submoduleEncoding:::
     +	If enabled, submodule gitdir paths are encoded to avoid filesystem
    -+	conflicts due to nested gitdirs or case insensitivity. For now, only
    -+	url-encoding (rfc3986) is available, with a small addition to encode
    -+	uppercase to lowercase letters (`A  -> _a`, `B -> _b` and so on).
    -+	Other encoding or hashing methods may be added in the future.
    -+	Any preexisting non-encoded submodule gitdirs are used as-is, to
    -+	ease migration and reduce risk of gitdirs not being recognized.
    -+
    - worktreeConfig::
    ++	conflicts due to nested gitdirs, case insensitivity or other issues
    ++	When enabled, the submodule.<name>.gitdir config is always set for
    ++	all submodulesand is the single point of authority for gitdir paths.
    ++
    + worktreeConfig:::
      	If enabled, then worktrees will load config settings from the
      	`$GIT_DIR/config.worktree` file in addition to the
     
      ## Documentation/config/submodule.adoc ##
     @@ Documentation/config/submodule.adoc: submodule.<name>.active::
    - submodule.<name>.gitdir::
    - 	This option sets the gitdir path for submodule <name>, allowing users
    - 	to override the default path or change the default path name encoding.
    -+	Submodule gitdir encoding is enabled via `extensions.submoduleEncoding`
    -+	(see linkgit:git-config[1]). This config works both with the extension
    -+	enabled or disabled.
    + 	submodule.active config option. See linkgit:gitsubmodules[7] for
    + 	details.
      
    ++submodule.<name>.gitdir::
    ++	This option sets the gitdir path for submodule <name>, allowing users to
    ++	override the default path. Only works when `extensions.submoduleEncoding`
    ++	is enabled, otherwise does nothing. See linkgit:git-config[1] for details.
    ++
      submodule.active::
      	A repeated field which contains a pathspec used to match against a
    + 	submodule's path to determine if the submodule is of interest to git
    +
    + ## builtin/submodule--helper.c ##
    +@@ builtin/submodule--helper.c: static int module_summary(int argc, const char **argv, const char *prefix,
    + 	return ret;
    + }
    + 
    ++static int module_gitdir(int argc, const char **argv, const char *prefix UNUSED,
    ++			 struct repository *repo)
    ++{
    ++	struct strbuf gitdir = STRBUF_INIT;
    ++
    ++	if (argc != 2)
    ++		usage(_("git submodule--helper gitdir <name>"));
    ++
    ++	submodule_name_to_gitdir(&gitdir, repo, argv[1]);
    ++
    ++	printf("%s\n", gitdir.buf);
    ++
    ++	strbuf_release(&gitdir);
    ++	return 0;
    ++}
    ++
    + struct sync_cb {
    + 	const char *prefix;
    + 	const char *super_prefix;
    +@@ builtin/submodule--helper.c: int cmd_submodule__helper(int argc,
    + 		NULL
    + 	};
    + 	struct option options[] = {
    ++		OPT_SUBCOMMAND("gitdir", &fn, module_gitdir),
    + 		OPT_SUBCOMMAND("clone", &fn, module_clone),
    + 		OPT_SUBCOMMAND("add", &fn, module_add),
    + 		OPT_SUBCOMMAND("update", &fn, module_update),
    +
    + ## repository.c ##
    +@@ repository.c: int repo_init(struct repository *repo,
    + 	repo->repository_format_worktree_config = format.worktree_config;
    + 	repo->repository_format_relative_worktrees = format.relative_worktrees;
    + 	repo->repository_format_precious_objects = format.precious_objects;
    ++	repo->repository_format_submodule_encoding = format.submodule_encoding;
    + 
    + 	/* take ownership of format.partial_clone */
    + 	repo->repository_format_partial_clone = format.partial_clone;
     
      ## repository.h ##
     @@ repository.h: struct repository {
    @@ setup.h: struct repository_format {
      	int compat_hash_algo;
     
      ## submodule.c ##
    -@@ submodule.c: int validate_submodule_git_dir(char *git_dir, const char *submodule_name)
    - 	char *p;
    +@@
    + #include "commit-reach.h"
    + #include "read-cache-ll.h"
    + #include "setup.h"
    ++#include "url.h"
    + 
    + static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF;
    + static int initialized_fetch_ref_tips;
    +@@ submodule.c: int submodule_move_head(const char *path, const char *super_prefix,
    + 	return ret;
    + }
    + 
    ++/*
    ++ * Find the last submodule name in the gitdir path (modules can be nested).
    ++ * Returns a pointer into `path` to the beginning of the name or NULL if not found.
    ++ */
    ++static char *find_last_submodule_name(char *git_dir_path)
    ++{
    ++	const char *modules_marker = "/modules/";
    ++	char *p = git_dir_path;
    ++	char *last = NULL;
    ++
    ++	while ((p = strstr(p, modules_marker))) {
    ++		last = p + strlen(modules_marker);
    ++		p++;
    ++	}
    ++
    ++	return last;
    ++}
    ++
    + int validate_submodule_git_dir(char *git_dir, const char *submodule_name)
    + {
    + 	size_t len = strlen(git_dir), suffix_len = strlen(submodule_name);
    +-	char *p;
    ++	char *p = git_dir + len - suffix_len;
    ++	bool suffixes_match = !strcmp(p, submodule_name);
      	int ret = 0;
      
    -+	/*
    -+	 * Skip these checks when extensions.submoduleEncoding is enabled because
    -+	 * it fixes the nesting issues and the suffixes will not match by design.
    -+	 */
    -+	if (the_repository->repository_format_submodule_encoding)
    +-	if (len <= suffix_len || (p = git_dir + len - suffix_len)[-1] != '/' ||
    +-	    strcmp(p, submodule_name))
    +-		BUG("submodule name '%s' not a suffix of git dir '%s'",
    +-		    submodule_name, git_dir);
    +-
    + 	/*
    + 	 * We prevent the contents of sibling submodules' git directories to
    + 	 * clash.
    +@@ submodule.c: int validate_submodule_git_dir(char *git_dir, const char *submodule_name)
    + 	 * but the latter directory is already designated to contain the hooks
    + 	 * of the former.
    + 	 */
    +-	for (; *p; p++) {
    ++	for (; *p && suffixes_match; p++) {
    + 		if (is_dir_sep(*p)) {
    + 			char c = *p;
    + 
    +@@ submodule.c: int validate_submodule_git_dir(char *git_dir, const char *submodule_name)
    + 		}
    + 	}
    + 
    ++	/* tests after this check are only for encoded names, when the extension is enabled */
    ++	if (!the_repository->repository_format_submodule_encoding)
     +		return 0;
     +
    - 	if (len <= suffix_len || (p = git_dir + len - suffix_len)[-1] != '/' ||
    - 	    strcmp(p, submodule_name))
    - 		BUG("submodule name '%s' not a suffix of git dir '%s'",
    ++	/* Prevent the use of '/' in names */
    ++	p = find_last_submodule_name(git_dir);
    ++	if (p && strchr(p, '/') != NULL)
    ++		return error("submodule gitdir name '%s' contains unexpected '/'", p);
    ++
    + 	return 0;
    + }
    + 
     @@ submodule.c: int submodule_to_gitdir(struct repository *repo,
      	return ret;
      }
      
    -+static void strbuf_addstr_case_encode(struct strbuf *dst, const char *src)
    ++static int validate_and_set_submodule_gitdir(struct strbuf *gitdir_path,
    ++					     const char *submodule_name)
     +{
    -+	for (; *src; src++) {
    -+		unsigned char c = *src;
    -+		if (c >= 'A' && c <= 'Z') {
    -+			strbuf_addch(dst, '_');
    -+			strbuf_addch(dst, c - 'A' + 'a');
    -+		} else {
    -+			strbuf_addch(dst, c);
    -+		}
    -+	}
    ++	char *key;
    ++
    ++	if (validate_submodule_git_dir(gitdir_path->buf, submodule_name))
    ++		return -1;
    ++
    ++	key = xstrfmt("submodule.%s.gitdir", submodule_name);
    ++	repo_config_set_gently(the_repository, key, gitdir_path->buf);
    ++	FREE_AND_NULL(key);
    ++
    ++	return 0;
    ++
     +}
     +
      void submodule_name_to_gitdir(struct strbuf *buf, struct repository *r,
      			      const char *submodule_name)
      {
    --	/*
    ++	const char *gitdir;
    ++	char *key;
    ++
    ++	repo_git_path_append(r, buf, "modules/");
    ++	strbuf_addstr(buf, submodule_name);
    ++
    ++	/* If extensions.submoduleEncoding is disabled, use the plain path set above */
    ++	if (!r->repository_format_submodule_encoding)
    ++		return;
    ++
    ++	/* Extension is enabled: use the gitdir config if it exists */
    ++	key = xstrfmt("submodule.%s.gitdir", submodule_name);
    ++	if (!repo_config_get_string_tmp(r, key, &gitdir)) {
    ++		strbuf_reset(buf);
    ++		strbuf_addstr(buf, gitdir);
    ++		FREE_AND_NULL(key);
    ++		return;
    ++	}
    ++	FREE_AND_NULL(key);
    ++
    + 	/*
     -	 * NEEDSWORK: The current way of mapping a submodule's name to
     -	 * its location in .git/modules/ has problems with some naming
     -	 * schemes. For example, if a submodule is named "foo" and
    @@ submodule.c: int submodule_to_gitdir(struct repository *repo,
     -	 * submodule.<name>.gitdir config in .gitmodules that repo
     -	 * administrators can explicitly set. Nothing has been decided,
     -	 * so for now, just append the name at the end of the path.
    --	 */
    - 	char *gitdir_path, *key;
    - 
    - 	/* Allow config override. */
    -@@ submodule.c: void submodule_name_to_gitdir(struct strbuf *buf, struct repository *r,
    - 
    - 	repo_git_path_append(r, buf, "modules/");
    - 	strbuf_addstr(buf, submodule_name);
    ++	 * The gitdir config does not exist, even though the extension is enabled.
    ++	 * Therefore we are in one of the following cases:
    + 	 */
     +
    -+	/* Existing legacy non-encoded names are used as-is */
    -+	if (is_git_directory(buf->buf))
    ++	/* Case 1: legacy migration of valid plain submodule names */
    ++	if (!validate_and_set_submodule_gitdir(buf, submodule_name))
     +		return;
     +
    -+	if (the_repository->repository_format_submodule_encoding) {
    -+		struct strbuf tmp = STRBUF_INIT;
    ++	/* Case 2: Try URI-safe (RFC3986) encoding first, this fixes nested gitdirs */
    ++	strbuf_reset(buf);
    + 	repo_git_path_append(r, buf, "modules/");
    +-	strbuf_addstr(buf, submodule_name);
    ++	strbuf_addstr_urlencode(buf, submodule_name, is_rfc3986_unreserved);
    ++	if (!validate_and_set_submodule_gitdir(buf, submodule_name))
    ++		return;
     +
    -+		strbuf_reset(buf);
    -+		repo_git_path_append(r, buf, "modules/");
    ++	/* Case 3: error out */
    ++	die(_("Cannot construct a valid gitdir path for submodule '%s': "
    ++	      "please set a unique git config for 'submodule.%s.gitdir'."),
    ++	    submodule_name, submodule_name);
    + }
    +
    + ## t/lib-verify-submodule-gitdir-path.sh (new) ##
    +@@
    ++# Helper to verify if repo $1 contains a submodule named $2 with gitdir path $3
     +
    -+		strbuf_addstr_urlencode(&tmp, submodule_name, is_rfc3986_unreserved);
    -+		strbuf_addstr_case_encode(buf, tmp.buf);
    ++# This does not check filesystem existence. That is done in submodule.c via the
    ++# submodule_name_to_gitdir() API which this helper ends up calling. The gitdirs
    ++# might or might not exist (e.g. when adding a new submodule), so this only
    ++# checks the expected configuration path, which might be overridden by the user.
     +
    -+		strbuf_release(&tmp);
    -+	}
    - }
    ++verify_submodule_gitdir_path() {
    ++	repo="$1" &&
    ++	name="$2" &&
    ++	path="$3" &&
    ++	(
    ++		cd "$repo" &&
    ++		# Compute expected absolute path
    ++		expected="$(git rev-parse --git-common-dir)/$path" &&
    ++		expected="$(test-tool path-utils real_path "$expected")" &&
    ++		# Compute actual absolute path
    ++		actual="$(git submodule--helper gitdir "$name")" &&
    ++		actual="$(test-tool path-utils real_path "$actual")" &&
    ++		echo "$expected" >expect &&
    ++		echo "$actual" >actual &&
    ++		test_cmp expect actual
    ++	)
    ++}
     
      ## t/meson.build ##
     @@ t/meson.build: integration_tests = [
    @@ t/t7425-submodule-encoding.sh (new)
     +
     +test_expect_success 'verify submodule name is properly encoded' '
     +	verify_submodule_gitdir_path main legacy modules/legacy &&
    -+	verify_submodule_gitdir_path main "New Sub" modules/_new%20_sub
    ++	verify_submodule_gitdir_path main "New Sub" "modules/New Sub"
     +'
     +
     +test_expect_success 'clone from repo with both legacy and new-style submodules' '
    @@ t/t7425-submodule-encoding.sh (new)
     +		cd cloned-encoding &&
     +
     +		test_path_is_dir .git/modules/legacy &&
    -+		test_path_is_dir .git/modules/_new%20_sub &&
    ++		test_path_is_dir ".git/modules/New Sub" &&
     +
     +		git submodule status >list &&
     +		test_grep "$legacy_rev legacy" list &&
    @@ t/t7425-submodule-encoding.sh (new)
     +		git submodule update --init --recursive &&
     +
     +		test_path_is_dir .git/modules/legacy &&
    -+		test_path_is_dir .git/modules/_new%20_sub &&
    ++		test_path_is_dir ".git/modules/New Sub" &&
     +
     +		# Verify both submodules are at the expected commits
     +		git submodule status >list &&
    @@ t/t7425-submodule-encoding.sh (new)
     +'
     +
     +test_done
    +
    + ## t/t9902-completion.sh ##
    +@@ t/t9902-completion.sh: test_expect_success 'git config set - variable name - __git_compute_second_level
    + 	submodule.sub.fetchRecurseSubmodules Z
    + 	submodule.sub.ignore Z
    + 	submodule.sub.active Z
    ++	submodule.sub.gitdir Z
    + 	EOF
    + '
    + 
5:  775cf131bf < -:  ---------- submodule: error out if gitdir name is too long
-:  ---------- > 4:  01a5b10d5a submodule: fix case-folding gitdir filesystem colisions

Adrian Ratiu (4):
  submodule--helper: use submodule_name_to_gitdir in add_submodule
  builtin/credential-store: move is_rfc3986_unreserved to url.[ch]
  submodule: add extension to encode gitdir paths
  submodule: fix case-folding gitdir filesystem colisions

 Documentation/config/extensions.adoc  |   6 +
 Documentation/config/submodule.adoc   |   5 +
 builtin/credential-store.c            |   7 +-
 builtin/submodule--helper.c           |  30 ++++-
 repository.c                          |   1 +
 repository.h                          |   1 +
 setup.c                               |   7 ++
 setup.h                               |   1 +
 submodule.c                           | 155 ++++++++++++++++++++-----
 t/lib-verify-submodule-gitdir-path.sh |  24 ++++
 t/meson.build                         |   1 +
 t/t7425-submodule-encoding.sh         | 161 ++++++++++++++++++++++++++
 t/t9902-completion.sh                 |   1 +
 url.c                                 |  23 ++++
 url.h                                 |   3 +
 15 files changed, 387 insertions(+), 39 deletions(-)
 create mode 100644 t/lib-verify-submodule-gitdir-path.sh
 create mode 100755 t/t7425-submodule-encoding.sh

-- 
2.51.0


  parent reply	other threads:[~2025-11-07 15:06 UTC|newest]

Thread overview: 219+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-16 21:36 [PATCH 0/9] Encode submodule gitdir names to avoid conflicts Adrian Ratiu
2025-08-16 21:36 ` [PATCH 1/9] submodule--helper: use submodule_name_to_gitdir in add_submodule Adrian Ratiu
2025-08-20 19:04   ` Josh Steadmon
2025-08-21 11:26     ` Adrian Ratiu
2025-08-16 21:36 ` [PATCH 2/9] submodule: create new gitdirs under submodules path Adrian Ratiu
2025-09-08 14:24   ` Phillip Wood
2025-09-08 15:46     ` Adrian Ratiu
2025-09-09  8:53       ` Phillip Wood
2025-09-09 10:57         ` Adrian Ratiu
2025-08-16 21:36 ` [PATCH 3/9] submodule: add gitdir path config override Adrian Ratiu
2025-08-20 19:37   ` Josh Steadmon
2025-08-21 12:18     ` Adrian Ratiu
2025-08-20 21:38   ` Josh Steadmon
2025-08-21 13:04     ` Adrian Ratiu
2025-08-20 21:50   ` Josh Steadmon
2025-08-21 13:05     ` Adrian Ratiu
2025-09-08 14:23   ` Phillip Wood
2025-09-09 12:02     ` Adrian Ratiu
2025-08-16 21:36 ` [PATCH 4/9] t: submodules: add basic mixed gitdir path tests Adrian Ratiu
2025-08-20 22:07   ` Josh Steadmon
2025-09-02 23:02   ` Junio C Hamano
2025-08-16 21:36 ` [PATCH 5/9] strbuf: bring back is_rfc3986_unreserved Adrian Ratiu
2025-08-16 21:56   ` Ben Knoble
2025-08-21 13:08     ` Adrian Ratiu
2025-08-16 21:36 ` [PATCH 6/9] submodule: encode gitdir paths to avoid conflicts Adrian Ratiu
2025-08-20 19:29   ` Jeff King
2025-08-21 13:14     ` Adrian Ratiu
2025-08-16 21:36 ` [PATCH 7/9] submodule: remove validate_submodule_git_dir() Adrian Ratiu
2025-09-08 14:23   ` Phillip Wood
2025-08-16 21:36 ` [PATCH 8/9] t: move nested gitdir tests to proper location Adrian Ratiu
2025-08-16 21:36 ` [PATCH 9/9] t: add gitdir encoding tests Adrian Ratiu
2025-08-18 22:06   ` Junio C Hamano
2025-08-21 13:17     ` Adrian Ratiu
2025-08-17 13:01 ` [PATCH 0/9] Encode submodule gitdir names to avoid conflicts Adrian Ratiu
2025-09-08 14:01 ` [PATCH v2 00/10] " Adrian Ratiu
2025-09-08 14:01   ` [PATCH v2 01/10] submodule--helper: use submodule_name_to_gitdir in add_submodule Adrian Ratiu
2025-09-30 13:37     ` Kristoffer Haugsbakk
2025-09-08 14:01   ` [PATCH v2 02/10] submodule: create new gitdirs under submodules path Adrian Ratiu
2025-09-09  7:40     ` Patrick Steinhardt
2025-09-09 16:17       ` Adrian Ratiu
2025-09-08 14:01   ` [PATCH v2 03/10] submodule: add gitdir path config override Adrian Ratiu
2025-09-09  7:40     ` Patrick Steinhardt
2025-09-09 17:46       ` Adrian Ratiu
2025-09-08 14:01   ` [PATCH v2 04/10] t7425: add basic mixed submodule gitdir path tests Adrian Ratiu
2025-09-08 14:01   ` [PATCH v2 05/10] strbuf: bring back is_rfc3986_unreserved Adrian Ratiu
2025-09-08 14:01   ` [PATCH v2 06/10] submodule: encode gitdir paths to avoid conflicts Adrian Ratiu
2025-09-10 18:15     ` SZEDER Gábor
2025-09-10 19:30       ` Adrian Ratiu
2025-09-10 20:18     ` Kristoffer Haugsbakk
2025-09-30 13:36     ` Kristoffer Haugsbakk
2025-09-08 14:01   ` [PATCH v2 07/10] submodule: error out if gitdir name is too long Adrian Ratiu
2025-09-08 15:51     ` Jeff King
2025-09-08 17:15       ` Adrian Ratiu
2025-09-30 13:35     ` Kristoffer Haugsbakk
2025-09-08 14:01   ` [PATCH v2 08/10] submodule: remove validate_submodule_git_dir() Adrian Ratiu
2025-09-30 13:35     ` Kristoffer Haugsbakk
2025-10-03  7:56       ` Adrian Ratiu
2025-09-08 14:01   ` [PATCH v2 09/10] t7450: move nested gitdir tests to t7425 Adrian Ratiu
2025-09-08 14:01   ` [PATCH v2 10/10] t7425: add gitdir encoding tests Adrian Ratiu
2025-10-06 11:25 ` [PATCH v3 0/5] Encode submodule gitdir names to avoid conflicts Adrian Ratiu
2025-10-06 11:25   ` [PATCH v3 1/5] submodule--helper: use submodule_name_to_gitdir in add_submodule Adrian Ratiu
2025-10-06 16:37     ` Junio C Hamano
2025-10-07  9:23       ` Adrian Ratiu
2025-10-06 11:25   ` [PATCH v3 2/5] submodule: add gitdir path config override Adrian Ratiu
2025-10-06 16:47     ` Junio C Hamano
2025-10-07 15:41       ` Junio C Hamano
2025-10-21  8:06         ` Patrick Steinhardt
2025-10-21 11:50           ` Adrian Ratiu
2025-10-21  8:05     ` Patrick Steinhardt
2025-10-21 11:57       ` Adrian Ratiu
2025-10-06 11:25   ` [PATCH v3 3/5] strbuf: bring back is_rfc3986_unreserved Adrian Ratiu
2025-10-06 16:51     ` Junio C Hamano
2025-10-06 17:47       ` Junio C Hamano
2025-10-07  9:43       ` Adrian Ratiu
2025-10-21  8:06     ` Patrick Steinhardt
2025-10-06 11:25   ` [PATCH v3 4/5] submodule: encode gitdir paths to avoid conflicts Adrian Ratiu
2025-10-06 16:57     ` Junio C Hamano
2025-10-07 14:10       ` Adrian Ratiu
2025-10-07 17:20         ` Junio C Hamano
2025-10-07 17:41           ` Adrian Ratiu
2025-10-07 19:55             ` Junio C Hamano
2025-10-06 11:25   ` [PATCH v3 5/5] submodule: error out if gitdir name is too long Adrian Ratiu
2025-10-06 17:06     ` Junio C Hamano
2025-10-07 10:17       ` Adrian Ratiu
2025-10-07 15:58         ` Junio C Hamano
2025-10-21  8:06     ` Patrick Steinhardt
2025-10-21 13:13       ` Adrian Ratiu
2025-10-06 16:21   ` [PATCH v3 0/5] Encode submodule gitdir names to avoid conflicts Junio C Hamano
2025-10-07 11:13     ` Adrian Ratiu
2025-10-07 15:36       ` Junio C Hamano
2025-10-07 16:58         ` Adrian Ratiu
2025-10-07 17:27         ` Junio C Hamano
2025-10-07 16:21       ` Junio C Hamano
2025-10-07 17:21         ` Adrian Ratiu
2025-11-07 15:05 ` Adrian Ratiu [this message]
2025-11-07 15:05   ` [PATCH v4 1/4] submodule--helper: use submodule_name_to_gitdir in add_submodule Adrian Ratiu
2025-11-07 15:05   ` [PATCH v4 2/4] builtin/credential-store: move is_rfc3986_unreserved to url.[ch] Adrian Ratiu
2025-11-07 15:05   ` [PATCH v4 3/4] submodule: add extension to encode gitdir paths Adrian Ratiu
2025-11-07 15:05   ` [PATCH v4 4/4] submodule: fix case-folding gitdir filesystem colisions Adrian Ratiu
2025-11-08 18:20     ` Aaron Schrab
2025-11-10 17:11       ` Adrian Ratiu
2025-11-10 17:31         ` Aaron Schrab
2025-11-10 18:27           ` Adrian Ratiu
2025-11-10 19:10         ` Junio C Hamano
2025-11-10 23:01           ` Adrian Ratiu
2025-11-10 23:17             ` Junio C Hamano
2025-11-11 12:41               ` Adrian Ratiu
2025-11-12 15:28     ` Adrian Ratiu
2025-11-14 23:03   ` [PATCH v4 0/4] Encode submodule gitdir names to avoid conflicts Josh Steadmon
2025-11-17 15:22     ` Adrian Ratiu
2025-11-19 21:10 ` [PATCH v5 0/7] " Adrian Ratiu
2025-11-19 21:10   ` [PATCH v5 1/7] submodule--helper: use submodule_name_to_gitdir in add_submodule Adrian Ratiu
2025-11-19 21:10   ` [PATCH v5 2/7] builtin/credential-store: move is_rfc3986_unreserved to url.[ch] Adrian Ratiu
2025-12-05 12:16     ` Patrick Steinhardt
2025-12-05 17:25       ` Adrian Ratiu
2025-11-19 21:10   ` [PATCH v5 3/7] submodule: always validate gitdirs inside submodule_name_to_gitdir Adrian Ratiu
2025-12-05 12:17     ` Patrick Steinhardt
2025-12-05 18:17       ` Adrian Ratiu
2025-11-19 21:10   ` [PATCH v5 4/7] submodule: add extension to encode gitdir paths Adrian Ratiu
2025-12-05 12:19     ` Patrick Steinhardt
2025-12-05 19:30       ` Adrian Ratiu
2025-12-05 22:47         ` Junio C Hamano
2025-12-06 11:59           ` Patrick Steinhardt
2025-12-06 16:38             ` Junio C Hamano
2025-12-08  9:01               ` Adrian Ratiu
2025-12-08 11:46                 ` Patrick Steinhardt
2025-12-08 15:48                   ` Adrian Ratiu
2025-12-08  9:10             ` Adrian Ratiu
2025-11-19 21:10   ` [PATCH v5 5/7] submodule: fix case-folding gitdir filesystem colisions Adrian Ratiu
2025-11-19 21:10   ` [PATCH v5 6/7] submodule: use hashed name for gitdir Adrian Ratiu
2025-11-19 21:10   ` [PATCH v5 7/7] meson/Makefile: allow setting submodule encoding at build time Adrian Ratiu
2025-12-05 12:19     ` Patrick Steinhardt
2025-12-05 19:42       ` Adrian Ratiu
2025-12-05 22:52         ` Junio C Hamano
2025-12-06 12:02           ` Patrick Steinhardt
2025-12-06 16:48             ` Junio C Hamano
2025-12-08  9:23             ` Adrian Ratiu
2025-12-08  9:42           ` Adrian Ratiu
2025-12-13  8:08 ` [PATCH v6 00/10] Add submodulePathConfig extension and gitdir encoding Adrian Ratiu
2025-12-13  8:08   ` [PATCH v6 01/10] submodule--helper: use submodule_name_to_gitdir in add_submodule Adrian Ratiu
2025-12-13  8:08   ` [PATCH v6 02/10] submodule: always validate gitdirs inside submodule_name_to_gitdir Adrian Ratiu
2025-12-16  9:09     ` Patrick Steinhardt
2025-12-13  8:08   ` [PATCH v6 03/10] builtin/submodule--helper: add gitdir command Adrian Ratiu
2025-12-13  8:08   ` [PATCH v6 04/10] submodule: introduce extensions.submodulePathConfig Adrian Ratiu
2025-12-16  9:09     ` Patrick Steinhardt
2025-12-16  9:45       ` Adrian Ratiu
2025-12-16 23:22     ` Josh Steadmon
2025-12-17  7:30       ` Adrian Ratiu
2025-12-13  8:08   ` [PATCH v6 05/10] submodule: allow runtime enabling extensions.submodulePathConfig Adrian Ratiu
2025-12-16  9:09     ` Patrick Steinhardt
2025-12-16 10:01       ` Adrian Ratiu
2025-12-13  8:08   ` [PATCH v6 06/10] submodule--helper: add gitdir migration command Adrian Ratiu
2025-12-16  9:09     ` Patrick Steinhardt
2025-12-16 10:17       ` Adrian Ratiu
2025-12-13  8:08   ` [PATCH v6 07/10] builtin/credential-store: move is_rfc3986_unreserved to url.[ch] Adrian Ratiu
2025-12-13  8:08   ` [PATCH v6 08/10] submodule--helper: fix filesystem collisions by encoding gitdir paths Adrian Ratiu
2025-12-13  8:08   ` [PATCH v6 09/10] submodule: fix case-folding gitdir filesystem collisions Adrian Ratiu
2025-12-13  8:08   ` [PATCH v6 10/10] submodule: hash the submodule name for the gitdir path Adrian Ratiu
2025-12-13 14:03   ` [PATCH v6 00/10] Add submodulePathConfig extension and gitdir encoding Ben Knoble
2025-12-15 16:28     ` Adrian Ratiu
2025-12-16  0:53       ` Junio C Hamano
2025-12-18  3:43       ` Ben Knoble
2025-12-16 23:20   ` Josh Steadmon
2025-12-17  8:17     ` Adrian Ratiu
2025-12-20 10:15 ` [PATCH v7 00/11] " Adrian Ratiu
2025-12-20 10:15   ` [PATCH v7 01/11] submodule--helper: use submodule_name_to_gitdir in add_submodule Adrian Ratiu
2025-12-20 10:15   ` [PATCH v7 02/11] submodule: always validate gitdirs inside submodule_name_to_gitdir Adrian Ratiu
2025-12-20 10:15   ` [PATCH v7 03/11] builtin/submodule--helper: add gitdir command Adrian Ratiu
2025-12-20 10:15   ` [PATCH v7 04/11] submodule: introduce extensions.submodulePathConfig Adrian Ratiu
2025-12-21  3:27     ` Junio C Hamano
2025-12-23 13:35       ` Adrian Ratiu
2026-01-06  7:25     ` Patrick Steinhardt
2026-01-07 16:31       ` Adrian Ratiu
2025-12-20 10:15   ` [PATCH v7 05/11] submodule: allow runtime enabling extensions.submodulePathConfig Adrian Ratiu
2026-01-06  7:25     ` Patrick Steinhardt
2026-01-07 16:40       ` Adrian Ratiu
2025-12-20 10:15   ` [PATCH v7 06/11] submodule--helper: add gitdir migration command Adrian Ratiu
2026-01-06  7:25     ` Patrick Steinhardt
2026-01-07 16:42       ` Adrian Ratiu
2025-12-20 10:15   ` [PATCH v7 07/11] builtin/credential-store: move is_rfc3986_unreserved to url.[ch] Adrian Ratiu
2025-12-20 10:15   ` [PATCH v7 08/11] submodule--helper: fix filesystem collisions by encoding gitdir paths Adrian Ratiu
2025-12-20 10:15   ` [PATCH v7 09/11] submodule: fix case-folding gitdir filesystem collisions Adrian Ratiu
2025-12-20 10:15   ` [PATCH v7 10/11] submodule: hash the submodule name for the gitdir path Adrian Ratiu
2025-12-20 10:15   ` [PATCH v7 11/11] submodule: detect conflicts with existing gitdir configs Adrian Ratiu
2026-01-06  7:26     ` Patrick Steinhardt
2025-12-21  2:39   ` [PATCH v7 00/11] Add submodulePathConfig extension and gitdir encoding Junio C Hamano
2026-01-06  7:25   ` Patrick Steinhardt
2026-01-07 23:01 ` [PATCH v8 " Adrian Ratiu
2026-01-07 23:01   ` [PATCH v8 01/11] submodule--helper: use submodule_name_to_gitdir in add_submodule Adrian Ratiu
2026-01-07 23:01   ` [PATCH v8 02/11] submodule: always validate gitdirs inside submodule_name_to_gitdir Adrian Ratiu
2026-01-07 23:01   ` [PATCH v8 03/11] builtin/submodule--helper: add gitdir command Adrian Ratiu
2026-01-07 23:01   ` [PATCH v8 04/11] submodule: introduce extensions.submodulePathConfig Adrian Ratiu
2026-01-07 23:01   ` [PATCH v8 05/11] submodule: allow runtime enabling extensions.submodulePathConfig Adrian Ratiu
2026-01-08  6:46     ` Patrick Steinhardt
2026-01-07 23:01   ` [PATCH v8 06/11] submodule--helper: add gitdir migration command Adrian Ratiu
2026-01-08  6:46     ` Patrick Steinhardt
2026-01-07 23:01   ` [PATCH v8 07/11] builtin/credential-store: move is_rfc3986_unreserved to url.[ch] Adrian Ratiu
2026-01-07 23:01   ` [PATCH v8 08/11] submodule--helper: fix filesystem collisions by encoding gitdir paths Adrian Ratiu
2026-01-07 23:01   ` [PATCH v8 09/11] submodule: fix case-folding gitdir filesystem collisions Adrian Ratiu
2026-01-07 23:01   ` [PATCH v8 10/11] submodule: hash the submodule name for the gitdir path Adrian Ratiu
2026-01-07 23:01   ` [PATCH v8 11/11] submodule: detect conflicts with existing gitdir configs Adrian Ratiu
2026-01-08  6:47   ` [PATCH v8 00/11] Add submodulePathConfig extension and gitdir encoding Patrick Steinhardt
2026-01-08 22:30     ` Josh Steadmon
2026-01-11 18:24       ` Junio C Hamano
2026-01-12 18:46 ` [PATCH v9 " Adrian Ratiu
2026-01-12 18:46   ` [PATCH v9 01/11] submodule--helper: use submodule_name_to_gitdir in add_submodule Adrian Ratiu
2026-01-12 18:46   ` [PATCH v9 02/11] submodule: always validate gitdirs inside submodule_name_to_gitdir Adrian Ratiu
2026-01-12 18:46   ` [PATCH v9 03/11] builtin/submodule--helper: add gitdir command Adrian Ratiu
2026-01-12 18:46   ` [PATCH v9 04/11] submodule: introduce extensions.submodulePathConfig Adrian Ratiu
2026-01-12 18:46   ` [PATCH v9 05/11] submodule: allow runtime enabling extensions.submodulePathConfig Adrian Ratiu
2026-01-12 18:46   ` [PATCH v9 06/11] submodule--helper: add gitdir migration command Adrian Ratiu
2026-01-12 18:46   ` [PATCH v9 07/11] builtin/credential-store: move is_rfc3986_unreserved to url.[ch] Adrian Ratiu
2026-01-12 18:46   ` [PATCH v9 08/11] submodule--helper: fix filesystem collisions by encoding gitdir paths Adrian Ratiu
2026-01-12 18:46   ` [PATCH v9 09/11] submodule: fix case-folding gitdir filesystem collisions Adrian Ratiu
2026-01-12 18:46   ` [PATCH v9 10/11] submodule: hash the submodule name for the gitdir path Adrian Ratiu
2026-01-12 18:46   ` [PATCH v9 11/11] submodule: detect conflicts with existing gitdir configs Adrian Ratiu
2026-01-12 20:17   ` [PATCH v9 00/11] Add submodulePathConfig extension and gitdir encoding Junio C Hamano
2026-01-12 20:51     ` Adrian Ratiu
2026-01-13  6:12       ` Patrick Steinhardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251107150547.3272180-1-adrian.ratiu@collabora.com \
    --to=adrian.ratiu@collabora$(echo .)com \
    --cc=aaron@schrab$(echo .)com \
    --cc=ben.knoble@gmail$(echo .)com \
    --cc=emilyshaffer@google$(echo .)com \
    --cc=git@vger$(echo .)kernel.org \
    --cc=gitster@pobox$(echo .)com \
    --cc=jrnieder@gmail$(echo .)com \
    --cc=peff@peff$(echo .)net \
    --cc=phillip.wood123@gmail$(echo .)com \
    --cc=ps@pks$(echo .)im \
    --cc=rdamazio@google$(echo .)com \
    --cc=steadmon@google$(echo .)com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox