Skip to content

Commit 7a3a4c7

Browse files
kevin-wormdscho
authored andcommitted
mingw: respect core.longPaths when initializing a new gitdir
Use case: Allow git to checkout a repository or submodule in a directory with a long path when core.longpaths = true. Example: > ./git.exe config --global core.longpaths true > ./git.exe clone https://github.com/git/git.git --recurse-submodules \ /c/eval/git_test/loooooooooooooooooooooooooooooooooooooooooooooooooooooooo\ oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\ oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\ oooooooong Context: $ sh --version GNU bash, version 4.4.23(1)-release (x86_64-pc-msys) $ ./git.exe --version --build-options git version 2.36.1.windows.1 cpu: x86_64 built from commit: e2ff68a sizeof-long: 4 sizeof-size_t: 8 shell-path: /bin/sh feature: fsmonitor--daemon Error: fatal: '$GIT_DIR' too big. Problem analysis: setup_explicit_git_dir in setup.c uses PATH_MAX to check if the git dir is to long. On Windows PATH_MAX is set by limit.h to 260 and setup_explicit_git_dir ignores core.longpaths. Solution: The implementation is based on the solution proposed by Johannes Schindelin, see: #3372 (comment) * Refactor the part of trace2_initialize() that reads the config. * Make tr2_sysenv_cb() a public function. * No longer calling it from trace2_initialize(), but from a static callback function in common-main.c. * Calling read_very_early_config() explicitly in main(), with that static callback function that calls into tr2_sysenv_cb(). * Extend the static callback function for Windows, and parse core.longPaths in that function. * Extend startup_info struct in cache.h with 'int max_long_path' so we can use it in setup_explicit_git_dir instead of PATH_MAX. This fixes #3372 Signed-off-by: Kevin Worm <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 3b059de commit 7a3a4c7

File tree

4 files changed

+15
-2
lines changed

4 files changed

+15
-2
lines changed

common-main.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ static void restore_sigpipe_to_default(void)
2727

2828
static int read_very_early_config_cb(const char *key, const char *value, void *d)
2929
{
30-
return tr2_sysenv_cb(key, value, d);
30+
if (starts_with(key, "core."))
31+
return platform_core_config(key, value, d);
32+
else
33+
return tr2_sysenv_cb(key, value, d);
3134
}
3235

3336
int main(int argc, const char **argv)

compat/mingw.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,12 @@ int is_valid_win32_path(const char *path, int allow_literal_nul);
552552
*/
553553
int handle_long_path(wchar_t *path, int len, int max_path, int expand);
554554

555+
static inline int mingw_get_max_path_size(void)
556+
{
557+
return core_long_paths ? MAX_LONG_PATH : MAX_PATH;
558+
}
559+
#define get_max_path_size mingw_get_max_path_size
560+
555561
/**
556562
* Converts UTF-8 encoded string to UTF-16LE.
557563
*

git-compat-util.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,10 @@ char *gitdirname(char *);
372372
#define PATH_MAX 4096
373373
#endif
374374

375+
#ifndef get_max_path_size
376+
#define get_max_path_size() PATH_MAX
377+
#endif
378+
375379
typedef uintmax_t timestamp_t;
376380
#define PRItime PRIuMAX
377381
#define parse_timestamp strtoumax

setup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -875,7 +875,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
875875
char *gitfile;
876876
int offset;
877877

878-
if (PATH_MAX - 40 < strlen(gitdirenv))
878+
if (get_max_path_size() - 40 < strlen(gitdirenv))
879879
die(_("'$%s' too big"), GIT_DIR_ENVIRONMENT);
880880

881881
gitfile = (char*)read_gitfile(gitdirenv);

0 commit comments

Comments
 (0)