Stow and replace existing dotfiles
Asked Answered
S

1

5

I'm using most recommended method of managing dotfiles on mac by using stow. e.g., https://alexpearce.me/2016/02/managing-dotfiles-with-stow/

I found that it works great and does what I need to if I'm doing a clean install. I have a folder structure that looks like this inside my ~/dotfiles folder

.
├── install.sh
└── zsh
    └── .zshrc

when I run

stow zsh

It correctly sets the symlink in place from ~/.zshrc

.zshrc -> dotfiles/zsh/.zshrc

Problem however is if .zshrc is already present in the home folder, then stow will not override it with symlink. Instead it will just throw and error.

WARNING! stowing zsh would cause conflicts:
  * existing target is neither a link nor a directory: .zshrc
All operations aborted.

I understand I can manually "rm ~/.zshrc" file before running stow and will work.

I'm trying to see if there is cleaner way of setting up symlinks without having to manually run rm command for all the existing dotfiles.

Stylite answered 29/4, 2022 at 20:43 Comment(1)
I have the same exact question. I'm new to stow but I don't understand this design decision. This basically prevents one to stow dotfiles directory into a fresh installation's home. To achieve the goal you have to rm the same exact files that are present in dotfiles dir recursively. If you rm .* then you can loose some "not-stow-ed" file.Carminacarminative
I
6

Assuming you have the dotfiles in a Git repository and that you have committed the current changes, you can use this "trick": stow provides this option:

--adopt               (Use with care!)  Import existing files into stow package
                      from target.  Please read docs before using.

By looking at the man page (https://www.gnu.org/software/stow/manual/html_node/Invoking-Stow.html):

When stowing, if a target is encountered which already exists but is a plain file (and hence not owned by any existing stow package), then normally Stow will register this as a conflict and refuse to proceed. This option changes that behaviour so that the file is moved to the same relative place within the package’s installation image within the stow directory, and then stowing proceeds as before. So effectively, the file becomes adopted by the stow package, without its contents changing.

So, assuming ~/.zshrc is an existing file, and you have ~/dotfiles/zsh/.zshrc, you run (instead of stow zsh, which would cause a conflict):

stow --adopt zsh

This will replace your ~/dotfiles/zsh/.zshrc with the contents of the existing ~/.zshrc and will create the link:

~/.zshrc -> ~/dotfiles/zsh/.zshrc

Now, you just need to restore your dotfiles/zsh/.zshrc, e.g., with git --reset hard.

In fact, the manual also says:

This is particularly useful when the stow package is under the control of a version control system, because it allows files in the target tree, with potentially different contents to the equivalent versions in the stow package’s installation image, to be adopted into the package, then compared by running something like ‘git diff ...’ inside the stow package, and finally either kept (e.g. via ‘git commit ...’) or discarded (‘git checkout HEAD ...’).

Isoline answered 6/6, 2023 at 12:6 Comment(2)
what if you want the other way around, to replace the file in your home directory with the one in the dotfiles directory?Tampa
@AlaaMahran as I said in my comment, that's not directly possible with stow (IIRC, by design): you have to apply the operations above to achieve what you want.Isoline

© 2022 - 2024 — McMap. All rights reserved.