diff options
author | Máximo Cuadros <mcuadros@gmail.com> | 2017-09-01 17:26:52 +0200 |
---|---|---|
committer | Máximo Cuadros <mcuadros@gmail.com> | 2017-09-01 17:26:52 +0200 |
commit | f1e58e0d30095cf768ff04d379b5e4145a874be8 (patch) | |
tree | 1922e3a721c4c19889557f96108076c325b95fbd /worktree.go | |
parent | 3ca370277427c5d508f0dedacbd559523a305121 (diff) | |
download | go-git-f1e58e0d30095cf768ff04d379b5e4145a874be8.tar.gz |
Worktree.Reset ignore untracked files on Merge mode
Diffstat (limited to 'worktree.go')
-rw-r--r-- | worktree.go | 188 |
1 files changed, 115 insertions, 73 deletions
diff --git a/worktree.go b/worktree.go index 4f8e740..e2f8562 100644 --- a/worktree.go +++ b/worktree.go @@ -107,7 +107,10 @@ func (w *Worktree) PullContext(ctx context.Context, o *PullOptions) error { return err } - if err := w.Reset(&ResetOptions{Commit: ref.Hash()}); err != nil { + if err := w.Reset(&ResetOptions{ + Mode: MergeReset, + Commit: ref.Hash(), + }); err != nil { return err } @@ -270,14 +273,12 @@ func (w *Worktree) Reset(opts *ResetOptions) error { } } - changes, err := w.diffCommitWithStaging(opts.Commit, true) - if err != nil { + if err := w.setHEADCommit(opts.Commit); err != nil { return err } - idx, err := w.r.Storer.Index() - if err != nil { - return err + if opts.Mode == SoftReset { + return nil } t, err := w.getTreeFromCommitHash(opts.Commit) @@ -285,50 +286,86 @@ func (w *Worktree) Reset(opts *ResetOptions) error { return err } - for _, ch := range changes { - if err := w.checkoutChange(ch, t, idx); err != nil { + if opts.Mode == MixedReset || opts.Mode == MergeReset || opts.Mode == HardReset { + if err := w.resetIndex(t); err != nil { return err } } - if err := w.r.Storer.SetIndex(idx); err != nil { - return err + if opts.Mode == MergeReset || opts.Mode == HardReset { + if err := w.resetWorktree(t); err != nil { + return err + } } - return w.setHEADCommit(opts.Commit) + return nil } -func (w *Worktree) containsUnstagedChanges() (bool, error) { - ch, err := w.diffStagingWithWorktree() +func (w *Worktree) resetIndex(t *object.Tree) error { + idx, err := w.r.Storer.Index() if err != nil { - return false, err + return err } - return len(ch) != 0, nil -} - -func (w *Worktree) setHEADCommit(commit plumbing.Hash) error { - head, err := w.r.Reference(plumbing.HEAD, false) + changes, err := w.diffTreeWithStaging(t, true) if err != nil { return err } - if head.Type() == plumbing.HashReference { - head = plumbing.NewHashReference(plumbing.HEAD, commit) - return w.r.Storer.SetReference(head) + for _, ch := range changes { + a, err := ch.Action() + if err != nil { + return err + } + + var name string + var e *object.TreeEntry + + switch a { + case merkletrie.Modify, merkletrie.Insert: + name = ch.To.String() + e, err = t.FindEntry(name) + if err != nil { + return err + } + case merkletrie.Delete: + name = ch.From.String() + } + + _, _ = idx.Remove(name) + if e == nil { + continue + } + + idx.Entries = append(idx.Entries, &index.Entry{ + Name: name, + Hash: e.Hash, + Mode: e.Mode, + }) + } - branch, err := w.r.Reference(head.Target(), false) + return w.r.Storer.SetIndex(idx) +} + +func (w *Worktree) resetWorktree(t *object.Tree) error { + changes, err := w.diffStagingWithWorktree(true) if err != nil { return err } - if !branch.Name().IsBranch() { - return fmt.Errorf("invalid HEAD target should be a branch, found %s", branch.Type()) + idx, err := w.r.Storer.Index() + if err != nil { + return err } - branch = plumbing.NewHashReference(branch.Name(), commit) - return w.r.Storer.SetReference(branch) + for _, ch := range changes { + if err := w.checkoutChange(ch, t, idx); err != nil { + return err + } + } + + return w.r.Storer.SetIndex(idx) } func (w *Worktree) checkoutChange(ch merkletrie.Change, t *object.Tree, idx *index.Index) error { @@ -351,13 +388,7 @@ func (w *Worktree) checkoutChange(ch merkletrie.Change, t *object.Tree, idx *ind isSubmodule = e.Mode == filemode.Submodule case merkletrie.Delete: - name = ch.From.String() - ie, err := idx.Entry(name) - if err != nil { - return err - } - - isSubmodule = ie.Mode == filemode.Submodule + return rmFileAndDirIfEmpty(w.Filesystem, ch.From.String()) } if isSubmodule { @@ -367,6 +398,52 @@ func (w *Worktree) checkoutChange(ch merkletrie.Change, t *object.Tree, idx *ind return w.checkoutChangeRegularFile(name, a, t, e, idx) } +func (w *Worktree) containsUnstagedChanges() (bool, error) { + ch, err := w.diffStagingWithWorktree(false) + if err != nil { + return false, err + } + + for _, c := range ch { + a, err := c.Action() + if err != nil { + return false, err + } + + if a == merkletrie.Insert { + continue + } + + return true, nil + } + + return false, nil +} + +func (w *Worktree) setHEADCommit(commit plumbing.Hash) error { + head, err := w.r.Reference(plumbing.HEAD, false) + if err != nil { + return err + } + + if head.Type() == plumbing.HashReference { + head = plumbing.NewHashReference(plumbing.HEAD, commit) + return w.r.Storer.SetReference(head) + } + + branch, err := w.r.Reference(head.Target(), false) + if err != nil { + return err + } + + if !branch.Name().IsBranch() { + return fmt.Errorf("invalid HEAD target should be a branch, found %s", branch.Type()) + } + + branch = plumbing.NewHashReference(branch.Name(), commit) + return w.r.Storer.SetReference(branch) +} + func (w *Worktree) checkoutChangeSubmodule(name string, a merkletrie.Action, e *object.TreeEntry, @@ -383,17 +460,7 @@ func (w *Worktree) checkoutChangeSubmodule(name string, return nil } - if err := w.rmIndexFromFile(name, idx); err != nil { - return err - } - - if err := w.addIndexFromTreeEntry(name, e, idx); err != nil { - return err - } - - // TODO: the submodule update should be reviewed as reported at: - // https://github.com/src-d/go-git/issues/415 - return sub.update(context.TODO(), &SubmoduleUpdateOptions{}, e.Hash) + return w.addIndexFromTreeEntry(name, e, idx) case merkletrie.Insert: mode, err := e.Mode.ToOSFileMode() if err != nil { @@ -405,12 +472,6 @@ func (w *Worktree) checkoutChangeSubmodule(name string, } return w.addIndexFromTreeEntry(name, e, idx) - case merkletrie.Delete: - if err := rmFileAndDirIfEmpty(w.Filesystem, name); err != nil { - return err - } - - return w.rmIndexFromFile(name, idx) } return nil @@ -424,9 +485,7 @@ func (w *Worktree) checkoutChangeRegularFile(name string, ) error { switch a { case merkletrie.Modify: - if err := w.rmIndexFromFile(name, idx); err != nil { - return err - } + _, _ = idx.Remove(name) // to apply perm changes the file is deleted, billy doesn't implement // chmod @@ -446,12 +505,6 @@ func (w *Worktree) checkoutChangeRegularFile(name string, } return w.addIndexFromFile(name, e.Hash, idx) - case merkletrie.Delete: - if err := rmFileAndDirIfEmpty(w.Filesystem, name); err != nil { - return err - } - - return w.rmIndexFromFile(name, idx) } return nil @@ -503,6 +556,7 @@ func (w *Worktree) checkoutFileSymlink(f *object.File) (err error) { } func (w *Worktree) addIndexFromTreeEntry(name string, f *object.TreeEntry, idx *index.Index) error { + _, _ = idx.Remove(name) idx.Entries = append(idx.Entries, &index.Entry{ Hash: f.Hash, Name: name, @@ -513,6 +567,7 @@ func (w *Worktree) addIndexFromTreeEntry(name string, f *object.TreeEntry, idx * } func (w *Worktree) addIndexFromFile(name string, h plumbing.Hash, idx *index.Index) error { + _, _ = idx.Remove(name) fi, err := w.Filesystem.Lstat(name) if err != nil { return err @@ -541,19 +596,6 @@ func (w *Worktree) addIndexFromFile(name string, h plumbing.Hash, idx *index.Ind return nil } -func (w *Worktree) rmIndexFromFile(name string, idx *index.Index) error { - for i, e := range idx.Entries { - if e.Name != name { - continue - } - - idx.Entries = append(idx.Entries[:i], idx.Entries[i+1:]...) - return nil - } - - return nil -} - func (w *Worktree) getTreeFromCommitHash(commit plumbing.Hash) (*object.Tree, error) { c, err := w.r.CommitObject(commit) if err != nil { |