twpayne / chezmoi

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

.chezmoiignore causes spurious error when ignoring directory with children #1928

Closed elldritch closed 2 years ago

elldritch commented 2 years ago

Describe the bug

If I .chezmoiignore a directory in my source state, running chezmoi add . in my target folder will then cause a parent directory not in source state error. To work around this, I have to manually chezmoi add DIR every directory except the ignored directory.

To reproduce

My source directory looks something like this:

~/.local/share/chezmoi/
  dot_xmonad/
    .chezmoiignore
    src/
    ...

I use this .chezmoiignore to ignore ~/.xmonad/dist-newstyle, which is a folder containing large built binary artifacts that I don't want to share between machines:

$ cat ~/.local/share/chezmoi/dot_xmonad/.chezmoiignore
xmonad.errors
dist-newstyle/

Unfortunately, with this .chezmoiignore, running chezmoi add . in ~/.xmonad returns an error:

$ chezmoi add .
chezmoi: ~/.xmonad/dist-newstyle/build: parent directory not in source state

My guess as to what's happening here is that the ignored folder is not being copied to the source state but is still being traversed, and an error is thrown when chezmoi tries to copy a child of the ignored directory into the source state.

Expected behavior

I would expect chezmoi to know to ignore all subdirectories of a .chezmoiignored directory without returning an error.

Output of command with the --verbose flag

$ chezmoi --verbose add .
chezmoi: ~/.xmonad/dist-newstyle/build: parent directory not in source state

Output of chezmoi doctor

```console $ chezmoi doctor RESULT CHECK MESSAGE warning version v2.13.0, built at 2022-02-26T08:30:45Z ok latest-version v2.13.0 ok os-arch linux/amd64 (Arch Linux) ok uname Linux arch-desktop-L 5.16.11-arch1-1 #1 SMP PREEMPT Thu, 24 Feb 2022 02:18:20 +0000 x86_64 GNU/Linux ok go-version go1.17.7 (gc) ok executable /usr/bin/chezmoi ok config-file ~/.config/chezmoi/chezmoi.toml ok source-dir ~/.local/share/chezmoi is a directory ok suspicious-entries no suspicious entries ok working-tree ~/.local/share/chezmoi is a directory ok dest-dir ~ is a directory ok shell-command found /usr/bin/zsh ok shell-args /usr/bin/zsh ok cd-command found /usr/bin/zsh ok cd-args /usr/bin/zsh warning edit-command vim not found in $PATH ok edit-args vim info diff-command not set ok umask 022 ok git-command found /usr/bin/git, version 2.35.1 warning merge-command vimdiff not found in $PATH info age-command age not found in $PATH ok gpg-command found /usr/bin/gpg, version 2.2.32 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 lastpass-command lpass not found in $PATH info pass-command pass not found in $PATH info vault-command vault not found in $PATH info secret-command not set ```
twpayne commented 2 years ago

The syntax of .chezmoiignore is different to .gitignore. You need to explicitly ignore subdirectories. The following should work:

$ cat ~/.local/share/chezmoi/dot_xmonad/.chezmoiignore
xmonad.errors
dist-newstyle
dist-newstyle/**
elldritch commented 2 years ago

Thank you, that works for me!