Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Improve documentation #259

Merged
merged 8 commits into from
Feb 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions plumbing/object/blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 {
Expand Down Expand Up @@ -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()
Expand Down
29 changes: 18 additions & 11 deletions plumbing/object/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
6 changes: 5 additions & 1 deletion plumbing/object/commit_walker.go
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
9 changes: 9 additions & 0 deletions plumbing/object/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down Expand Up @@ -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()
Expand Down
25 changes: 16 additions & 9 deletions plumbing/object/object.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Package object contains implementations of all Git objects and utility
// functions to work with them.
package object

import (
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down
29 changes: 19 additions & 10 deletions plumbing/object/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,22 @@ import (
// contains meta-information about the tag, including the tagger, tag date and
// message.
//
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add some info about Lightweight Tags and say that this method does not return this kind, can help people that don't know this two kinds of tags.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

// 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
}
Expand Down Expand Up @@ -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 {
Expand Down
11 changes: 6 additions & 5 deletions plumbing/object/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
18 changes: 4 additions & 14 deletions utils/ioutil/common.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package ioutil implements some I/O utility functions.
package ioutil

import (
Expand Down Expand Up @@ -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
Expand Down
23 changes: 23 additions & 0 deletions utils/ioutil/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ioutil
import (
"bytes"
"io/ioutil"
"strings"
"testing"

. "gopkg.in/check.v1"
Expand Down Expand Up @@ -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)
}
}