Steps to Reproduce:
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
It's because vscode runs this command on clicking "Discard all changes":
git checkout -q -- file/path/1 file/path/2 file/path/3 file/path/4 file/path/5 ...
It seems like it's actually a shortcoming of git itself.
Using git checkout -q -- . can be a viable alternative, would you agree?
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> with git 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?
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.
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.
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.
That's correct... Perhaps some sort of batching needs to be implemented to handle these type of cases?
The underlying issue is not specific to Discard All nor is it even specific to Discard in general. This affects any git command that has the potential of containing a long list of files -- if you select a large number of modified/added files and Stage/Unstage them, for example.
The problem is as @rcbevans stated: the command ends up being too long because it's just a concatenated list of files.
It looks like some commands (like git reset) support the --stdin flag which gets around the shell limits (see https://github.com/desktop/desktop/pull/2877), but it's not official and not every command allows it. Probably the best solution at the time is to check the length and break the command into multiple calls if it's too big. The SmartGit client does this, and it works well.
I get the same issue. Is there any temporary solution to resolve that?
@joaomoreno is this fixed in a commit? or did you close it by mistake? or is there some other plan to tackle this?
@kumarharsh https://github.com/microsoft/vscode/pull/66095
Is this released in the latest version of VSCode. I don't know by looking at #66095
@rsaritzky As far as I can tell, it is. The PR was merged and some changes were made to clean it up and reorganize some things. The changes seem to be there in the 1.38.1 tag. Of course, the best way to verify is to try a command that used to fail and see if it works in the latest version.
Hi,
I am a relatively new VSCode user, but as far as I can tell I am on the latest version of VSCode – An update ran this morning. The “Git Discard all changes” command still fails with ENAMETOOLONG if there are more than about 400 files:
[cid:[email protected]]
From: Herohtar notifications@github.com
Sent: Thursday, September 12, 2019 12:29 PM
To: microsoft/vscode vscode@noreply.github.com
Cc: Ron Saritzky rons@cryobank.com; Mention mention@noreply.github.com
Subject: Re: [microsoft/vscode] Git Discard All Changes fails with "ENAMETOOLONG" (#65693)
@rsaritzkyhttps://github.com/rsaritzky As far as I can tell, it is. The PR was merged and some changes were made to clean it up and reorganize some things. Of course, the best test is to try a command that used to fail and see if it works in the latest version.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHubhttps://github.com/microsoft/vscode/issues/65693?email_source=notifications&email_token=AMBA5Y26XF4POTZ4BKQD2E3QJKJ7LA5CNFSM4GMHGOYKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD6S7OHI#issuecomment-530970397, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AMBA5Y3CQTQOZCQLYBIF2ILQJKJ7LANCNFSM4GMHGOYA.
@rsaritzky Go to Help -> About in VS Code and check which version you are running. I just tested on my installation which is running 1.38.0 and was able to do a Discard All with 1,130 modified files.
I sent you a screenshot of my Help/About – it is 1.38.1. The error occurs under certain circumstances. I will try to replicate it and give you exact conditions. We use a source code management addon for our Microsoft Dynamics NAV development and it generates the files, so I have to determine the exact circumstance. I will send the output of the command as well.
Thank you for the reply.
Ron Saritzky
From: Herohtar notifications@github.com
Sent: Thursday, September 12, 2019 3:02 PM
To: microsoft/vscode vscode@noreply.github.com
Cc: Ron Saritzky rons@cryobank.com; Mention mention@noreply.github.com
Subject: Re: [microsoft/vscode] Git Discard All Changes fails with "ENAMETOOLONG" (#65693)
@rsaritzkyhttps://github.com/rsaritzky Go to Help -> About in VS Code and check which version you are running. I just tested on my installation which is running 1.38.0 and was able to do a Discard All with 1,130 modified files.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHubhttps://github.com/microsoft/vscode/issues/65693?email_source=notifications&email_token=AMBA5Y5P2RQHCF7BV2FFFBTQJK333A5CNFSM4GMHGOYKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD6TMMWI#issuecomment-531023449, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AMBA5YYY6K2UW4FZFQ2EWTTQJK333ANCNFSM4GMHGOYA.
Most helpful comment
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-limitswill 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?