From: "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Johannes Schindelin <johannes.schindelin@gmx.de>,
Johannes Schindelin <johannes.schindelin@gmx.de>
Subject: [PATCH] mingw: align symlinks-related rmdir() behavior with Linux
Date: Thu, 29 Jul 2021 19:21:33 +0000 [thread overview]
Message-ID: <pull.1008.git.1627586493659.gitgitgadget@gmail.com> (raw)
From: Johannes Schindelin <johannes.schindelin@gmx.de>
When performing a rebase, rmdir() is called on the folder .git/logs. On
Unix rmdir() exits without deleting anything in case .git/logs is a
symbolic link but the equivalent functions on Windows (_rmdir, _wrmdir
and RemoveDirectoryW) do not behave the same and remove the folder if it
is symlinked even if it is not empty.
This creates issues when folders in .git/ are symlinks which is
especially the case when git-repo[1] is used.
This commit updates mingw_rmdir() so that its behavior is the same as
Linux rmdir() in case of symbolic links.
This fixes https://github.com/git-for-windows/git/issues/2967
[1]: git-repo is a python tool built on top of Git which helps manage
many Git repositories. It stores all the .git/ folders in a central
place by taking advantage of symbolic links.
More information: https://gerrit.googlesource.com/git-repo/
Signed-off-by: Thomas Bétous <tomspycell@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
mingw: support the git-repo tool better
This addresses an issue, originally reported at
https://github.com/git-for-windows/git/issues/2967, where the git-repo
tool [https://gerrit.googlesource.com/git-repo/] replaces folders in
.git/ with symlinks and mingw_rmdir() erroneously removes the symlink
target directory's contents.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1008%2Fdscho%2Ffix-rmdir-with-symlinks-on-windows-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1008/dscho/fix-rmdir-with-symlinks-on-windows-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/1008
compat/mingw.c | 15 +++++++++++++++
t/t3400-rebase.sh | 10 ++++++++++
t/test-lib.sh | 6 ++++++
3 files changed, 31 insertions(+)
diff --git a/compat/mingw.c b/compat/mingw.c
index aa647b367b0..685d3efa3c0 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -341,6 +341,21 @@ int mingw_rmdir(const char *pathname)
{
int ret, tries = 0;
wchar_t wpathname[MAX_PATH];
+ struct stat st;
+
+ /*
+ * Contrary to Linux rmdir(), Windows' _wrmdir() and _rmdir()
+ * will remove the directory at the path if it is a symbolic link
+ * which leads to issues when symlinks are used in the .git folder
+ * (in the context of git-repo for instance). So before calling _wrmdir()
+ * we first check if the path is a symbolic link. If it is, we exit
+ * and return the same error as Linux rmdir() in this case (ENOTDIR).
+ */
+ if (!mingw_lstat(pathname, &st) && S_ISLNK(st.st_mode)) {
+ errno = ENOTDIR;
+ return -1;
+ }
+
if (xutftowcs_path(wpathname, pathname) < 0)
return -1;
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index 0bb88aa982b..23dbd3c82ed 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -406,4 +406,14 @@ test_expect_success 'refuse to switch to branch checked out elsewhere' '
test_i18ngrep "already checked out" err
'
+test_expect_success MINGW,SYMLINKS_WINDOWS 'rebase when .git/logs is a symlink' '
+ git checkout main &&
+ mv .git/logs actual_logs &&
+ cmd //c "mklink /D .git\logs ..\actual_logs" &&
+ git rebase -f HEAD^ &&
+ test -L .git/logs &&
+ rm .git/logs &&
+ mv actual_logs .git/logs
+'
+
test_done
diff --git a/t/test-lib.sh b/t/test-lib.sh
index adaf03543e8..73f6d645b66 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -1513,6 +1513,12 @@ test_lazy_prereq SYMLINKS '
ln -s x y && test -h y
'
+test_lazy_prereq SYMLINKS_WINDOWS '
+ # test whether symbolic links are enabled on Windows
+ test_have_prereq MINGW &&
+ cmd //c "mklink y x" &> /dev/null && test -h y
+'
+
test_lazy_prereq FILEMODE '
test "$(git config --bool core.filemode)" = true
'
base-commit: ebf3c04b262aa27fbb97f8a0156c2347fecafafb
--
gitgitgadget
next reply other threads:[~2021-07-29 19:21 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-29 19:21 Johannes Schindelin via GitGitGadget [this message]
2021-07-29 19:23 ` [PATCH] mingw: align symlinks-related rmdir() behavior with Linux Johannes Schindelin
2021-07-29 20:03 ` Junio C Hamano
2021-08-02 20:17 ` Johannes Schindelin
2021-07-29 20:12 ` Eric Sunshine
2021-08-02 20:28 ` Johannes Schindelin
2021-08-02 21:07 ` [PATCH v2] " Johannes Schindelin via GitGitGadget
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=pull.1008.git.1627586493659.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=git@vger.kernel.org \
--cc=johannes.schindelin@gmx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.