diff --git a/utils/merkletrie/change.go b/utils/merkletrie/change.go index 450feb4ba..562ff8902 100644 --- a/utils/merkletrie/change.go +++ b/utils/merkletrie/change.go @@ -131,7 +131,9 @@ func (l *Changes) addRecursive(root noder.Path, ctor noderToChangeFn) error { } if !root.IsDir() { - l.Add(ctor(root)) + if !root.Skip() { + l.Add(ctor(root)) + } return nil } diff --git a/utils/merkletrie/difftree.go b/utils/merkletrie/difftree.go index 4ef2d9907..7fc8d02d7 100644 --- a/utils/merkletrie/difftree.go +++ b/utils/merkletrie/difftree.go @@ -297,18 +297,16 @@ func DiffTreeContext(ctx context.Context, fromTree, toTree noder.Noder, case noMoreNoders: return ret, nil case onlyFromRemains: - if err = ret.AddRecursiveDelete(from); err != nil { - return nil, err + if !from.Skip() { + if err = ret.AddRecursiveDelete(from); err != nil { + return nil, err + } } if err = ii.nextFrom(); err != nil { return nil, err } case onlyToRemains: - if to.Skip() { - if err = ret.AddRecursiveDelete(to); err != nil { - return nil, err - } - } else { + if !to.Skip() { if err = ret.AddRecursiveInsert(to); err != nil { return nil, err } @@ -317,26 +315,25 @@ func DiffTreeContext(ctx context.Context, fromTree, toTree noder.Noder, return nil, err } case bothHaveNodes: - if from.Skip() { - if err = ret.AddRecursiveDelete(from); err != nil { - return nil, err - } - if err := ii.nextBoth(); err != nil { - return nil, err + var err error + switch { + case from.Skip(): + if from.Name() == to.Name() { + err = ii.nextBoth() + } else { + err = ii.nextFrom() } - break - } - if to.Skip() { - if err = ret.AddRecursiveDelete(to); err != nil { - return nil, err - } - if err := ii.nextBoth(); err != nil { - return nil, err + case to.Skip(): + if from.Name() == to.Name() { + err = ii.nextBoth() + } else { + err = ii.nextTo() } - break + default: + err = diffNodes(&ret, ii) } - if err = diffNodes(&ret, ii); err != nil { + if err != nil { return nil, err } default: diff --git a/worktree_test.go b/worktree_test.go index a3dbcfeb3..db2fd7cde 100644 --- a/worktree_test.go +++ b/worktree_test.go @@ -1359,7 +1359,24 @@ func (s *WorktreeSuite) TestStatusAfterCheckout(c *C) { status, err := w.Status() c.Assert(err, IsNil) c.Assert(status.IsClean(), Equals, true) +} + +func (s *WorktreeSuite) TestStatusAfterSparseCheckout(c *C) { + fs := memfs.New() + w := &Worktree{ + r: s.Repository, + Filesystem: fs, + } + err := w.Checkout(&CheckoutOptions{ + SparseCheckoutDirectories: []string{"php"}, + Force: true, + }) + c.Assert(err, IsNil) + + status, err := w.Status() + c.Assert(err, IsNil) + c.Assert(status.IsClean(), Equals, true) } func (s *WorktreeSuite) TestStatusModified(c *C) {