94ecd166e4
Progress bar output temporarily removed, some things still broken
122 lines
2.6 KiB
Go
122 lines
2.6 KiB
Go
package commands
|
|
|
|
import (
|
|
"os"
|
|
"os/exec"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/github/git-lfs/git"
|
|
"github.com/github/git-lfs/lfs"
|
|
"github.com/github/git-lfs/vendor/_nuts/github.com/rubyist/tracerx"
|
|
"github.com/github/git-lfs/vendor/_nuts/github.com/spf13/cobra"
|
|
)
|
|
|
|
var (
|
|
fetchCmd = &cobra.Command{
|
|
Use: "fetch",
|
|
Short: "fetch",
|
|
Run: fetchCommand,
|
|
}
|
|
)
|
|
|
|
func fetchCommand(cmd *cobra.Command, args []string) {
|
|
var ref string
|
|
var err error
|
|
|
|
if len(args) == 1 {
|
|
ref = args[0]
|
|
} else {
|
|
ref, err = git.CurrentRef()
|
|
if err != nil {
|
|
Panic(err, "Could not fetch")
|
|
}
|
|
}
|
|
|
|
pointers, err := lfs.ScanRefs(ref, "", nil)
|
|
if err != nil {
|
|
Panic(err, "Could not scan for Git LFS files")
|
|
}
|
|
|
|
q := lfs.NewDownloadQueue(lfs.Config.ConcurrentTransfers(), len(pointers))
|
|
|
|
for _, p := range pointers {
|
|
q.Add(lfs.NewDownloadable(p))
|
|
}
|
|
|
|
target, err := git.ResolveRef(ref)
|
|
if err != nil {
|
|
Panic(err, "Could not resolve git ref")
|
|
}
|
|
|
|
current, err := git.CurrentRef()
|
|
if err != nil {
|
|
Panic(err, "Could not fetch the current git ref")
|
|
}
|
|
|
|
var wait sync.WaitGroup
|
|
wait.Add(1)
|
|
|
|
if target == current {
|
|
// We just downloaded the files for the current ref, we can copy them into
|
|
// the working directory and update the git index. We're doing this in a
|
|
// goroutine so they can be copied as they come in, for efficiency.
|
|
watch := q.Watch()
|
|
|
|
go func() {
|
|
files := make(map[string]*lfs.WrappedPointer, len(pointers))
|
|
for _, pointer := range pointers {
|
|
files[pointer.Oid] = pointer
|
|
}
|
|
|
|
// Fire up the update-index command
|
|
cmd := exec.Command("git", "update-index", "-q", "--refresh", "--stdin")
|
|
stdin, err := cmd.StdinPipe()
|
|
if err != nil {
|
|
Panic(err, "Could not update the index")
|
|
}
|
|
|
|
if err := cmd.Start(); err != nil {
|
|
Panic(err, "Could not update the index")
|
|
}
|
|
|
|
// As files come in, write them to the wd and update the index
|
|
for oid := range watch {
|
|
pointer, ok := files[oid]
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
file, err := os.Create(pointer.Name)
|
|
if err != nil {
|
|
Panic(err, "Could not create working directory file")
|
|
}
|
|
|
|
if err := lfs.PointerSmudge(file, pointer.Pointer, pointer.Name, nil); err != nil {
|
|
Panic(err, "Could not write working directory file")
|
|
}
|
|
file.Close()
|
|
|
|
stdin.Write([]byte(pointer.Name + "\n"))
|
|
}
|
|
|
|
stdin.Close()
|
|
if err := cmd.Wait(); err != nil {
|
|
Panic(err, "Error updating the git index")
|
|
}
|
|
wait.Done()
|
|
}()
|
|
} else {
|
|
wait.Done()
|
|
}
|
|
|
|
processQueue := time.Now()
|
|
q.Wait()
|
|
tracerx.PerformanceSince("process queue", processQueue)
|
|
wait.Wait()
|
|
}
|
|
|
|
func init() {
|
|
RootCmd.AddCommand(fetchCmd)
|
|
}
|