From e7b02be89f2d98fcfe900d71b3b7ecdca8441ed2 Mon Sep 17 00:00:00 2001 From: Sunny Date: Mon, 4 Dec 2017 19:10:16 +0530 Subject: git: worktree, add Clean() method for git clean This change implement git clean with a `Dir` option. By default, clean removes only the untracked files in the working directory. If `Dir` option is set to true, untracked files under other directories are also cleaned. --- options.go | 5 +++++ worktree.go | 27 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/options.go b/options.go index d2cec4b..e5745ea 100644 --- a/options.go +++ b/options.go @@ -360,3 +360,8 @@ type ListOptions struct { // Auth credentials, if required, to use with the remote repository. Auth transport.AuthMethod } + +// CleanOptions describes how a clean should be performed. +type CleanOptions struct { + Dir bool +} diff --git a/worktree.go b/worktree.go index 67d7f08..e87f567 100644 --- a/worktree.go +++ b/worktree.go @@ -684,6 +684,33 @@ func (w *Worktree) readGitmodulesFile() (*config.Modules, error) { return m, m.Unmarshal(input) } +// Clean the worktree by removing untracked files. +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 { + 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 { + return err + } + } + } + + return nil +} + func rmFileAndDirIfEmpty(fs billy.Filesystem, name string) error { if err := util.RemoveAll(fs, name); err != nil { return err -- cgit From d43f17481253b76b558bfe4cc1e1b17bfb0c74e4 Mon Sep 17 00:00:00 2001 From: Sunny Date: Mon, 4 Dec 2017 20:44:00 +0530 Subject: test: git, Worktree.Clean() --- worktree_test.go | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/worktree_test.go b/worktree_test.go index 1bdf946..46c1faa 100644 --- a/worktree_test.go +++ b/worktree_test.go @@ -1252,3 +1252,38 @@ func (s *WorktreeSuite) TestMoveToExistent(c *C) { c.Assert(hash.IsZero(), Equals, true) c.Assert(err, Equals, ErrDestinationExists) } + +func (s *WorktreeSuite) TestClean(c *C) { + fs := fixtures.ByTag("dirty").One().Worktree() + + // Open the repo. + fs, err := fs.Chroot("repo") + c.Assert(err, IsNil) + r, err := PlainOpen(fs.Root()) + c.Assert(err, IsNil) + + wt, err := r.Worktree() + c.Assert(err, IsNil) + + // Status before cleaning. + status, err := wt.Status() + c.Assert(len(status), Equals, 2) + + err = wt.Clean(&CleanOptions{}) + c.Assert(err, IsNil) + + // Status after cleaning. + status, err = wt.Status() + c.Assert(err, IsNil) + + c.Assert(len(status), Equals, 1) + + // Clean with Dir: true. + err = wt.Clean(&CleanOptions{Dir: true}) + c.Assert(err, IsNil) + + status, err = wt.Status() + c.Assert(err, IsNil) + + c.Assert(len(status), Equals, 0) +} -- cgit