github.com/purpleclay/gitz@v0.8.2-0.20240515052600-43f80eea2fe1/pull.go (about) 1 package git 2 3 import ( 4 "strings" 5 ) 6 7 // PullOption provides a way for setting specific options while pulling changes 8 // from the remote. Each supported option can customize how changes are pulled 9 // from the remote and integrated into the current repository (working directory) 10 type PullOption func(*pullOptions) 11 12 type pullOptions struct { 13 Config []string 14 fetchOptions 15 } 16 17 // WithPullConfig allows temporary git config to be set while pulling 18 // changes from the remote. Config set using this approach will override 19 // any config defined within existing git config files. Config must be 20 // provided as key value pairs, mismatched config will result in an 21 // [ErrMissingConfigValue] error. Any invalid paths will result in an 22 // [ErrInvalidConfigPath] error 23 func WithPullConfig(kv ...string) PullOption { 24 return func(opts *pullOptions) { 25 opts.Config = trim(kv...) 26 } 27 } 28 29 // WithFetchAll will fetch the latest changes from all tracked remotes 30 func WithFetchAll() PullOption { 31 return func(opts *pullOptions) { 32 opts.All = true 33 } 34 } 35 36 // WithFetchTags will fetch all tags from the remote into local tag 37 // references with the same name 38 func WithFetchTags() PullOption { 39 return func(opts *pullOptions) { 40 opts.Tags = true 41 } 42 } 43 44 // WithFetchDepthTo will limit the number of commits to be fetched from the 45 // remotes history. If fetching into a shallow clone of a repository, 46 // this can be used to shorten or deepen the existing history 47 func WithFetchDepthTo(depth int) PullOption { 48 return func(opts *pullOptions) { 49 opts.Depth = depth 50 } 51 } 52 53 // WithFetchForce will force the fetching of a remote branch into a local 54 // branch with a different name (or refspec). Default behavior within 55 // git prevents such an operation. Typically used in conjunction with 56 // the [WithFetchRefSpecs] option 57 func WithFetchForce() PullOption { 58 return func(opts *pullOptions) { 59 opts.Force = true 60 } 61 } 62 63 // WithFetchIgnoreTags disables local tracking of tags from the remote 64 func WithFetchIgnoreTags() PullOption { 65 return func(opts *pullOptions) { 66 opts.NoTags = true 67 } 68 } 69 70 // WithPullRefSpecs allows remote references to be cherry-picked and 71 // fetched into the current repository (working copy) during a pull. A 72 // reference (or refspec) can be as simple as a name, where git will 73 // automatically resolve any ambiguity, or as explicit as providing a 74 // source and destination for reference within the remote. Check out the 75 // official git documentation on how to write a more complex [refspec] 76 // [refspec]: https://git-scm.com/docs/git-pull#Documentation/git-pull.txt-ltrefspecgt 77 func WithPullRefSpecs(refs ...string) PullOption { 78 return func(opts *pullOptions) { 79 opts.RefSpecs = trim(refs...) 80 } 81 } 82 83 // Pull all changes from a remote repository and immediately update the current 84 // repository (working directory) with those changes. This ensures that your current 85 // repository keeps track of remote changes and stays in sync 86 func (c *Client) Pull(opts ...PullOption) (string, error) { 87 options := &pullOptions{} 88 for _, opt := range opts { 89 opt(options) 90 } 91 92 cfg, err := ToInlineConfig(options.Config...) 93 if err != nil { 94 return "", err 95 } 96 97 var buf strings.Builder 98 buf.WriteString("git") 99 100 if len(cfg) > 0 { 101 buf.WriteString(" ") 102 buf.WriteString(strings.Join(cfg, " ")) 103 } 104 105 buf.WriteString(" pull") 106 buf.WriteString(options.fetchOptions.String()) 107 return c.exec(buf.String()) 108 }