aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--worktree_commit.go108
-rw-r--r--worktree_status.go52
-rw-r--r--worktree_test.go11
3 files changed, 56 insertions, 115 deletions
diff --git a/worktree_commit.go b/worktree_commit.go
index fc63d16..a342240 100644
--- a/worktree_commit.go
+++ b/worktree_commit.go
@@ -1,8 +1,6 @@
package git
import (
- "io"
- "os"
"path/filepath"
"strings"
@@ -11,7 +9,6 @@ import (
"gopkg.in/src-d/go-git.v4/plumbing/format/index"
"gopkg.in/src-d/go-git.v4/plumbing/object"
"gopkg.in/src-d/go-git.v4/storage"
- "gopkg.in/src-d/go-git.v4/utils/ioutil"
"gopkg.in/src-d/go-billy.v3"
)
@@ -34,12 +31,12 @@ func (w *Worktree) Commit(msg string, opts *CommitOptions) (plumbing.Hash, error
return plumbing.ZeroHash, err
}
- h := &commitIndexHelper{
+ h := &buildTreeHelper{
fs: w.fs,
s: w.r.Storer,
}
- tree, err := h.buildTreeAndBlobObjects(idx)
+ tree, err := h.BuildTree(idx)
if err != nil {
return plumbing.ZeroHash, err
}
@@ -103,10 +100,10 @@ func (w *Worktree) buildCommitObject(msg string, opts *CommitOptions, tree plumb
return w.r.Storer.SetEncodedObject(obj)
}
-// commitIndexHelper converts a given index.Index file into multiple git objects
+// buildTreeHelper converts a given index.Index file into multiple git objects
// reading the blobs from the given filesystem and creating the trees from the
// index structure. The created objects are pushed to a given Storer.
-type commitIndexHelper struct {
+type buildTreeHelper struct {
fs billy.Filesystem
s storage.Storer
@@ -114,9 +111,9 @@ type commitIndexHelper struct {
entries map[string]*object.TreeEntry
}
-// buildTreesAndBlobs builds the objects and push its to the storer, the hash
+// BuildTree builds the tree objects and push its to the storer, the hash
// of the root tree is returned.
-func (h *commitIndexHelper) buildTreeAndBlobObjects(idx *index.Index) (plumbing.Hash, error) {
+func (h *buildTreeHelper) BuildTree(idx *index.Index) (plumbing.Hash, error) {
const rootNode = ""
h.trees = map[string]*object.Tree{rootNode: {}}
h.entries = map[string]*object.TreeEntry{}
@@ -130,7 +127,7 @@ func (h *commitIndexHelper) buildTreeAndBlobObjects(idx *index.Index) (plumbing.
return h.copyTreeToStorageRecursive(rootNode, h.trees[rootNode])
}
-func (h *commitIndexHelper) commitIndexEntry(e *index.Entry) error {
+func (h *buildTreeHelper) commitIndexEntry(e *index.Entry) error {
parts := strings.Split(e.Name, string(filepath.Separator))
var path string
@@ -138,25 +135,19 @@ func (h *commitIndexHelper) commitIndexEntry(e *index.Entry) error {
parent := path
path = filepath.Join(path, part)
- if !h.buildTree(e, parent, path) {
- continue
- }
-
- if err := h.copyIndexEntryToStorage(e); err != nil {
- return err
- }
+ h.doBuildTree(e, parent, path)
}
return nil
}
-func (h *commitIndexHelper) buildTree(e *index.Entry, parent, path string) bool {
+func (h *buildTreeHelper) doBuildTree(e *index.Entry, parent, path string) {
if _, ok := h.trees[path]; ok {
- return false
+ return
}
if _, ok := h.entries[path]; ok {
- return false
+ return
}
te := object.TreeEntry{Name: filepath.Base(path)}
@@ -170,84 +161,9 @@ func (h *commitIndexHelper) buildTree(e *index.Entry, parent, path string) bool
}
h.trees[parent].Entries = append(h.trees[parent].Entries, te)
- return true
-}
-
-func (h *commitIndexHelper) copyIndexEntryToStorage(e *index.Entry) error {
- _, err := h.s.EncodedObject(plumbing.BlobObject, e.Hash)
- if err == nil {
- return nil
- }
-
- if err != plumbing.ErrObjectNotFound {
- return err
- }
-
- return h.doCopyIndexEntryToStorage(e)
-}
-
-func (h *commitIndexHelper) doCopyIndexEntryToStorage(e *index.Entry) (err error) {
- fi, err := h.fs.Lstat(e.Name)
- if err != nil {
- return err
- }
-
- if fi.Mode()&os.ModeSymlink != 0 {
- return h.doCopyIndexEntryFromSymlinkToStorage(e, fi)
- }
-
- obj := h.s.NewEncodedObject()
- obj.SetType(plumbing.BlobObject)
- obj.SetSize(fi.Size())
-
- reader, err := h.fs.Open(e.Name)
- if err != nil {
- return err
- }
-
- defer ioutil.CheckClose(reader, &err)
-
- writer, err := obj.Writer()
- if err != nil {
- return err
- }
-
- defer ioutil.CheckClose(writer, &err)
-
- if _, err := io.Copy(writer, reader); err != nil {
- return err
- }
-
- _, err = h.s.SetEncodedObject(obj)
- return err
-}
-
-func (h *commitIndexHelper) doCopyIndexEntryFromSymlinkToStorage(e *index.Entry, fi os.FileInfo) error {
- obj := h.s.NewEncodedObject()
- obj.SetType(plumbing.BlobObject)
- obj.SetSize(fi.Size())
-
- writer, err := obj.Writer()
- if err != nil {
- return err
- }
-
- defer ioutil.CheckClose(writer, &err)
-
- target, err := h.fs.Readlink(e.Name)
- if err != nil {
- return err
- }
-
- if _, err := writer.Write([]byte(target)); err != nil {
- return err
- }
-
- _, err = h.s.SetEncodedObject(obj)
- return err
}
-func (h *commitIndexHelper) copyTreeToStorageRecursive(parent string, t *object.Tree) (plumbing.Hash, error) {
+func (h *buildTreeHelper) copyTreeToStorageRecursive(parent string, t *object.Tree) (plumbing.Hash, error) {
for i, e := range t.Entries {
if e.Mode != filemode.Dir && !e.Hash.IsZero() {
continue
diff --git a/worktree_status.go b/worktree_status.go
index 648ea89..7116445 100644
--- a/worktree_status.go
+++ b/worktree_status.go
@@ -227,7 +227,7 @@ func (w *Worktree) Add(path string) (plumbing.Hash, error) {
return plumbing.ZeroHash, err
}
- h, err := w.calculateBlobHash(path)
+ h, err := w.copyFileToStorage(path)
if err != nil {
return h, err
}
@@ -243,45 +243,59 @@ func (w *Worktree) Add(path string) (plumbing.Hash, error) {
return h, err
}
-func (w *Worktree) calculateBlobHash(filename string) (hash plumbing.Hash, err error) {
- fi, err := w.fs.Lstat(filename)
+func (w *Worktree) copyFileToStorage(path string) (hash plumbing.Hash, err error) {
+ fi, err := w.fs.Lstat(path)
if err != nil {
return plumbing.ZeroHash, err
}
- if fi.Mode()&os.ModeSymlink != 0 {
- return w.calculateBlobHashFromSymlink(filename)
- }
+ obj := w.r.Storer.NewEncodedObject()
+ obj.SetType(plumbing.BlobObject)
+ obj.SetSize(fi.Size())
- f, err := w.fs.Open(filename)
+ writer, err := obj.Writer()
if err != nil {
return plumbing.ZeroHash, err
}
- defer ioutil.CheckClose(f, &err)
+ defer ioutil.CheckClose(writer, &err)
+
+ if fi.Mode()&os.ModeSymlink != 0 {
+ err = w.fillEncodedObjectFromSymlink(writer, path, fi)
+ } else {
+ err = w.fillEncodedObjectFromFile(writer, path, fi)
+ }
- h := plumbing.NewHasher(plumbing.BlobObject, fi.Size())
- if _, err := io.Copy(h, f); err != nil {
+ if err != nil {
return plumbing.ZeroHash, err
}
- hash = h.Sum()
- return
+ return w.r.Storer.SetEncodedObject(obj)
}
-func (w *Worktree) calculateBlobHashFromSymlink(link string) (plumbing.Hash, error) {
- target, err := w.fs.Readlink(link)
+func (w *Worktree) fillEncodedObjectFromFile(dst io.Writer, path string, fi os.FileInfo) (err error) {
+ src, err := w.fs.Open(path)
if err != nil {
- return plumbing.ZeroHash, err
+ return err
}
- h := plumbing.NewHasher(plumbing.BlobObject, int64(len(target)))
- _, err = h.Write([]byte(target))
+ defer ioutil.CheckClose(src, &err)
+
+ if _, err := io.Copy(dst, src); err != nil {
+ return err
+ }
+
+ return err
+}
+
+func (w *Worktree) fillEncodedObjectFromSymlink(dst io.Writer, path string, fi os.FileInfo) error {
+ target, err := w.fs.Readlink(path)
if err != nil {
- return plumbing.ZeroHash, err
+ return err
}
- return h.Sum(), nil
+ _, err = dst.Write([]byte(target))
+ return err
}
func (w *Worktree) addOrUpdateFileToIndex(filename string, h plumbing.Hash) error {
diff --git a/worktree_test.go b/worktree_test.go
index 06f82ca..5d0d131 100644
--- a/worktree_test.go
+++ b/worktree_test.go
@@ -614,6 +614,11 @@ func (s *WorktreeSuite) TestAddUntracked(c *C) {
file := status.File("foo")
c.Assert(file.Staging, Equals, Added)
c.Assert(file.Worktree, Equals, Unmodified)
+
+ obj, err := w.r.Storer.EncodedObject(plumbing.BlobObject, hash)
+ c.Assert(err, IsNil)
+ c.Assert(obj, NotNil)
+ c.Assert(obj.Size(), Equals, int64(3))
}
func (s *WorktreeSuite) TestAddModified(c *C) {
@@ -690,6 +695,12 @@ func (s *WorktreeSuite) TestAddSymlink(c *C) {
h, err = w.Add("bar")
c.Assert(err, IsNil)
c.Assert(h, Equals, plumbing.NewHash("19102815663d23f8b75a47e7a01965dcdc96468c"))
+
+ obj, err := w.r.Storer.EncodedObject(plumbing.BlobObject, h)
+ c.Assert(err, IsNil)
+ c.Assert(obj, NotNil)
+ c.Assert(obj.Size(), Equals, int64(3))
+
}
func (s *WorktreeSuite) TestRemove(c *C) {