twpayne / chezmoi

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

Merge results are lost #2598

Closed rivaldi8 closed 1 year ago

rivaldi8 commented 1 year ago

Describe the bug

The results of chezmoi merge some-file are lost. Neither the file in the home directory nor the one in the working copy are modified.

To reproduce

Start with .bashrc managed by chezmoi, having the home directory and the working copy with the same content (chezmoi diff prints no differences):

  1. Modify ~/.bashrc.
  2. chezmoi diff shows the differences.
  3. chezmoi merge opens vimdiff with ~/.bashrc, ~/.local/share/chezmoi/dot_bashrc and /tmp/chezmoi-merge3965727730/.bashrc.
  4. Add # new line at the end of /tmp/chezmoi-merge3965727730/.bashrc, save the changes and quit vimdiff.
  5. Neither ~/.bashrc nor ~/.local/share/chezmoi/dot_bashrc have # new line line.

Expected behavior

~/.bashrc should have # new line line at the end.

Output of command with the --verbose flag

$ chezmoi --verbose merge .bashrc
3 files to edit

Output of chezmoi doctor

```console $ chezmoi doctor RESULT CHECK MESSAGE ok version v2.27.2, commit 882d0808feb1fc8112b411ed2216f31306656861, built at 2022-11-24T23:41:28Z, built by goreleaser ok latest-version v2.27.2 ok os-arch linux/amd64 (Ubuntu 22.10 (Kinetic Kudu)) ok uname Linux cotton 5.19.0-23-generic #24-Ubuntu SMP PREEMPT_DYNAMIC Fri Oct 14 15:39:57 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux ok go-version go1.19.3 (gc) ok executable /snap/chezmoi/564/chezmoi ok upgrade-method snap-refresh ok config-file no config file found ok source-dir ~/.local/share/chezmoi is a git working tree (clean) ok suspicious-entries no suspicious entries ok working-tree ~/.local/share/chezmoi is a git working tree (clean) ok dest-dir ~ is a directory ok umask 002 ok cd-command found /bin/bash ok cd-args /bin/bash info diff-command not set ok edit-command found /usr/bin/vim ok edit-args /usr/bin/vim ok git-command found /usr/bin/git, version 2.37.2 ok merge-command found /usr/bin/vimdiff ok shell-command found /bin/bash ok shell-args /bin/bash info age-command age not found in $PATH ok gpg-command found /usr/bin/gpg, version 2.2.35 info pinentry-command not set info 1password-command op not found in $PATH info bitwarden-command bw 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 vault-command vault not found in $PATH info secret-command not set ```

Additional context

Nothing relevant that I can think of.

twpayne commented 1 year ago

/tmp/chezmoi-merge3965727730/.bashrc is a temporary file created by chezmoi to show you what the target state of the file looks like.

If you want to make changes to ~/.bashrc or ~/.local/share/chezmoi/dot_bashrc then you have to edit and save these files in your merge tool.

rivaldi8 commented 1 year ago

Ok, that really confused me. I'm used to merge tools like ones from VS Code or IntelliJ where you have two panes with the two file versions and a third with the result of the merge. So that's why I expected the third pane content to end up in ~/.bashrc.

In fact, my confusion really comes from the "target state". After taking another look at the documentation I'm still not sure of its meaning.

Anyway, knowing that what I want is to modify the other two panes and ignore the 'target' is enough for my use case. Thanks for the clarification and sorry for the noise.

twpayne commented 1 year ago

You can configure the order of the files in the merge tool using merge.args.

For the target state, it's perhaps easiest to think of chezmoi is a program that generates your dotfiles for the current machine. Consider the case where you're generating ~/.bashrc from a template. The source state (file) is ~/.local/share/chezmoi/dot_bashrc.tmpl. The target state is the result of executing the template, and is what you want the contents of ~/.bashrc to be. The destination state is the current contents of ~/.bashrc.

These three states - source, target, and destination - can drift out of sync if you change your dotfiles without making equivalent changes to the source state. If this happens, the merge tool can help you update your source state with the changes to the destination state.