vscode: Git Discard All Changes fails with "ENAMETOOLONG"
- VSCode Version: 1.30.1
- OS Version: Windows 10 Pro 1809
Steps to Reproduce:
- Modify two thousand files in your working directory
- Open the Source Control tab
- Hover over the Changes sidebar group and click the Discard All Changes button.
- VSCode throws a ENAMETOOLONG error.
Reported earlier at https://github.com/Microsoft/vscode/issues/23943, but the issue was closed.
Does this issue occur when all extensions are disabled?: Yes
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 2
- Comments: 15 (8 by maintainers)
I have reproed this locally. In my test repo, I can see that discarding 2001 modified files creates a command line which is 78949 characters long, but the windows limit is 32767, assuming node is calling CreateProcess under the covers, and based on the info provided here: https://blogs.msdn.microsoft.com/oldnewthing/20031210-00/?p=41553/.
The problem is, the UI for discard all changes, in commands.ts:cleanAll, is translating the cleanAll into a repository.ts:clean with a list of all of the modified files. The repository itself doesn’t know that this list of resources is all of the changes in the repository.
Furthermore, this issue doesn’t affect only discard all changes. I was able to select the top change, and scroll down then shift click to select a subset of all of the changes, then right click, and select discard to see the same ENAMETOOLONG error message.
Simply replacing
git checkout -q -- <files>
withgit checkout -q -- .
won’t fix the real issue, which is that the git operations aren’t sanity checking their length prior to attempting to spawn the git command.Looking in the code at repository.ts:clean, I suspect a similar issue may occur with git.ts:clean, and it may occur with other repository types, other that git, if they do anything similar in terms of concatenating the list of resources.
Two possible options for a fix:
Fixing in respository.ts means that any SCS underneath will benefit from being called with a list of files of a reasonable length.
The maximum allowable length will vary from system to system, with Windows having a much smaller maximum allowable size than others.
xargs --show-limits
will show the maximum allowable command line argument length for a unix, and most unix-like systems, based on the hardware and environment variables. Maybe the code which decides how to break down the argument could/should be configurable based on the system? As a first attempt, the code could take 4096 as an upper limit, which is the minimum allowable max length of a unix system, as reported by xargs, and is the smallest common denominator?@kumarharsh https://github.com/microsoft/vscode/pull/66095
@joaomoreno is this fixed in a commit? or did you close it by mistake? or is there some other plan to tackle this?
But it won’t fix the problem. As I mentioned, if I select a long subset of changes, not all, it still goes through the same code path and gives the same error. If
git checkout -q -- .
gets called there, it will incorrectly revert all files, not just the ones selected.Still, if this would solve the problem, I’d take it. I forgot why we had to list all files explicitly, but I’m assuming we’ll remember as soon as we give it a try. We have to experiment with it.