diff options
-rw-r--r-- | prune_test.go | 72 | ||||
-rw-r--r-- | repository.go | 17 | ||||
-rw-r--r-- | repository_test.go | 61 |
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) |