diff options
author | Máximo Cuadros <mcuadros@gmail.com> | 2017-04-12 15:18:41 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-12 15:18:41 +0200 |
commit | 932ced9f55f556de02610425cfa161c35c6a758b (patch) | |
tree | 9b5dd9ad1665fad8424dfbdc5bd93b531f714b09 /plumbing | |
parent | 9b45f468c61a0756dd19d09b64c2b1a88cc99ec5 (diff) | |
parent | 5bcf802213e801c4d52102612f007defa5d0397f (diff) | |
download | go-git-932ced9f55f556de02610425cfa161c35c6a758b.tar.gz |
Merge pull request #339 from mcuadros/status
worktree, status and reset implementation based on merkletrie
Diffstat (limited to 'plumbing')
-rw-r--r-- | plumbing/format/index/index.go | 26 | ||||
-rw-r--r-- | plumbing/object/difftree.go | 4 | ||||
-rw-r--r-- | plumbing/object/tree.go | 8 | ||||
-rw-r--r-- | plumbing/object/tree_test.go | 6 | ||||
-rw-r--r-- | plumbing/object/treenoder.go | 26 |
5 files changed, 49 insertions, 21 deletions
diff --git a/plumbing/format/index/index.go b/plumbing/format/index/index.go index ee50efd..61e7d66 100644 --- a/plumbing/format/index/index.go +++ b/plumbing/format/index/index.go @@ -2,8 +2,11 @@ package index import ( "errors" + "fmt" "time" + "bytes" + "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/src-d/go-git.v4/plumbing/filemode" ) @@ -47,6 +50,16 @@ type Index struct { ResolveUndo *ResolveUndo } +// String is equivalent to `git ls-files --stage --debug` +func (i *Index) String() string { + buf := bytes.NewBuffer(nil) + for _, e := range i.Entries { + buf.WriteString(e.String()) + } + + return buf.String() +} + // Entry represents a single file (or stage of a file) in the cache. An entry // represents exactly one stage of a file. If a file path is unmerged then // multiple Entry instances may appear for the same path name. @@ -78,6 +91,19 @@ type Entry struct { IntentToAdd bool } +func (e Entry) String() string { + buf := bytes.NewBuffer(nil) + + fmt.Fprintf(buf, "%06o %s %d\t%s\n", e.Mode, e.Hash, e.Stage, e.Name) + fmt.Fprintf(buf, " ctime: %d:%d\n", e.CreatedAt.Unix(), e.CreatedAt.Nanosecond()) + fmt.Fprintf(buf, " mtime: %d:%d\n", e.ModifiedAt.Unix(), e.ModifiedAt.Nanosecond()) + fmt.Fprintf(buf, " dev: %d\tino: %d\n", e.Dev, e.Inode) + fmt.Fprintf(buf, " uid: %d\tgid: %d\n", e.UID, e.GID) + fmt.Fprintf(buf, " size: %d\tflags: %x\n", e.Size, 0) + + return buf.String() +} + // Tree contains pre-computed hashes for trees that can be derived from the // index. It helps speed up tree object generation from index for a new commit. type Tree struct { diff --git a/plumbing/object/difftree.go b/plumbing/object/difftree.go index 87a7153..ac58c4d 100644 --- a/plumbing/object/difftree.go +++ b/plumbing/object/difftree.go @@ -10,8 +10,8 @@ import ( // DiffTree compares the content and mode of the blobs found via two // tree objects. func DiffTree(a, b *Tree) (Changes, error) { - from := newTreeNoder(a) - to := newTreeNoder(b) + from := NewTreeRootNode(a) + to := NewTreeRootNode(b) hashEqual := func(a, b noder.Hasher) bool { return bytes.Equal(a.Hash(), b.Hash()) diff --git a/plumbing/object/tree.go b/plumbing/object/tree.go index e70b5cd..d2265a8 100644 --- a/plumbing/object/tree.go +++ b/plumbing/object/tree.go @@ -67,7 +67,7 @@ type TreeEntry struct { // File returns the hash of the file identified by the `path` argument. // The path is interpreted as relative to the tree receiver. func (t *Tree) File(path string) (*File, error) { - e, err := t.findEntry(path) + e, err := t.FindEntry(path) if err != nil { return nil, ErrFileNotFound } @@ -86,7 +86,7 @@ func (t *Tree) File(path string) (*File, error) { // Tree returns the tree identified by the `path` argument. // The path is interpreted as relative to the tree receiver. func (t *Tree) Tree(path string) (*Tree, error) { - e, err := t.findEntry(path) + e, err := t.FindEntry(path) if err != nil { return nil, ErrDirectoryNotFound } @@ -109,7 +109,8 @@ func (t *Tree) TreeEntryFile(e *TreeEntry) (*File, error) { return NewFile(e.Name, e.Mode, blob), nil } -func (t *Tree) findEntry(path string) (*TreeEntry, error) { +// FindEntry search a TreeEntry in this tree or any subtree. +func (t *Tree) FindEntry(path string) (*TreeEntry, error) { pathParts := strings.Split(path, "/") var tree *Tree @@ -146,6 +147,7 @@ func (t *Tree) entry(baseName string) (*TreeEntry, error) { if t.m == nil { t.buildMap() } + entry, ok := t.m[baseName] if !ok { return nil, errEntryNotFound diff --git a/plumbing/object/tree_test.go b/plumbing/object/tree_test.go index cf5ad5f..aa86517 100644 --- a/plumbing/object/tree_test.go +++ b/plumbing/object/tree_test.go @@ -107,6 +107,12 @@ func (s *TreeSuite) TestFiles(c *C) { c.Assert(count, Equals, 9) } +func (s *TreeSuite) TestFindEntry(c *C) { + e, err := s.Tree.FindEntry("vendor/foo.go") + c.Assert(err, IsNil) + c.Assert(e.Name, Equals, "foo.go") +} + // This plumbing.EncodedObject implementation has a reader that only returns 6 // bytes at a time, this should simulate the conditions when a read // returns less bytes than asked, for example when reading a hash which diff --git a/plumbing/object/treenoder.go b/plumbing/object/treenoder.go index 4da8298..bd65abc 100644 --- a/plumbing/object/treenoder.go +++ b/plumbing/object/treenoder.go @@ -1,13 +1,5 @@ package object -// A treenoder is a helper type that wraps git trees into merkletrie -// noders. -// -// As a merkletrie noder doesn't understand the concept of modes (e.g. -// file permissions), the treenoder includes the mode of the git tree in -// the hash, so changes in the modes will be detected as modifications -// to the file contents by the merkletrie difftree algorithm. This is -// consistent with how the "git diff-tree" command works. import ( "io" @@ -16,6 +8,14 @@ import ( "gopkg.in/src-d/go-git.v4/utils/merkletrie/noder" ) +// A treenoder is a helper type that wraps git trees into merkletrie +// noders. +// +// As a merkletrie noder doesn't understand the concept of modes (e.g. +// file permissions), the treenoder includes the mode of the git tree in +// the hash, so changes in the modes will be detected as modifications +// to the file contents by the merkletrie difftree algorithm. This is +// consistent with how the "git diff-tree" command works. type treeNoder struct { parent *Tree // the root node is its own parent name string // empty string for the root node @@ -24,7 +24,8 @@ type treeNoder struct { children []noder.Noder // memoized } -func newTreeNoder(t *Tree) *treeNoder { +// NewTreeRootNode returns the root node of a Tree +func NewTreeRootNode(t *Tree) noder.Noder { if t == nil { return &treeNoder{} } @@ -45,13 +46,6 @@ func (t *treeNoder) String() string { return "treeNoder <" + t.name + ">" } -// The hash of a treeNoder is the result of concatenating the hash of -// its contents and its mode; that way the difftree algorithm will -// detect changes in the contents of files and also in their mode. -// -// Files with Regular and Deprecated file modes are considered the same -// for the purpose of difftree, so Regular will be used as the mode for -// Deprecated files here. func (t *treeNoder) Hash() []byte { if t.mode == filemode.Deprecated { return append(t.hash[:], filemode.Regular.Bytes()...) |