extracts skipped ref calculation
This commit is contained in:
parent
3c9be7da75
commit
40cac1ee4a
@ -1,7 +1,8 @@
|
||||
package lfs
|
||||
|
||||
type GitScanner struct {
|
||||
remote string
|
||||
remote string
|
||||
skippedRefs []string
|
||||
}
|
||||
|
||||
func NewGitScanner() *GitScanner {
|
||||
@ -10,6 +11,7 @@ func NewGitScanner() *GitScanner {
|
||||
|
||||
func (s *GitScanner) Remote(r string) {
|
||||
s.remote = r
|
||||
s.skippedRefs = calcSkippedRefs(r)
|
||||
}
|
||||
|
||||
func (s *GitScanner) ScanLeftToRemote(left string) (*PointerChannelWrapper, error) {
|
||||
@ -41,8 +43,7 @@ func (s *GitScanner) ScanAll() (*PointerChannelWrapper, error) {
|
||||
func (s *GitScanner) opts(mode ScanningMode) *ScanRefsOptions {
|
||||
opts := newScanRefsOptions()
|
||||
opts.ScanMode = mode
|
||||
if len(s.remote) > 0 {
|
||||
opts.RemoteName = s.remote
|
||||
}
|
||||
opts.RemoteName = s.remote
|
||||
opts.skippedRefs = s.skippedRefs
|
||||
return opts
|
||||
}
|
||||
|
46
lfs/gitscanner_remotes.go
Normal file
46
lfs/gitscanner_remotes.go
Normal file
@ -0,0 +1,46 @@
|
||||
package lfs
|
||||
|
||||
import (
|
||||
"github.com/git-lfs/git-lfs/git"
|
||||
"github.com/git-lfs/git-lfs/tools"
|
||||
)
|
||||
|
||||
// calcSkippedRefs checks that locally cached versions of remote refs are still
|
||||
// present on the remote before they are used as a 'from' point. If the server
|
||||
// implements garbage collection and a remote branch had been deleted since we
|
||||
// last did 'git fetch --prune', then the objects in that branch may have also
|
||||
// been deleted on the server if unreferenced. If some refs are missing on the
|
||||
// remote, use a more explicit diff command.
|
||||
func calcSkippedRefs(remote string) []string {
|
||||
cachedRemoteRefs, _ := git.CachedRemoteRefs(remote)
|
||||
actualRemoteRefs, _ := git.RemoteRefs(remote)
|
||||
|
||||
// Only check for missing refs on remote; if the ref is different it has moved
|
||||
// forward probably, and if not and the ref has changed to a non-descendant
|
||||
// (force push) then that will cause a re-evaluation in a subsequent command.
|
||||
missingRefs := tools.NewStringSet()
|
||||
for _, cachedRef := range cachedRemoteRefs {
|
||||
found := false
|
||||
for _, realRemoteRef := range actualRemoteRefs {
|
||||
if cachedRef.Type == realRemoteRef.Type && cachedRef.Name == realRemoteRef.Name {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
missingRefs.Add(cachedRef.Name)
|
||||
}
|
||||
}
|
||||
|
||||
if len(missingRefs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
skippedRefs := make([]string, 0, len(cachedRemoteRefs)-missingRefs.Cardinality())
|
||||
for _, cachedRef := range cachedRemoteRefs {
|
||||
if !missingRefs.Contains(cachedRef.Name) {
|
||||
skippedRefs = append(skippedRefs, "^"+cachedRef.Sha)
|
||||
}
|
||||
}
|
||||
return skippedRefs
|
||||
}
|
@ -78,6 +78,7 @@ type ScanRefsOptions struct {
|
||||
ScanMode ScanningMode
|
||||
RemoteName string
|
||||
SkipDeletedBlobs bool
|
||||
skippedRefs []string
|
||||
nameMap map[string]string
|
||||
mutex *sync.Mutex
|
||||
}
|
||||
@ -273,52 +274,20 @@ func ScanIndex(ref string) ([]*WrappedPointer, error) {
|
||||
}
|
||||
|
||||
// Get additional arguments needed to limit 'git rev-list' to just the changes
|
||||
// in revTo that are also not on remoteName.
|
||||
// in refTo that are also not on remoteName.
|
||||
//
|
||||
// Returns a slice of string command arguments, and a slice of string git
|
||||
// commits to pass to `git rev-list` via STDIN.
|
||||
func revListArgsRefVsRemote(refTo, remoteName string) ([]string, []string) {
|
||||
// We need to check that the locally cached versions of remote refs are still
|
||||
// present on the remote before we use them as a 'from' point. If the
|
||||
// server implements garbage collection and a remote branch had been deleted
|
||||
// since we last did 'git fetch --prune', then the objects in that branch may
|
||||
// have also been deleted on the server if unreferenced.
|
||||
// If some refs are missing on the remote, use a more explicit diff
|
||||
|
||||
cachedRemoteRefs, _ := git.CachedRemoteRefs(remoteName)
|
||||
actualRemoteRefs, _ := git.RemoteRefs(remoteName)
|
||||
|
||||
// Only check for missing refs on remote; if the ref is different it has moved
|
||||
// forward probably, and if not and the ref has changed to a non-descendant
|
||||
// (force push) then that will cause a re-evaluation in a subsequent command anyway
|
||||
missingRefs := tools.NewStringSet()
|
||||
for _, cachedRef := range cachedRemoteRefs {
|
||||
found := false
|
||||
for _, realRemoteRef := range actualRemoteRefs {
|
||||
if cachedRef.Type == realRemoteRef.Type && cachedRef.Name == realRemoteRef.Name {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
missingRefs.Add(cachedRef.Name)
|
||||
}
|
||||
}
|
||||
|
||||
if len(missingRefs) > 0 {
|
||||
// Use only the non-missing refs as 'from' points
|
||||
commits := make([]string, 1, len(cachedRemoteRefs)+1)
|
||||
commits[0] = refTo
|
||||
for _, cachedRef := range cachedRemoteRefs {
|
||||
if !missingRefs.Contains(cachedRef.Name) {
|
||||
commits = append(commits, "^"+cachedRef.Sha)
|
||||
}
|
||||
}
|
||||
return []string{"--stdin"}, commits
|
||||
} else {
|
||||
func revListArgsRefVsRemote(refTo, remoteName string, skippedRefs []string) ([]string, []string) {
|
||||
if len(skippedRefs) < 1 {
|
||||
// Safe to use cached
|
||||
return []string{refTo, "--not", "--remotes=" + remoteName}, nil
|
||||
}
|
||||
|
||||
// Use only the non-missing refs as 'from' points
|
||||
commits := make([]string, 1, len(skippedRefs)+1)
|
||||
commits[0] = refTo
|
||||
return []string{"--stdin"}, append(commits, skippedRefs...)
|
||||
}
|
||||
|
||||
// revListShas uses git rev-list to return the list of object sha1s
|
||||
@ -342,7 +311,7 @@ func revListShas(refLeft, refRight string, opt *ScanRefsOptions) (*StringChannel
|
||||
case ScanAllMode:
|
||||
refArgs = append(refArgs, "--all")
|
||||
case ScanLeftToRemoteMode:
|
||||
args, commits := revListArgsRefVsRemote(refLeft, opt.RemoteName)
|
||||
args, commits := revListArgsRefVsRemote(refLeft, opt.RemoteName, opt.skippedRefs)
|
||||
refArgs = append(refArgs, args...)
|
||||
if len(commits) > 0 {
|
||||
stdin = commits
|
||||
|
Loading…
Reference in New Issue
Block a user