diff --git a/find_replace.go b/find_replace.go index 9bdbe79..07d53a4 100644 --- a/find_replace.go +++ b/find_replace.go @@ -151,6 +151,11 @@ func (fr *findReplace) WalkDir(f *File) { // the rename step; the failure is returned so the walker can log it and // continue with siblings. func (fr *findReplace) HandleFile(f *File) error { + if f.Base() == ".git" { + // Skip .git whether it is a directory or a worktree/submodule pointer file. + return nil + } + info, err := f.Info() if err != nil { return err @@ -158,10 +163,6 @@ func (fr *findReplace) HandleFile(f *File) error { // If file is a directory, recurse immediately (depth-first). if info.IsDir() { - // Ignore certain directories - if f.Base() == ".git" { - return nil - } fr.WalkDir(f) } else { // Replace the contents of regular files. diff --git a/find_replace_test.go b/find_replace_test.go index 9a54564..f169da8 100644 --- a/find_replace_test.go +++ b/find_replace_test.go @@ -660,6 +660,29 @@ func withWorkingDir(t *testing.T, dir string) { t.Cleanup(func() { _ = os.Chdir(prev) }) } + +func TestHandleFileSkipsGitWorktreeFile(t *testing.T) { + dir := t.TempDir() + path := filepath.Join(dir, ".git") + const original = "gitdir: /path/to/main/.git/worktrees/foo\n" + if err := os.WriteFile(path, []byte(original), 0o644); err != nil { + t.Fatal(err) + } + f := newFileOrFatal(t, path) + + fr := findReplace{find: "git", replace: "got"} + if err := fr.HandleFile(f); err != nil { + t.Fatal(err) + } + got, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + if string(got) != original { + t.Fatalf("content = %q; want unchanged worktree .git file", got) + } +} + func CloneRepoToTestDir(b *testing.B, repoUrl string) *File { b.Helper() d := newTestDir(b, "", "*")