Skip to content

Commit 3568fae

Browse files
committed
Merge branch 'ar/submodule-gitdir-tweak' into seen
* ar/submodule-gitdir-tweak: t7425: add gitdir encoding tests t7450: move nested gitdir tests to t7425 submodule: remove validate_submodule_git_dir() submodule: error out if gitdir name is too long submodule: encode gitdir paths to avoid conflicts strbuf: bring back is_rfc3986_unreserved t7425: add basic mixed submodule gitdir path tests submodule: add gitdir path config override submodule: create new gitdirs under submodules path submodule--helper: use submodule_name_to_gitdir in add_submodule
2 parents f111f4b + e55ab8e commit 3568fae

39 files changed

Lines changed: 481 additions & 287 deletions

Documentation/config/submodule.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ submodule.<name>.active::
5252
submodule.active config option. See linkgit:gitsubmodules[7] for
5353
details.
5454

55+
submodule.<name>.gitdir::
56+
This option sets the gitdir path for submodule <name>, allowing users
57+
to override the default path or change the default path name encoding.
58+
5559
submodule.active::
5660
A repeated field which contains a pathspec used to match against a
5761
submodule's path to determine if the submodule is of interest to git

Documentation/fetch-options.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ ifndef::git-pull[]
215215
submodule that has commits that are referenced by a newly fetched
216216
superproject commit but are missing in the local submodule clone. A
217217
changed submodule can be fetched as long as it is present locally e.g.
218-
in `$GIT_DIR/modules/` (see linkgit:gitsubmodules[7]); if the upstream
218+
in `$GIT_DIR/submodules/` (see linkgit:gitsubmodules[7]); if the upstream
219219
adds a new submodule, that submodule cannot be fetched until it is
220220
cloned e.g. by `git submodule update`.
221221
+

Documentation/git-fetch.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ include::config/fetch.adoc[]
304304
BUGS
305305
----
306306
Using --recurse-submodules can only fetch new commits in submodules that are
307-
present locally e.g. in `$GIT_DIR/modules/`. If the upstream adds a new
307+
present locally e.g. in `$GIT_DIR/submodules/`. If the upstream adds a new
308308
submodule, that submodule cannot be fetched until it is cloned e.g. by `git
309309
submodule update`. This is expected to be fixed in a future Git version.
310310

Documentation/git-submodule.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ registered submodules, and sync any nested submodules within.
266266
absorbgitdirs::
267267
If a git directory of a submodule is inside the submodule,
268268
move the git directory of the submodule into its superproject's
269-
`$GIT_DIR/modules` path and then connect the git directory and
269+
`$GIT_DIR/submodules` path and then connect the git directory and
270270
its working directory by setting the `core.worktree` and adding
271271
a .git file pointing to the git directory embedded in the
272272
superprojects git directory.

Documentation/gitsubmodules.adoc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ The submodule has its own history; the repository it is embedded
2222
in is called a superproject.
2323
2424
On the filesystem, a submodule usually (but not always - see FORMS below)
25-
consists of (i) a Git directory located under the `$GIT_DIR/modules/`
25+
consists of (i) a Git directory located under the `$GIT_DIR/submodules/`
2626
directory of its superproject, (ii) a working directory inside the
2727
superproject's working directory, and a `.git` file at the root of
2828
the submodule's working directory pointing to (i).
2929
30-
Assuming the submodule has a Git directory at `$GIT_DIR/modules/foo/`
30+
Assuming the submodule has a Git directory at `$GIT_DIR/submodules/foo/`
3131
and a working directory at `path/to/bar/`, the superproject tracks the
3232
submodule via a `gitlink` entry in the tree at `path/to/bar` and an entry
3333
in its `.gitmodules` file (see linkgit:gitmodules[5]) of the form
@@ -138,7 +138,7 @@ using older versions of Git.
138138
It is possible to construct these old form repositories manually.
139139
+
140140
When deinitialized or deleted (see below), the submodule's Git
141-
directory is automatically moved to `$GIT_DIR/modules/<name>/`
141+
directory is automatically moved to `$GIT_DIR/submodules/<name>/`
142142
of the superproject.
143143
144144
* Deinitialized submodule: A `gitlink`, and a `.gitmodules` entry,
@@ -163,7 +163,7 @@ possible to checkout past commits without requiring fetching
163163
from another repository.
164164
+
165165
To completely remove a submodule, manually delete
166-
`$GIT_DIR/modules/<name>/`.
166+
`$GIT_DIR/submodules/<name>/`.
167167
168168
ACTIVE SUBMODULES
169169
-----------------

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2246,6 +2246,11 @@ ifndef HAVE_PLATFORM_PROCINFO
22462246
COMPAT_OBJS += compat/stub/procinfo.o
22472247
endif
22482248

2249+
ifdef NO_PATHCONF
2250+
COMPAT_CFLAGS += -DNO_PATHCONF
2251+
COMPAT_OBJS += compat/pathconf.o
2252+
endif
2253+
22492254
ifdef RUNTIME_PREFIX
22502255

22512256
ifdef HAVE_BSD_KERN_PROC_SYSCTL

builtin/credential-store.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,6 @@ static void rewrite_credential_file(const char *fn, struct credential *c,
7676
die_errno("unable to write credential store");
7777
}
7878

79-
static int is_rfc3986_unreserved(char ch)
80-
{
81-
return isalnum(ch) ||
82-
ch == '-' || ch == '_' || ch == '.' || ch == '~';
83-
}
84-
8579
static int is_rfc3986_reserved_or_unreserved(char ch)
8680
{
8781
if (is_rfc3986_unreserved(ch))

builtin/submodule--helper.c

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,6 +1214,22 @@ static int module_summary(int argc, const char **argv, const char *prefix,
12141214
return ret;
12151215
}
12161216

1217+
static int module_gitdir(int argc, const char **argv, const char *prefix UNUSED,
1218+
struct repository *repo UNUSED)
1219+
{
1220+
struct strbuf gitdir = STRBUF_INIT;
1221+
1222+
if (argc != 2)
1223+
usage(_("git submodule--helper gitdir <name>"));
1224+
1225+
submodule_name_to_gitdir(&gitdir, the_repository, argv[1]);
1226+
1227+
printf("%s\n", gitdir.buf);
1228+
1229+
strbuf_release(&gitdir);
1230+
return 0;
1231+
}
1232+
12171233
struct sync_cb {
12181234
const char *prefix;
12191235
const char *super_prefix;
@@ -1709,10 +1725,6 @@ static int clone_submodule(const struct module_clone_data *clone_data,
17091725
clone_data_path = to_free = xstrfmt("%s/%s", repo_get_work_tree(the_repository),
17101726
clone_data->path);
17111727

1712-
if (validate_submodule_git_dir(sm_gitdir, clone_data->name) < 0)
1713-
die(_("refusing to create/use '%s' in another submodule's "
1714-
"git dir"), sm_gitdir);
1715-
17161728
if (!file_exists(sm_gitdir)) {
17171729
if (clone_data->require_init && !stat(clone_data_path, &st) &&
17181730
!is_empty_dir(clone_data_path))
@@ -1786,23 +1798,6 @@ static int clone_submodule(const struct module_clone_data *clone_data,
17861798
free(path);
17871799
}
17881800

1789-
/*
1790-
* We already performed this check at the beginning of this function,
1791-
* before cloning the objects. This tries to detect racy behavior e.g.
1792-
* in parallel clones, where another process could easily have made the
1793-
* gitdir nested _after_ it was created.
1794-
*
1795-
* To prevent further harm coming from this unintentionally-nested
1796-
* gitdir, let's disable it by deleting the `HEAD` file.
1797-
*/
1798-
if (validate_submodule_git_dir(sm_gitdir, clone_data->name) < 0) {
1799-
char *head = xstrfmt("%s/HEAD", sm_gitdir);
1800-
unlink(head);
1801-
free(head);
1802-
die(_("refusing to create/use '%s' in another submodule's "
1803-
"git dir"), sm_gitdir);
1804-
}
1805-
18061801
connect_work_tree_and_git_dir(clone_data_path, sm_gitdir, 0);
18071802

18081803
p = repo_submodule_path(the_repository, clone_data_path, "config");
@@ -3193,13 +3188,13 @@ static void append_fetch_remotes(struct strbuf *msg, const char *git_dir_path)
31933188

31943189
static int add_submodule(const struct add_data *add_data)
31953190
{
3196-
char *submod_gitdir_path;
31973191
struct module_clone_data clone_data = MODULE_CLONE_DATA_INIT;
31983192
struct string_list reference = STRING_LIST_INIT_NODUP;
31993193
int ret = -1;
32003194

32013195
/* perhaps the path already exists and is already a git repo, else clone it */
32023196
if (is_directory(add_data->sm_path)) {
3197+
char *submod_gitdir_path;
32033198
struct strbuf sm_path = STRBUF_INIT;
32043199
strbuf_addstr(&sm_path, add_data->sm_path);
32053200
submod_gitdir_path = xstrfmt("%s/.git", add_data->sm_path);
@@ -3213,10 +3208,11 @@ static int add_submodule(const struct add_data *add_data)
32133208
free(submod_gitdir_path);
32143209
} else {
32153210
struct child_process cp = CHILD_PROCESS_INIT;
3211+
struct strbuf submod_gitdir = STRBUF_INIT;
32163212

3217-
submod_gitdir_path = xstrfmt(".git/modules/%s", add_data->sm_name);
3213+
submodule_name_to_gitdir(&submod_gitdir, the_repository, add_data->sm_name);
32183214

3219-
if (is_directory(submod_gitdir_path)) {
3215+
if (is_directory(submod_gitdir.buf)) {
32203216
if (!add_data->force) {
32213217
struct strbuf msg = STRBUF_INIT;
32223218
char *die_msg;
@@ -3225,8 +3221,8 @@ static int add_submodule(const struct add_data *add_data)
32253221
"locally with remote(s):\n"),
32263222
add_data->sm_name);
32273223

3228-
append_fetch_remotes(&msg, submod_gitdir_path);
3229-
free(submod_gitdir_path);
3224+
append_fetch_remotes(&msg, submod_gitdir.buf);
3225+
strbuf_release(&submod_gitdir);
32303226

32313227
strbuf_addf(&msg, _("If you want to reuse this local git "
32323228
"directory instead of cloning again from\n"
@@ -3244,7 +3240,7 @@ static int add_submodule(const struct add_data *add_data)
32443240
"submodule '%s'\n"), add_data->sm_name);
32453241
}
32463242
}
3247-
free(submod_gitdir_path);
3243+
strbuf_release(&submod_gitdir);
32483244

32493245
clone_data.prefix = add_data->prefix;
32503246
clone_data.path = add_data->sm_path;
@@ -3596,6 +3592,7 @@ int cmd_submodule__helper(int argc,
35963592
NULL
35973593
};
35983594
struct option options[] = {
3595+
OPT_SUBCOMMAND("gitdir", &fn, module_gitdir),
35993596
OPT_SUBCOMMAND("clone", &fn, module_clone),
36003597
OPT_SUBCOMMAND("add", &fn, module_add),
36013598
OPT_SUBCOMMAND("update", &fn, module_update),

compat/pathconf.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include "git-compat-util.h"
2+
3+
/*
4+
* Minimal stub for platforms without pathconf() (e.g. Windows),
5+
* to fall back to NAME_MAX from limits.h or compat/posix.h.
6+
*/
7+
long git_pathconf(const char *path UNUSED, int name UNUSED)
8+
{
9+
return -1;
10+
}

compat/posix.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,14 @@ char *gitdirname(char *);
250250
#define NAME_MAX 255
251251
#endif
252252

253+
#ifdef NO_PATHCONF
254+
#ifndef _PC_NAME_MAX
255+
#define _PC_NAME_MAX 1 /* dummy value, only used for git_pathconf */
256+
#endif
257+
#define pathconf(a,b) git_pathconf(a,b)
258+
long git_pathconf(const char *path, int name);
259+
#endif
260+
253261
typedef uintmax_t timestamp_t;
254262
#define PRItime PRIuMAX
255263
#define parse_timestamp strtoumax

0 commit comments

Comments
 (0)