File 0001-win32-emulate-Git-for-Windows-in-symlink-support.patch of Package libgit2.28345
From b433a22a979ae78c28c8b16f8c3487e2787cb73e Mon Sep 17 00:00:00 2001
From: Edward Thomson <ethomson@edwardthomson.com>
Date: Fri, 19 Oct 2018 03:14:53 -0700
Subject: [PATCH] win32: emulate Git for Windows in symlink support
Emulate the Git for Windows `core.symlinks` support. Since symbolic
links are generally enabled for Administrator (and _may_ be enabled due
to enabling Developer mode) but symbolic links are still sufficiently
uncommon on Windows that Git users are expected to explicitly opt-in to
symbolic links by enabling `core.symlinks=true` in a global (or xdg or
system) configuration.
When `core.symlinks=true` is set globally _and_ symbolic links support
is detected then new repositories created will not have a
`core.symlinks` set. If `core.symlinks` is _not_ set then no detection
will be performed, and `core.symlinks=false` will be set in the
repository configuration.
---
src/repository.c | 52 ++++++++++++++++++++++++++++++++++++++----------
1 file changed, 42 insertions(+), 10 deletions(-)
diff --git a/src/repository.c b/src/repository.c
index a2f88a28342..9af06793339 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -1411,24 +1411,56 @@ static bool is_filesystem_case_insensitive(const char *gitdir_path)
static bool are_symlinks_supported(const char *wd_path)
{
+ git_config *config = NULL;
git_buf path = GIT_BUF_INIT;
int fd;
struct stat st;
- int symlinks_supported = -1;
+ bool symlinks = false;
+
+ /*
+ * To emulate Git for Windows, symlinks on Windows must be explicitly
+ * opted-in. We examine the system configuration for a core.symlinks
+ * set to true. If found, we then examine the filesystem to see if
+ * symlinks are _actually_ supported by the current user. If that is
+ * _not_ set, then we do not test or enable symlink support.
+ */
+#ifdef GIT_WIN32
+ git_buf global_buf = GIT_BUF_INIT;
+ git_buf xdg_buf = GIT_BUF_INIT;
+ git_buf system_buf = GIT_BUF_INIT;
+ git_buf programdata_buf = GIT_BUF_INIT;
+
+ git_config_find_global(&global_buf);
+ git_config_find_xdg(&xdg_buf);
+ git_config_find_system(&system_buf);
+ git_config_find_programdata(&programdata_buf);
+
+ if (load_config(&config, NULL,
+ path_unless_empty(&global_buf),
+ path_unless_empty(&xdg_buf),
+ path_unless_empty(&system_buf),
+ path_unless_empty(&programdata_buf)) < 0)
+ goto done;
+
+ if (git_config_get_bool(&symlinks, config, "core.symlinks") < 0 || !symlinks)
+ goto done;
+#endif
if ((fd = git_futils_mktmp(&path, wd_path, 0666)) < 0 ||
- p_close(fd) < 0 ||
- p_unlink(path.ptr) < 0 ||
- p_symlink("testing", path.ptr) < 0 ||
- p_lstat(path.ptr, &st) < 0)
- symlinks_supported = false;
- else
- symlinks_supported = (S_ISLNK(st.st_mode) != 0);
+ p_close(fd) < 0 ||
+ p_unlink(path.ptr) < 0 ||
+ p_symlink("testing", path.ptr) < 0 ||
+ p_lstat(path.ptr, &st) < 0)
+ goto done;
+
+ symlinks = (S_ISLNK(st.st_mode) != 0);
(void)p_unlink(path.ptr);
#- git_buf_dispose(&path);
- git_buf_free(&path);
- return symlinks_supported;
+done:
+ git_buf_free(&path);
+ git_config_free(config);
+ return symlinks;
}
static int create_empty_file(const char *path, mode_t mode)