I’m a big fan of chezmoi (https://www.chezmoi.io/) which is a very capable dotfile manager. Chezmoi supports some useful advanced capabilities like work/home profiles and secrets manager integration.
Same for me. I'd done the same thing as the author with various methods like stow, symlink farms, etc. over the years. Chezmoi is good enough that I'm willing to let someone else handle maintaining all logic.
Yup, I tried a number of dotfile managers. I think yadm was the first one I started with and then ended up with chezmoi.
The main reason was because I discovered the power of templating. With Yadm it required an external dependency, envptl, then j2cli, and both of these became unmaintained, while chezmoi used the text/template standard library. After the task of converting my jinja2 templates to gotmpl I never looked back.
One of the other things I like about chezmoi is I significantly cut down any "scripts" to just a few as most of the logic became "deterministic", ie I would set conditions based on the host in chezmoi.toml.tmpl and then that would define how everything under that would run across multiple hosts, and devices.
I migrated to chezmoi recently my only gripe is `chezmoi cd` opening in a new shell but `chezmoi git` usually is what I need. The age [0] integration is nice.
I added an alias `cm='cd $(chezmoi source-path)'` to my shell config to cd to the chezmoi directory (without opening a new shell) so I can use all the usual commands (e.g. git) without need the chezmoi prefix. The alias is in a chezmoi-managed file, naturally.
Hey, I had never heard about chezmoi before reading your comment, but I just installed it. Took less than 10 minutes to set up from start to finish. I noticed that if you choose to use it to manage your `~/.ssh/config/`, by default chezmoi sets it up as `private_dot_ssh/` and so if your dotfiles are public it doesn't expose sensitive data like private key files such as `~/.ssh/id_rsa`. Smart!
The private_ only applies to file permissions so in this case it makes the .ssh directory only readable by the owner. This is checked for by openssh and the config will be ignored if it's readable by the group or all.
If you make your dotfiles repo publicly accessible, you will leak your private keys unless you use other features in chezmoi to protect them.
also a big fan of it because the templating feature makes it very easy to handle dotfiles with different locations on multiple machines and if you use multiple operating systems. Really not that many tools around that have good windows support.
What happens when you need to link a file that does not support comments like that? For example, something which stores its config as plain JSON.
Or how about when you want to symlink an entire directory? For example something like neovim, considering that you may want to split config into separate files for organization. My neovim configuration has an "autoload setup" so any lua files inside the config directory are automatically required.
Lastly, this approach does not appear to support running commands. My dotfile install script ensures that tmux plugins are installed, the terminal font I use is available, and some other stuff that you need to invoke a command or script to achieve.
I like that the approach is simple, but I do not think it can support even relatively common use cases very well.
I'm not using a dotfiles manager, i track my ~/.config in git and have a script that globs for ~/.config/*/dot.* files to create symlinks for them. Like ~/.config/bash/dot.bashrc . Works with directories.
I prefer using ONE symlinked ~/.zshrc -> ~/dotfiles/etc/zsh/.zshrc and then using ENV-Variables within the .zshrc to specifiy other config file locations:
So one symlink is enough :-) Something similar can be done for ssh config (this file can not be symlinked for security reasons, so be careful working around this "feature"):
# contents of $HOME/.ssh/config
Include ~/dotfiles/etc/ssh/hosts.d/*
Every time I see these tools for “managing” dotfiles, or something for “managing” notes I get a bit perplexed as to what the use is, but then I am reminded of and impressed with how different people’s brains are and how we work and think.
I was getting by with bare git and then YADM until I grew tired of managing the logic to keep everything in sync across multiple machines and types or versions of OS, on top of managing my configs already.
Or if you follow just the right amount. Apart from the implementation issues, it's a great idea. MacOS essentially has a similar thing available through defaults.
What I realized after 25 years is that configuration comes in three parts:
1/ the defaults, either built in or read from /etc;
2/ my defaults, included in each file (or with ssh, at the bottom) with that particular config’s native version of #include; and
3/ local specifics that are rarely if ever used anywhere else, or trivially short as to be copy-paste-able.
Almost everything I want to customize goes into (2) so I wrote a single Python function that manages a block at the top (or with ssh, at the bottom) of each config file:
# BEGIN my foo stuff
include = /my/repo/foo/config
# END my foo stuff
That way foo starts out with (1) the system defaults; then adds (2) my personal foo defaults as defined in a working copy at /my/repo; (3) anything else I insert in the file after that which isn’t centrally managed and that’s ok.
I haven’t ever needed anything more complicated. I do not have any work specific configs that I need to gate. I no longer have to manage different configs based on whether I am using Debian, Debian (old), Debian (very old), SunOS (very very old), or AIX (very very very old) because those days are behind me.
If you do still need to manage slightly different but ethereally different configs on different hosts then I’m sorry to hear that. Rationalising my computing life so that I use the latest version of some Linux distribution everywhere has been very helpful!
IMO you don't need a special tool to manage your home directory / dotfiles. Git is the tool. Your home directory is a repo with a .git directory like any other repo. No other tools; no symlinks; nothing else. Commit what you want and gitignore the rest. I've done this since 2008.
That's what I do as well. Since you can .gitignore entire directories, that makes it easy. And one major advantage is having `git status` tell you if new things show up, so you can decide whether to track or ignore them (or change how/whether they're created in the first place).
I just put dotfiles directly where they are and majr a .git directory in my $HOME. .gitignore everything and git add -f files when I need to. no symlinking or anything.
Some responders here almost seem offended you wouldn't use chezmoi. Kind of strange. I couldn't care less about someone using chezmoi/tool x - big deal - but I'm always interested to read how people approach automation of their workflows, the tradeoffs, any cool tricks they employed that I might not have heard of before. Are engineers discouraged from problem solving now? It's not like youre doing this on company time; you are allowed to do things for fun/interest's sake..
The main reason was because I discovered the power of templating. With Yadm it required an external dependency, envptl, then j2cli, and both of these became unmaintained, while chezmoi used the text/template standard library. After the task of converting my jinja2 templates to gotmpl I never looked back.
One of the other things I like about chezmoi is I significantly cut down any "scripts" to just a few as most of the logic became "deterministic", ie I would set conditions based on the host in chezmoi.toml.tmpl and then that would define how everything under that would run across multiple hosts, and devices.
[0] - https://github.com/FiloSottile/age
If you make your dotfiles repo publicly accessible, you will leak your private keys unless you use other features in chezmoi to protect them.
Or how about when you want to symlink an entire directory? For example something like neovim, considering that you may want to split config into separate files for organization. My neovim configuration has an "autoload setup" so any lua files inside the config directory are automatically required.
Lastly, this approach does not appear to support running commands. My dotfile install script ensures that tmux plugins are installed, the terminal font I use is available, and some other stuff that you need to invoke a command or script to achieve.
I like that the approach is simple, but I do not think it can support even relatively common use cases very well.
Symlinking a directory - admittedly didn't come up for my dotfiles, maybe `.ln` files with a similar format in dir roots.
Commands - yes, I still keep a set of shell scripts alongside my config files.
https://www.chezmoi.io/user-guide/manage-machine-to-machine-...
1/ the defaults, either built in or read from /etc;
2/ my defaults, included in each file (or with ssh, at the bottom) with that particular config’s native version of #include; and
3/ local specifics that are rarely if ever used anywhere else, or trivially short as to be copy-paste-able.
Almost everything I want to customize goes into (2) so I wrote a single Python function that manages a block at the top (or with ssh, at the bottom) of each config file:
That way foo starts out with (1) the system defaults; then adds (2) my personal foo defaults as defined in a working copy at /my/repo; (3) anything else I insert in the file after that which isn’t centrally managed and that’s ok.I haven’t ever needed anything more complicated. I do not have any work specific configs that I need to gate. I no longer have to manage different configs based on whether I am using Debian, Debian (old), Debian (very old), SunOS (very very old), or AIX (very very very old) because those days are behind me.
If you do still need to manage slightly different but ethereally different configs on different hosts then I’m sorry to hear that. Rationalising my computing life so that I use the latest version of some Linux distribution everywhere has been very helpful!
IMO you don't need a special tool to manage your home directory / dotfiles. Git is the tool. Your home directory is a repo with a .git directory like any other repo. No other tools; no symlinks; nothing else. Commit what you want and gitignore the rest. I've done this since 2008.
Never had a problem with it.
Also less need on any scripts to set things up, due to chezmoi being more "deterministic" which means applying everything was a lot faster too.
On the off chance there's anyone else who sees this as worth exploring here's a <1min demo video - https://www.reddit.com/r/unixporn/comments/1f9u1xk/oc_better...
https://www.atlassian.com/git/tutorials/dotfiles