twpayne / chezmoi

Manage your dotfiles across multiple diverse machines, securely.
https://www.chezmoi.io/
MIT License
13.05k stars 486 forks source link

Are symlinks second class citizens? #980

Closed adrian5 closed 3 years ago

adrian5 commented 3 years ago

I ran into #167 and saw the suggested workaround, as well as the following statement:

(…) chezmoi creates real files in your home directory. chezmoi does not create symbolic links back to the source directory (unless you explicitly want that).

There's also an obvious absense of the symlink topic in the documentation, barring a few exceptions.

This gives me the impression that symlinks aren't part of the intended chezmoi workflow. Is that the case?

If so, the documentation should really spell this out early on! If not, it would be good to have more examples about symlinks. Without trial and error, it is not obvious how symlinks are handled by chezmoi, and that doesn't inspire confidence when planning the switch from another solution.

twpayne commented 3 years ago

Thanks for the question and the links that indicate that you properly researched this :)

Symlinks are first class citizens: chezmoi supports creating them, updating them, removing them, and even more advanced features not found elsewhere like having the same symlink point to different targets on different machines by using templates.

I suspect the question arises because, with chezmoi, you only use symlinks where you really need a symlink, in contrast to some other dotfile managers (e.g. GNU Stow) which require the use of symlinks as a layer of indirection between a dotfile's location (which can be anywhere in your home directory) and a dotfile's content (which needs to be in a centralized directory that you manage with version control). chezmoi solves this problem in a different way.

Instead of using a symlink to redirect from the dotfile's location to the centralized directory, chezmoi generates the dotfile in its final location from the contents of the centralized directory. Not only is no symlink is needed, this has the advantages that chezmoi is better able to cope with differences from machine to machine (as a dotfile's contents can be unique to that machine) and the dotfiles that chezmoi creates are just regular files. There's nothing special about dotfiles managed by chezmoi, whereas dotfiles managed with GNU Stow are special because they're actually symlinks to somewhere else.

As far as I can tell, the only advantage to using GNU Stow-style symlinks is that changes that you make to the dotfile's contents in the centralized directory are immediately visible, whereas chezmoi currently requires you to run chezmoi apply or chezmoi edit --apply. chezmoi will likely get an alternative solution to this too, see #752.

You can configure chezmoi to work like GNU Stow and have it create a bunch of symlinks back to a central directory, but this currently requires a bit of manual work (as described in #167). chezmoi might get some automation to help (see #886 for example) but it does need some convincing use cases that demonstrate that a symlink from a dotfile's location to its contents in a central directory is better than just having the correct dotfile contents.

Thanks again for the question. Once we've discussed a bit more here I'll add an entry on this to the FAQ.

adrian5 commented 3 years ago

Thanks for the elaborate response and Happy New Year :tada:, this was really helpful!

One brief followup question: Files have to be edited within the source directory (chezmoi edit), correct? I'm just very used to editing files in their target location (symlink approach), but that can be unlearned. Some dotfile-managers take an approach where they compare the target with the source, and update the source if desired; so you edit your files as usual and sync them back into the source via the CLI. I reckon that wouldn't work well with the directionality of chezmoi apply (and templates ofc).

twpayne commented 3 years ago

chezmoi edit is a convenience command that has a couple of useful features, but you don't have to use it. Personally, I tend to run chezmoi cd and then just edit the files in the source state directly with my $EDITOR. After I save an edited file I run chezmoi diff to check what effect my changes would have, and run chezmoi apply once I'm happy with the result.

chezmoi edit provides the following useful features:

Note also that the arguments to chezmoi edit are the files in their target location. So, rather than unlearning your current approach, you can add an alias:

alias edit-dotfile="chezmoi edit --apply"

And you'll get just the same functionality, e.g. you can run edit-dotfile .bashrc and you'll get your $EDITOR open with the right file to edit and your changes immediately applied afterwards.

Some dotfile-managers take an approach where they compare the target with the source, and update the source if desired; so you edit your files as usual and sync them back into the source via the CLI. I reckon that wouldn't work well with the directionality of chezmoi apply (and templates ofc).

I agree. The symlink or sync-back-into-source approach is sufficient if your dotfiles don't vary between machines, but it quickly breaks down as your work across an increasing variety of machines. I use my personal dotfiles on macOS, Linux, and Windows running on both my physical machines and various virtual machines running locally (Docker containers and VirtualBox VMs) and remotely (e.g. GitHub CodeSpaces). I think chezmoi's templating approach and writing of real files, not symlinks, really wins out.

adrian5 commented 3 years ago

Great, that workflow makes sense now. Thanks again and I shall close it with that.