Skip to content

Commit 7bdcd80

Browse files
authored
Merge pull request src-d#1145 from linuxerwang/master
Worktree: keep local changes when checkout branch
2 parents 24de5ef + d1e34a7 commit 7bdcd80

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

options.go

+5
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,11 @@ type CheckoutOptions struct {
242242
// Force, if true when switching branches, proceed even if the index or the
243243
// working tree differs from HEAD. This is used to throw away local changes
244244
Force bool
245+
// Keep, if true when switching branches, local changes (the index or the
246+
// working tree changes) will be kept so that they can be committed to the
247+
// target branch. Force and Keep are mutually exclusive, should not be both
248+
// set to true.
249+
Keep bool
245250
}
246251

247252
// Validate validates the fields and sets the default values.

worktree.go

+2
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ func (w *Worktree) Checkout(opts *CheckoutOptions) error {
160160
ro := &ResetOptions{Commit: c, Mode: MergeReset}
161161
if opts.Force {
162162
ro.Mode = HardReset
163+
} else if opts.Keep {
164+
ro.Mode = SoftReset
163165
}
164166

165167
if !opts.Hash.IsZero() && !opts.Create {

worktree_test.go

+40
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,46 @@ func (s *WorktreeSuite) TestCheckoutForce(c *C) {
314314
c.Assert(entries, HasLen, 8)
315315
}
316316

317+
func (s *WorktreeSuite) TestCheckoutKeep(c *C) {
318+
w := &Worktree{
319+
r: s.Repository,
320+
Filesystem: memfs.New(),
321+
}
322+
323+
err := w.Checkout(&CheckoutOptions{
324+
Force: true,
325+
})
326+
c.Assert(err, IsNil)
327+
328+
// Create a new branch and create a new file.
329+
err = w.Checkout(&CheckoutOptions{
330+
Branch: plumbing.NewBranchReferenceName("new-branch"),
331+
Create: true,
332+
})
333+
c.Assert(err, IsNil)
334+
335+
w.Filesystem = memfs.New()
336+
f, err := w.Filesystem.Create("new-file.txt")
337+
c.Assert(err, IsNil)
338+
_, err = f.Write([]byte("DUMMY"))
339+
c.Assert(err, IsNil)
340+
c.Assert(f.Close(), IsNil)
341+
342+
// Add the file to staging.
343+
_, err = w.Add("new-file.txt")
344+
c.Assert(err, IsNil)
345+
346+
// Switch branch to master, and verify that the new file was kept in staging.
347+
err = w.Checkout(&CheckoutOptions{
348+
Keep: true,
349+
})
350+
c.Assert(err, IsNil)
351+
352+
fi, err := w.Filesystem.Stat("new-file.txt")
353+
c.Assert(err, IsNil)
354+
c.Assert(fi.Size(), Equals, int64(5))
355+
}
356+
317357
func (s *WorktreeSuite) TestCheckoutSymlink(c *C) {
318358
if runtime.GOOS == "windows" {
319359
c.Skip("git doesn't support symlinks by default in windows")

0 commit comments

Comments
 (0)