MCPcopy
hub / github.com/cli/cli / tryDetermineDefaultPushTarget

Function tryDetermineDefaultPushTarget

pkg/cmd/pr/shared/find_refs_resolution.go:317–394  ·  view source on GitHub ↗

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)

Source from the content-addressed store, hash-verified

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.
317func 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

Callers 1

Calls 5

newDefaultPushTargetFunction · 0.85
PushRevisionMethod · 0.65
ReadBranchConfigMethod · 0.65
PushDefaultMethod · 0.65
RemotePushDefaultMethod · 0.65

Tested by

no test coverage detected