From 0167dabb78412ed5fb76cb4b174a6708c3be52b8 Mon Sep 17 00:00:00 2001 From: kuba-- Date: Fri, 24 Aug 2018 23:44:44 +0200 Subject: Remove empty dirs when cleaning with Dir opt. Signed-off-by: kuba-- --- worktree.go | 58 ++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 14 deletions(-) (limited to 'worktree.go') diff --git a/worktree.go b/worktree.go index 99b2cd1..921e600 100644 --- a/worktree.go +++ b/worktree.go @@ -713,29 +713,56 @@ func (w *Worktree) readGitmodulesFile() (*config.Modules, error) { } // Clean the worktree by removing untracked files. +// An empty dir could be removed - this is what `git clean -f -d .` does. func (w *Worktree) Clean(opts *CleanOptions) error { s, err := w.Status() if err != nil { return err } - // Check Worktree status to be Untracked, obtain absolute path and delete. - for relativePath, status := range s { - // Check if the path contains a directory and if Dir options is false, - // skip the path. - if relativePath != filepath.Base(relativePath) && !opts.Dir { + root := "" + files, err := w.Filesystem.ReadDir(root) + if err != nil { + return err + } + return w.doClean(s, opts, root, files) +} + +func (w *Worktree) doClean(status Status, opts *CleanOptions, dir string, files []os.FileInfo) error { + for _, fi := range files { + if fi.Name() == ".git" { continue } - // Remove the file only if it's an untracked file. - if status.Worktree == Untracked { - absPath := filepath.Join(w.Filesystem.Root(), relativePath) - if err := os.Remove(absPath); err != nil { + // relative path under the root + path := filepath.Join(dir, fi.Name()) + if fi.IsDir() { + if !opts.Dir { + continue + } + + subfiles, err := w.Filesystem.ReadDir(path) + if err != nil { + return err + } + err = w.doClean(status, opts, path, subfiles) + if err != nil { return err } + } else { + // check if file is 'Untracked' + s, ok := (status)[filepath.ToSlash(path)] + if ok && s.Worktree == Untracked { + if err := w.Filesystem.Remove(path); err != nil { + return err + } + } } } + if opts.Dir { + return doCleanDirectories(w.Filesystem, dir) + } return nil } @@ -881,15 +908,18 @@ func rmFileAndDirIfEmpty(fs billy.Filesystem, name string) error { return err } - path := filepath.Dir(name) - files, err := fs.ReadDir(path) + dir := filepath.Dir(name) + return doCleanDirectories(fs, dir) +} + +// doCleanDirectories removes empty subdirs (without files) +func doCleanDirectories(fs billy.Filesystem, dir string) error { + files, err := fs.ReadDir(dir) if err != nil { return err } - if len(files) == 0 { - fs.Remove(path) + return fs.Remove(dir) } - return nil } -- cgit From 75fa41d21c8d27ee0d5d7c7cb7ceeb2b765be330 Mon Sep 17 00:00:00 2001 From: kuba-- Date: Wed, 29 Aug 2018 14:56:25 +0200 Subject: Add Status.IsUntracked function Signed-off-by: kuba-- --- worktree.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'worktree.go') diff --git a/worktree.go b/worktree.go index 921e600..e45d815 100644 --- a/worktree.go +++ b/worktree.go @@ -750,9 +750,7 @@ func (w *Worktree) doClean(status Status, opts *CleanOptions, dir string, files return err } } else { - // check if file is 'Untracked' - s, ok := (status)[filepath.ToSlash(path)] - if ok && s.Worktree == Untracked { + if status.IsUntracked(path) { if err := w.Filesystem.Remove(path); err != nil { return err } -- cgit