Commit b433a22a by Edward Thomson

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.
parent 628dae8b
...@@ -1411,24 +1411,56 @@ static bool is_filesystem_case_insensitive(const char *gitdir_path) ...@@ -1411,24 +1411,56 @@ static bool is_filesystem_case_insensitive(const char *gitdir_path)
static bool are_symlinks_supported(const char *wd_path) static bool are_symlinks_supported(const char *wd_path)
{ {
git_config *config = NULL;
git_buf path = GIT_BUF_INIT; git_buf path = GIT_BUF_INIT;
int fd; int fd;
struct stat st; 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 || if ((fd = git_futils_mktmp(&path, wd_path, 0666)) < 0 ||
p_close(fd) < 0 || p_close(fd) < 0 ||
p_unlink(path.ptr) < 0 || p_unlink(path.ptr) < 0 ||
p_symlink("testing", path.ptr) < 0 || p_symlink("testing", path.ptr) < 0 ||
p_lstat(path.ptr, &st) < 0) p_lstat(path.ptr, &st) < 0)
symlinks_supported = false; goto done;
else
symlinks_supported = (S_ISLNK(st.st_mode) != 0); symlinks = (S_ISLNK(st.st_mode) != 0);
(void)p_unlink(path.ptr); (void)p_unlink(path.ptr);
git_buf_dispose(&path);
return symlinks_supported; done:
git_buf_dispose(&path);
git_config_free(config);
return symlinks;
} }
static int create_empty_file(const char *path, mode_t mode) static int create_empty_file(const char *path, mode_t mode)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment