twpayne / chezmoi

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

`chezmoi apply` overwrites any files that were placed by chezmoi, no matter the source #3871

Closed noahdotpy closed 1 month ago

noahdotpy commented 1 month ago

Describe the bug

I have a ~/.local/share/chezmoi (let's call source 'b') that has the file ~/.config/nushell/env.nu and another source at ~/.myublue/config/homefiles/common/ (let's call it source 'a'). I would do chezmoi apply (using source a) usually. I have an automated script to chezmoi apply with source b. Source b has ~/.config/nushell/env.nu, the same file path as source a, with different contents. What happens is that ~/.config/nushell/env.nu gets overwritten by what chezmoi gets from source b. There are no extra flags other than --source to change the source that chezmoi is getting it from.

To reproduce

Make a test folder

Create two chezmoi repos inside this test folder. Add a dot_zshrc inside each repo, with file contents indicating which source it is from.

Then do this:

$ chezmoi apply --destination ./pretend-home --source ./source-a && cat ./pretend-home/.zshrc

Notice how the contents of the .zshrc file is from source a

Then do the same command with source b:

$ chezmoi apply --destination ./pretend-home --source ./source-b && cat ./pretend-home/.zshrc

Notice how the contents of the .zshrc file is from source b now, with no interactive prompt as would be expected if the .zshrc file was just there (not put there by chezmoi).

Expected behavior

A clear and concise description of what you expected to happen.

Output of command with the --verbose flag

$ chezmoi apply --destination ./pretend-home --source ./source-b --verbose && cat ./pretend-home/.zshrc 
diff --git a/.zshrc b/.zshrc
index 35e9da58a2c74a0c3a3ae7482f7e123613b23d5a..5b77ec49c5ecde91e8d7eb8c467f5ce6e630b67e 100644
--- a/.zshrc
+++ b/.zshrc
@@ -1 +1 @@
-from source a
+from source b
from source b

Output of chezmoi doctor

```console $ chezmoi doctor RESULT CHECK MESSAGE ok version v2.51.0, commit Homebrew, built at 2024-07-15T19:36:30Z, built by Homebrew ok latest-version v2.51.0 ok os-arch linux/amd64 (Fedora Linux 40.20240716.0 (Silverblue)) ok uname Linux ideapad-s145 6.8.11-300.fc40.x86_64 #1 SMP PREEMPT_DYNAMIC Mon May 27 14:53:33 UTC 2024 x86_64 GNU/Linux ok go-version go1.22.5 (gc) ok executable /var/home/linuxbrew/.linuxbrew/Cellar/chezmoi/2.51.0/bin/chezmoi ok upgrade-method brew-upgrade ok config-file ~/.config/chezmoi/chezmoi.toml, last modified 2024-07-10T20:26:05+10:00 ok source-dir ~/.local/share/chezmoi is a git working tree (clean) warning suspicious-entries ~/.local/share/chezmoi/chezmoi/private_dot_config/chezmoi/chezmoi.toml ok working-tree ~/.local/share/chezmoi is a git working tree (clean) ok dest-dir ~ is a directory ok umask 022 ok cd-command found /usr/bin/zsh ok cd-args /usr/bin/zsh info diff-command not set ok edit-command found /home/linuxbrew/.linuxbrew/bin/nvim ok edit-args /home/linuxbrew/.linuxbrew/bin/nvim ok git-command found /usr/bin/git, version 2.45.2 ok merge-command found /usr/bin/vimdiff ok shell-command found /usr/bin/zsh ok shell-args /usr/bin/zsh info age-command age not found in $PATH ok gpg-command found /home/linuxbrew/.linuxbrew/bin/gpg, version 2.4.5 info pinentry-command not set info 1password-command op not found in $PATH info bitwarden-command bw not found in $PATH info bitwarden-secrets-command bws not found in $PATH info dashlane-command dcli not found in $PATH info doppler-command doppler not found in $PATH info gopass-command gopass not found in $PATH info keepassxc-command keepassxc-cli not found in $PATH info keepassxc-db not set info keeper-command keeper not found in $PATH info lastpass-command lpass not found in $PATH info pass-command pass not found in $PATH info passhole-command ph not found in $PATH info rbw-command rbw not found in $PATH info vault-command vault not found in $PATH info vlt-command vlt not found in $PATH info secret-command not set ```

Additional context

Add any other context about the problem here.

halostatue commented 1 month ago

If you’re using multiple sources, you should also be using multiple configurations (or at least multiple state files). In Can chezmoi support multiple sources or multiple source states?, this example script is given:

chezmoi-apply() {
    chezmoi apply --config ~/.config/chezmoi-home/chezmoi.toml \
                  --source ~/.local/share/chezmoi-home && \
    chezmoi apply --config ~/.config/chezmoi-work/chezmoi.toml \
                  --source ~/.local/share/chezmoi-work
}

As it is, because you’re reusing the same state file, ~/.zshrc is seen to be owned by whichever source you’re passing. I’m sure that the chezmoi state data could be extended to include the source path, but that would prevent the use of git work trees to switch between multiple versions of the same source, or relocating the source to a different location.

twpayne commented 1 month ago

Closing this because I assume that the problem is solved. Please re-open if needed.