github.com/purpleclay/gitz@v0.8.2-0.20240515052600-43f80eea2fe1/checkout.go (about) 1 package git 2 3 import ( 4 "strings" 5 ) 6 7 // CheckoutOption provides a way for setting specific options while attempting 8 // to checkout a branch. Each supported option can customize how a branch is checked 9 // out from the remote and integrated into the current repository (working directory) 10 type CheckoutOption func(*checkoutOptions) 11 12 type checkoutOptions struct { 13 Config []string 14 } 15 16 // WithCheckoutConfig allows temporary git config to be set while checking 17 // out a branch from the remote. Config set using this approach will override 18 // any config defined within existing git config files. Config must be 19 // provided as key value pairs, mismatched config will result in an 20 // [ErrMissingConfigValue] error. Any invalid paths will result in an 21 // [ErrInvalidConfigPath] error 22 func WithCheckoutConfig(kv ...string) CheckoutOption { 23 return func(opts *checkoutOptions) { 24 opts.Config = trim(kv...) 25 } 26 } 27 28 // Checkout will attempt to checkout a branch with the given name. If the branch 29 // does not exist, it is created at the current working tree reference (or commit), 30 // and then switched to. If the branch does exist, then switching to it restores 31 // all working tree files 32 func (c *Client) Checkout(branch string, opts ...CheckoutOption) (string, error) { 33 options := &checkoutOptions{} 34 for _, opt := range opts { 35 opt(options) 36 } 37 38 cfg, err := ToInlineConfig(options.Config...) 39 if err != nil { 40 return "", err 41 } 42 43 // Query the repository for all existing branches, both local and remote. 44 // If a pull hasn't been done, there is a chance that an expected 45 // remote branch will not be tracked 46 out, err := c.exec("git branch --all --format='%(refname:short)'") 47 if err != nil { 48 return out, err 49 } 50 51 var buf strings.Builder 52 buf.WriteString("git") 53 54 if len(cfg) > 0 { 55 buf.WriteString(" ") 56 buf.WriteString(strings.Join(cfg, " ")) 57 } 58 buf.WriteString(" checkout ") 59 60 for _, ref := range strings.Split(out, "\n") { 61 if strings.HasSuffix(ref, branch) { 62 return c.exec(buf.String() + branch) 63 } 64 } 65 66 buf.WriteString(" -b ") 67 return c.exec(buf.String() + branch) 68 }