aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Stribling <strib@alum.mit.edu>2017-11-29 14:52:01 -0800
committerJeremy Stribling <strib@alum.mit.edu>2017-11-29 16:04:09 -0800
commit88acc31c76a3033a4d02e0d6cc751c74b9aeeea5 (patch)
treea2ae4d5027f28f26e46f2ae0e8c5a74ab37eaee4
parent4c1569511db5e1d26e42e9cd8dadb9e65ccafb20 (diff)
downloadgo-git-88acc31c76a3033a4d02e0d6cc751c74b9aeeea5.tar.gz
repository: add tests for pruning and object re-packing
Also, object re-packing should clean up any loose objects that were packed.
-rw-r--r--prune_test.go72
-rw-r--r--repository.go17
-rw-r--r--repository_test.go61
3 files changed, 150 insertions, 0 deletions
diff --git a/prune_test.go b/prune_test.go
new file mode 100644
index 0000000..613fb0f
--- /dev/null
+++ b/prune_test.go
@@ -0,0 +1,72 @@
+package git
+
+import (
+ "time"
+
+ "gopkg.in/src-d/go-git.v4/plumbing"
+ "gopkg.in/src-d/go-git.v4/plumbing/storer"
+ "gopkg.in/src-d/go-git.v4/storage"
+ "gopkg.in/src-d/go-git.v4/storage/filesystem"
+
+ . "gopkg.in/check.v1"
+ "gopkg.in/src-d/go-git-fixtures.v3"
+)
+
+type PruneSuite struct {
+ BaseSuite
+}
+
+var _ = Suite(&PruneSuite{})
+
+func (s *PruneSuite) TestPrune(c *C, deleteTime time.Time) {
+ srcFs := fixtures.ByTag("unpacked").One().DotGit()
+ var sto storage.Storer
+ var err error
+ sto, err = filesystem.NewStorage(srcFs)
+ c.Assert(err, IsNil)
+
+ los := sto.(storer.LooseObjectStorer)
+ c.Assert(los, NotNil)
+
+ count := 0
+ err = los.ForEachObjectHash(func(_ plumbing.Hash) error {
+ count++
+ return nil
+ })
+ c.Assert(err, IsNil)
+
+ r, err := Open(sto, srcFs)
+ c.Assert(err, IsNil)
+ c.Assert(r, NotNil)
+
+ // Remove a branch so we can prune some objects.
+ err = sto.RemoveReference(plumbing.ReferenceName("refs/heads/v4"))
+ c.Assert(err, IsNil)
+ err = sto.RemoveReference(plumbing.ReferenceName("refs/remotes/origin/v4"))
+ c.Assert(err, IsNil)
+
+ err = r.Prune(PruneOptions{
+ Handler: r.DeleteObject,
+ })
+ c.Assert(err, IsNil)
+
+ newCount := 0
+ err = los.ForEachObjectHash(func(_ plumbing.Hash) error {
+ newCount++
+ return nil
+ })
+ if deleteTime.IsZero() {
+ c.Assert(newCount < count, Equals, true)
+ } else {
+ // Assume a delete time older than any of the objects was passed in.
+ c.Assert(newCount, Equals, count)
+ }
+}
+
+func (s *PruneSuite) TestPrune(c *C) {
+ s.testPrune(c, time.Time{})
+}
+
+func (s *PruneSuite) TestPruneWithNoDelete(c *C) {
+ s.testPrune(c, time.Unix(0, 1))
+}
diff --git a/repository.go b/repository.go
index d7cca89..7cdc0d5 100644
--- a/repository.go
+++ b/repository.go
@@ -1088,5 +1088,22 @@ func (r *Repository) createNewObjectPack(cfg *RepackConfig) (h plumbing.Hash, er
if err != nil {
return h, err
}
+
+ // Delete the packed, loose objects.
+ if los, ok := r.Storer.(storer.LooseObjectStorer); ok {
+ err = los.ForEachObjectHash(func(hash plumbing.Hash) error {
+ if ow.isSeen(hash) {
+ err := los.DeleteLooseObject(hash)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+ })
+ if err != nil {
+ return h, err
+ }
+ }
+
return h, err
}
diff --git a/repository_test.go b/repository_test.go
index 9d82651..2ebc597 100644
--- a/repository_test.go
+++ b/repository_test.go
@@ -10,10 +10,13 @@ import (
"os/exec"
"path/filepath"
"strings"
+ "time"
"gopkg.in/src-d/go-git.v4/config"
"gopkg.in/src-d/go-git.v4/plumbing"
"gopkg.in/src-d/go-git.v4/plumbing/object"
+ "gopkg.in/src-d/go-git.v4/plumbing/storer"
+ "gopkg.in/src-d/go-git.v4/storage"
"gopkg.in/src-d/go-git.v4/storage/filesystem"
"gopkg.in/src-d/go-git.v4/storage/memory"
@@ -1313,6 +1316,64 @@ func (s *RepositorySuite) TestResolveRevisionWithErrors(c *C) {
}
}
+func (s *RepositorySuite) testRepackObjects(
+ c *C, deleteTime time.Time, expectedPacks int) {
+ srcFs := fixtures.ByTag("unpacked").One().DotGit()
+ var sto storage.Storer
+ var err error
+ sto, err = filesystem.NewStorage(srcFs)
+ c.Assert(err, IsNil)
+
+ los := sto.(storer.LooseObjectStorer)
+ c.Assert(los, NotNil)
+
+ numLooseStart := 0
+ err = los.ForEachObjectHash(func(_ plumbing.Hash) error {
+ numLooseStart++
+ return nil
+ })
+ c.Assert(err, IsNil)
+ c.Assert(numLooseStart > 0, Equals, true)
+
+ pos := sto.(storer.PackedObjectStorer)
+ c.Assert(los, NotNil)
+
+ packs, err := pos.ObjectPacks()
+ c.Assert(err, IsNil)
+ numPacksStart := len(packs)
+ c.Assert(numPacksStart > 1, Equals, true)
+
+ r, err := Open(sto, srcFs)
+ c.Assert(err, IsNil)
+ c.Assert(r, NotNil)
+
+ err = r.RepackObjects(&RepackConfig{
+ OnlyDeletePacksOlderThan: deleteTime,
+ })
+ c.Assert(err, IsNil)
+
+ numLooseEnd := 0
+ err = los.ForEachObjectHash(func(_ plumbing.Hash) error {
+ numLooseEnd++
+ return nil
+ })
+ c.Assert(err, IsNil)
+ c.Assert(numLooseEnd, Equals, 0)
+
+ packs, err = pos.ObjectPacks()
+ c.Assert(err, IsNil)
+ numPacksEnd := len(packs)
+ c.Assert(numPacksEnd, Equals, expectedPacks)
+}
+
+func (s *RepositorySuite) TestRepackObjects(c *C) {
+ s.testRepackObjects(c, time.Time{}, 1)
+}
+
+func (s *RepositorySuite) TestRepackObjectsWithNoDelete(c *C) {
+ s.testRepackObjects(c, time.Unix(0, 1), 3)
+}
+
func ExecuteOnPath(c *C, path string, cmds ...string) error {
for _, cmd := range cmds {
err := executeOnPath(path, cmd)