aboutsummaryrefslogtreecommitdiffstats
path: root/worktree_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'worktree_test.go')
-rw-r--r--worktree_test.go171
1 files changed, 171 insertions, 0 deletions
diff --git a/worktree_test.go b/worktree_test.go
index 636ccbe..e1a6c0a 100644
--- a/worktree_test.go
+++ b/worktree_test.go
@@ -25,6 +25,7 @@ import (
"github.com/go-git/go-git/v5/storage/memory"
"github.com/stretchr/testify/assert"
+ "github.com/go-git/go-billy/v5"
"github.com/go-git/go-billy/v5/memfs"
"github.com/go-git/go-billy/v5/osfs"
"github.com/go-git/go-billy/v5/util"
@@ -3053,3 +3054,173 @@ func TestWindowsValidPath(t *testing.T) {
})
}
}
+
+var statusCodeNames = map[StatusCode]string{
+ Unmodified: "Unmodified",
+ Untracked: "Untracked",
+ Modified: "Modified",
+ Added: "Added",
+ Deleted: "Deleted",
+ Renamed: "Renamed",
+ Copied: "Copied",
+ UpdatedButUnmerged: "UpdatedButUnmerged",
+}
+
+func setupForRestore(c *C, s *WorktreeSuite) (fs billy.Filesystem, w *Worktree, names []string) {
+ fs = memfs.New()
+ w = &Worktree{
+ r: s.Repository,
+ Filesystem: fs,
+ }
+
+ err := w.Checkout(&CheckoutOptions{})
+ c.Assert(err, IsNil)
+
+ names = []string{"foo", "CHANGELOG", "LICENSE", "binary.jpg"}
+ verifyStatus(c, "Checkout", w, names, []FileStatus{
+ {Worktree: Untracked, Staging: Untracked},
+ {Worktree: Untracked, Staging: Untracked},
+ {Worktree: Untracked, Staging: Untracked},
+ {Worktree: Untracked, Staging: Untracked},
+ })
+
+ // Touch of bunch of files including create a new file and delete an exsiting file
+ for _, name := range names {
+ err = util.WriteFile(fs, name, []byte("Foo Bar"), 0755)
+ c.Assert(err, IsNil)
+ }
+ err = util.RemoveAll(fs, names[3])
+ c.Assert(err, IsNil)
+
+ // Confirm the status after doing the edits without staging anything
+ verifyStatus(c, "Edits", w, names, []FileStatus{
+ {Worktree: Untracked, Staging: Untracked},
+ {Worktree: Modified, Staging: Unmodified},
+ {Worktree: Modified, Staging: Unmodified},
+ {Worktree: Deleted, Staging: Unmodified},
+ })
+
+ // Stage all files and verify the updated status
+ for _, name := range names {
+ _, err = w.Add(name)
+ c.Assert(err, IsNil)
+ }
+ verifyStatus(c, "Staged", w, names, []FileStatus{
+ {Worktree: Unmodified, Staging: Added},
+ {Worktree: Unmodified, Staging: Modified},
+ {Worktree: Unmodified, Staging: Modified},
+ {Worktree: Unmodified, Staging: Deleted},
+ })
+
+ // Add secondary changes to a file to make sure we only restore the staged file
+ err = util.WriteFile(fs, names[1], []byte("Foo Bar:11"), 0755)
+ c.Assert(err, IsNil)
+ err = util.WriteFile(fs, names[2], []byte("Foo Bar:22"), 0755)
+ c.Assert(err, IsNil)
+
+ verifyStatus(c, "Secondary Edits", w, names, []FileStatus{
+ {Worktree: Unmodified, Staging: Added},
+ {Worktree: Modified, Staging: Modified},
+ {Worktree: Modified, Staging: Modified},
+ {Worktree: Unmodified, Staging: Deleted},
+ })
+
+ return
+}
+
+func verifyStatus(c *C, marker string, w *Worktree, files []string, statuses []FileStatus) {
+ c.Assert(len(files), Equals, len(statuses))
+
+ status, err := w.Status()
+ c.Assert(err, IsNil)
+
+ for i, file := range files {
+ current := status.File(file)
+ expected := statuses[i]
+ c.Assert(current.Worktree, Equals, expected.Worktree, Commentf("%s - [%d] : %s Worktree %s != %s", marker, i, file, statusCodeNames[current.Worktree], statusCodeNames[expected.Worktree]))
+ c.Assert(current.Staging, Equals, expected.Staging, Commentf("%s - [%d] : %s Staging %s != %s", marker, i, file, statusCodeNames[current.Staging], statusCodeNames[expected.Staging]))
+ }
+}
+
+func (s *WorktreeSuite) TestRestoreStaged(c *C) {
+ fs, w, names := setupForRestore(c, s)
+
+ // Attempt without files should throw an error like the git restore --staged
+ opts := RestoreOptions{Staged: true}
+ err := w.Restore(&opts)
+ c.Assert(err, Equals, ErrNoRestorePaths)
+
+ // Restore Staged files in 2 groups and confirm status
+ opts.Files = []string{names[0], names[1]}
+ err = w.Restore(&opts)
+ c.Assert(err, IsNil)
+ verifyStatus(c, "Restored First", w, names, []FileStatus{
+ {Worktree: Untracked, Staging: Untracked},
+ {Worktree: Modified, Staging: Unmodified},
+ {Worktree: Modified, Staging: Modified},
+ {Worktree: Unmodified, Staging: Deleted},
+ })
+
+ // Make sure the restore didn't overwrite our secondary changes
+ contents, err := util.ReadFile(fs, names[1])
+ c.Assert(err, IsNil)
+ c.Assert(string(contents), Equals, "Foo Bar:11")
+
+ opts.Files = []string{names[2], names[3]}
+ err = w.Restore(&opts)
+ c.Assert(err, IsNil)
+ verifyStatus(c, "Restored Second", w, names, []FileStatus{
+ {Worktree: Untracked, Staging: Untracked},
+ {Worktree: Modified, Staging: Unmodified},
+ {Worktree: Modified, Staging: Unmodified},
+ {Worktree: Deleted, Staging: Unmodified},
+ })
+
+ // Make sure the restore didn't overwrite our secondary changes
+ contents, err = util.ReadFile(fs, names[2])
+ c.Assert(err, IsNil)
+ c.Assert(string(contents), Equals, "Foo Bar:22")
+}
+
+func (s *WorktreeSuite) TestRestoreWorktree(c *C) {
+ _, w, names := setupForRestore(c, s)
+
+ // Attempt without files should throw an error like the git restore
+ opts := RestoreOptions{}
+ err := w.Restore(&opts)
+ c.Assert(err, Equals, ErrNoRestorePaths)
+
+ opts.Files = []string{names[0], names[1]}
+ err = w.Restore(&opts)
+ c.Assert(err, Equals, ErrRestoreWorktreeOnlyNotSupported)
+}
+
+func (s *WorktreeSuite) TestRestoreBoth(c *C) {
+ _, w, names := setupForRestore(c, s)
+
+ // Attempt without files should throw an error like the git restore --staged --worktree
+ opts := RestoreOptions{Staged: true, Worktree: true}
+ err := w.Restore(&opts)
+ c.Assert(err, Equals, ErrNoRestorePaths)
+
+ // Restore Staged files in 2 groups and confirm status
+ opts.Files = []string{names[0], names[1]}
+ err = w.Restore(&opts)
+ c.Assert(err, IsNil)
+ verifyStatus(c, "Restored First", w, names, []FileStatus{
+ {Worktree: Untracked, Staging: Untracked},
+ {Worktree: Untracked, Staging: Untracked},
+ {Worktree: Modified, Staging: Modified},
+ {Worktree: Unmodified, Staging: Deleted},
+ })
+
+ opts.Files = []string{names[2], names[3]}
+ err = w.Restore(&opts)
+ c.Assert(err, IsNil)
+ verifyStatus(c, "Restored Second", w, names, []FileStatus{
+ {Worktree: Untracked, Staging: Untracked},
+ {Worktree: Untracked, Staging: Untracked},
+ {Worktree: Untracked, Staging: Untracked},
+ {Worktree: Untracked, Staging: Untracked},
+ })
+}