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

Commit dfd68a1

Browse files
authored
Merge pull request #441 from mcuadros/fix-add
worktree: Add create and push the blob objects to the storer
2 parents fc268a1 + 85a9126 commit dfd68a1

File tree

3 files changed

+56
-115
lines changed

3 files changed

+56
-115
lines changed

worktree_commit.go

+12-96
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package git
22

33
import (
4-
"io"
5-
"os"
64
"path/filepath"
75
"strings"
86

@@ -11,7 +9,6 @@ import (
119
"gopkg.in/src-d/go-git.v4/plumbing/format/index"
1210
"gopkg.in/src-d/go-git.v4/plumbing/object"
1311
"gopkg.in/src-d/go-git.v4/storage"
14-
"gopkg.in/src-d/go-git.v4/utils/ioutil"
1512

1613
"gopkg.in/src-d/go-billy.v3"
1714
)
@@ -34,12 +31,12 @@ func (w *Worktree) Commit(msg string, opts *CommitOptions) (plumbing.Hash, error
3431
return plumbing.ZeroHash, err
3532
}
3633

37-
h := &commitIndexHelper{
34+
h := &buildTreeHelper{
3835
fs: w.fs,
3936
s: w.r.Storer,
4037
}
4138

42-
tree, err := h.buildTreeAndBlobObjects(idx)
39+
tree, err := h.BuildTree(idx)
4340
if err != nil {
4441
return plumbing.ZeroHash, err
4542
}
@@ -103,20 +100,20 @@ func (w *Worktree) buildCommitObject(msg string, opts *CommitOptions, tree plumb
103100
return w.r.Storer.SetEncodedObject(obj)
104101
}
105102

106-
// commitIndexHelper converts a given index.Index file into multiple git objects
103+
// buildTreeHelper converts a given index.Index file into multiple git objects
107104
// reading the blobs from the given filesystem and creating the trees from the
108105
// index structure. The created objects are pushed to a given Storer.
109-
type commitIndexHelper struct {
106+
type buildTreeHelper struct {
110107
fs billy.Filesystem
111108
s storage.Storer
112109

113110
trees map[string]*object.Tree
114111
entries map[string]*object.TreeEntry
115112
}
116113

117-
// buildTreesAndBlobs builds the objects and push its to the storer, the hash
114+
// BuildTree builds the tree objects and push its to the storer, the hash
118115
// of the root tree is returned.
119-
func (h *commitIndexHelper) buildTreeAndBlobObjects(idx *index.Index) (plumbing.Hash, error) {
116+
func (h *buildTreeHelper) BuildTree(idx *index.Index) (plumbing.Hash, error) {
120117
const rootNode = ""
121118
h.trees = map[string]*object.Tree{rootNode: {}}
122119
h.entries = map[string]*object.TreeEntry{}
@@ -130,33 +127,27 @@ func (h *commitIndexHelper) buildTreeAndBlobObjects(idx *index.Index) (plumbing.
130127
return h.copyTreeToStorageRecursive(rootNode, h.trees[rootNode])
131128
}
132129

133-
func (h *commitIndexHelper) commitIndexEntry(e *index.Entry) error {
130+
func (h *buildTreeHelper) commitIndexEntry(e *index.Entry) error {
134131
parts := strings.Split(e.Name, string(filepath.Separator))
135132

136133
var path string
137134
for _, part := range parts {
138135
parent := path
139136
path = filepath.Join(path, part)
140137

141-
if !h.buildTree(e, parent, path) {
142-
continue
143-
}
144-
145-
if err := h.copyIndexEntryToStorage(e); err != nil {
146-
return err
147-
}
138+
h.doBuildTree(e, parent, path)
148139
}
149140

150141
return nil
151142
}
152143

153-
func (h *commitIndexHelper) buildTree(e *index.Entry, parent, path string) bool {
144+
func (h *buildTreeHelper) doBuildTree(e *index.Entry, parent, path string) {
154145
if _, ok := h.trees[path]; ok {
155-
return false
146+
return
156147
}
157148

158149
if _, ok := h.entries[path]; ok {
159-
return false
150+
return
160151
}
161152

162153
te := object.TreeEntry{Name: filepath.Base(path)}
@@ -170,84 +161,9 @@ func (h *commitIndexHelper) buildTree(e *index.Entry, parent, path string) bool
170161
}
171162

172163
h.trees[parent].Entries = append(h.trees[parent].Entries, te)
173-
return true
174-
}
175-
176-
func (h *commitIndexHelper) copyIndexEntryToStorage(e *index.Entry) error {
177-
_, err := h.s.EncodedObject(plumbing.BlobObject, e.Hash)
178-
if err == nil {
179-
return nil
180-
}
181-
182-
if err != plumbing.ErrObjectNotFound {
183-
return err
184-
}
185-
186-
return h.doCopyIndexEntryToStorage(e)
187-
}
188-
189-
func (h *commitIndexHelper) doCopyIndexEntryToStorage(e *index.Entry) (err error) {
190-
fi, err := h.fs.Lstat(e.Name)
191-
if err != nil {
192-
return err
193-
}
194-
195-
if fi.Mode()&os.ModeSymlink != 0 {
196-
return h.doCopyIndexEntryFromSymlinkToStorage(e, fi)
197-
}
198-
199-
obj := h.s.NewEncodedObject()
200-
obj.SetType(plumbing.BlobObject)
201-
obj.SetSize(fi.Size())
202-
203-
reader, err := h.fs.Open(e.Name)
204-
if err != nil {
205-
return err
206-
}
207-
208-
defer ioutil.CheckClose(reader, &err)
209-
210-
writer, err := obj.Writer()
211-
if err != nil {
212-
return err
213-
}
214-
215-
defer ioutil.CheckClose(writer, &err)
216-
217-
if _, err := io.Copy(writer, reader); err != nil {
218-
return err
219-
}
220-
221-
_, err = h.s.SetEncodedObject(obj)
222-
return err
223-
}
224-
225-
func (h *commitIndexHelper) doCopyIndexEntryFromSymlinkToStorage(e *index.Entry, fi os.FileInfo) error {
226-
obj := h.s.NewEncodedObject()
227-
obj.SetType(plumbing.BlobObject)
228-
obj.SetSize(fi.Size())
229-
230-
writer, err := obj.Writer()
231-
if err != nil {
232-
return err
233-
}
234-
235-
defer ioutil.CheckClose(writer, &err)
236-
237-
target, err := h.fs.Readlink(e.Name)
238-
if err != nil {
239-
return err
240-
}
241-
242-
if _, err := writer.Write([]byte(target)); err != nil {
243-
return err
244-
}
245-
246-
_, err = h.s.SetEncodedObject(obj)
247-
return err
248164
}
249165

250-
func (h *commitIndexHelper) copyTreeToStorageRecursive(parent string, t *object.Tree) (plumbing.Hash, error) {
166+
func (h *buildTreeHelper) copyTreeToStorageRecursive(parent string, t *object.Tree) (plumbing.Hash, error) {
251167
for i, e := range t.Entries {
252168
if e.Mode != filemode.Dir && !e.Hash.IsZero() {
253169
continue

worktree_status.go

+33-19
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ func (w *Worktree) Add(path string) (plumbing.Hash, error) {
227227
return plumbing.ZeroHash, err
228228
}
229229

230-
h, err := w.calculateBlobHash(path)
230+
h, err := w.copyFileToStorage(path)
231231
if err != nil {
232232
return h, err
233233
}
@@ -243,45 +243,59 @@ func (w *Worktree) Add(path string) (plumbing.Hash, error) {
243243
return h, err
244244
}
245245

246-
func (w *Worktree) calculateBlobHash(filename string) (hash plumbing.Hash, err error) {
247-
fi, err := w.fs.Lstat(filename)
246+
func (w *Worktree) copyFileToStorage(path string) (hash plumbing.Hash, err error) {
247+
fi, err := w.fs.Lstat(path)
248248
if err != nil {
249249
return plumbing.ZeroHash, err
250250
}
251251

252-
if fi.Mode()&os.ModeSymlink != 0 {
253-
return w.calculateBlobHashFromSymlink(filename)
254-
}
252+
obj := w.r.Storer.NewEncodedObject()
253+
obj.SetType(plumbing.BlobObject)
254+
obj.SetSize(fi.Size())
255255

256-
f, err := w.fs.Open(filename)
256+
writer, err := obj.Writer()
257257
if err != nil {
258258
return plumbing.ZeroHash, err
259259
}
260260

261-
defer ioutil.CheckClose(f, &err)
261+
defer ioutil.CheckClose(writer, &err)
262+
263+
if fi.Mode()&os.ModeSymlink != 0 {
264+
err = w.fillEncodedObjectFromSymlink(writer, path, fi)
265+
} else {
266+
err = w.fillEncodedObjectFromFile(writer, path, fi)
267+
}
262268

263-
h := plumbing.NewHasher(plumbing.BlobObject, fi.Size())
264-
if _, err := io.Copy(h, f); err != nil {
269+
if err != nil {
265270
return plumbing.ZeroHash, err
266271
}
267272

268-
hash = h.Sum()
269-
return
273+
return w.r.Storer.SetEncodedObject(obj)
270274
}
271275

272-
func (w *Worktree) calculateBlobHashFromSymlink(link string) (plumbing.Hash, error) {
273-
target, err := w.fs.Readlink(link)
276+
func (w *Worktree) fillEncodedObjectFromFile(dst io.Writer, path string, fi os.FileInfo) (err error) {
277+
src, err := w.fs.Open(path)
274278
if err != nil {
275-
return plumbing.ZeroHash, err
279+
return err
276280
}
277281

278-
h := plumbing.NewHasher(plumbing.BlobObject, int64(len(target)))
279-
_, err = h.Write([]byte(target))
282+
defer ioutil.CheckClose(src, &err)
283+
284+
if _, err := io.Copy(dst, src); err != nil {
285+
return err
286+
}
287+
288+
return err
289+
}
290+
291+
func (w *Worktree) fillEncodedObjectFromSymlink(dst io.Writer, path string, fi os.FileInfo) error {
292+
target, err := w.fs.Readlink(path)
280293
if err != nil {
281-
return plumbing.ZeroHash, err
294+
return err
282295
}
283296

284-
return h.Sum(), nil
297+
_, err = dst.Write([]byte(target))
298+
return err
285299
}
286300

287301
func (w *Worktree) addOrUpdateFileToIndex(filename string, h plumbing.Hash) error {

worktree_test.go

+11
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,11 @@ func (s *WorktreeSuite) TestAddUntracked(c *C) {
614614
file := status.File("foo")
615615
c.Assert(file.Staging, Equals, Added)
616616
c.Assert(file.Worktree, Equals, Unmodified)
617+
618+
obj, err := w.r.Storer.EncodedObject(plumbing.BlobObject, hash)
619+
c.Assert(err, IsNil)
620+
c.Assert(obj, NotNil)
621+
c.Assert(obj.Size(), Equals, int64(3))
617622
}
618623

619624
func (s *WorktreeSuite) TestAddModified(c *C) {
@@ -690,6 +695,12 @@ func (s *WorktreeSuite) TestAddSymlink(c *C) {
690695
h, err = w.Add("bar")
691696
c.Assert(err, IsNil)
692697
c.Assert(h, Equals, plumbing.NewHash("19102815663d23f8b75a47e7a01965dcdc96468c"))
698+
699+
obj, err := w.r.Storer.EncodedObject(plumbing.BlobObject, h)
700+
c.Assert(err, IsNil)
701+
c.Assert(obj, NotNil)
702+
c.Assert(obj.Size(), Equals, int64(3))
703+
693704
}
694705

695706
func (s *WorktreeSuite) TestRemove(c *C) {

0 commit comments

Comments
 (0)