undot
Declutter a project's root directory by taming configuration file sprawl.
before after
────── ─────
.claude/ .config/
.cursor/ .github/
.editorconfig src/
.github/
.npmrc
.yarn/
src/
Every tool wants a dotfile at the repository root. undot moves them into a single
tracked .config/ directory. Gitignored symlinks point back to the root, so every tool
keeps working. A pre-commit hook (or
prek) recreates the symlinks on every clone and checkout.
Teammates install nothing and notice nothing.
Install
uv tool install undot # or: pip install undot
Small static binaries (~200KB, instant startup) for Linux and macOS, also on GitHub releases. The pre-commit hook (below) needs no install at all.
Migrate an existing repository
undot migrate # or name entries: undot migrate .claude .cursor
git add -A && git commit
pre-commit install
One idempotent command:
- moves the configs
- creates the symlinks
- updates
.gitignore(existing rules that reached inside a moved directory get matching.config/patterns) - registers the git hook below
Clones and new repos set themselves up
migrate writes this hook config. After clone, checkout, merge, or rebase, it
restores any missing symlink:
default_install_hook_types: [pre-commit, post-checkout, post-merge, post-rewrite]
repos:
- repo: https://github.com/jmelahman/undot
rev: v0.3.0
hooks:
- id: undot
CI configs migrate too
CI checkouts don't run hooks. Most tools accept an explicit config path, so a file like
.goreleaser.yaml can live in .config/ with no symlink at all:
undot migrate .goreleaser.yaml
echo 'nolink .goreleaser.yaml' >> .config/undot.conf
- run: goreleaser release --clean --config .config/.goreleaser.yaml
Guardrails
.git*files are never migrated..githuband.pre-commit-config.yamlrequire--force, because a fresh clone must be able to bootstrap the hook.- Caches, secrets, and CI-read configs (
.venv,.env,.golangci.yml, ...) are skipped unless you name them. - Conflicts are reported, never overwritten. Migrating a tracked file prints the
git rm --cachedcommand you'll want afterwards.
Tune the scan in .config/undot.conf or ~/.config/undot/undot.conf, one
name or glob per line:
# never migrate these here
.idea*
# do migrate .env, despite the default skip
!.env
# keep in .config/ without a root symlink
nolink .goreleaser.yaml
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file undot-0.3.0.tar.gz.
File metadata
- Download URL: undot-0.3.0.tar.gz
- Upload date:
- Size: 48.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
da90864282ef713cec47289a6f014fb15fe2c09d92eadf73fbb25c185add369a
|
|
| MD5 |
0106d71e9f428181171c4f62aa42ed70
|
|
| BLAKE2b-256 |
661678ecb742de7399cc33540f81c4b2416751cf51d2af1768e78f54962664e7
|
File details
Details for the file undot-0.3.0-py3-none-manylinux_2_17_x86_64.whl.
File metadata
- Download URL: undot-0.3.0-py3-none-manylinux_2_17_x86_64.whl
- Upload date:
- Size: 127.1 kB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4972f247461666a48f52cd61c546bc73a1031f24eaa5dca83ab43a235bbe0061
|
|
| MD5 |
e334ad7111c31e61f7ba0f6323612df6
|
|
| BLAKE2b-256 |
21ebb9406545cee70045be12925b9bb26944bb95b084b015d16137f7fcfc59ea
|
File details
Details for the file undot-0.3.0-py3-none-manylinux_2_17_aarch64.whl.
File metadata
- Download URL: undot-0.3.0-py3-none-manylinux_2_17_aarch64.whl
- Upload date:
- Size: 132.2 kB
- Tags: Python 3, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
90a7f1c6b59ab11166b1ae0cdfac1be70bac9973bb817e186bea779b15eeaf7b
|
|
| MD5 |
f4b700c7a972d2a527e46917ca27cae2
|
|
| BLAKE2b-256 |
24f25d1c6d841c992df0ecc60e8bdccad249a4b850c389fa050631eb844eea8c
|
File details
Details for the file undot-0.3.0-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: undot-0.3.0-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 57.9 kB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
019d4bac57c1b5a07c7aec7b0a6cbd76fed6329f0f98843fc33b3ca03eb48151
|
|
| MD5 |
7d9222bc03058c2ad9bdda0f16835a4a
|
|
| BLAKE2b-256 |
39dd02580262a38051b987bf2ad691451be75f0f74402ad5dae1f4398844e432
|
File details
Details for the file undot-0.3.0-py3-none-macosx_10_12_x86_64.whl.
File metadata
- Download URL: undot-0.3.0-py3-none-macosx_10_12_x86_64.whl
- Upload date:
- Size: 57.8 kB
- Tags: Python 3, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a960fd58bf305568263780f8a3f51a2338b8bf1e3c00823dbfe8d3d5daddc8da
|
|
| MD5 |
000d95bd725526b26f8e41cf56c9291a
|
|
| BLAKE2b-256 |
b431024f1cf80c2b8d3ab25fbea7627352be27a9c15810722fdec52ef5180548
|