6 ms·
Show HN: Lnk – Git-native dotfiles manager
Move dotfiles to ~/.config/lnk, get symlinks back, use Git normally. Single binary, no config files, no fluff. Built because chezmoi was too complex and plain Git was too manual.
- peterhadlaw 1y agoHow is this different from GNU stow?
- yar-kravtsov 1y agoGreat question! GNU Stow and lnk solve similar problems but with different approaches: GNU Stow: - Package-based structure: Requires organizing dotfiles into "packages" (subdirectories) - Symlink-only: Just handles symlinking, no version control integration - Manual Git: You manage Git separately (git clone → stow package-name) - Perl dependency: Requires Perl to be installed - No safety net: No atomic operations or rollback if something goes wrong lnk: - File-based workflow: Takes your existing dotfiles as-is, moves them to managed location - Git-integrated: Wraps Git commands (lnk push, lnk pull) for seamless workflow - Atomic operations: If something fails, automatically rolls back changes - Single binary: No dependencies, just download and run - New machine workflow: lnk init -r repo && lnk pull handles clone + restore in one step Key Difference in Workflow: Stow approach: # Organize files into packages first mkdir -p ~/.dotfiles/vim/.config/nvim mv ~/.config/nvim/init.lua ~/.dotfiles/vim/.config/nvim/ git add . && git commit # On new machine: git clone repo ~/.dotfiles stow vim # Creates symlinks lnk approach: # Start with files where they are lnk add ~/.config/nvim/init.lua # Moves and links automatically lnk push "added nvim config" # On new machine: lnk init -r repo && lnk pull # Clone + restore in one command Bottom line: Stow is a pure symlinking tool that you combine with Git manually. lnk is an opinionated workflow that handles the entire dotfiles lifecycle (move → version → sync → restore).
- delusional 1y ago[flagged]
- justusthane 1y agoThe comment or the code? The comment does not read like AI to me, but who knows.
- keybored 1y ago[flagged]
- wanderingmind 1y agoThere are so many secrets spread across dot files. Is it possible to encrypt and store them in remote and de-encrypt when it’s pulled to local machines?
- OptionX 1y agoI don't have many, but the few I do are set in environment vars by a file sourced in my bashrc. Then you can just not track that file in the tool and figure out a safe way to back it up.
- drewcoo 1y agoThat moves the problem to "how do we securely manage shared keys." And it adds "how safe are those encrypted secrets [edit: changed from "keys" to more general language] that are committed?" and "what about previous revisions . . . because it's version control?" and "are we sure we're managing offboarding securely?" There are probably other concerns but those are the ones the immediately shout at me.
- hk1337 1y agoKeybase.io was a good option at one point
- porridgeraisin 1y agoCurious, what happened to keyvase?
- jakejarvis 1y agoAcquired by Zoom (yes, that Zoom) and left to rot. A huge loss for the internet IMO. :(
- whilenot-dev 1y agoYou might be interested in sops: https://github.com/getsops/sops https://github.com/getsops/sops
- denysvitali 1y agoSeems very similar (but less mature) to Chezmoi. How is Chezmoi too complex for your use case? I'm puzzled
- deleted 1y ago[deleted]
- globular-toast 1y agoI do the git branch thing with GNU stow and it absolutely sucks, but it's the only thing that sucks. This seems to solve different problems that I don't have but not the one that I do. I've been meaning to try chezmoi specifically because managing machine-specific branches sucks.
- amar1729 1y agoI switched over to chezmoi a few years ago - previously had been managing a "main" (macOS) and "Ubuntu" branch for dots. turned out to be a huge pain especially once I ran into work-specific config, or wanted to try other Linux flavors. figuring out the templating and ignore rules to [merge everything](https://github.com/Amar1729/dotfiles/commit/00177e45b09bba80e7072731273a58ac152b4f15 https://github.com/Amar1729/dotfiles/commit/00177e45b09bba80...) took about a weekend's effort but it was so worth it
- retrodaredevil 1y agoI have a Makefile that runs certain stow commands depending on the hostname of whatever machine I'm on. I keep machine specific files in their own directory, and I also have a shared directory for shared dotfiles. It works well for my needs.
- sureglymop 1y agoChezmoi seems to "do it all" but it also seems overly large and relatively complex. I'm just a bit afraid I'll have to read through the documentation over and over again, especially if it's been a while.
- sam_lowry_ 1y agoI have chosen the following approach to handle dotfiles: 1. `git init` 2. add * into .gitignore 3. `git add -f` dotfile The rest is normal git. If a dotfile differs by computer, differences live in their own branches and are regulary rebased on the common branch.
- deleted 1y ago[deleted]
- efitz 1y agoI have a feature suggestion: When you ‘lnk add’ a file, check it for patterns that might indicate it contains a secret, and warn the user if indications of a secret are found. Require —force or something to override.
- m000 1y agoMy main gripe with dotfile managers (including lnk) is that they assume a uniform environment. I haven't found one that doesn't make this fundamendal assumption. Some scenarios where dot fils may differ between computers: - My .gitconfig is different on my work laptop than my desktop. - I don't have neovim installed on my pi zero running DNS for my home network. - My zsh functions for making animated gifs won't work if specific tools are not installed. - An alias to open an image with the default image viewer is different between macos and linux. - I only have rust toolchain installed on my home desktop, so I shouldn't see it in my PATH on my work laptop. Is there any solution out there that can handle similar cases? Or are these requirements unique to me? (I don't quite believe they are.)
- Galanwe 1y agoI believe most dotfile managers offer the possibility to switch config based on hosts (e.g. chez-moi has templates https://www.chezmoi.io/user-guide/manage-machine-to-machine-differences/ https://www.chezmoi.io/user-guide/manage-machine-to-machine-... ). I guess with lnk being git centric that would be through branches. In any case you can manage your bashrc/profile and handle conditional logic to install packages there.
- yonatan8070 1y agoFor shell stuff, I use fish, and my fish config has a bunch of if...end blocks around most things, for example: ```if command -q exa alias ls="exa" alias ll="exa -lah" alias tree="exa --tree" end if command -q eza alias ls="eza" alias ll="eza -lah" alias tree="eza --tree" end```
- hk1337 1y agoFish seems to keep it contained to .config/fish which is nice. Most others tend to spread out outside of .config I’ve started modeling fish with zsh and OMZ customs
- setopt 1y agoThis plugin simplifies that workflow: https://github.com/jabirali/fish-abbrfile https://github.com/jabirali/fish-abbrfile
- nrvn 1y agoI have been using the "bare git at $HOMEDIR"[0] approach for several years. Benefits: 1. no extra tools. 2. one off task for setting up the git repo and alias `dotfiles='/usr/bin/git --git-dir=${HOME}/.config/dotfiles --work-tree=${HOME}'` 3. all files are where they are, no symlinks, copies, etc. Caveats: 1. $HOME/.gitignore just ignores everything because it contains a single "*" char[1]. So adding new files must be done with dotfiles add -f ~/.newfile to track. Refs: [0] - https://www.atlassian.com/git/tutorials/dotfiles https://www.atlassian.com/git/tutorials/dotfiles [1] - https://github.com/nrvnrvn/dotfiles/blob/main/.gitignore https://github.com/nrvnrvn/dotfiles/blob/main/.gitignore
- deleted 1y ago[deleted]
- hk1337 1y agoI don’t do the * in the gitignore because I use the confit alias and disable showing untracked files. That way I can use the .gitignore in the home as my global gitignore I love the bare repo method though. I’ve been using it for several years and haven’t had a need for another
- yencabulator 1y agoYou can use ~/.config/git/ignore (core.excludesFile).
- hk1337 1y agoIs that an automatic/default setting or did you just pick that path and you have to set the ignore filename in .gitconfig? Because, I know I could name it ~/.gitignore_global too.
- yencabulator 1y agoThat's the default path, you can change it. Original comment has the config variable.
- dcre 1y agoThis looks fine to use, but considering you can a achieve the same with a git repo and a 20 line bash script to make the symlinks[0], it seems to me precisely the kind of thing beginners should learn to do themselves rather than trust the magic and assume there’s something complicated going on they couldn’t understand. The fact that all of the commands are the same as the underlying git commands is probably better than the alternative (a bunch of random stuff) but it also makes clear you could do the same with git directly. [0]: https://crespo.business/posts/version-your-dotfiles/ https://crespo.business/posts/version-your-dotfiles/
- deleted 1y ago[deleted]
- dmacvicar 1y agoI have managed my dotfiles in git for over a decade, and I have never needed anything else than git and GNU stow. I organize dotfiles in a few modules, and then I stand in the top of the git checkout and do: "stow modulename", and it will symlink everything. If you don't like separate dotfiles in modules/packages, you can just have one (e.g. "main"). Stow has been around since 1993 or something, so I expect to be around for a while in my distro.
- keybored 1y agoSame for me. I don’t remember a problem with dotfiles. I’m sure there were ones that maybe I got used to. I also use it for ~/bin scripts. There the limitations are more noticable. Stow plus Git is a setup that already “doesn't suck.” Whatever that means here.
- danlitt 1y agoThe only thing I don't like about stow is that I can't move files around easily. If I decide to move some files around within modules, I have to unstow, then move them, the stow again. If I forget then it leaves dangling symlinks hanging around.
- deleted 1y ago[deleted]
- hk1337 1y agoI like the method I saw on atlassian and haven’t needed any other option. Clone to a bare repo and make your home directory the git home. Then I can easily edit the files and push changes. https://www.atlassian.com/git/tutorials/dotfiles https://www.atlassian.com/git/tutorials/dotfiles The whole symlink thing seems like a kludgey mess and pain in the ass to manage Even GNU Stow seems like a pain
- mathstuf 1y agoOne big benefit of symlinks (really, "not storing it in the deployment") is that my Git repo doesn't have a bunch of hidden files in it because they can appear in the link's path rather than the repo's path. I can also split up files based on "why it exists" rather than "where it lives". For example, I can have the "enable Rust support" group of configurations: - add Rust things to the list of packages to install - add any Rust-specific configurations for Neovim and `zsh` - bring in any Rust-oriented Neovim plugins These files all then live next to each other rather than being scatter-shot between Neovim, zsh, and some giant list of packages. Additionally, if I later decide to disable "Rust support" on a machine, the broken symlinks in `$HOME` let me clean up easily without having to actually excise things from the repository. That said, I have my own system that I built up years ago and it's never been abstracted out for anyone else to use so of course it's going to fit my needs better than anything else.
- threecheese 1y agoInteresting; these methods seem to follow the same pattern. They both track specific files in a controlled bare git repo, and both transparently link a $HOME file into that repo. Differences are the git method “links” - within the work tree - while ‘lnk’ creates a filesystem link. They both require a special command - a shell alias, vs an installed binary, and both indirectly leverage git subcommands (via the shell alias or the binary). An advantage of the git method is it doesn’t touch $HOME, and so if the git repo gets wiped out there’s no harm. Am I missing anything?
- deleted 1y ago[deleted]
- curtisszmania 1y ago[dead]
- deleted 1y ago[deleted]
- deleted 1y ago[deleted]
- SuperCuber 1y agoFunny that I see this post right after refreshing the documentation on my own project, Dotter[1] It offers a more involved approach to managing the dotfiles, but (imo) addresses the need to have differences between dotfiles on different machines. [1]: https://github.com/SuperCuber/dotter https://github.com/SuperCuber/dotter
- deleted 1y ago[deleted]
- NicolaiS 1y agoAnother approach that avoids symlinks and avoids a git repo in $HOME (i.e. everything is a subdir of that git repo) is to use the option "git-dir" to clone into a subdir, e.g. `$HOME/.dotfiles/` but checkout into $HOME: git clone --bare git@github.com:.../dotfiles.git $HOME/.dotfiles git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME checkout alias dotfiles='git --git-dir=$HOME/.dotfiles/ --work-tree=$HOME' dotfiles config --local status.showUntrackedFiles no Now the "dotfiles"-alias can be used like git, "dotfiles add, checkout, log", no symlinks are needed and you avoid "contaminating" subdirs of $HOME (git searches parent dirs for ".git", so a ".git" folder in $HOME kinda sucks)
- andy24 1y agoI use this approach as well, works absolutely great for me.
- abound 1y agoSame, I think I originally got it from the Arch Linux wiki[1], which explains it well. It in turn references HN, to come full circle. [1] https://wiki.archlinux.org/title/Dotfiles#Tracking_dotfiles_directly_with_Git https://wiki.archlinux.org/title/Dotfiles#Tracking_dotfiles_...
- deleted 1y ago[deleted]
- pabs3 1y agoMore dotfiles resources here: https://dotfiles.github.io/ https://dotfiles.github.io/ https://vcs-home.branchable.com/ https://vcs-home.branchable.com/