From 93abd6f1b3a1748a6ee37a42da3df7c96aeb8005 Mon Sep 17 00:00:00 2001 From: Taketoshi Fujiwara Date: Tue, 3 Jan 2023 15:24:17 +0900 Subject: [PATCH 1/5] git: fix doAddDirectory to add removed files. Fixes #223 --- worktree_status.go | 19 +++++++++++++++++++ worktree_test.go | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/worktree_status.go b/worktree_status.go index c639f1320..f55eb0454 100644 --- a/worktree_status.go +++ b/worktree_status.go @@ -306,6 +306,25 @@ func (w *Worktree) doAddDirectory(idx *index.Index, s Status, directory string, } } + // add removed files in the directory + entries, err := idx.Glob(path.Join(directory, "*")) + if err != nil { + return + } + + for _, entry := range entries { + var a bool + a, _, err = w.doAddFile(idx, s, entry.Name, ignorePattern) + + if err != nil { + return + } + + if !added && a { + added = true + } + } + return } diff --git a/worktree_test.go b/worktree_test.go index 4c0633355..a2159af63 100644 --- a/worktree_test.go +++ b/worktree_test.go @@ -1398,6 +1398,40 @@ func (s *WorktreeSuite) TestAddRemoved(c *C) { c.Assert(file.Staging, Equals, Deleted) } +func (s *WorktreeSuite) TestAddRemovedInDirectory(c *C) { + fs := memfs.New() + w := &Worktree{ + r: s.Repository, + Filesystem: fs, + } + + err := w.Checkout(&CheckoutOptions{Force: true}) + c.Assert(err, IsNil) + + idx, err := w.r.Storer.Index() + c.Assert(err, IsNil) + c.Assert(idx.Entries, HasLen, 9) + + err = w.Filesystem.Remove(filepath.Join("go", "example.go")) + c.Assert(err, IsNil) + + hash, err := w.Add(".") + c.Assert(err, IsNil) + c.Assert(hash.IsZero(), Equals, true) + + e, err := idx.Entry(filepath.Join("go", "example.go")) + c.Assert(err, IsNil) + c.Assert(e.Hash, Equals, plumbing.NewHash("880cd14280f4b9b6ed3986d6671f907d7cc2a198")) + c.Assert(e.Mode, Equals, filemode.Regular) + + status, err := w.Status() + c.Assert(err, IsNil) + c.Assert(status, HasLen, 1) + + file := status.File(filepath.Join("go", "example.go")) + c.Assert(file.Staging, Equals, Deleted) +} + func (s *WorktreeSuite) TestAddSymlink(c *C) { dir, clean := s.TemporalDir() defer clean() From a6fc9bcb6384a857e394328a9dd4dd91e2fc043b Mon Sep 17 00:00:00 2001 From: Taketoshi Fujiwara Date: Tue, 3 Jan 2023 16:27:43 +0900 Subject: [PATCH 2/5] updated a test case --- worktree_test.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/worktree_test.go b/worktree_test.go index a2159af63..72b8d08d3 100644 --- a/worktree_test.go +++ b/worktree_test.go @@ -1415,7 +1415,10 @@ func (s *WorktreeSuite) TestAddRemovedInDirectory(c *C) { err = w.Filesystem.Remove(filepath.Join("go", "example.go")) c.Assert(err, IsNil) - hash, err := w.Add(".") + err = w.Filesystem.Remove(filepath.Join("json", "short.json")) + c.Assert(err, IsNil) + + hash, err := w.Add("go") c.Assert(err, IsNil) c.Assert(hash.IsZero(), Equals, true) @@ -1424,12 +1427,20 @@ func (s *WorktreeSuite) TestAddRemovedInDirectory(c *C) { c.Assert(e.Hash, Equals, plumbing.NewHash("880cd14280f4b9b6ed3986d6671f907d7cc2a198")) c.Assert(e.Mode, Equals, filemode.Regular) + e, err = idx.Entry(filepath.Join("json", "short.json")) + c.Assert(err, IsNil) + c.Assert(e.Hash, Equals, plumbing.NewHash("c8f1d8c61f9da76f4cb49fd86322b6e685dba956")) + c.Assert(e.Mode, Equals, filemode.Regular) + status, err := w.Status() c.Assert(err, IsNil) - c.Assert(status, HasLen, 1) + c.Assert(status, HasLen, 2) file := status.File(filepath.Join("go", "example.go")) c.Assert(file.Staging, Equals, Deleted) + + file = status.File(filepath.Join("json", "short.json")) + c.Assert(file.Staging, Equals, Unmodified) } func (s *WorktreeSuite) TestAddSymlink(c *C) { From 40fbbf2fe84f1a6ef4f9f9f85462aa278161f1cd Mon Sep 17 00:00:00 2001 From: Taketoshi Fujiwara Date: Tue, 3 Jan 2023 18:14:42 +0900 Subject: [PATCH 3/5] stop using recursion, just iterate status --- worktree_status.go | 40 +++++++--------------------------------- 1 file changed, 7 insertions(+), 33 deletions(-) diff --git a/worktree_status.go b/worktree_status.go index f55eb0454..fd84e7ec7 100644 --- a/worktree_status.go +++ b/worktree_status.go @@ -270,10 +270,6 @@ func (w *Worktree) Add(path string) (plumbing.Hash, error) { } func (w *Worktree) doAddDirectory(idx *index.Index, s Status, directory string, ignorePattern []gitignore.Pattern) (added bool, err error) { - files, err := w.Filesystem.ReadDir(directory) - if err != nil { - return false, err - } if len(ignorePattern) > 0 { m := gitignore.NewMatcher(ignorePattern) matchPath := strings.Split(directory, string(os.PathSeparator)) @@ -283,39 +279,17 @@ func (w *Worktree) doAddDirectory(idx *index.Index, s Status, directory string, } } - for _, file := range files { - name := path.Join(directory, file.Name()) - - var a bool - if file.IsDir() { - if file.Name() == GitDirName { - // ignore special git directory - continue - } - a, err = w.doAddDirectory(idx, s, name, ignorePattern) - } else { - a, _, err = w.doAddFile(idx, s, name, ignorePattern) - } - - if err != nil { - return - } - - if !added && a { - added = true - } + if directory == "." { + directory = "" } - // add removed files in the directory - entries, err := idx.Glob(path.Join(directory, "*")) - if err != nil { - return - } + for name := range s { + if !strings.HasPrefix(name, directory) { + continue + } - for _, entry := range entries { var a bool - a, _, err = w.doAddFile(idx, s, entry.Name, ignorePattern) - + a, _, err = w.doAddFile(idx, s, name, ignorePattern) if err != nil { return } From 587048c03927a216ccd8656971d6af44683eb824 Mon Sep 17 00:00:00 2001 From: Taketoshi Fujiwara Date: Tue, 3 Jan 2023 20:01:17 +0900 Subject: [PATCH 4/5] fixed a bug --- worktree_status.go | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/worktree_status.go b/worktree_status.go index fd84e7ec7..6d276046d 100644 --- a/worktree_status.go +++ b/worktree_status.go @@ -279,12 +279,8 @@ func (w *Worktree) doAddDirectory(idx *index.Index, s Status, directory string, } } - if directory == "." { - directory = "" - } - for name := range s { - if !strings.HasPrefix(name, directory) { + if !isPathInDirectory(name, directory) { continue } @@ -302,6 +298,26 @@ func (w *Worktree) doAddDirectory(idx *index.Index, s Status, directory string, return } +func isPathInDirectory(path, directory string) bool { + ps := strings.Split(filepath.Clean(path), string(os.PathSeparator)) + ds := strings.Split(filepath.Clean(directory), string(os.PathSeparator)) + + if len(ds) == 1 && ds[0] == "." { + return true + } + + if len(ps) < len(ds) { + return false + } + + for i := 0; i < len(ds); i++ { + if ps[i] != ds[i] { + return false + } + } + return true +} + // AddWithOptions file contents to the index, updates the index using the // current content found in the working tree, to prepare the content staged for // the next commit. From 1232687eb1d37d4560e5089a589515fb1d6cf227 Mon Sep 17 00:00:00 2001 From: Taketoshi Fujiwara Date: Wed, 4 Jan 2023 10:16:24 +0900 Subject: [PATCH 5/5] fix test failure --- worktree_status.go | 6 +++--- worktree_test.go | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/worktree_status.go b/worktree_status.go index 6d276046d..f3091cff6 100644 --- a/worktree_status.go +++ b/worktree_status.go @@ -280,7 +280,7 @@ func (w *Worktree) doAddDirectory(idx *index.Index, s Status, directory string, } for name := range s { - if !isPathInDirectory(name, directory) { + if !isPathInDirectory(name, filepath.ToSlash(filepath.Clean(directory))) { continue } @@ -299,8 +299,8 @@ func (w *Worktree) doAddDirectory(idx *index.Index, s Status, directory string, } func isPathInDirectory(path, directory string) bool { - ps := strings.Split(filepath.Clean(path), string(os.PathSeparator)) - ds := strings.Split(filepath.Clean(directory), string(os.PathSeparator)) + ps := strings.Split(path, "/") + ds := strings.Split(directory, "/") if len(ds) == 1 && ds[0] == "." { return true diff --git a/worktree_test.go b/worktree_test.go index 72b8d08d3..d545b01eb 100644 --- a/worktree_test.go +++ b/worktree_test.go @@ -1412,22 +1412,22 @@ func (s *WorktreeSuite) TestAddRemovedInDirectory(c *C) { c.Assert(err, IsNil) c.Assert(idx.Entries, HasLen, 9) - err = w.Filesystem.Remove(filepath.Join("go", "example.go")) + err = w.Filesystem.Remove("go/example.go") c.Assert(err, IsNil) - err = w.Filesystem.Remove(filepath.Join("json", "short.json")) + err = w.Filesystem.Remove("json/short.json") c.Assert(err, IsNil) hash, err := w.Add("go") c.Assert(err, IsNil) c.Assert(hash.IsZero(), Equals, true) - e, err := idx.Entry(filepath.Join("go", "example.go")) + e, err := idx.Entry("go/example.go") c.Assert(err, IsNil) c.Assert(e.Hash, Equals, plumbing.NewHash("880cd14280f4b9b6ed3986d6671f907d7cc2a198")) c.Assert(e.Mode, Equals, filemode.Regular) - e, err = idx.Entry(filepath.Join("json", "short.json")) + e, err = idx.Entry("json/short.json") c.Assert(err, IsNil) c.Assert(e.Hash, Equals, plumbing.NewHash("c8f1d8c61f9da76f4cb49fd86322b6e685dba956")) c.Assert(e.Mode, Equals, filemode.Regular) @@ -1436,10 +1436,10 @@ func (s *WorktreeSuite) TestAddRemovedInDirectory(c *C) { c.Assert(err, IsNil) c.Assert(status, HasLen, 2) - file := status.File(filepath.Join("go", "example.go")) + file := status.File("go/example.go") c.Assert(file.Staging, Equals, Deleted) - file = status.File(filepath.Join("json", "short.json")) + file = status.File("json/short.json") c.Assert(file.Staging, Equals, Unmodified) }