diff options
author | Máximo Cuadros <mcuadros@gmail.com> | 2017-12-01 00:45:11 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-01 00:45:11 +0100 |
commit | b0f6b4786b58b4add6e54d354311fc1084764b36 (patch) | |
tree | ebc3ad2f840da271aeac9cf33cc3912feb9f9e12 /prune.go | |
parent | 174fd8e5b2150dbd4cf522bb4a98fb9d79ebc6f4 (diff) | |
parent | d53264806f0d5ddef259f45f4490a19398a102ba (diff) | |
download | go-git-b0f6b4786b58b4add6e54d354311fc1084764b36.tar.gz |
Merge pull request #669 from keybase/strib/gh-gc
storage/repository: add new functions for garbage collection
Diffstat (limited to 'prune.go')
-rw-r--r-- | prune.go | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/prune.go b/prune.go new file mode 100644 index 0000000..04913d6 --- /dev/null +++ b/prune.go @@ -0,0 +1,66 @@ +package git + +import ( + "errors" + "time" + + "gopkg.in/src-d/go-git.v4/plumbing" + "gopkg.in/src-d/go-git.v4/plumbing/storer" +) + +type PruneHandler func(unreferencedObjectHash plumbing.Hash) error +type PruneOptions struct { + // OnlyObjectsOlderThan if set to non-zero value + // selects only objects older than the time provided. + OnlyObjectsOlderThan time.Time + // Handler is called on matching objects + Handler PruneHandler +} + +var ErrLooseObjectsNotSupported = errors.New("Loose objects not supported") + +// DeleteObject deletes an object from a repository. +// The type conveniently matches PruneHandler. +func (r *Repository) DeleteObject(hash plumbing.Hash) error { + los, ok := r.Storer.(storer.LooseObjectStorer) + if !ok { + return ErrLooseObjectsNotSupported + } + + return los.DeleteLooseObject(hash) +} + +func (r *Repository) Prune(opt PruneOptions) error { + los, ok := r.Storer.(storer.LooseObjectStorer) + if !ok { + return ErrLooseObjectsNotSupported + } + + pw := newObjectWalker(r.Storer) + err := pw.walkAllRefs() + if err != nil { + return err + } + // Now walk all (loose) objects in storage. + return los.ForEachObjectHash(func(hash plumbing.Hash) error { + // Get out if we have seen this object. + if pw.isSeen(hash) { + return nil + } + // Otherwise it is a candidate for pruning. + // Check out for too new objects next. + if opt.OnlyObjectsOlderThan != (time.Time{}) { + // Errors here are non-fatal. The object may be e.g. packed. + // Or concurrently deleted. Skip such objects. + t, err := los.LooseObjectTime(hash) + if err != nil { + return nil + } + // Skip too new objects. + if !t.Before(opt.OnlyObjectsOlderThan) { + return nil + } + } + return opt.Handler(hash) + }) +} |