2016-11-16 19:56:07 +00:00
|
|
|
package lfs
|
|
|
|
|
2016-11-17 16:42:56 +00:00
|
|
|
import "fmt"
|
|
|
|
|
|
|
|
// GitScanner scans objects in a Git repository for LFS pointers.
|
2016-11-16 19:56:07 +00:00
|
|
|
type GitScanner struct {
|
2016-11-16 23:05:03 +00:00
|
|
|
remote string
|
|
|
|
skippedRefs []string
|
2016-11-16 19:56:07 +00:00
|
|
|
}
|
|
|
|
|
2016-11-17 16:42:56 +00:00
|
|
|
// NewGitScanner initializes a *GitScanner for a Git repository in the current
|
|
|
|
// working directory.
|
2016-11-16 19:56:07 +00:00
|
|
|
func NewGitScanner() *GitScanner {
|
|
|
|
return &GitScanner{}
|
|
|
|
}
|
|
|
|
|
2016-11-17 16:42:56 +00:00
|
|
|
// RemoteForPush sets up this *GitScanner to scan for objects to push to the
|
|
|
|
// given remote. Needed for ScanLeftToRemote().
|
|
|
|
func (s *GitScanner) RemoteForPush(r string) {
|
2016-11-16 20:43:12 +00:00
|
|
|
s.remote = r
|
2016-11-16 23:05:03 +00:00
|
|
|
s.skippedRefs = calcSkippedRefs(r)
|
2016-11-16 20:43:12 +00:00
|
|
|
}
|
|
|
|
|
2016-11-17 16:42:56 +00:00
|
|
|
// ScanLeftToRemote scans through all commits starting at the given ref that the
|
|
|
|
// given remote does not have. See RemoteForPush().
|
2016-11-16 20:43:12 +00:00
|
|
|
func (s *GitScanner) ScanLeftToRemote(left string) (*PointerChannelWrapper, error) {
|
2016-11-17 16:42:56 +00:00
|
|
|
if len(s.remote) == 0 {
|
|
|
|
return nil, fmt.Errorf("Unable to scan starting at %q: no remote set.", left)
|
|
|
|
}
|
2016-11-16 20:51:36 +00:00
|
|
|
return scanRefsToChan(left, "", s.opts(ScanLeftToRemoteMode))
|
2016-11-16 20:43:12 +00:00
|
|
|
}
|
|
|
|
|
2016-11-17 16:42:56 +00:00
|
|
|
// ScanRefRange scans through all commits from the given left and right refs,
|
|
|
|
// including git objects that have been modified or deleted.
|
2016-11-16 20:33:51 +00:00
|
|
|
func (s *GitScanner) ScanRefRange(left, right string) (*PointerChannelWrapper, error) {
|
2016-11-16 20:43:12 +00:00
|
|
|
opts := s.opts(ScanRefsMode)
|
2016-11-16 20:33:51 +00:00
|
|
|
opts.SkipDeletedBlobs = false
|
2016-11-16 20:51:36 +00:00
|
|
|
return scanRefsToChan(left, right, opts)
|
2016-11-16 20:33:51 +00:00
|
|
|
}
|
|
|
|
|
2016-11-17 16:42:56 +00:00
|
|
|
// ScanRefWithDeleted scans through all objects in the given ref, including
|
|
|
|
// git objects that have been modified or deleted.
|
2016-11-16 20:33:51 +00:00
|
|
|
func (s *GitScanner) ScanRefWithDeleted(ref string) (*PointerChannelWrapper, error) {
|
|
|
|
return s.ScanRefRange(ref, "")
|
|
|
|
}
|
|
|
|
|
2016-11-17 16:42:56 +00:00
|
|
|
// ScanRef scans through all objects in the current ref, excluding git objects
|
|
|
|
// that have been modified or deleted before the ref.
|
2016-11-16 20:02:45 +00:00
|
|
|
func (s *GitScanner) ScanRef(ref string) (*PointerChannelWrapper, error) {
|
2016-11-16 20:43:12 +00:00
|
|
|
opts := s.opts(ScanRefsMode)
|
2016-11-16 20:02:45 +00:00
|
|
|
opts.SkipDeletedBlobs = true
|
2016-11-16 20:51:36 +00:00
|
|
|
return scanRefsToChan(ref, "", opts)
|
2016-11-16 20:02:45 +00:00
|
|
|
}
|
|
|
|
|
2016-11-17 16:42:56 +00:00
|
|
|
// ScanAll scans through all objects in the git repository.
|
2016-11-16 20:02:45 +00:00
|
|
|
func (s *GitScanner) ScanAll() (*PointerChannelWrapper, error) {
|
2016-11-16 20:43:12 +00:00
|
|
|
opts := s.opts(ScanAllMode)
|
2016-11-16 19:56:07 +00:00
|
|
|
opts.SkipDeletedBlobs = false
|
2016-11-16 20:51:36 +00:00
|
|
|
return scanRefsToChan("", "", opts)
|
2016-11-16 19:56:07 +00:00
|
|
|
}
|
2016-11-16 20:43:12 +00:00
|
|
|
|
|
|
|
func (s *GitScanner) opts(mode ScanningMode) *ScanRefsOptions {
|
2016-11-16 20:53:56 +00:00
|
|
|
opts := newScanRefsOptions()
|
2016-11-16 20:43:12 +00:00
|
|
|
opts.ScanMode = mode
|
2016-11-16 23:05:03 +00:00
|
|
|
opts.RemoteName = s.remote
|
|
|
|
opts.skippedRefs = s.skippedRefs
|
2016-11-16 20:43:12 +00:00
|
|
|
return opts
|
|
|
|
}
|