github.com/driusan/dgit@v0.0.0-20221118233547-f39f0c15edbb/git/fetch.go (about) 1 package git 2 3 import ( 4 "fmt" 5 "log" 6 ) 7 8 type FetchOptions struct { 9 Force bool 10 FetchPackOptions 11 } 12 13 // Fetch implements the "git fetch" command, fetching refs from rmt. 14 // If refs is nil, all remote refs will be fetched from the remote. 15 func Fetch(c *Client, opts FetchOptions, rmt Remote, refs []RefSpec) error { 16 opts.FetchPackOptions.All = (refs == nil) 17 opts.FetchPackOptions.Verbose = true 18 19 // If none were provided then we check to see if there are any 20 // configured refspecs for this remote 21 if refs == nil { 22 // FIXME this only handles one value for the configuration while there can be many with different refspecs for this operation 23 cfg := c.GetConfig(fmt.Sprintf("remote.%s.fetch", rmt)) 24 if cfg != "" { 25 refs = []RefSpec{RefSpec(cfg)} 26 } 27 } 28 29 var wants []Refname 30 for _, ref := range refs { 31 wants = append(wants, ref.Src()) 32 } 33 newrefs, err := FetchPack(c, opts.FetchPackOptions, rmt, wants) 34 if err != nil { 35 if err.Error() == "Already up to date." { 36 return nil 37 } 38 return err 39 } 40 if refs == nil { 41 // Fake a refspec if one wasn't specified so that things to 42 // to the default location under refs. 43 refs = append( 44 refs, 45 RefSpec(fmt.Sprintf("refs/heads/*:refs/remotes/%s/*", rmt)), 46 ) 47 } 48 log.Printf("fetch: refspecs are %+v\n", refs) 49 if c.GitDir != "" { 50 log.Printf("fetch: newrefs is %+v\n", newrefs) 51 for _, ref := range newrefs { 52 for _, spec := range refs { 53 if match, dst := ref.MatchesRefSpecSrc(spec); match { 54 if !dst.Exists(c) { 55 fmt.Printf("[new branch] %v", dst) 56 } else { 57 fmt.Printf("%v %v", ref.Value, dst) 58 } 59 err := UpdateRef( 60 c, 61 UpdateRefOptions{NoDeref: true}, 62 string(dst), 63 CommitID(ref.Value), 64 "Ref updated by fetch", 65 ) 66 if err != nil { 67 // FIXME: I don't think we should be 68 // erroring out here. 69 return err 70 } 71 } 72 } 73 } 74 } 75 return nil 76 }