Fix ELOOP error when comparing folders with circular symlinks
Problem
Users encounter ELOOP: too many symbolic links encountered errors when comparing folders that contain circular symbolic links. The error occurs in the dir-compare library when it tries to stat a symlink that forms an infinite loop, causing the comparison to fail completely.
Example error:
Error: ELOOP: too many symbolic links encountered, stat '/home/user/project/folder/circular-link'
Root Cause
The issue stems from the dir-compare library (v4.2.0) which only handles broken symlinks (ENOENT errors) but doesn't catch ELOOP errors that occur when encountering circular symbolic links. The error happens in the getStatIgnoreBrokenLink function before any symlink filtering can take place.
Solution
This PR adds two improvements to handle this scenario:
1. New skipSymlinks Configuration Option
Added a new user-configurable setting compareFolders.skipSymlinks (default: false) that allows users to skip symbolic links during comparison. This option is passed to the dir-compare library and helps avoid various symlink-related issues during folder comparison.
Usage:
{
"compareFolders.skipSymlinks": true
}
2. Enhanced Error Handling
The comparison logic now specifically catches ELOOP errors and provides a helpful, actionable error message that includes the path to the problematic symlink:
Circular symbolic link detected. Please remove or fix the circular symlink before comparing. Path: /path/to/circular-link
This gives users clear guidance on what went wrong and where to find the issue.
Limitations
Due to the timing of when ELOOP errors occur in the dir-compare library (during the initial stat call), the skipSymlinks option cannot prevent these specific errors. However, it remains useful for filtering out symlinks in general and avoiding other symlink-related issues. Users encountering ELOOP errors will need to fix or remove the circular symlinks manually.
Changes
- Added
compareFolders.skipSymlinksconfiguration option topackage.json - Updated
IConfigurationsinterface insrc/services/configuration.ts - Enhanced error handling in
src/services/comparer.tsto catch and reportELOOPerrors with helpful messages - Updated README.md with documentation for the new option
Testing
- ✅ Code compiles without errors
- ✅ Type safety verified for error handling
- ✅ Configuration option properly integrated into the extension settings
Fixes #[issue_number]
[!WARNING]
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
update.code.visualstudio.com
- Triggering command:
/usr/local/bin/node ./out/test/runTest.js(dns block)If you need me to access, download, or install something from one of these locations, you can either:
- Configure Actions setup steps to set up my environment, which run before the firewall is enabled
- Add the appropriate URLs or hosts to the custom allowlist in this repository's Copilot coding agent settings (admins only)
Original prompt
This section details on the original issue you should resolve
<issue_title>[error] ELOOP: too many symbolic links encountered, stat '/home/liuyawu/workcode/deby_trixie_scarthgap/out1/tmp/work-shared/gcc-14.2.0-r0/gcc-14-14.2.0/src/libasan/libsanitizer'</issue_title> <issue_description>Original message: Oops, something went wrong while comparing
System Info Editor version: 1.104.0 Extension version: 0.25.3 OS: linux 5.4.0-174-generic
Stack Error: ELOOP: too many symbolic links encountered, stat '/home/liuyawu/workcode/deby_trixie_scarthgap/out1/tmp/work-shared/gcc-14.2.0-r0/gcc-14-14.2.0/src/libasan/libsanitizer' at Object.statSync (node:fs:1739:25) at getStatIgnoreBrokenLink (/home/gitadmin/.vscode-server/extensions/moshfeu.compare-folders-0.25.3/node_modules/dir-compare/build/src/Entry/EntryBuilder.js:69:32) at Object.buildEntry (/home/gitadmin/.vscode-server/extensions/moshfeu.compare-folders-0.25.3/node_modules/dir-compare/build/src/Entry/EntryBuilder.js:32:23) at Object.buildDirEntries (/home/gitadmin/.vscode-server/extensions/moshfeu.compare-folders-0.25.3/node_modules/dir-compare/build/src/Entry/EntryBuilder.js:21:32) at /home/gitadmin/.vscode-server/extensions/moshfeu.compare-folders-0.25.3/node_modules/dir-compare/build/src/compareAsync.js:33:58 at async Promise.all (index 1) </issue_description>
<agent_instructions>If you think that the issue is on the user side, let us inow</agent_instructions>
Comments on the Issue (you are @copilot in this section)
Fixes moshfeu/vscode-compare-folders#226
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.
@copilot Can you explain how to reproduce and test this on mac working locally (no ssh or something)?
@copilot Can you explain how to reproduce and test this on mac working locally (no ssh or something)?
To reproduce and test the ELOOP error on macOS locally:
1. Create test folders with circular symlinks:
# Create test structure
mkdir -p /tmp/test-eloop/folder1 /tmp/test-eloop/folder2
# Create a circular symlink in folder1
cd /tmp/test-eloop/folder1
ln -s link1 link2
ln -s link2 link1
echo "test file" > normalfile.txt
# Create some content in folder2
cd /tmp/test-eloop/folder2
echo "different content" > normalfile.txt
2. Test in VS Code:
- Open VS Code with the extension installed
- Run "Compare Folders" command
- Select
/tmp/test-eloop/folder1and/tmp/test-eloop/folder2 -
Before the fix: You'll see
ELOOP: too many symbolic links encounterederror -
After the fix: You'll see a clearer error:
Circular symbolic link detected. Please remove or fix the circular symlink before comparing. Path: /tmp/test-eloop/folder1/link1
3. Test the skipSymlinks option:
- Add to VS Code settings:
"compareFolders.skipSymlinks": true - This helps filter out symlinks in general, though circular symlinks causing ELOOP still need manual fixing
4. Verify the circular symlink:
# This will show the ELOOP error
ls -la /tmp/test-eloop/folder1/link1
# Or try to stat it
stat /tmp/test-eloop/folder1/link1
Cleanup:
rm -rf /tmp/test-eloop
The key is creating symlinks that point to each other (link1 → link2 → link1), which creates an infinite loop that triggers the ELOOP error when trying to follow the symlink chain.