Skip to content

Last preparations before upstreaming Git for Windows' symlink support

Johannes Schindelin via GitGitGadget git 2 versions – In review

Get series with b4
b4 am [email protected]

Versions newest first · linked by author and title

  1. v2 Latest5 patches 2 repliesIn review
  2. v15 patches 7 repliesSuperseded

Changes in v2 from the cover letter

* Fixed Karsten's email address
* Instead of allowing unlimited symlink target lengths, it is now increased from 2*PATH_MAX to 32,767.

Patches in v2 No applies recorded yet

#Subject and filesSizeRepliesApplied
1/5mingw: do resolve symlinks in `getcwd()`compat/mingw.c+7 -110 replies
2/5init: do parse _all_ core.* settings earlyenvironment.c environment.h setup.c+5 -30 replies
3/5strbuf_readlink(): avoid calling `readlink()` twice in corner-casesstrbuf.c+3 -30 replies
4/5strbuf_readlink(): support link targets that exceed 2*PATH_MAXstrbuf.c+1 -10 replies
5/5trim_last_path_component(): avoid hard-coding the directory separatorlockfile.c+2 -20 replies

Reviews trailers per patch

None of the 5 patches has a Reviewed-by or Acked-by.

PatchKarsten Blees
1/5
2/5
3/5
4/5Based-on-a-patch-by
5/5

Trailers given in replies are filled; those carried in the patches from earlier versions are outlined with dashes.

Read the v2 thread

Cover letter [PATCH v2 0/5] Last preparations before upstreaming Git for Windows' symlink support

After preparing Git's test suite for the upcoming support for symlinks on Windows, this patch series touches up a couple of code paths that might not seem to be related at first, but need to be adjusted for the symlink support to work as expected.

This is based on js/test-symlink-windows.

Changes since v1:

* Fixed Karsten's email address
* Instead of allowing unlimited symlink target lengths, it is now increased from 2*PATH_MAX to 32,767.

Johannes Schindelin (3):
mingw: do resolve symlinks in getcwd()
init: do parse _all_ core.* settings early strbuf_readlink(): support link targets that exceed 2*PATH_MAX

Karsten Blees (2):
strbuf_readlink(): avoid calling readlink() twice in corner-cases trim_last_path_component(): avoid hard-coding the directory separator

 compat/mingw.c | 18 +++++++-----------
 environment.c  |  4 ++--
 environment.h  |  2 ++
 lockfile.c     |  4 ++--
 setup.c        |  2 +-
 strbuf.c       |  8 ++++----
 6 files changed, 18 insertions(+), 20 deletions(-)

base-commit: ef6dd000ad813fc34a05c4b9055578df13a2eaa6
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2017%2Fdscho%2Flast-preparations-before-mingw-symlinks-support-next-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2017/dscho/last-preparations-before-mingw-symlinks-support-next-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/2017

Range-diff vs v1:

 1:  1928738b464 = 1:  eb95a74d6eb mingw: do resolve symlinks in `getcwd()`
 2:  31497b01988 = 2:  9fee7bd16f5 init: do parse _all_ core.* settings early
 3:  dba281027a8 ! 3:  7fe463d68aa strbuf_readlink(): avoid calling `readlink()` twice in corner-cases

@@
## Metadata ##
-Author: Karsten Blees <[email protected]> +Author: Karsten Blees <[email protected]>

## Commit message ##
strbuf_readlink(): avoid calling readlink() twice in corner-cases
@@ Commit message

Use hint + 1 as buffer size to prevent this.

- Signed-off-by: Karsten Blees <[email protected]>
+ Signed-off-by: Karsten Blees <[email protected]>

## strbuf.c ##
4: db1feb2293d ! 4: accb6d5f0ae strbuf_readlink(): support link targets that exceed PATH_MAX
@@
## Metadata ##
-Author: Karsten Blees <[email protected]>
+Author: Johannes Schindelin <[email protected]>

## Commit message ##
- strbuf_readlink(): support link targets that exceed PATH_MAX
+ strbuf_readlink(): support link targets that exceed 2*PATH_MAX

The strbuf_readlink() function refuses to read link targets that
- exceed PATH_MAX (even if a sufficient size was specified by the caller).
+ exceed 2*PATH_MAX (even if a sufficient size was specified by the
+ caller).

- As some platforms (*cough* Windows *cough*) support longer paths, remove
- this restriction (similar to strbuf_getcwd()).
+ The reason that that limit is 2*PATH_MAX instead of PATH_MAX is that
+ the symlink targets do not need to be normalized. After running
+ ln -s a/../a/../a/../a/../b c, the target of the symlink c will not
+ be normalized to b but instead be much longer. As such, symlink
+ targets' lengths can far exceed PATH_MAX.

- Signed-off-by: Karsten Blees <[email protected]>
+ They are frequently much longer than 2*PATH_MAX on Windows, which
+ actually supports paths up to 32,767 characters, but sets PATH_MAX to
+ 260 for backwards compatibility. For full details, see
+ https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
+
+ Let's just hard-code the limit used by strbuf_readlink() to 32,767 and
+ make it independent of the current platform's PATH_MAX.
+
+ Based-on-a-patch-by: Karsten Blees <[email protected]>

## strbuf.c ##
@@ strbuf.c: ssize_t strbuf_write(struct strbuf *sb, FILE *f)
}

-#define STRBUF_MAXLINK (2*PATH_MAX)
--
++#define STRBUF_MAXLINK (32767)
+
int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint)
{
- size_t oldalloc = sb->alloc;
-@@ strbuf.c: int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint)
- if (hint < 32)
- hint = 32;
-
-- while (hint < STRBUF_MAXLINK) {
-+ for (;;) {
- ssize_t len;
-
- strbuf_grow(sb, hint + 1);
5: 3521180e0f7 ! 5: 9823cbb6df8 trim_last_path_component(): avoid hard-coding the directory separator
@@
## Metadata ##
-Author: Karsten Blees <[email protected]>
+Author: Karsten Blees <[email protected]>

## Commit message ##
trim_last_path_component(): avoid hard-coding the directory separator
@@ Commit message

Prepare that function to be useful also in that context.

- Signed-off-by: Karsten Blees <[email protected]>
+ Signed-off-by: Karsten Blees <[email protected]>

## lockfile.c ##

Signature · 1 line
gitgitgadget