Repository: cli/cli
File: pkg/cmd/pr/shared/find_refs_resolution.go (Go)

Code before:
// If none of these are set, we indicate that we were unable to determine the
// remote by returning a None value for the remote.
//
// The branch name is always set. The default configuration for push.default (current) indicates
// that a git push should use the same remote branch name as the local branch name. If push.default
// is set to upstream or tracking (deprecated form of upstream), then we use the branch name from the merge ref.
func tryDetermineDefaultPushTarget(gitClient GitConfigClient, localBranchName string) (defaultPushTarget, error) {
	// If @{push} resolves, then we have the remote tracking branch already, no problem.
	if pushRevisionRef, err := gitClient.PushRevision(context.Background(), localBranchName); err == nil {
		return newDefaultPushTarget(remoteName{pushRevisionRef.Remote}, pushRevisionRef.Branch), nil
	}

	// But it doesn't always resolve, so we can suppress the error and move on to other means
	// of determination. We'll first look at branch and remote configuration to make a determination.
	branchConfig, err := gitClient.ReadBranchConfig(context.Background(), localBranchName)
	if err != nil {
		return defaultPushTarget{}, err
	}

	pushDefault, err := gitClient.PushDefault(context.Background())
	if err != nil {
		return defaultPushTarget{}, err
	}

	// We assume the PR's branch name is the same as whatever was provided, unless the user has specified
	// push.default = upstream or tracking, then we use the branch name from the merge ref.
	remoteBranch := localBranchName
	if pushDefault == git.PushDefaultUpstream || pushDefault == git.PushDefaultTracking {
		mergeRef := strings.TrimPrefix(branchConfig.MergeRef, "refs/heads/")
		if mergeRef != "" {
			remoteBranch = mergeRef
		}
	}

	// To get the remote, we look to the git config. It comes from one of the following, in order of precedence:
	// 1. branch.<name>.pushRemote (which may be a name or a URL)
	// 2. remote.pushDefault (which is a remote name)
	// 3. branch.<name>.remote (which may be a name or a URL)
	if branchConfig.PushRemoteName != "" {
		return newDefaultPushTarget(
			remoteName{branchConfig.PushRemoteName},
			remoteBranch,
		), nil
	}

	if branchConfig.PushRemoteURL != nil {
		return newDefaultPushTarget(
			remoteURL{branchConfig.PushRemoteURL},
			remoteBranch,
		), nil
	}

Review comment (suggestion):
```suggestion
	// 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
```

Code after:
// If none of these are set, we indicate that we were unable to determine the
// remote by returning a None value for the remote.
//
// The branch name is always set. The default configuration for push.default (current) indicates
// that a git push should use the same remote branch name as the local branch name. If push.default
// is set to upstream or tracking (deprecated form of upstream), then we use the branch name from the merge ref.
func tryDetermineDefaultPushTarget(gitClient GitConfigClient, localBranchName string) (defaultPushTarget, error) {
	// If @{push} resolves, then we have the remote tracking branch already, no problem.
	if pushRevisionRef, err := gitClient.PushRevision(context.Background(), localBranchName); err == nil {
		return newDefaultPushTarget(remoteName{pushRevisionRef.Remote}, pushRevisionRef.Branch), nil
	}

	// But it doesn't always resolve, so we can suppress the error and move on to other means
	// of determination. We'll first look at branch and remote configuration to make a determination.
	branchConfig, err := gitClient.ReadBranchConfig(context.Background(), localBranchName)
	if err != nil {
		return defaultPushTarget{}, err
	}

	pushDefault, err := gitClient.PushDefault(context.Background())
	if err != nil {
		return defaultPushTarget{}, err
	}

	// We assume the PR's branch name is the same as whatever was provided, unless the user has specified
	// 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
	remoteBranch := localBranchName
	if pushDefault == git.PushDefaultUpstream || pushDefault == git.PushDefaultTracking {
		mergeRef := strings.TrimPrefix(branchConfig.MergeRef, "refs/heads/")
		if mergeRef != "" {
			remoteBranch = mergeRef
		}
	}

	// To get the remote, we look to the git config. It comes from one of the following, in order of precedence:
	// 1. branch.<name>.pushRemote (which may be a name or a URL)
	// 2. remote.pushDefault (which is a remote name)
	// 3. branch.<name>.remote (which may be a name or a URL)
	if branchConfig.PushRemoteName != "" {
		return newDefaultPushTarget(
			remoteName{branchConfig.PushRemoteName},
			remoteBranch,
		), nil
	}

	if branchConfig.PushRemoteURL != nil {
		return newDefaultPushTarget(
			remoteURL{branchConfig.PushRemoteURL},
			remoteBranch,
		), nil
	}