diff --git a/internal/chezmoi/externaldiffsystem.go b/internal/chezmoi/externaldiffsystem.go index 3f5a9b3..c1e7c5b 100644 --- a/internal/chezmoi/externaldiffsystem.go +++ b/internal/chezmoi/externaldiffsystem.go @@ -115,7 +115,7 @@ func (s *ExternalDiffSystem) Mkdir(name AbsPath, perm fs.FileMode) error { if err := os.MkdirAll(targetAbsPath.String(), perm); err != nil { return err } - if err := s.RunDiffCommand(devNullAbsPath, targetAbsPath); err != nil { + if err := s.RunDiffCommand(DevNullAbsPath, targetAbsPath); err != nil { return err } } @@ -151,7 +151,7 @@ func (s *ExternalDiffSystem) Remove(name AbsPath) error { case err != nil: return err case s.filter.IncludeFileInfo(fileInfo): - if err := s.RunDiffCommand(name, devNullAbsPath); err != nil { + if err := s.RunDiffCommand(name, DevNullAbsPath); err != nil { return err } } @@ -168,7 +168,7 @@ func (s *ExternalDiffSystem) RemoveAll(name AbsPath) error { case err != nil: return err case s.filter.IncludeFileInfo(fileInfo): - if err := s.RunDiffCommand(name, devNullAbsPath); err != nil { + if err := s.RunDiffCommand(name, DevNullAbsPath); err != nil { return err } } @@ -304,7 +304,7 @@ func (s *ExternalDiffSystem) RunScript(scriptName RelPath, dir AbsPath, data []b if err := os.WriteFile(targetAbsPath.String(), toData, 0o700); err != nil { return err } - if err := s.RunDiffCommand(devNullAbsPath, targetAbsPath); err != nil { + if err := s.RunDiffCommand(DevNullAbsPath, targetAbsPath); err != nil { return err } } @@ -340,7 +340,7 @@ func (s *ExternalDiffSystem) WriteFile(filename AbsPath, data []byte, perm fs.Fi fromAbsPath := filename switch fileInfo, err := os.Lstat(fromAbsPath.String()); { case errors.Is(err, fs.ErrNotExist): - fromAbsPath = devNullAbsPath + fromAbsPath = DevNullAbsPath case err != nil: return err case s.textConvFunc != nil: diff --git a/internal/chezmoi/path_unix.go b/internal/chezmoi/path_unix.go index bc9db14..8f515e7 100644 --- a/internal/chezmoi/path_unix.go +++ b/internal/chezmoi/path_unix.go @@ -7,7 +7,7 @@ import ( "strings" ) -var devNullAbsPath = NewAbsPath("/dev/null") +var DevNullAbsPath = NewAbsPath("/dev/null") // NewAbsPathFromExtPath returns a new AbsPath by converting extPath to use // slashes, performing tilde expansion, and making the path absolute. diff --git a/internal/chezmoi/path_windows.go b/internal/chezmoi/path_windows.go index 0b1d5f1..e67693a 100644 --- a/internal/chezmoi/path_windows.go +++ b/internal/chezmoi/path_windows.go @@ -5,7 +5,7 @@ import ( "strings" ) -var devNullAbsPath = NewAbsPath("NUL:") +var DevNullAbsPath = NewAbsPath("NUL:") // NewAbsPathFromExtPath returns a new AbsPath by converting extPath to use // slashes, performing tilde expansion, making the path absolute, and converting diff --git a/internal/cmd/config.go b/internal/cmd/config.go index 06d3abf..c480750 100644 --- a/internal/cmd/config.go +++ b/internal/cmd/config.go @@ -1197,9 +1197,13 @@ func (c *Config) defaultPreApplyFunc( case err != nil: return err case choice == "diff": + destAbsPath := c.DestDirAbsPath.Join(targetRelPath) + if actualEntryState.Type == chezmoi.EntryStateTypeRemove { + destAbsPath = chezmoi.DevNullAbsPath + } if err := c.diffFile( targetRelPath, - c.DestDirAbsPath.Join(targetRelPath), actualContents, actualEntryState.Mode, + destAbsPath, actualContents, actualEntryState.Mode, chezmoi.EmptyAbsPath, targetContents, targetEntryState.Mode, ); err != nil { return err diff --git a/internal/cmd/testdata/scripts/diffcommand_unix.txtar b/internal/cmd/testdata/scripts/diffcommand_unix.txtar index b2be758..6235e16 100644 --- a/internal/cmd/testdata/scripts/diffcommand_unix.txtar +++ b/internal/cmd/testdata/scripts/diffcommand_unix.txtar @@ -1,5 +1,6 @@ [windows] skip 'UNIX only' +chmod 755 bin/diff-exists chmod 755 bin/diff-pager # test that chezmoi diff invokes diff.command when configured @@ -59,10 +60,30 @@ cp golden/dot_file $CHEZMOISOURCEDIR exec chezmoi diff stdout diff-pager +chhome home7/user + +stdin golden/diff-no +exec chezmoi apply --interactive --no-tty +stdout \s/dev/null\s+${WORK@R}/.*/\.file$ +! exists $HOME/.file + +-- bin/diff-exists -- +#!/bin/sh + +for arg in "$@"; do + if [ ! -e "$arg" ]; then + echo "$arg: no such file" >&2 + exit 2 + fi +done +echo "$@" -- bin/diff-pager -- #!/bin/sh echo diff-pager +-- golden/diff-no -- +diff +no -- golden/diff-umask-002.diff -- diff --git a/.file b/.file index bd729e8ee3cc005444c67dc77eed60016886b5e0..b508963510528ab709627ec448026a10a64c72ef 100664 @@ -118,3 +139,8 @@ index bd729e8ee3cc005444c67dc77eed60016886b5e0..b508963510528ab709627ec448026a10 [diff] pager = "diff-pager" -- home6/user/.local/share/chezmoi/.keep -- +-- home7/user/.config/chezmoi/chezmoi.toml -- +[diff] + command = "diff-exists" +-- home7/user/.local/share/chezmoi/dot_file -- +# contents of .file