Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Worktree: keep local changes when checkout branch #1145

Merged
merged 1 commit into from
May 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,11 @@ type CheckoutOptions struct {
// Force, if true when switching branches, proceed even if the index or the
// working tree differs from HEAD. This is used to throw away local changes
Force bool
// Keep, if true when switching branches, local changes (the index or the
// working tree changes) will be kept so that they can be committed to the
// target branch. Force and Keep are mutually exclusive, should not be both
// set to true.
Keep bool
}

// Validate validates the fields and sets the default values.
Expand Down
2 changes: 2 additions & 0 deletions worktree.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ func (w *Worktree) Checkout(opts *CheckoutOptions) error {
ro := &ResetOptions{Commit: c, Mode: MergeReset}
if opts.Force {
ro.Mode = HardReset
} else if opts.Keep {
ro.Mode = SoftReset
}

if !opts.Hash.IsZero() && !opts.Create {
Expand Down
40 changes: 40 additions & 0 deletions worktree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,46 @@ func (s *WorktreeSuite) TestCheckoutForce(c *C) {
c.Assert(entries, HasLen, 8)
}

func (s *WorktreeSuite) TestCheckoutKeep(c *C) {
w := &Worktree{
r: s.Repository,
Filesystem: memfs.New(),
}

err := w.Checkout(&CheckoutOptions{
Force: true,
})
c.Assert(err, IsNil)

// Create a new branch and create a new file.
err = w.Checkout(&CheckoutOptions{
Branch: plumbing.NewBranchReferenceName("new-branch"),
Create: true,
})
c.Assert(err, IsNil)

w.Filesystem = memfs.New()
f, err := w.Filesystem.Create("new-file.txt")
c.Assert(err, IsNil)
_, err = f.Write([]byte("DUMMY"))
c.Assert(err, IsNil)
c.Assert(f.Close(), IsNil)

// Add the file to staging.
_, err = w.Add("new-file.txt")
c.Assert(err, IsNil)

// Switch branch to master, and verify that the new file was kept in staging.
err = w.Checkout(&CheckoutOptions{
Keep: true,
})
c.Assert(err, IsNil)

fi, err := w.Filesystem.Stat("new-file.txt")
c.Assert(err, IsNil)
c.Assert(fi.Size(), Equals, int64(5))
}

func (s *WorktreeSuite) TestCheckoutSymlink(c *C) {
if runtime.GOOS == "windows" {
c.Skip("git doesn't support symlinks by default in windows")
Expand Down