Skip to content

fix: untrack a node_modules symlink carrying an absolute local path - #119

Merged
fas89 merged 1 commit into
mainfrom
fix/untrack-node-modules
Sep 14, 2026
Merged

fas89 merged 1 commit into
mainfrom
fix/untrack-node-modules

Conversation

@fas89

@fas89 fas89 commented Sep 14, 2026

Copy link
Copy Markdown
Collaborator

node_modules is tracked on main as a symlink (mode 120000) whose content is an absolute path on one contributor's machine:

$ git ls-tree main node_modules
120000 blob 4305c92…    node_modules
$ git cat-file -p main:node_modules
/Users/…/forge_docs/node_modules

A fresh clone gets a dangling link pointing at a directory that does not exist, and the local path is published in a public repository.

Why the existing ignore rule did not catch it

.gitignore already had node_modules/. The trailing slash matches a directory, and this is a symlink with that name — so the rule never applied and git add -A staged it. Both forms are now listed.

How it got here

The docs branches were built in parallel git worktree checkouts, and each worktree had node_modules symlinked back to the main checkout so the VuePress build could run without a second 297-package install. A git add -A in one of those worktrees staged the link.

The lesson isn't "be careful with add -A" — it's that the ignore rule was shaped for the wrong object type all along. Any contributor symlinking node_modules for any reason would have hit exactly this.

Not a history rewrite

The value is a local directory path, not a credential. Rewriting a public repository's history invalidates every clone, fork and commit SHA, which is not a trade worth making here.

`node_modules` was committed as a **symlink** (mode 120000) whose content is an
absolute path on one contributor's machine. A fresh clone therefore gets a
dangling link pointing at a directory that does not exist, and the path itself
is published.

`.gitignore` already had `node_modules/`. The trailing slash matches a
DIRECTORY, and this is a symlink with that name, so the ignore rule never
applied and `git add -A` picked it up. Both forms are now listed.

How it got here, since the mechanism matters more than the file: the docs branches
were built in parallel `git worktree` checkouts, and each worktree had
`node_modules` symlinked to the main checkout so the VuePress build would run
without a second install. `git add -A` in one of those worktrees then staged the
link. The lesson is not "be careful with add -A" but that the ignore rule was
shaped for the wrong object type all along — any contributor doing the same
thing would have hit it.

No history rewrite: the path is a local directory name, not a credential, and
rewriting a public repo's history invalidates every clone and fork.
@fas89
fas89 merged commit eeb401d into main Sep 14, 2026
4 checks passed

This branch was successfully deployed

1 active deployment
github-pages — 052a838b Deployed Sep 14, 2026 by fas89 via deploy #146
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.

1 participant