diff options
-rw-r--r-- | plumbing/object/blob.go | 16 | ||||
-rw-r--r-- | plumbing/object/commit.go | 29 | ||||
-rw-r--r-- | plumbing/object/commit_walker.go | 6 | ||||
-rw-r--r-- | plumbing/object/file.go | 9 | ||||
-rw-r--r-- | plumbing/object/object.go | 25 | ||||
-rw-r--r-- | plumbing/object/tag.go | 29 | ||||
-rw-r--r-- | plumbing/object/tree.go | 11 | ||||
-rw-r--r-- | utils/ioutil/common.go | 18 | ||||
-rw-r--r-- | utils/ioutil/common_test.go | 23 |
9 files changed, 110 insertions, 56 deletions
diff --git a/plumbing/object/blob.go b/plumbing/object/blob.go index f274e70..4c9e84d 100644 --- a/plumbing/object/blob.go +++ b/plumbing/object/blob.go @@ -8,9 +8,11 @@ import ( "srcd.works/go-git.v4/utils/ioutil" ) -// Blob is used to store file data - it is generally a file. +// Blob is used to store arbitrary data - it is generally a file. type Blob struct { + // Hash of the blob. Hash plumbing.Hash + // Size of the (uncompressed) blob. Size int64 obj plumbing.EncodedObject @@ -26,6 +28,7 @@ func GetBlob(s storer.EncodedObjectStorer, h plumbing.Hash) (*Blob, error) { return DecodeBlob(o) } +// DecodeObject decodes an encoded object into a *Blob. func DecodeBlob(o plumbing.EncodedObject) (*Blob, error) { b := &Blob{} if err := b.Decode(o); err != nil { @@ -91,16 +94,17 @@ type BlobIter struct { s storer.EncodedObjectStorer } -// NewBlobIter returns a BlobIter for the given repository and underlying -// object iterator. +// NewBlobIter takes a storer.EncodedObjectStorer and a +// storer.EncodedObjectIter and returns a *BlobIter that iterates over all +// blobs contained in the storer.EncodedObjectIter. // -// The returned BlobIter will automatically skip over non-blob objects. +// Any non-blob object returned by the storer.EncodedObjectIter is skipped. func NewBlobIter(s storer.EncodedObjectStorer, iter storer.EncodedObjectIter) *BlobIter { return &BlobIter{iter, s} } -// Next moves the iterator to the next blob and returns a pointer to it. If it -// has reached the end of the set it will return io.EOF. +// Next moves the iterator to the next blob and returns a pointer to it. If +// there are no more blobs, it returns io.EOF. func (iter *BlobIter) Next() (*Blob, error) { for { obj, err := iter.EncodedObjectIter.Next() diff --git a/plumbing/object/commit.go b/plumbing/object/commit.go index 394f04f..7238f5c 100644 --- a/plumbing/object/commit.go +++ b/plumbing/object/commit.go @@ -22,10 +22,15 @@ type Hash plumbing.Hash // commit, a pointer to the previous commit(s), etc. // http://schacon.github.io/gitbook/1_the_git_object_model.html type Commit struct { - Hash plumbing.Hash - Author Signature + // Hash of the commit object. + Hash plumbing.Hash + // Author is the original author of the commit. + Author Signature + // Committer is the one performing the commit, might be different from + // Author. Committer Signature - Message string + // Message is the commit message, contains arbitrary text. + Message string tree plumbing.Hash parents []plumbing.Hash @@ -53,12 +58,12 @@ func DecodeCommit(s storer.EncodedObjectStorer, o plumbing.EncodedObject) (*Comm return c, nil } -// Tree returns the Tree from the commit +// Tree returns the Tree from the commit. func (c *Commit) Tree() (*Tree, error) { return GetTree(c.s, c.tree) } -// Parents return a CommitIter to the parent Commits +// Parents return a CommitIter to the parent Commits. func (c *Commit) Parents() *CommitIter { return NewCommitIter(c.s, storer.NewEncodedObjectLookupIter(c.s, plumbing.CommitObject, c.parents), @@ -158,7 +163,8 @@ func (c *Commit) Decode(o plumbing.EncodedObject) (err error) { } } -// History return a slice with the previous commits in the history of this commit +// History returns a slice with the previous commits in the history of this +// commit, sorted in reverse chronological order. func (c *Commit) History() ([]*Commit, error) { var commits []*Commit err := WalkCommitHistory(c, func(commit *Commit) error { @@ -231,16 +237,17 @@ type CommitIter struct { s storer.EncodedObjectStorer } -// NewCommitIter returns a CommitIter for the given object storer and underlying -// object iterator. +// NewCommitIter takes a storer.EncodedObjectStorer and a +// storer.EncodedObjectIter and returns a *CommitIter that iterates over all +// commits contained in the storer.EncodedObjectIter. // -// The returned CommitIter will automatically skip over non-commit objects. +// Any non-commit object returned by the storer.EncodedObjectIter is skipped. func NewCommitIter(s storer.EncodedObjectStorer, iter storer.EncodedObjectIter) *CommitIter { return &CommitIter{iter, s} } -// Next moves the iterator to the next commit and returns a pointer to it. If it -// has reached the end of the set it will return io.EOF. +// Next moves the iterator to the next commit and returns a pointer to it. If +// there are no more commits, it returns io.EOF. func (iter *CommitIter) Next() (*Commit, error) { obj, err := iter.EncodedObjectIter.Next() if err != nil { diff --git a/plumbing/object/commit_walker.go b/plumbing/object/commit_walker.go index 1514cb3..8d70abe 100644 --- a/plumbing/object/commit_walker.go +++ b/plumbing/object/commit_walker.go @@ -13,7 +13,11 @@ type commitWalker struct { cb func(*Commit) error } -// WalkCommitHistory walks the commit history +// WalkCommitHistory walks the commit history, starting at the given commit and +// visiting its parents in pre-order. The given callback will be called for each +// visited commit. Each commit will be visited only once. If the callback returns +// an error, walking will stop and will return the error. Other errors might be +// returned if the history cannot be traversed (e.g. missing objects). func WalkCommitHistory(c *Commit, cb func(*Commit) error) error { w := &commitWalker{ seen: make(map[plumbing.Hash]bool), diff --git a/plumbing/object/file.go b/plumbing/object/file.go index 618cea7..35e7f24 100644 --- a/plumbing/object/file.go +++ b/plumbing/object/file.go @@ -12,8 +12,12 @@ import ( // File represents git file objects. type File struct { + // Name is the path of the file. It might be relative to a tree, + // depending of the function that generates it. Name string + // Mode is the file mode. Mode os.FileMode + // Blob with the contents of the file. Blob } @@ -56,15 +60,20 @@ func (f *File) Lines() ([]string, error) { return splits, nil } +// FileIter provides an iterator for the files in a tree. type FileIter struct { s storer.EncodedObjectStorer w TreeWalker } +// NewFileIter takes a storer.EncodedObjectStorer and a Tree and returns a +// *FileIter that iterates over all files contained in the tree, recursively. func NewFileIter(s storer.EncodedObjectStorer, t *Tree) *FileIter { return &FileIter{s: s, w: *NewTreeWalker(t, true)} } +// Next moves the iterator to the next file and returns a pointer to it. If +// there are no more files, it returns io.EOF. func (iter *FileIter) Next() (*File, error) { for { name, entry, err := iter.w.Next() diff --git a/plumbing/object/object.go b/plumbing/object/object.go index 51d9bc4..ca5c541 100644 --- a/plumbing/object/object.go +++ b/plumbing/object/object.go @@ -1,3 +1,5 @@ +// Package object contains implementations of all Git objects and utility +// functions to work with them. package object import ( @@ -35,8 +37,9 @@ var ErrUnsupportedObject = errors.New("unsupported object type") // } // } // -// This interface is intentionally different from plumbing.EncodedObject, which is a lower -// level interface used by storage implementations to read and write objects. +// This interface is intentionally different from plumbing.EncodedObject, which +// is a lower level interface used by storage implementations to read and write +// objects in its encoded form. type Object interface { ID() plumbing.Hash Type() plumbing.ObjectType @@ -74,11 +77,14 @@ func DecodeObject(s storer.EncodedObjectStorer, o plumbing.EncodedObject) (Objec // DateFormat is the format being used in the original git implementation const DateFormat = "Mon Jan 02 15:04:05 2006 -0700" -// Signature represents an action signed by a person +// Signature is used to identify who and when created a commit or tag. type Signature struct { - Name string + // Name represents a person name. It is an arbitrary string. + Name string + // Email is an email, but it cannot be assumed to be well-formed. Email string - When time.Time + // When is the timestamp of the signature. + When time.Time } // Decode decodes a byte slice into a signature @@ -155,14 +161,15 @@ type ObjectIter struct { s storer.EncodedObjectStorer } -// NewObjectIter returns a ObjectIter for the given repository and underlying -// object iterator. +// NewObjectIter takes a storer.EncodedObjectStorer and a +// storer.EncodedObjectIter and returns an *ObjectIter that iterates over all +// objects contained in the storer.EncodedObjectIter. func NewObjectIter(s storer.EncodedObjectStorer, iter storer.EncodedObjectIter) *ObjectIter { return &ObjectIter{iter, s} } -// Next moves the iterator to the next object and returns a pointer to it. If it -// has reached the end of the set it will return io.EOF. +// Next moves the iterator to the next object and returns a pointer to it. If +// there are no more objects, it returns io.EOF. func (iter *ObjectIter) Next() (Object, error) { for { obj, err := iter.EncodedObjectIter.Next() diff --git a/plumbing/object/tag.go b/plumbing/object/tag.go index 1b18dbf..549e337 100644 --- a/plumbing/object/tag.go +++ b/plumbing/object/tag.go @@ -18,14 +18,22 @@ import ( // contains meta-information about the tag, including the tagger, tag date and // message. // +// Note that this is not used for lightweight tags. +// // https://git-scm.com/book/en/v2/Git-Internals-Git-References#Tags type Tag struct { - Hash plumbing.Hash - Name string - Tagger Signature - Message string + // Hash of the tag. + Hash plumbing.Hash + // Name of the tag. + Name string + // Tagger is the one who created the tag. + Tagger Signature + // Message is an arbitrary text message. + Message string + // TargetType is the object type of the target. TargetType plumbing.ObjectType - Target plumbing.Hash + // Target is the hash of the target object. + Target plumbing.Hash s storer.EncodedObjectStorer } @@ -223,16 +231,17 @@ type TagIter struct { s storer.EncodedObjectStorer } -// NewTagIter returns a TagIter for the given object storer and underlying -// object iterator. +// NewTagIter takes a storer.EncodedObjectStorer and a +// storer.EncodedObjectIter and returns a *TagIter that iterates over all +// tags contained in the storer.EncodedObjectIter. // -// The returned TagIter will automatically skip over non-tag objects. +// Any non-tag object returned by the storer.EncodedObjectIter is skipped. func NewTagIter(s storer.EncodedObjectStorer, iter storer.EncodedObjectIter) *TagIter { return &TagIter{iter, s} } -// Next moves the iterator to the next tag and returns a pointer to it. If it -// has reached the end of the set it will return io.EOF. +// Next moves the iterator to the next tag and returns a pointer to it. If +// there are no more tags, it returns io.EOF. func (iter *TagIter) Next() (*Tag, error) { obj, err := iter.EncodedObjectIter.Next() if err != nil { diff --git a/plumbing/object/tree.go b/plumbing/object/tree.go index 546dd74..3bcd80a 100644 --- a/plumbing/object/tree.go +++ b/plumbing/object/tree.go @@ -431,16 +431,17 @@ type TreeIter struct { s storer.EncodedObjectStorer } -// NewTreeIter returns a TreeIter for the given repository and underlying -// object iterator. +// NewTreeIter takes a storer.EncodedObjectStorer and a +// storer.EncodedObjectIter and returns a *TreeIter that iterates over all +// tree contained in the storer.EncodedObjectIter. // -// The returned TreeIter will automatically skip over non-tree objects. +// Any non-tree object returned by the storer.EncodedObjectIter is skipped. func NewTreeIter(s storer.EncodedObjectStorer, iter storer.EncodedObjectIter) *TreeIter { return &TreeIter{iter, s} } -// Next moves the iterator to the next tree and returns a pointer to it. If it -// has reached the end of the set it will return io.EOF. +// Next moves the iterator to the next tree and returns a pointer to it. If +// there are no more trees, it returns io.EOF. func (iter *TreeIter) Next() (*Tree, error) { for { obj, err := iter.EncodedObjectIter.Next() diff --git a/utils/ioutil/common.go b/utils/ioutil/common.go index a847abd..73cc9c3 100644 --- a/utils/ioutil/common.go +++ b/utils/ioutil/common.go @@ -1,3 +1,4 @@ +// Package ioutil implements some I/O utility functions. package ioutil import ( @@ -63,20 +64,9 @@ func WriteNopCloser(w io.Writer) io.WriteCloser { return writeNopCloser{w} } -// CheckClose is used with defer to close the given io.Closer and check its -// returned error value. If Close returns an error and the given *error -// is not nil, *error is set to the error returned by Close. -// -// CheckClose is typically used with named return values like so: -// -// func do(obj *Object) (err error) { -// w, err := obj.Writer() -// if err != nil { -// return nil -// } -// defer CheckClose(w, &err) -// // work with w -// } +// CheckClose calls Close on the given io.Closer. If the given *error points to +// nil, it will be assigned the error returned by Close. Otherwise, any error +// returned by Close will be ignored. CheckClose is usually called with defer. func CheckClose(c io.Closer, err *error) { if cerr := c.Close(); cerr != nil && *err == nil { *err = cerr diff --git a/utils/ioutil/common_test.go b/utils/ioutil/common_test.go index f5017f7..2d6ef80 100644 --- a/utils/ioutil/common_test.go +++ b/utils/ioutil/common_test.go @@ -3,6 +3,7 @@ package ioutil import ( "bytes" "io/ioutil" + "strings" "testing" . "gopkg.in/check.v1" @@ -53,3 +54,25 @@ func (s *CommonSuite) TestNewReadCloser(c *C) { c.Assert(r.Close(), IsNil) c.Assert(closer.called, Equals, 1) } + +func ExampleCheckClose() { + // CheckClose is commonly used with named return values + f := func() (err error) { + // Get a io.ReadCloser + r := ioutil.NopCloser(strings.NewReader("foo")) + + // defer CheckClose call with an io.Closer and pointer to error + defer CheckClose(r, &err) + + // ... work with r ... + + // if err is not nil, CheckClose will assign any close errors to it + return err + + } + + err := f() + if err != nil { + panic(err) + } +} |