func pullCommand(cmd *cobra.Command, args []string) { requireInRepo() if len(args) > 0 { // Remote is first arg if err := git.ValidateRemote(args[0]); err != nil { Panic(err, fmt.Sprintf("Invalid remote name '%v'", args[0])) } lfs.Config.CurrentRemote = args[0] } else { // Actively find the default remote, don't just assume origin defaultRemote, err := git.DefaultRemote() if err != nil { Panic(err, "No default remote") } lfs.Config.CurrentRemote = defaultRemote } ref, err := git.CurrentRef() if err != nil { Panic(err, "Could not pull") } includePaths, excludePaths := determineIncludeExcludePaths(pullIncludeArg, pullExcludeArg) c := fetchRefToChan(ref.Sha, includePaths, excludePaths) checkoutFromFetchChan(includePaths, excludePaths, c) }
func pullCommand(cmd *cobra.Command, args []string) { requireInRepo() if len(args) > 0 { // Remote is first arg if err := git.ValidateRemote(args[0]); err != nil { Panic(err, fmt.Sprintf("Invalid remote name '%v'", args[0])) } config.Config.CurrentRemote = args[0] } else { // Actively find the default remote, don't just assume origin defaultRemote, err := git.DefaultRemote() if err != nil { Panic(err, "No default remote") } config.Config.CurrentRemote = defaultRemote } pull(determineIncludeExcludePaths(config.Config, pullIncludeArg, pullExcludeArg)) }
func fetchCommand(cmd *cobra.Command, args []string) { requireInRepo() var refs []*git.Ref if len(args) > 0 { // Remote is first arg if err := git.ValidateRemote(args[0]); err != nil { Exit("Invalid remote name %q", args[0]) } lfs.Config.CurrentRemote = args[0] } else { // Actively find the default remote, don't just assume origin defaultRemote, err := git.DefaultRemote() if err != nil { Exit("No default remote") } lfs.Config.CurrentRemote = defaultRemote } if len(args) > 1 { for _, r := range args[1:] { ref, err := git.ResolveRef(r) if err != nil { Panic(err, "Invalid ref argument") } refs = append(refs, ref) } } else { ref, err := git.CurrentRef() if err != nil { Panic(err, "Could not fetch") } refs = []*git.Ref{ref} } success := true if fetchAllArg { if fetchRecentArg || len(args) > 1 { Exit("Cannot combine --all with ref arguments or --recent") } if fetchIncludeArg != "" || fetchExcludeArg != "" { Exit("Cannot combine --all with --include or --exclude") } if len(lfs.Config.FetchIncludePaths()) > 0 || len(lfs.Config.FetchExcludePaths()) > 0 { Print("Ignoring global include / exclude paths to fulfil --all") } success = fetchAll() } else { // !all includePaths, excludePaths := determineIncludeExcludePaths(fetchIncludeArg, fetchExcludeArg) // Fetch refs sequentially per arg order; duplicates in later refs will be ignored for _, ref := range refs { Print("Fetching %v", ref.Name) s := fetchRef(ref.Sha, includePaths, excludePaths) success = success && s } if fetchRecentArg || lfs.Config.FetchPruneConfig().FetchRecentAlways { s := fetchRecent(refs, includePaths, excludePaths) success = success && s } } if fetchPruneArg { verify := lfs.Config.FetchPruneConfig().PruneVerifyRemoteAlways // no dry-run or verbose options in fetch, assume false prune(verify, false, false) } if !success { Exit("Warning: errors occurred") } }
// Fetch and report completion of each OID to a channel (optional, pass nil to skip) // Returns true if all completed with no errors, false if errors were written to stderr/log func fetchAndReportToChan(allpointers []*lfs.WrappedPointer, include, exclude []string, out chan<- *lfs.WrappedPointer) bool { // Lazily initialize the current remote. if len(cfg.CurrentRemote) == 0 { // Actively find the default remote, don't just assume origin defaultRemote, err := git.DefaultRemote() if err != nil { Exit("No default remote") } cfg.CurrentRemote = defaultRemote } ready, pointers, totalSize := readyAndMissingPointers(allpointers, include, exclude) q := lfs.NewDownloadQueue(len(pointers), totalSize, false) if out != nil { // If we already have it, or it won't be fetched // report it to chan immediately to support pull/checkout for _, p := range ready { out <- p } dlwatch := q.Watch() go func() { // fetch only reports single OID, but OID *might* be referenced by multiple // WrappedPointers if same content is at multiple paths, so map oid->slice oidToPointers := make(map[string][]*lfs.WrappedPointer, len(pointers)) for _, pointer := range pointers { plist := oidToPointers[pointer.Oid] oidToPointers[pointer.Oid] = append(plist, pointer) } for oid := range dlwatch { plist, ok := oidToPointers[oid] if !ok { continue } for _, p := range plist { out <- p } } close(out) }() } for _, p := range pointers { tracerx.Printf("fetch %v [%v]", p.Name, p.Oid) q.Add(lfs.NewDownloadable(p)) } processQueue := time.Now() q.Wait() tracerx.PerformanceSince("process queue", processQueue) ok := true for _, err := range q.Errors() { ok = false FullError(err) } return ok }