Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9693157
t9700: accommodate for Windows paths
dscho Dec 16, 2025
33ccd0f
apply: symbolic links lack a "trustable executable bit"
dscho Dec 16, 2025
78d52c8
mingw: special-case `open(symlink, O_CREAT | O_EXCL)`
dscho Dec 16, 2025
c8fb79c
t0001: handle `diff --no-index` gracefully
dscho Dec 16, 2025
d2de5d9
t0301: another fix for Windows compatibility
dscho Dec 16, 2025
14b033f
t0600: fix incomplete prerequisite for a test case
dscho Dec 5, 2025
c670ae3
t1006: accommodate for symlink support in MSYS2
dscho Dec 16, 2025
d265cde
t1305: skip symlink tests that do not apply to Windows
dscho Dec 16, 2025
02ea262
t6423: introduce Windows-specific handling for symlinking to /dev/null
dscho Dec 16, 2025
a4c7170
t7800: work around the MSYS path conversion on Windows
dscho Dec 16, 2025
359de97
Merge branch 'js/test-symlink-windows' into js/prep-symlink-windows
gitster Dec 16, 2025
df27101
mingw: do resolve symlinks in `getcwd()`
dscho Dec 16, 2025
722e65d
init: do parse _all_ core.* settings early
dscho Dec 16, 2025
f6b8e4a
strbuf_readlink(): avoid calling `readlink()` twice in corner-cases
kblees Dec 16, 2025
9ce11d9
strbuf_readlink(): support link targets that exceed PATH_MAX
kblees Dec 16, 2025
6f6fe02
trim_last_path_component(): avoid hard-coding the directory separator
kblees Dec 16, 2025
dae450d
mingw: don't call `GetFileAttributes()` twice in `mingw_lstat()`
kblees May 12, 2015
c36848e
mingw: implement `stat()` with symlink support
kblees May 15, 2015
aa0ca80
mingw: drop the separate `do_lstat()` function
kblees May 11, 2015
8860443
mingw: let `mingw_lstat()` error early upon problems with reparse points
kblees May 23, 2015
db1d156
mingw: teach dirent about symlinks
kblees Jan 10, 2017
4c49a3d
mingw: compute the correct size for symlinks in `mingw_lstat()`
billziss-gh May 28, 2020
ad74d54
mingw: factor out the retry logic
kblees May 19, 2015
25313ce
mingw: change default of `core.symlinks` to false
kblees May 23, 2015
b698f4a
mingw: add symlink-specific error codes
kblees May 15, 2015
282aba4
mingw: handle symlinks to directories in `mingw_unlink()`
kblees May 23, 2015
5cb3b10
mingw: support renaming symlinks
kblees May 19, 2015
4992083
mingw: allow `mingw_chdir()` to change to symlink-resolved directories
kblees May 23, 2015
8fef822
mingw: implement `readlink()`
kblees May 23, 2015
1dd5f9d
mingw: implement basic `symlink()` functionality (file symlinks only)
kblees May 23, 2015
7b6dbc7
mingw: add support for symlinks to directories
kblees May 23, 2015
d3b89c2
mingw: try to create symlinks without elevated permissions
dscho May 30, 2017
2e73ab4
mingw: emulate `stat()` a little more faithfully
dscho Mar 2, 2020
817f488
mingw: special-case index entries for symlinks with buggy size
dscho Jun 4, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apply.c
Original file line number Diff line number Diff line change
Expand Up @@ -3818,7 +3818,7 @@ static int check_preimage(struct apply_state *state,
if (*ce && !(*ce)->ce_mode)
BUG("ce_mode == 0 for path '%s'", old_name);

if (trust_executable_bit)
if (trust_executable_bit || !S_ISREG(st->st_mode))
st_mode = ce_mode_from_stat(*ce, st->st_mode);
else if (*ce)
st_mode = (*ce)->ce_mode;
Expand Down
6 changes: 2 additions & 4 deletions compat/mingw-posix.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,6 @@ struct utsname {
* trivial stubs
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the Git mailing list, Johannes Sixt wrote (reply to this):

Am 17.12.25 um 15:08 schrieb Karsten Blees via GitGitGadget:
> From: Karsten Blees <blees@dcon.de>
> 
> Implement `readlink()` by reading NTFS reparse points via the
> `read_reparse_point()` function that was introduced earlier to determine
> the length of symlink targets. Works for symlinks and directory
> junctions. If symlinks are disabled, fail with `ENOSYS`.

This last sentence is obsolete, I think, because I cannot see how the
patch achieves a failure with ENOSYS.

> 
> Signed-off-by: Karsten Blees <blees@dcon.de>
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
>  compat/mingw-posix.h |  3 +--
>  compat/mingw.c       | 24 ++++++++++++++++++++++++
>  2 files changed, 25 insertions(+), 2 deletions(-)
> 
> diff --git a/compat/mingw-posix.h b/compat/mingw-posix.h
> index 0939feff27..896aa976b1 100644
> --- a/compat/mingw-posix.h
> +++ b/compat/mingw-posix.h
> @@ -121,8 +121,6 @@ struct utsname {
>   * trivial stubs
>   */
>  
> -static inline int readlink(const char *path UNUSED, char *buf UNUSED, size_t bufsiz UNUSED)
> -{ errno = ENOSYS; return -1; }
>  static inline int symlink(const char *oldpath UNUSED, const char *newpath UNUSED)
>  { errno = ENOSYS; return -1; }
>  static inline int fchmod(int fildes UNUSED, mode_t mode UNUSED)
> @@ -197,6 +195,7 @@ int setitimer(int type, struct itimerval *in, struct itimerval *out);
>  int sigaction(int sig, struct sigaction *in, struct sigaction *out);
>  int link(const char *oldpath, const char *newpath);
>  int uname(struct utsname *buf);
> +int readlink(const char *path, char *buf, size_t bufsiz);
>  
>  /*
>   * replacements of existing functions
> diff --git a/compat/mingw.c b/compat/mingw.c
> index 5d2a8c247c..b407a2ac07 100644
> --- a/compat/mingw.c
> +++ b/compat/mingw.c
> @@ -2698,6 +2698,30 @@ int link(const char *oldpath, const char *newpath)
>  	return 0;
>  }
>  
> +int readlink(const char *path, char *buf, size_t bufsiz)
> +{
> +	WCHAR wpath[MAX_PATH];
> +	char tmpbuf[MAX_PATH];
> +	int len;
> +	DWORD tag;
> +
> +	if (xutftowcs_path(wpath, path) < 0)
> +		return -1;
> +
> +	if (read_reparse_point(wpath, TRUE, tmpbuf, &len, &tag) < 0)
> +		return -1;
> +
> +	/*
> +	 * Adapt to strange readlink() API: Copy up to bufsiz *bytes*, potentially
> +	 * cutting off a UTF-8 sequence. Insufficient bufsize is *not* a failure
> +	 * condition. There is no conversion function that produces invalid UTF-8,
> +	 * so convert to a (hopefully large enough) temporary buffer, then memcpy
> +	 * the requested number of bytes (including '\0' for robustness).
> +	 */
> +	memcpy(buf, tmpbuf, min(bufsiz, len + 1));
> +	return min(bufsiz, len);
> +}
> +
>  pid_t waitpid(pid_t pid, int *status, int options)
>  {
>  	HANDLE h = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION,

-- Hannes

*/

static inline int readlink(const char *path UNUSED, char *buf UNUSED, size_t bufsiz UNUSED)
{ errno = ENOSYS; return -1; }
static inline int symlink(const char *oldpath UNUSED, const char *newpath UNUSED)
{ errno = ENOSYS; return -1; }
static inline int fchmod(int fildes UNUSED, mode_t mode UNUSED)
{ errno = ENOSYS; return -1; }
#ifndef __MINGW64_VERSION_MAJOR
Expand Down Expand Up @@ -197,6 +193,8 @@ int setitimer(int type, struct itimerval *in, struct itimerval *out);
int sigaction(int sig, struct sigaction *in, struct sigaction *out);
int link(const char *oldpath, const char *newpath);
int uname(struct utsname *buf);
int symlink(const char *target, const char *link);
int readlink(const char *path, char *buf, size_t bufsiz);

/*
* replacements of existing functions
Expand Down
Loading
Loading