aboutsummaryrefslogtreecommitdiffstats
path: root/plumbing/format
diff options
context:
space:
mode:
Diffstat (limited to 'plumbing/format')
-rw-r--r--plumbing/format/diff/unified_encoder.go8
-rw-r--r--plumbing/format/diff/unified_encoder_test.go37
-rw-r--r--plumbing/format/gitignore/pattern.go3
-rw-r--r--plumbing/format/gitignore/pattern_test.go6
-rw-r--r--plumbing/format/idxfile/idxfile.go69
-rw-r--r--plumbing/format/idxfile/idxfile_test.go15
-rw-r--r--plumbing/format/packfile/encoder_advanced_test.go7
-rw-r--r--plumbing/format/packfile/fsobject.go10
-rw-r--r--plumbing/format/packfile/packfile.go17
9 files changed, 165 insertions, 7 deletions
diff --git a/plumbing/format/diff/unified_encoder.go b/plumbing/format/diff/unified_encoder.go
index 58edd95..8bd6d8a 100644
--- a/plumbing/format/diff/unified_encoder.go
+++ b/plumbing/format/diff/unified_encoder.go
@@ -237,9 +237,13 @@ func (c *hunksGenerator) addLineNumbers(la, lb int, linesBefore int, i int, op O
// we need to search for a reference for the next diff
switch {
case linesBefore != 0 && c.ctxLines != 0:
- clb = lb - c.ctxLines + 1
+ if lb > c.ctxLines {
+ clb = lb - c.ctxLines + 1
+ } else {
+ clb = 1
+ }
case c.ctxLines == 0:
- clb = lb - c.ctxLines
+ clb = lb
case i != len(c.chunks)-1:
next := c.chunks[i+1]
if next.Type() == op || next.Type() == Equal {
diff --git a/plumbing/format/diff/unified_encoder_test.go b/plumbing/format/diff/unified_encoder_test.go
index 0e419ca..7736af1 100644
--- a/plumbing/format/diff/unified_encoder_test.go
+++ b/plumbing/format/diff/unified_encoder_test.go
@@ -155,6 +155,43 @@ var fixtures []*fixture = []*fixture{{
filePatches: []testFilePatch{{
from: &testFile{
mode: filemode.Regular,
+ path: "README.md",
+ seed: "hello\nworld\n",
+ },
+ to: &testFile{
+ mode: filemode.Regular,
+ path: "README.md",
+ seed: "hello\nbug\n",
+ },
+ chunks: []testChunk{{
+ content: "hello",
+ op: Equal,
+ }, {
+ content: "world",
+ op: Delete,
+ }, {
+ content: "bug",
+ op: Add,
+ }},
+ }},
+ },
+ desc: "positive negative number",
+ context: 2,
+ diff: `diff --git a/README.md b/README.md
+index 94954abda49de8615a048f8d2e64b5de848e27a1..f3dad9514629b9ff9136283ae331ad1fc95748a8 100644
+--- a/README.md
++++ b/README.md
+@@ -1,2 +1,2 @@
+ hello
+-world
++bug
+`,
+}, {
+ patch: testPatch{
+ message: "",
+ filePatches: []testFilePatch{{
+ from: &testFile{
+ mode: filemode.Regular,
path: "test.txt",
seed: "test",
},
diff --git a/plumbing/format/gitignore/pattern.go b/plumbing/format/gitignore/pattern.go
index 2603352..098cb50 100644
--- a/plumbing/format/gitignore/pattern.go
+++ b/plumbing/format/gitignore/pattern.go
@@ -133,6 +133,9 @@ func (p *pattern) globMatch(path []string, isDir bool) bool {
} else if match {
matched = true
break
+ } else if len(path) == 0 {
+ // if nothing left then fail
+ matched = false
}
}
} else {
diff --git a/plumbing/format/gitignore/pattern_test.go b/plumbing/format/gitignore/pattern_test.go
index f94cef3..c410442 100644
--- a/plumbing/format/gitignore/pattern_test.go
+++ b/plumbing/format/gitignore/pattern_test.go
@@ -281,3 +281,9 @@ func (s *PatternSuite) TestGlobMatch_wrongPattern_onTraversal_mismatch(c *C) {
r := p.Match([]string{"value", "head", "vol["}, false)
c.Assert(r, Equals, NoMatch)
}
+
+func (s *PatternSuite) TestGlobMatch_issue_923(c *C) {
+ p := ParsePattern("**/android/**/GeneratedPluginRegistrant.java", nil)
+ r := p.Match([]string{"packages", "flutter_tools", "lib", "src", "android", "gradle.dart"}, false)
+ c.Assert(r, Equals, NoMatch)
+}
diff --git a/plumbing/format/idxfile/idxfile.go b/plumbing/format/idxfile/idxfile.go
index c977bee..5fed278 100644
--- a/plumbing/format/idxfile/idxfile.go
+++ b/plumbing/format/idxfile/idxfile.go
@@ -3,6 +3,7 @@ package idxfile
import (
"bytes"
"io"
+ "sort"
"gopkg.in/src-d/go-git.v4/plumbing"
"gopkg.in/src-d/go-git.v4/utils/binary"
@@ -34,6 +35,9 @@ type Index interface {
Count() (int64, error)
// Entries returns an iterator to retrieve all index entries.
Entries() (EntryIter, error)
+ // EntriesByOffset returns an iterator to retrieve all index entries ordered
+ // by offset.
+ EntriesByOffset() (EntryIter, error)
}
// MemoryIndex is the in memory representation of an idx file.
@@ -215,6 +219,36 @@ func (idx *MemoryIndex) Entries() (EntryIter, error) {
return &idxfileEntryIter{idx, 0, 0, 0}, nil
}
+// EntriesByOffset implements the Index interface.
+func (idx *MemoryIndex) EntriesByOffset() (EntryIter, error) {
+ count, err := idx.Count()
+ if err != nil {
+ return nil, err
+ }
+
+ iter := &idxfileEntryOffsetIter{
+ entries: make(entriesByOffset, count),
+ }
+
+ entries, err := idx.Entries()
+ if err != nil {
+ return nil, err
+ }
+
+ for pos := 0; int64(pos) < count; pos++ {
+ entry, err := entries.Next()
+ if err != nil {
+ return nil, err
+ }
+
+ iter.entries[pos] = entry
+ }
+
+ sort.Sort(iter.entries)
+
+ return iter, nil
+}
+
// EntryIter is an iterator that will return the entries in a packfile index.
type EntryIter interface {
// Next returns the next entry in the packfile index.
@@ -276,3 +310,38 @@ type Entry struct {
CRC32 uint32
Offset uint64
}
+
+type idxfileEntryOffsetIter struct {
+ entries entriesByOffset
+ pos int
+}
+
+func (i *idxfileEntryOffsetIter) Next() (*Entry, error) {
+ if i.pos >= len(i.entries) {
+ return nil, io.EOF
+ }
+
+ entry := i.entries[i.pos]
+ i.pos++
+
+ return entry, nil
+}
+
+func (i *idxfileEntryOffsetIter) Close() error {
+ i.pos = len(i.entries) + 1
+ return nil
+}
+
+type entriesByOffset []*Entry
+
+func (o entriesByOffset) Len() int {
+ return len(o)
+}
+
+func (o entriesByOffset) Less(i int, j int) bool {
+ return o[i].Offset < o[j].Offset
+}
+
+func (o entriesByOffset) Swap(i int, j int) {
+ o[i], o[j] = o[j], o[i]
+}
diff --git a/plumbing/format/idxfile/idxfile_test.go b/plumbing/format/idxfile/idxfile_test.go
index d15accf..0e0ca2a 100644
--- a/plumbing/format/idxfile/idxfile_test.go
+++ b/plumbing/format/idxfile/idxfile_test.go
@@ -115,6 +115,21 @@ func (s *IndexSuite) TestFindHash(c *C) {
}
}
+func (s *IndexSuite) TestEntriesByOffset(c *C) {
+ idx, err := fixtureIndex()
+ c.Assert(err, IsNil)
+
+ entries, err := idx.EntriesByOffset()
+ c.Assert(err, IsNil)
+
+ for _, pos := range fixtureOffsets {
+ e, err := entries.Next()
+ c.Assert(err, IsNil)
+
+ c.Assert(e.Offset, Equals, uint64(pos))
+ }
+}
+
var fixtureHashes = []plumbing.Hash{
plumbing.NewHash("303953e5aa461c203a324821bc1717f9b4fff895"),
plumbing.NewHash("5296768e3d9f661387ccbff18c4dea6c997fd78c"),
diff --git a/plumbing/format/packfile/encoder_advanced_test.go b/plumbing/format/packfile/encoder_advanced_test.go
index fc1419e..e15126e 100644
--- a/plumbing/format/packfile/encoder_advanced_test.go
+++ b/plumbing/format/packfile/encoder_advanced_test.go
@@ -8,6 +8,7 @@ import (
"gopkg.in/src-d/go-billy.v4/memfs"
"gopkg.in/src-d/go-git.v4/plumbing"
+ "gopkg.in/src-d/go-git.v4/plumbing/cache"
"gopkg.in/src-d/go-git.v4/plumbing/format/idxfile"
. "gopkg.in/src-d/go-git.v4/plumbing/format/packfile"
"gopkg.in/src-d/go-git.v4/plumbing/storer"
@@ -32,8 +33,7 @@ func (s *EncoderAdvancedSuite) TestEncodeDecode(c *C) {
fixs = append(fixs, fixtures.ByURL("https://github.com/src-d/go-git.git").
ByTag("packfile").ByTag(".git").One())
fixs.Test(c, func(f *fixtures.Fixture) {
- storage, err := filesystem.NewStorage(f.DotGit())
- c.Assert(err, IsNil)
+ storage := filesystem.NewStorage(f.DotGit(), cache.NewObjectLRUDefault())
s.testEncodeDecode(c, storage, 10)
})
}
@@ -47,8 +47,7 @@ func (s *EncoderAdvancedSuite) TestEncodeDecodeNoDeltaCompression(c *C) {
fixs = append(fixs, fixtures.ByURL("https://github.com/src-d/go-git.git").
ByTag("packfile").ByTag(".git").One())
fixs.Test(c, func(f *fixtures.Fixture) {
- storage, err := filesystem.NewStorage(f.DotGit())
- c.Assert(err, IsNil)
+ storage := filesystem.NewStorage(f.DotGit(), cache.NewObjectLRUDefault())
s.testEncodeDecode(c, storage, 0)
})
}
diff --git a/plumbing/format/packfile/fsobject.go b/plumbing/format/packfile/fsobject.go
index 6fd3ca5..330cb73 100644
--- a/plumbing/format/packfile/fsobject.go
+++ b/plumbing/format/packfile/fsobject.go
@@ -47,6 +47,16 @@ func NewFSObject(
// Reader implements the plumbing.EncodedObject interface.
func (o *FSObject) Reader() (io.ReadCloser, error) {
+ obj, ok := o.cache.Get(o.hash)
+ if ok {
+ reader, err := obj.Reader()
+ if err != nil {
+ return nil, err
+ }
+
+ return reader, nil
+ }
+
f, err := o.fs.Open(o.path)
if err != nil {
return nil, err
diff --git a/plumbing/format/packfile/packfile.go b/plumbing/format/packfile/packfile.go
index 5feb781..852a834 100644
--- a/plumbing/format/packfile/packfile.go
+++ b/plumbing/format/packfile/packfile.go
@@ -258,6 +258,19 @@ func (p *Packfile) nextObject() (plumbing.EncodedObject, error) {
}
func (p *Packfile) getObjectContent(offset int64) (io.ReadCloser, error) {
+ ref, err := p.FindHash(offset)
+ if err == nil {
+ obj, ok := p.cacheGet(ref)
+ if ok {
+ reader, err := obj.Reader()
+ if err != nil {
+ return nil, err
+ }
+
+ return reader, nil
+ }
+ }
+
if _, err := p.s.SeekFromStart(offset); err != nil {
return nil, err
}
@@ -306,6 +319,8 @@ func (p *Packfile) fillRegularObjectContent(obj plumbing.EncodedObject) error {
}
_, _, err = p.s.NextObject(w)
+ p.cachePut(obj)
+
return err
}
@@ -394,7 +409,7 @@ func (p *Packfile) GetByType(typ plumbing.ObjectType) (storer.EncodedObjectIter,
plumbing.TreeObject,
plumbing.CommitObject,
plumbing.TagObject:
- entries, err := p.Entries()
+ entries, err := p.EntriesByOffset()
if err != nil {
return nil, err
}