6 "github.com/rubyist/tracerx"
9 type RefUpdate struct {
16 func NewRefUpdate(g Env, remote string, l, r *Ref) *RefUpdate {
25 func (u *RefUpdate) Left() *Ref {
29 func (u *RefUpdate) LeftCommitish() string {
30 return refCommitish(u.Left())
33 func (u *RefUpdate) Right() *Ref {
35 u.right = defaultRemoteRef(u.git, u.remote, u.Left())
40 // defaultRemoteRef returns the remote ref receiving a push based on the current
41 // repository config and local ref being pushed.
43 // See push.default rules in https://git-scm.com/docs/git-config
44 func defaultRemoteRef(g Env, remote string, left *Ref) *Ref {
45 pushMode, _ := g.Get("push.default")
48 brRemote, _ := g.Get(fmt.Sprintf("branch.%s.remote", left.Name))
49 if brRemote == remote {
50 // in centralized workflow, work like 'upstream' with an added safety to
51 // refuse to push if the upstream branch’s name is different from the
53 return trackingRef(g, left)
56 // When pushing to a remote that is different from the remote you normally
57 // pull from, work as current.
59 case "upstream", "tracking":
60 // push the current branch back to the branch whose changes are usually
61 // integrated into the current branch
62 return trackingRef(g, left)
64 // push the current branch to update a branch with the same name on the
68 tracerx.Printf("WARNING: %q push mode not supported", pushMode)
73 func trackingRef(g Env, left *Ref) *Ref {
74 if merge, ok := g.Get(fmt.Sprintf("branch.%s.merge", left.Name)); ok {
75 return ParseRef(merge, "")
80 func (u *RefUpdate) RightCommitish() string {
81 return refCommitish(u.Right())
84 func refCommitish(r *Ref) string {
93 Get(key string) (val string, ok bool)