diff options
-rw-r--r-- | plumbing/storer/object.go | 5 | ||||
-rw-r--r-- | plumbing/storer/object_test.go | 4 | ||||
-rw-r--r-- | repository.go | 26 | ||||
-rw-r--r-- | storage/filesystem/internal/dotgit/dotgit.go | 16 | ||||
-rw-r--r-- | storage/filesystem/object.go | 4 | ||||
-rw-r--r-- | storage/memory/storage.go | 4 |
6 files changed, 44 insertions, 15 deletions
diff --git a/plumbing/storer/object.go b/plumbing/storer/object.go index 29e0090..e5f98d7 100644 --- a/plumbing/storer/object.go +++ b/plumbing/storer/object.go @@ -55,8 +55,9 @@ type EncodedObjectStorer interface { // ObjectPacks returns hashes of object packs if the underlying // implementation has pack files. ObjectPacks() ([]plumbing.Hash, error) - // DeleteObjectPackAndIndex deletes an object pack and the corresponding index file if they exist. - DeleteObjectPackAndIndex(plumbing.Hash) error + // DeleteOldObjectPackAndIndex deletes an object pack and the corresponding index file if they exist. + // Deletion is only performed if the pack is older than the supplied time (or the time is zero). + DeleteOldObjectPackAndIndex(plumbing.Hash, time.Time) error } // DeltaObjectStorer is an EncodedObjectStorer that can return delta diff --git a/plumbing/storer/object_test.go b/plumbing/storer/object_test.go index 68e8e10..da0db81 100644 --- a/plumbing/storer/object_test.go +++ b/plumbing/storer/object_test.go @@ -165,3 +165,7 @@ func (o *MockObjectStorage) DeleteLooseObject(plumbing.Hash) error { func (o *MockObjectStorage) ObjectPacks() ([]plumbing.Hash, error) { return nil, nil } + +func (o *MockObjectStorage) DeleteOldObjectPackAndIndex(plumbing.Hash, time.Time) error { + return plumbing.ErrObjectNotFound +} diff --git a/repository.go b/repository.go index 51cd077..999cc6d 100644 --- a/repository.go +++ b/repository.go @@ -8,6 +8,7 @@ import ( "os" "path/filepath" "strings" + "time" "gopkg.in/src-d/go-git.v4/config" "gopkg.in/src-d/go-git.v4/internal/revision" @@ -1013,7 +1014,18 @@ func (r *Repository) ResolveRevision(rev plumbing.Revision) (*plumbing.Hash, err return &commit.Hash, nil } -func (r *Repository) RepackObjects() (err error) { +type RepackConfig struct { + // UseRefDeltas configures whether packfile encoder will use reference deltas. + // By default OFSDeltaObject is used. + UseRefDeltas bool + // PackWindow for packing objects. + PackWindow uint + // OnlyDeletePacksOlderThan if set to non-zero value + // selects only objects older than the time provided. + OnlyDeletePacksOlderThan time.Time +} + +func (r *Repository) RepackObjects(cfg *RepackConfig) (err error) { // Get the existing object packs. hs, err := r.Storer.ObjectPacks() if err != nil { @@ -1021,7 +1033,7 @@ func (r *Repository) RepackObjects() (err error) { } // Create a new pack. - nh, err := r.createNewObjectPack() + nh, err := r.createNewObjectPack(cfg) if err != nil { return err } @@ -1032,7 +1044,7 @@ func (r *Repository) RepackObjects() (err error) { if h == nh { continue } - err = r.Storer.DeleteObjectPackAndIndex(h) + err = r.Storer.DeleteOldObjectPackAndIndex(h, cfg.OnlyDeletePacksOlderThan) if err != nil { return err } @@ -1044,12 +1056,12 @@ func (r *Repository) RepackObjects() (err error) { // createNewObjectPack is a helper for RepackObjects taking care // of creating a new pack. It is used so the the PackfileWriter // deferred close has the right scope. -func (r *Repository) createNewObjectPack() (h plumbing.Hash, err error) { +func (r *Repository) createNewObjectPack(cfg *RepackConfig) (h plumbing.Hash, err error) { pfw, ok := r.Storer.(storer.PackfileWriter) if !ok { return h, fmt.Errorf("Repository storer is not a storer.PackfileWriter") } - wc, err := pfw.PackfileWriter(nil) + wc, err := pfw.PackfileWriter() if err != nil { return h, err } @@ -1066,8 +1078,8 @@ func (r *Repository) createNewObjectPack() (h plumbing.Hash, err error) { if err != nil { return h, err } - enc := packfile.NewEncoder(wc, r.Storer, false) - h, err = enc.Encode(objs, 10, nil) + enc := packfile.NewEncoder(wc, r.Storer, cfg.UseRefDeltas) + h, err = enc.Encode(objs, cfg.PackWindow) if err != nil { return h, err } diff --git a/storage/filesystem/internal/dotgit/dotgit.go b/storage/filesystem/internal/dotgit/dotgit.go index 09688c1..cd4f517 100644 --- a/storage/filesystem/internal/dotgit/dotgit.go +++ b/storage/filesystem/internal/dotgit/dotgit.go @@ -9,6 +9,7 @@ import ( stdioutil "io/ioutil" "os" "strings" + "time" "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/src-d/go-git.v4/utils/ioutil" @@ -193,8 +194,19 @@ func (d *DotGit) ObjectPackIdx(hash plumbing.Hash) (billy.File, error) { return d.objectPackOpen(hash, `idx`) } -func (d *DotGit) DeleteObjectPackAndIndex(hash plumbing.Hash) error { - err := d.fs.Remove(d.objectPackPath(hash, `pack`)) +func (d *DotGit) DeleteOldObjectPackAndIndex(hash plumbing.Hash, t time.Time) error { + path := d.objectPackPath(hash, `pack`) + if !t.IsZero() { + fi, err := d.fs.Stat(path) + if err != nil { + return err + } + // too new, skip deletion. + if !fi.ModTime().Before(t) { + return nil + } + } + err := d.fs.Remove(path) if err != nil { return err } diff --git a/storage/filesystem/object.go b/storage/filesystem/object.go index f235204..13b8ddb 100644 --- a/storage/filesystem/object.go +++ b/storage/filesystem/object.go @@ -508,6 +508,6 @@ func (s *ObjectStorage) ObjectPacks() ([]plumbing.Hash, error) { return s.dir.ObjectPacks() } -func (s *ObjectStorage) DeleteObjectPackAndIndex(h plumbing.Hash) error { - return s.dir.DeleteObjectPackAndIndex(h) +func (s *ObjectStorage) DeleteOldObjectPackAndIndex(h plumbing.Hash, t time.Time) error { + return s.dir.DeleteOldObjectPackAndIndex(h, t) } diff --git a/storage/memory/storage.go b/storage/memory/storage.go index 5049036..2d1a4b6 100644 --- a/storage/memory/storage.go +++ b/storage/memory/storage.go @@ -173,8 +173,8 @@ func (o *ObjectStorage) ForEachObjectHash(fun func(plumbing.Hash) error) error { func (o *ObjectStorage) ObjectPacks() ([]plumbing.Hash, error) { return nil, nil } -func (o *ObjectStorage) DeleteObjectPackAndIndex(plumbing.Hash) error { - return errNotSupported +func (o *ObjectStorage) DeleteOldObjectPackAndIndex(plumbing.Hash, time.Time) error { + return nil } var errNotSupported = fmt.Errorf("Not supported") |