简体   繁体   中英

Git on WSL: error: unable to unlink old <file> Permission denied

I use git in WSL. I'm always developing a project which uses a web server, which I have running in a process in my IDE in Windows. When I try to pull, switch branches, stash and similar, I often get this message:

error: unable to unlink old '<filename>': Permission denied

That file is always the file that contains the code that starts the web server.

I am able to edit the file in my IDE, and I am also able to edit the file from the terminal inside WSL (where I'm running my git commands) using nano or piping text from echo into the file. In WSL I have linux rights to the directory containing the file and the file itself. Stopping the process that runs the web server allows me to perform my git commands with no trouble, but it takes a long time to start the web server, which is why I want to find a way around this.

When this problem occurs, the git checkout command (or whatever) leaves my local checkout in an annoying state where some files have been changed but others have not, which is worse than not running the command at all.

Things to note:

  • This is not a linux permissions issue; I can edit the file from inside WSL just fine; only git commands have a problem.
  • I am running a web server process in Windows which is (presumably) locking the file, and I am trying to find a solution that does not involve stopping that process. I am able to edit the file inside both Windows and WSL without stopping the process; only git commands have a problem.

If I can edit the file from both WSL and Windows, why can't git unlink it? How can I either:

  1. Force git to unlink the file
  2. Abort git operations where a file cannot be unlinked

My Windows is fully up to date but I'm not on an Insider ring.

Update: here's the end of the output from running strace git co master :

wait4(4973, error: unable to unlink old 'signal/dev/dev.clj': Permission denied
error: unable to unlink old 'signal/src/clj/signal/lot.clj': Permission denied
error: unable to unlink old 'signal/src/clj/signal/web.clj': Permission denied
M       signal/dev/dev.clj
M       signal/src/clj/signal/lot.clj
M       signal/src/clj/signal/web.clj
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
[{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 4973
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=4973, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
exit_group(0)                           = ?
+++ exited with 0 +++

This is a limitation of Windows. Windows, by default, does not allow a process to remove a file which is in use, and when Git checks out files, it may unlink some of them. This is perfectly normal on Unix, which allows you to remove a file in use, but it causes problems on Windows. Concurrent modifications typically aren't a problem.

If you need to be able to remove files in use via Git, you'll need to use versions of Clojure and Java that run in WSL, where you can perform these operations successfully. Alternatively, you can try storing your program in your home directory on the WSL side and use a \\\\WSL$\\ path to access them in your Windows-based programs; this may or may not work.

Git doesn't provide an option to avoid this issue, because it assumes that systems provide sane POSIX behavior, and it has no way to force the operation, because the behavior stems from a deliberate design decision in the operating system.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM