aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--options.go2
-rw-r--r--plumbing/cache/object_lru.go5
-rw-r--r--plumbing/cache/object_test.go15
-rw-r--r--remote.go9
-rw-r--r--remote_test.go9
-rw-r--r--worktree_status.go6
-rw-r--r--worktree_test.go28
7 files changed, 70 insertions, 4 deletions
diff --git a/options.go b/options.go
index f5a46ec..7c9e687 100644
--- a/options.go
+++ b/options.go
@@ -229,7 +229,7 @@ var (
ErrCreateRequiresBranch = errors.New("Branch is mandatory when Create is used")
)
-// CheckoutOptions describes how a checkout 31operation should be performed.
+// CheckoutOptions describes how a checkout operation should be performed.
type CheckoutOptions struct {
// Hash is the hash of the commit to be checked out. If used, HEAD will be
// in detached mode. If Create is not used, Branch and Hash are mutually
diff --git a/plumbing/cache/object_lru.go b/plumbing/cache/object_lru.go
index 53d8b02..cd3712b 100644
--- a/plumbing/cache/object_lru.go
+++ b/plumbing/cache/object_lru.go
@@ -61,6 +61,11 @@ func (c *ObjectLRU) Put(obj plumbing.EncodedObject) {
c.actualSize += objSize
for c.actualSize > c.MaxSize {
last := c.ll.Back()
+ if last == nil {
+ c.actualSize = 0
+ break
+ }
+
lastObj := last.Value.(plumbing.EncodedObject)
lastSize := FileSize(lastObj.Size())
diff --git a/plumbing/cache/object_test.go b/plumbing/cache/object_test.go
index b3e5f79..2e8fa7b 100644
--- a/plumbing/cache/object_test.go
+++ b/plumbing/cache/object_test.go
@@ -153,6 +153,19 @@ func (s *ObjectSuite) TestDefaultLRU(c *C) {
c.Assert(defaultLRU.MaxSize, Equals, DefaultMaxSize)
}
+func (s *ObjectSuite) TestObjectUpdateOverflow(c *C) {
+ o := NewObjectLRU(9 * Byte)
+
+ a1 := newObject(s.aObject.Hash().String(), 9*Byte)
+ a2 := newObject(s.aObject.Hash().String(), 1*Byte)
+ b := newObject(s.bObject.Hash().String(), 1*Byte)
+
+ o.Put(a1)
+ a1.SetSize(-5)
+ o.Put(a2)
+ o.Put(b)
+}
+
type dummyObject struct {
hash plumbing.Hash
size FileSize
@@ -169,6 +182,6 @@ func (d *dummyObject) Hash() plumbing.Hash { return d.hash }
func (*dummyObject) Type() plumbing.ObjectType { return plumbing.InvalidObject }
func (*dummyObject) SetType(plumbing.ObjectType) {}
func (d *dummyObject) Size() int64 { return int64(d.size) }
-func (*dummyObject) SetSize(s int64) {}
+func (d *dummyObject) SetSize(s int64) { d.size = FileSize(s) }
func (*dummyObject) Reader() (io.ReadCloser, error) { return nil, nil }
func (*dummyObject) Writer() (io.WriteCloser, error) { return nil, nil }
diff --git a/remote.go b/remote.go
index de537ce..8060409 100644
--- a/remote.go
+++ b/remote.go
@@ -1020,7 +1020,12 @@ func pushHashes(
if err != nil {
return nil, err
}
- done := make(chan error)
+
+ // Set buffer size to 1 so the error message can be written when
+ // ReceivePack fails. Otherwise the goroutine will be blocked writing
+ // to the channel.
+ done := make(chan error, 1)
+
go func() {
e := packfile.NewEncoder(wr, s, useRefDeltas)
if _, err := e.Encode(hs, config.Pack.Window); err != nil {
@@ -1033,6 +1038,8 @@ func pushHashes(
rs, err := sess.ReceivePack(ctx, req)
if err != nil {
+ // close the pipe to unlock encode write
+ _ = rd.Close()
return nil, err
}
diff --git a/remote_test.go b/remote_test.go
index 28b0a3a..58a0598 100644
--- a/remote_test.go
+++ b/remote_test.go
@@ -6,6 +6,8 @@ import (
"io"
"io/ioutil"
"os"
+ "runtime"
+ "time"
"gopkg.in/src-d/go-git.v4/config"
"gopkg.in/src-d/go-git.v4/plumbing"
@@ -448,10 +450,17 @@ func (s *RemoteSuite) TestPushContext(c *C) {
ctx, cancel := context.WithCancel(context.Background())
cancel()
+ numGoroutines := runtime.NumGoroutine()
+
err = r.PushContext(ctx, &PushOptions{
RefSpecs: []config.RefSpec{"refs/tags/*:refs/tags/*"},
})
c.Assert(err, NotNil)
+
+ // let the goroutine from pushHashes finish and check that the number of
+ // goroutines is the same as before
+ time.Sleep(100 * time.Millisecond)
+ c.Assert(runtime.NumGoroutine(), Equals, numGoroutines)
}
func (s *RemoteSuite) TestPushTags(c *C) {
diff --git a/worktree_status.go b/worktree_status.go
index 0e113d0..16ce937 100644
--- a/worktree_status.go
+++ b/worktree_status.go
@@ -142,12 +142,16 @@ func (w *Worktree) diffStagingWithWorktree(reverse bool) (merkletrie.Changes, er
func (w *Worktree) excludeIgnoredChanges(changes merkletrie.Changes) merkletrie.Changes {
patterns, err := gitignore.ReadPatterns(w.Filesystem, nil)
- if err != nil || len(patterns) == 0 {
+ if err != nil {
return changes
}
patterns = append(patterns, w.Excludes...)
+ if len(patterns) == 0 {
+ return changes
+ }
+
m := gitignore.NewMatcher(patterns)
var res merkletrie.Changes
diff --git a/worktree_test.go b/worktree_test.go
index 872cd82..afedc91 100644
--- a/worktree_test.go
+++ b/worktree_test.go
@@ -1129,6 +1129,34 @@ func (s *WorktreeSuite) TestIgnored(c *C) {
c.Assert(file.Worktree, Equals, Untracked)
}
+func (s *WorktreeSuite) TestExcludedNoGitignore(c *C) {
+ f := fixtures.ByTag("empty").One()
+ r := s.NewRepository(f)
+
+ fs := memfs.New()
+ w := &Worktree{
+ r: r,
+ Filesystem: fs,
+ }
+
+ _, err := fs.Open(".gitignore")
+ c.Assert(err, Equals, os.ErrNotExist)
+
+ w.Excludes = make([]gitignore.Pattern, 0)
+ w.Excludes = append(w.Excludes, gitignore.ParsePattern("foo", nil))
+
+ err = util.WriteFile(w.Filesystem, "foo", []byte("FOO"), 0755)
+ c.Assert(err, IsNil)
+
+ status, err := w.Status()
+ c.Assert(err, IsNil)
+ c.Assert(status, HasLen, 0)
+
+ file := status.File("foo")
+ c.Assert(file.Staging, Equals, Untracked)
+ c.Assert(file.Worktree, Equals, Untracked)
+}
+
func (s *WorktreeSuite) TestAddModified(c *C) {
fs := memfs.New()
w := &Worktree{