Skip to content

Fix symlink loop detection to allow shared symlink targets#299

Open
psss wants to merge 2 commits into
mainfrom
psss-symlink-loops
Open

Fix symlink loop detection to allow shared symlink targets#299
psss wants to merge 2 commits into
mainfrom
psss-symlink-loops

Conversation

@psss
Copy link
Copy Markdown
Member

@psss psss commented May 13, 2026

The previous implementation used a single shared list of visited symlink targets across the entire tree. This caused sibling symlinks pointing to the same directory to be incorrectly skipped as loops, because the second symlink found its target already recorded by the first one.

Replace the shared list with a per-branch set of ancestor real paths. Each child node gets its own copy of the set, so sibling branches cannot interfere with each other. A symlink is now only skipped when its target resolves to an ancestor directory of the current walk path, which is the actual condition for a cycle.

Add tests for both the shared symlink target scenario and for the symlink loop detection to prevent future regressions.

Assisted-by: Claude Opus 4.6

Checklist

  • implement the feature
  • extend the test coverage
  • include a release note

The previous implementation used a single shared list of visited
symlink targets across the entire tree. This caused sibling symlinks
pointing to the same directory to be incorrectly skipped as loops,
because the second symlink found its target already recorded by the
first one.

Replace the shared list with a per-branch set of ancestor real
paths. Each child node gets its own copy of the set, so sibling
branches cannot interfere with each other. A symlink is now only
skipped when its target resolves to an ancestor directory of the
current walk path, which is the actual condition for a cycle.

Add tests for both the shared symlink target scenario and for the
symlink loop detection to prevent future regressions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@psss psss added this to planning May 13, 2026
@github-project-automation github-project-automation Bot moved this to backlog in planning May 13, 2026
@psss
Copy link
Copy Markdown
Member Author

psss commented May 13, 2026

@petr-janda, this should fix the problem with directory symlinks.

@psss psss added the base label May 13, 2026
Comment thread tests/unit/test_base.py
Comment on lines +586 to +587
common = os.path.join(directory, 'common')
os.mkdir(common)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please let's use pathlib

Comment thread tests/unit/test_base.py
def test_symlink_shared_target(self):
"""
Multiple symlinks pointing to the same directory should all be followed
"""
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you embed the output of tree in here. If I follow this correctly it is:

$ tree -al .
.
├── common
│   └── main.fmf
├── .fmf
│   └── version
├── one
│   ├── main.fmf
│   └── plan -> ../common  [recursive, not followed]
└── two
    ├── main.fmf
    └── plan -> ../common  [recursive, not followed]

Comment thread fmf/base.py
@petr-janda
Copy link
Copy Markdown

@petr-janda, this should fix the problem with directory symlinks.

Yes it does. With this patch I can symlink a directory with plans to multiple directories. Together with inheritance it eases my life. Thank you.

@psss
Copy link
Copy Markdown
Member Author

psss commented May 15, 2026

Great, thanks for verifying!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: backlog

Development

Successfully merging this pull request may close these issues.

3 participants