aboutsummaryrefslogtreecommitdiffstats
path: root/worktree.go
diff options
context:
space:
mode:
Diffstat (limited to 'worktree.go')
-rw-r--r--worktree.go49
1 files changed, 39 insertions, 10 deletions
diff --git a/worktree.go b/worktree.go
index 02f90a9..d28ba32 100644
--- a/worktree.go
+++ b/worktree.go
@@ -410,7 +410,7 @@ func (w *Worktree) checkoutChange(ch merkletrie.Change, t *object.Tree, idx *ind
isSubmodule = e.Mode == filemode.Submodule
case merkletrie.Delete:
- return rmFileAndDirIfEmpty(w.Filesystem, ch.From.String())
+ return rmFileAndDirsIfEmpty(w.Filesystem, ch.From.String())
}
if isSubmodule {
@@ -778,8 +778,10 @@ func (w *Worktree) doClean(status Status, opts *CleanOptions, dir string, files
}
if opts.Dir && dir != "" {
- return doCleanDirectories(w.Filesystem, dir)
+ _, err := removeDirIfEmpty(w.Filesystem, dir)
+ return err
}
+
return nil
}
@@ -920,25 +922,52 @@ func findMatchInFile(file *object.File, treeName string, opts *GrepOptions) ([]G
return grepResults, nil
}
-func rmFileAndDirIfEmpty(fs billy.Filesystem, name string) error {
+// will walk up the directory tree removing all encountered empty
+// directories, not just the one containing this file
+func rmFileAndDirsIfEmpty(fs billy.Filesystem, name string) error {
if err := util.RemoveAll(fs, name); err != nil {
return err
}
dir := filepath.Dir(name)
- return doCleanDirectories(fs, dir)
+ for {
+ removed, err := removeDirIfEmpty(fs, dir)
+ if err != nil {
+ return err
+ }
+
+ if !removed {
+ // directory was not empty and not removed,
+ // stop checking parents
+ break
+ }
+
+ // move to parent directory
+ dir = filepath.Dir(dir)
+ }
+
+ return nil
}
-// doCleanDirectories removes empty subdirs (without files)
-func doCleanDirectories(fs billy.Filesystem, dir string) error {
+// removeDirIfEmpty will remove the supplied directory `dir` if
+// `dir` is empty
+// returns true if the directory was removed
+func removeDirIfEmpty(fs billy.Filesystem, dir string) (bool, error) {
files, err := fs.ReadDir(dir)
if err != nil {
- return err
+ return false, err
}
- if len(files) == 0 {
- return fs.Remove(dir)
+
+ if len(files) > 0 {
+ return false, nil
}
- return nil
+
+ err = fs.Remove(dir)
+ if err != nil {
+ return false, err
+ }
+
+ return true, nil
}
type indexBuilder struct {