Skip to content

prune stale link_children symlinks with --remove-existing - #478

Merged
deadc0de6 merged 2 commits into
deadc0de6:masterfrom
vladkens:prune-stale-link-children
Aug 11, 2026
Merged

prune stale link_children symlinks with --remove-existing#478
deadc0de6 merged 2 commits into
deadc0de6:masterfrom
vladkens:prune-stale-link-children

Conversation

@vladkens

Copy link
Copy Markdown
Contributor

Summary

  • extend the existing opt-in --remove-existing behavior to link_children
  • remove only dangling direct-child symlinks whose source child no longer exists and whose resolved target is inside the dotfile source directory or Dotdrop workdir
  • preserve regular files, directories, live symlinks, unrelated dangling symlinks, nested entries, and source-declared broken symlinks
  • report removals normally and intended removals during --dry
  • document the behavior and cover absolute and relative targets

Example

Consider a link_children dotfile that installs Codex skills:

source: ~/Code/dotfiles/codex-skills
destination: ~/.codex/skills

After installation:

~/Code/dotfiles/codex-skills/
├── english/
└── planning/

~/.codex/skills/
├── .system/
├── english -> ~/Code/dotfiles/codex-skills/english
└── planning -> ~/Code/dotfiles/codex-skills/planning

If english is removed from the source repository, its destination link becomes dangling:

~/Code/dotfiles/codex-skills/
└── planning/

~/.codex/skills/
├── .system/
├── english -> ~/Code/dotfiles/codex-skills/english  # dangling
└── planning -> ~/Code/dotfiles/codex-skills/planning

Running dotdrop install --remove-existing removes only the stale english link:

~/.codex/skills/
├── .system/
└── planning -> ~/Code/dotfiles/codex-skills/planning

The .system directory is preserved because it is not a symlink managed by this dotfile. Live links and unrelated dangling links are preserved as well.

Rationale

#403 and #414 introduced --remove-existing for explicit install-time cleanup of nolink directories. Reusing that opt-in is consistent, but applying its broad recursive removal behavior to link_children would violate its semantics: destination directories may intentionally contain files, directories, and symlinks that Dotdrop does not manage.

Tests

  • full unit suite: 71 passed
  • scripts/check-syntax.sh
  • tests-ng/install-and-remove.sh
  • tests-ng/install-link-children.sh

@deadc0de6

Copy link
Copy Markdown
Owner

Thanks for this!
It would be really nice if you could add a dedicated tests-ng test script that would test that, can you?

@vladkens

Copy link
Copy Markdown
Contributor Author

Sure — I’ve added a dedicated tests-ng test. Please let me know if it matches the project’s style.

@deadc0de6

Copy link
Copy Markdown
Owner

It does, thanks a lot!
Will review and merge.
Do you need me to release a new version or are you using dotdrop from git directly (in which case I will wait a bit if other features/bug fixes come in before releasing a new version)?

@deadc0de6
deadc0de6 merged commit 376fb2a into deadc0de6:master Aug 11, 2026
10 checks passed
@vladkens

Copy link
Copy Markdown
Contributor Author

No release needed for me — I’m handling the cleanup locally with a Dotdrop action for now, so feel free to wait. Thanks for merging!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants