Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VSCode prevents moving any git directory under the working directory on Windows #104251

Closed
Klaim opened this issue Aug 7, 2020 · 8 comments
Closed
Assignees
Labels
*duplicate Issue identified as a duplicate of another issue(s)

Comments

@Klaim
Copy link

Klaim commented Aug 7, 2020

Context

Version: 1.48.0-insider (user setup)
Commit: 2277c8e
Date: 2020-08-07T11:32:09.993Z
Electron: 7.3.2
Chrome: 78.0.3904.130
Node.js: 12.8.1
V8: 7.8.279.23-electron.0
OS: Windows_NT x64 10.0.17134

> git --version
git version 2.27.0.windows.1

NOTE: This issue have been there for a long time, in years, but I only figured the root now.

It prevents some usage patterns when using build2 because build2's package manager can retrieve packages from git repositories, in which case it will attempt to move them.

This issue seems related to #71221 which is currently wrongly closed as it also affects other situations like #71340 and probably other interracting tools.

I have been seeing this issue on 2 other Windows 10 computers, with different hardware and various VSCode, git and build2 versions

Steps to Reproduce

BEWARE: do NOT attempt to reproduce these steps through an executable script (either .sh or .bat), as the result might succeed. (yeah, I know, weird!). See below for an example.

  1. Open VSCode in an empty directory.
  2. Open a console in that directory. You can do it from inside VSCode or outside, it doesn't change a thing. The issue is visible with cmd, powershell and git-bash. If using git-bash, use mv instead of move in the following commnands.
  3. Run:
mkdir xxx
cd xxx
git init
cd ..
  1. Now run (manually, not from a script): move xxx yyy (or mv xxx yyy with git-bash)
    This is where the issue happens.
  2. Close the instance of VSCode open in that directory, then re-try step 4. (There can be other VScode instances open to different directories, it will not interract with this issue as long as it's a different directory)

Observed

Step 4 triggers an error:

cmd:

C:\Users\jlamotte\tmp\vscode_fails>move xxx yyy
Access is denied.
        0 dir(s) moved.

Powershell:

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\Users\jlamotte\tmp\vscode_fails> mkdir xxx


    Directory: C:\Users\jlamotte\tmp\vscode_fails


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2020-08-07     16:13                xxx


PS C:\Users\jlamotte\tmp\vscode_fails> cd xxx
PS C:\Users\jlamotte\tmp\vscode_fails\xxx> git init
Initialized empty Git repository in C:/Users/jlamotte/tmp/vscode_fails/xxx/.git/
PS C:\Users\jlamotte\tmp\vscode_fails\xxx> cd ..
PS C:\Users\jlamotte\tmp\vscode_fails> move xxx yyy
move : Access to the path 'C:\Users\jlamotte\tmp\vscode_fails\xxx' is denied.
At line:1 char:1
+ move xxx yyy
+ ~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (C:\Users\jlamotte\tmp\vscode_fails\xxx:DirectoryInfo) [Move-Item], IOException
    + FullyQualifiedErrorId : MoveDirectoryItemIOError,Microsoft.PowerShell.Commands.MoveItemCommand

git-bash:

$ mv xxx yyy
mv: cannot move 'xxx' to 'yyy': Permission denied

Step 5 (closing VSCode and retrying step 4) Will succeed.

cmd:

C:\Users\jlamotte\tmp\vscode_fails>move xxx yyy
        1 dir(s) moved.

powershell:

PS C:\Users\jlamotte\tmp\vscode_fails> move xxx yyy
PS C:\Users\jlamotte\tmp\vscode_fails> dir


    Directory: C:\Users\jlamotte\tmp\vscode_fails


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2020-08-07     16:37                yyy
-a----       2020-08-07     16:35             46 repro.sh

git-bash

$ mv xxx yyy

Expected

mv and move should never fail when VSCode is open in the directory.

Additional Information

Assuming VSCode is open in the directory, if I create a file repro.sh with :

mkdir xxx
cd xxx
git init
cd ..

mv xxx yyy

Then run it using git-bash:

$ ./repro.sh
Initialized empty Git repository in C:/Users/jlamotte/tmp/vscode_fails/xxx/.git/

$ ls
repro.sh  yyy

No problem. Same if I rename repro.sh to repro.bat and replace mv by move then I run it in cmd.
For some reason (race/speed? rights?) running these commands via a script works.

How to see that issue affecting build2

  1. Install build2 : https://build2.org/install.xhtml
  2. In the empty directory, run bdep new repro - this will create a complete hello-world executable project in the repro/ directory.
  3. Add a dependency to a package provided by a git repository, for example:
  • in repro/manifest uncomment this line: depends: libhello ^1.0.0 (remove the #)
  • in repro/repositories.manifest uncomment (remove the #) this block:
:
role: prerequisite
location: https://git.build2.org/hello/libhello.git
  1. Initialize the project:
cd repro
bdep init -C ../build-repro cc

This will first create a (build) configuration in the specified directory, then configure the current project(s) in that configuration. Part of the process is acquisition of the dependencies, so it will clone the repository whrere libhello will be found, and attempt to move the fetched git repository and will fail if VSCode can see the configuration directory.

$ bdep init -C ../build-repro cc
initializing in project C:\Users\jlamotte\tmp\vscode_fails\repro\
created configuration C:\Users\jlamotte\tmp\vscode_fails\build-repro\ 1 default,forwarded,auto-synchronized
fetching git:build2.org/hello/libhello (prerequisite of dir:C:\Users\jlamotte\tmp\vscode_fails\repro)
querying https://git.build2.org/hello/libhello.git
fetching from https://git.build2.org/hello/libhello.git
remote: Counting objects: 79, done.
remote: Compressing objects: 100% (68/68), done.
remote: Total 79 (delta 15), reused 0 (delta 0)
Unpacking objects: 100% (79/79), 11.44 KiB | 12.00 KiB/s, done.
error: unable to move directory C:\Users\jlamotte\tmp\vscode_fails\build-repro\.bpkg\tmp\60495f3d0bf2\ to C:\Users\jlamotte\tmp\vscode_fails\build-repro\.bpkg\repos\60495f3d0bf2\: access is denied

(use -V to see the specific commands invoked by build2)

Note that we attempted to retry the move several times in a row without success, even when retrying for 10 minutes.

Why is this important for build2 users

When working on C++ projects with build2, I like to use VSCode as it's "intellisense" will take into account all the files accessible in the working directory. When my project use dependencies, I like VSCode to be aware of the code from these dependencies.

With that issue, I cannot have the configuration directory open by VSCode, which means that VSCode is not aware of that directory's content which is mostly the code of the dependencies of my project and the generated code from them and my project.

If that issue was not there, I could use VSCode on all platforms the same way, no biggie. Currently on Windows I have to open only the source directory of my project and never their dependencies. VSCode therefore by default will mark errors of names it cannot find until I manually open source directories from the configuration.
The configuration content can change through working on the project, so this is very far from ideal.

Does this issue occur when all extensions are disabled?: Yes

@Klaim
Copy link
Author

Klaim commented Aug 31, 2020

Did anyone tried to reproduce this? It's becoming problematic for me...

@joaomoreno
Copy link
Member

@bpasero Could this be related to file watching?

@joaomoreno
Copy link
Member

@Klaim Is this maybe about moving things which contain folders which start with a dot .?

@bpasero
Copy link
Member

bpasero commented Sep 1, 2020

Hm, not sure, if that was the case people could not delete folders in VSCode since we install a recursive watcher.

@Klaim
Copy link
Author

Klaim commented Sep 1, 2020

@bpasero Could this be related to file watching?

I believe it is, though I think it's specific to git support because...

@Klaim Is this maybe about moving things which contain folders which start with a dot .?

...I did try with several kinds of directories and the only case was if it was a real git repository. If you create a .git/ repository even with dummy files in it, it will work as expected. It have to be a real git repo to fail.

Hm, not sure, if that was the case people could not delete folders in VSCode since we install a recursive watcher.

What's super weird is that it only impacts moving, not deleting or anything else.

@joaomoreno
Copy link
Member

What about the following error?

error: unable to move directory C:\Users\jlamotte\tmp\vscode_fails\build-repro\.bpkg\tmp\60495f3d0bf2\ to C:\Users\jlamotte\tmp\vscode_fails\build-repro\.bpkg\repos\60495f3d0bf2\: access is denied

@Klaim
Copy link
Author

Klaim commented Sep 1, 2020

What about the following error?

error: unable to move directory C:\Users\jlamotte\tmp\vscode_fails\build-repro\.bpkg\tmp\60495f3d0bf2\ to C:\Users\jlamotte\tmp\vscode_fails\build-repro\.bpkg\repos\60495f3d0bf2\: access is denied

That's what initially suggested me to try with .something directories, but after checking, it's actually working as long as there is no git repository involved.

The .bpkg directory contains several stuffs, including package information for build2. IFF the packages comes from a git repository, then build2 will make a clone of that repository to start working on it (and then move it around, which is where it fails, as explained in the issue description).

If the .bpkg direcrtory never contain any git clone (because we got packages from archive repositories like https://cppget.org, not from git repositories), then the move works as expected and there is no problem.

That's what made me realized that it was related to git: I tried to completely remove build2 from the equation, which lead me to check that it works with only a git repository freshly initialized (with not even a commit). Then I tried with various .something directories without any problem, and even .git directory with dummy files in it would still work. It have to be a real .git repository to fail.

And it will fail for any directory that contains a git repository, recursively, and that you try to move.
That's why I'm reporting here: it's super specific to VSCode + git.

BTW, my repro is super simple and quick to reproduce. Do you manage to reproduce the issue on your side? I have it on all my windows (3 different machines). I had it for years actually but didn't do enough research to figure out a very small repro at the time.

@joaomoreno
Copy link
Member

Got it, I was able to repro.

This is due to the watching mechanism in:

const rootWatcher = watch(repository.dotGit);

Unfortunately this is an issue with the Windows NTFS file system and is unlikely to change until we adopt a different file watching mechanism or our API supports arbitrary watching: #3025

Will have to close it as designed/duplicate for now. Sorry about that!

@github-actions github-actions bot locked and limited conversation to collaborators Oct 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
*duplicate Issue identified as a duplicate of another issue(s)
Projects
None yet
Development

No branches or pull requests

4 participants
@joaomoreno @Klaim @bpasero and others