mirror of
https://github.com/yarlson/lnk.git
synced 2025-09-01 18:02:34 +02:00
refactoring
Lnk
Git-native dotfiles management that doesn't suck.
Move your dotfiles to ~/.config/lnk
, symlink them back, and use Git like normal. Supports both common configurations and host-specific setups.
lnk init
lnk add ~/.vimrc ~/.bashrc # Common config
lnk add --host work ~/.ssh/config # Host-specific config
lnk push "setup"
Install
# Quick install (recommended)
curl -sSL https://raw.githubusercontent.com/yarlson/lnk/main/install.sh | bash
# Homebrew (macOS/Linux)
brew tap yarlson/lnk
brew install lnk
# Manual download
wget https://github.com/yarlson/lnk/releases/latest/download/lnk-$(uname -s | tr '[:upper:]' '[:lower:]')-amd64
chmod +x lnk-* && sudo mv lnk-* /usr/local/bin/lnk
# From source
git clone https://github.com/yarlson/lnk.git && cd lnk && go build . && sudo mv lnk /usr/local/bin/
Usage
Setup
# Fresh start
lnk init
# With existing repo
lnk init -r git@github.com:user/dotfiles.git
Daily workflow
# Add files/directories (common config)
lnk add ~/.vimrc ~/.config/nvim ~/.gitconfig
# Add host-specific files
lnk add --host laptop ~/.ssh/config
lnk add --host work ~/.gitconfig
# List managed files
lnk list # Common config only
lnk list --host laptop # Laptop-specific config
lnk list --all # All configurations
# Check status
lnk status
# Sync changes
lnk push "updated vim config"
lnk pull # Pull common config
lnk pull --host laptop # Pull laptop-specific config
How it works
Common files:
Before: ~/.vimrc (file)
After: ~/.vimrc -> ~/.config/lnk/.vimrc (symlink)
Host-specific files:
Before: ~/.ssh/config (file)
After: ~/.ssh/config -> ~/.config/lnk/laptop.lnk/.ssh/config (symlink)
Your files live in ~/.config/lnk
(a Git repo). Common files go in the root, host-specific files go in <host>.lnk/
subdirectories. Lnk creates symlinks back to original locations. Edit files normally, use Git normally.
Multihost Support
Lnk supports both common configurations (shared across all machines) and host-specific configurations (unique per machine).
File Organization
~/.config/lnk/
├── .lnk # Tracks common files
├── .lnk.laptop # Tracks laptop-specific files
├── .lnk.work # Tracks work-specific files
├── .vimrc # Common file
├── .gitconfig # Common file
├── laptop.lnk/ # Laptop-specific storage
│ ├── .ssh/
│ │ └── config
│ └── .tmux.conf
└── work.lnk/ # Work-specific storage
├── .ssh/
│ └── config
└── .gitconfig
Usage Patterns
# Common config (shared everywhere)
lnk add ~/.vimrc ~/.bashrc ~/.gitconfig
# Host-specific config (unique per machine)
lnk add --host $(hostname) ~/.ssh/config
lnk add --host work ~/.gitconfig
# List configurations
lnk list # Common only
lnk list --host work # Work host only
lnk list --all # Everything
# Pull configurations
lnk pull # Common config
lnk pull --host work # Work-specific config
Why not just Git?
You could git init ~/.config/lnk
and manually symlink everything. Lnk just automates the tedious parts:
- Moving files safely
- Creating relative symlinks
- Handling conflicts
- Tracking what's managed
Examples
First time setup
lnk init -r git@github.com:you/dotfiles.git
# Add common config (shared across all machines)
lnk add ~/.bashrc ~/.vimrc ~/.gitconfig
# Add host-specific config
lnk add --host $(hostname) ~/.ssh/config ~/.tmux.conf
lnk push "initial setup"
On a new machine
lnk init -r git@github.com:you/dotfiles.git
# Pull common config
lnk pull
# Pull host-specific config (if it exists)
lnk pull --host $(hostname)
Daily edits
vim ~/.vimrc # edit normally
lnk list # see common config
lnk list --host $(hostname) # see host-specific config
lnk list --all # see everything
lnk status # check what changed
lnk push "new plugins" # commit & push
Multi-machine workflow
# On your laptop
lnk add --host laptop ~/.ssh/config
lnk add ~/.vimrc # Common config
lnk push "laptop ssh config"
# On your work machine
lnk pull # Get common config
lnk add --host work ~/.gitconfig
lnk push "work git config"
# Back on laptop
lnk pull # Get updates (work config won't affect laptop)
Commands
lnk init [-r remote]
- Create repolnk add [--host HOST] <files>
- Move files to repo, create symlinkslnk rm [--host HOST] <files>
- Move files back, remove symlinkslnk list [--host HOST] [--all]
- List files managed by lnklnk status
- Git status + sync infolnk push [msg]
- Stage all, commit, pushlnk pull [--host HOST]
- Pull + restore missing symlinks
Command Options
--host HOST
- Manage files for specific host (default: common configuration)--all
- Show all configurations (common + all hosts) when listing-r, --remote URL
- Clone from remote URL when initializing
Technical bits
- Single binary (~8MB, no deps)
- Relative symlinks (portable)
- XDG compliant (
~/.config/lnk
) - Multihost support (common + host-specific configs)
- Git-native (standard Git repo, no special formats)
Alternatives
Tool | Complexity | Why choose it |
---|---|---|
lnk | Minimal | Just works, no config, Git-native, multihost |
chezmoi | High | Templates, encryption, cross-platform |
yadm | Medium | Git power user, encryption |
dotbot | Low | YAML config, basic features |
stow | Low | Perl, symlink only |
Contributing
git clone https://github.com/yarlson/lnk.git
cd lnk
make deps # Install golangci-lint
make check # Runs fmt, vet, lint, test
What we use:
- Runtime deps: Only
cobra
(CLI framework) - Test deps:
testify
for assertions - Build pipeline: Standard Makefile with quality checks
Before submitting:
make check # Runs all quality checks + tests
Adding features:
- Put integration tests in
test/integration_test.go
- Use conventional commits:
feat:
,fix:
,docs:
License
Languages
Go
94.9%
Makefile
2.8%
Shell
2.3%