tryDetermineDefaultPushTarget uses git configuration to make a best guess about where a branch is pushed to, and where it would be pushed to if the user ran `git push` with no additional arguments. Firstly, it attempts to resolve the @{push} ref, which is the most reliable method, as this is what g
(gitClient GitConfigClient, localBranchName string)
| 315 | // that a git push should use the same remote branch name as the local branch name. If push.default |
| 316 | // is set to upstream or tracking (deprecated form of upstream), then we use the branch name from the merge ref. |
| 317 | func tryDetermineDefaultPushTarget(gitClient GitConfigClient, localBranchName string) (defaultPushTarget, error) { |
| 318 | // If @{push} resolves, then we have the remote tracking branch already, no problem. |
| 319 | if pushRevisionRef, err := gitClient.PushRevision(context.Background(), localBranchName); err == nil { |
| 320 | return newDefaultPushTarget(remoteName{pushRevisionRef.Remote}, pushRevisionRef.Branch), nil |
| 321 | } |
| 322 | |
| 323 | // But it doesn't always resolve, so we can suppress the error and move on to other means |
| 324 | // of determination. We'll first look at branch and remote configuration to make a determination. |
| 325 | branchConfig, err := gitClient.ReadBranchConfig(context.Background(), localBranchName) |
| 326 | if err != nil { |
| 327 | return defaultPushTarget{}, err |
| 328 | } |
| 329 | |
| 330 | pushDefault, err := gitClient.PushDefault(context.Background()) |
| 331 | if err != nil { |
| 332 | return defaultPushTarget{}, err |
| 333 | } |
| 334 | |
| 335 | // We assume the PR's branch name is the same as whatever was provided, unless the user has specified |
| 336 | // push.default = upstream or tracking, then we use the branch name from the merge ref if it exists. Otherwise, we fall back to the local branch name |
| 337 | remoteBranch := localBranchName |
| 338 | if pushDefault == git.PushDefaultUpstream || pushDefault == git.PushDefaultTracking { |
| 339 | mergeRef := strings.TrimPrefix(branchConfig.MergeRef, "refs/heads/") |
| 340 | if mergeRef != "" { |
| 341 | remoteBranch = mergeRef |
| 342 | } |
| 343 | } |
| 344 | |
| 345 | // To get the remote, we look to the git config. It comes from one of the following, in order of precedence: |
| 346 | // 1. branch.<name>.pushRemote (which may be a name or a URL) |
| 347 | // 2. remote.pushDefault (which is a remote name) |
| 348 | // 3. branch.<name>.remote (which may be a name or a URL) |
| 349 | if branchConfig.PushRemoteName != "" { |
| 350 | return newDefaultPushTarget( |
| 351 | remoteName{branchConfig.PushRemoteName}, |
| 352 | remoteBranch, |
| 353 | ), nil |
| 354 | } |
| 355 | |
| 356 | if branchConfig.PushRemoteURL != nil { |
| 357 | return newDefaultPushTarget( |
| 358 | remoteURL{branchConfig.PushRemoteURL}, |
| 359 | remoteBranch, |
| 360 | ), nil |
| 361 | } |
| 362 | |
| 363 | remotePushDefault, err := gitClient.RemotePushDefault(context.Background()) |
| 364 | if err != nil { |
| 365 | return defaultPushTarget{}, err |
| 366 | } |
| 367 | |
| 368 | if remotePushDefault != "" { |
| 369 | return newDefaultPushTarget( |
| 370 | remoteName{remotePushDefault}, |
| 371 | remoteBranch, |
| 372 | ), nil |
| 373 | } |
| 374 |
no test coverage detected