Skip to content

Commit a03b2cb

Browse files
committed
git: worktree, Don't delete local untracked files when resetting worktree. Fixes go-git#53
1 parent 93ed29d commit a03b2cb

File tree

2 files changed

+33
-11
lines changed

2 files changed

+33
-11
lines changed

worktree.go

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -309,14 +309,15 @@ func (w *Worktree) ResetSparsely(opts *ResetOptions, dirs []string) error {
309309
return err
310310
}
311311

312+
var removedFiles []string
312313
if opts.Mode == MixedReset || opts.Mode == MergeReset || opts.Mode == HardReset {
313-
if err := w.resetIndex(t, dirs, opts.Files); err != nil {
314+
if removedFiles, err = w.resetIndex(t, dirs, opts.Files); err != nil {
314315
return err
315316
}
316317
}
317318

318319
if opts.Mode == MergeReset || opts.Mode == HardReset {
319-
if err := w.resetWorktree(t, opts.Files); err != nil {
320+
if err := w.resetWorktree(t, removedFiles); err != nil {
320321
return err
321322
}
322323
}
@@ -369,23 +370,24 @@ func (w *Worktree) Reset(opts *ResetOptions) error {
369370
return w.ResetSparsely(opts, nil)
370371
}
371372

372-
func (w *Worktree) resetIndex(t *object.Tree, dirs []string, files []string) error {
373+
func (w *Worktree) resetIndex(t *object.Tree, dirs []string, files []string) ([]string, error) {
373374
idx, err := w.r.Storer.Index()
374375
if err != nil {
375-
return err
376+
return nil, err
376377
}
377378

378379
b := newIndexBuilder(idx)
379380

380381
changes, err := w.diffTreeWithStaging(t, true)
381382
if err != nil {
382-
return err
383+
return nil, err
383384
}
384385

386+
var removedFiles []string
385387
for _, ch := range changes {
386388
a, err := ch.Action()
387389
if err != nil {
388-
return err
390+
return nil, err
389391
}
390392

391393
var name string
@@ -396,7 +398,7 @@ func (w *Worktree) resetIndex(t *object.Tree, dirs []string, files []string) err
396398
name = ch.To.String()
397399
e, err = t.FindEntry(name)
398400
if err != nil {
399-
return err
401+
return nil, err
400402
}
401403
case merkletrie.Delete:
402404
name = ch.From.String()
@@ -410,6 +412,7 @@ func (w *Worktree) resetIndex(t *object.Tree, dirs []string, files []string) err
410412
}
411413

412414
b.Remove(name)
415+
removedFiles = append(removedFiles, name)
413416
if e == nil {
414417
continue
415418
}
@@ -428,7 +431,7 @@ func (w *Worktree) resetIndex(t *object.Tree, dirs []string, files []string) err
428431
idx.SkipUnless(dirs)
429432
}
430433

431-
return w.r.Storer.SetIndex(idx)
434+
return removedFiles, w.r.Storer.SetIndex(idx)
432435
}
433436

434437
func inFiles(files []string, v string) bool {
@@ -454,6 +457,11 @@ func (w *Worktree) resetWorktree(t *object.Tree, files []string) error {
454457
}
455458
b := newIndexBuilder(idx)
456459

460+
status, err := w.Status()
461+
if err != nil {
462+
return err
463+
}
464+
457465
for _, ch := range changes {
458466
if err := w.validChange(ch); err != nil {
459467
return err
@@ -477,8 +485,13 @@ func (w *Worktree) resetWorktree(t *object.Tree, files []string) error {
477485
}
478486
}
479487

480-
if err := w.checkoutChange(ch, t, b); err != nil {
481-
return err
488+
// only checkout an untracked file if it is in the list of files
489+
// a reset should leave untracked files alone
490+
file := nameFromAction(&ch)
491+
if status.File(file).Worktree != Untracked || inFiles(files, file) {
492+
if err := w.checkoutChange(ch, t, b); err != nil {
493+
return err
494+
}
482495
}
483496
}
484497

worktree_test.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1138,7 +1138,16 @@ func (s *WorktreeSuite) TestResetWithUntracked() {
11381138

11391139
status, err := w.Status()
11401140
s.NoError(err)
1141-
s.True(status.IsClean())
1141+
for file, st := range status {
1142+
if file == "foo" {
1143+
s.Equal(Untracked, st.Worktree)
1144+
s.Equal(Untracked, st.Staging)
1145+
continue
1146+
}
1147+
if st.Worktree != Unmodified || st.Staging != Unmodified {
1148+
s.Fail("file %s not unmodified", file)
1149+
}
1150+
}
11421151
}
11431152

11441153
func (s *WorktreeSuite) TestResetSoft() {

0 commit comments

Comments
 (0)