diff --git a/internal/fs/fs.go b/internal/fs/fs.go index 21cf96e69..a9f717c1b 100644 --- a/internal/fs/fs.go +++ b/internal/fs/fs.go @@ -64,7 +64,7 @@ var ( ) // CopyDir recursively copies a directory tree, attempting to preserve permissions. -// Source directory must exist, destination directory must *not* exist. +// Source directory must exist. func CopyDir(src, dst string) error { src = filepath.Clean(src) dst = filepath.Clean(dst) @@ -83,9 +83,6 @@ func CopyDir(src, dst string) error { if err != nil && !os.IsNotExist(err) { return err } - if err == nil { - return errDstExist - } if err = os.MkdirAll(dst, fi.Mode()); err != nil { return fmt.Errorf("cannot mkdir %s: %w", dst, err) diff --git a/internal/fs/rename.go b/internal/fs/rename.go index bad1f4778..068a76d68 100644 --- a/internal/fs/rename.go +++ b/internal/fs/rename.go @@ -20,10 +20,12 @@ func renameFallback(err error, src, dst string) error { // copy if we detect that case. syscall.EXDEV is the common name for the // cross device link error which has varying output text across different // operating systems. + // Rename may also fail if the directory already exists, which occurs when + // mapping to the root of another repo. Copy should still succeed. terr, ok := err.(*os.LinkError) if !ok { return err - } else if terr.Err != syscall.EXDEV { + } else if terr.Err != syscall.EXDEV && terr.Err != syscall.EEXIST { return fmt.Errorf("link error: cannot rename %s to %s: %w", src, dst, terr) }