[compare] Improve upstream branch detection & error messages

- Correctly detect when the current branch is pushed to a fork
- Support upstream configuration with full remote URL
- More precise errors instead of just printing usage synopsis:
  - no current branch
  - the current branch doesn't seem pushed to a remote
  - the current branch is the same as the default branch
  - `--base` value is the same as current branch
This commit is contained in:
Mislav Marohnić 2019-10-01 16:45:53 +02:00
Родитель 4813e859ae
Коммит 1282f19c71
2 изменённых файлов: 55 добавлений и 43 удалений

Просмотреть файл

@ -59,58 +59,60 @@ func compare(command *Command, args *Args) {
localRepo, err := github.LocalRepo()
utils.Check(err)
var (
branch *github.Branch
project *github.Project
r string
)
mainProject, err := localRepo.MainProject()
utils.Check(err)
host, err := github.CurrentConfig().PromptForHost(mainProject.Host)
utils.Check(err)
var r string
flagCompareBase := args.Flag.Value("--base")
if args.IsParamsEmpty() {
branch, project, err = localRepo.RemoteBranchAndProject("", false)
utils.Check(err)
if branch == nil ||
(branch.IsMaster() && flagCompareBase == "") ||
(flagCompareBase == branch.ShortName()) {
utils.Check(command.UsageError(""))
} else {
r = branch.ShortName()
if flagCompareBase != "" {
r = parseCompareRange(flagCompareBase + "..." + r)
currentBranch, err := localRepo.CurrentBranch()
if err != nil {
utils.Check(command.UsageError(err.Error()))
}
var remoteBranch *github.Branch
var remoteProject *github.Project
remoteBranch, remoteProject, err = findPushTarget(currentBranch)
if err != nil {
if remoteProject, err = deducePushTarget(currentBranch, host.User); err == nil {
remoteBranch = currentBranch
} else {
utils.Check(fmt.Errorf("the current branch '%s' doesn't seem pushed to a remote", currentBranch.ShortName()))
}
}
r = remoteBranch.ShortName()
if remoteProject.SameAs(mainProject) {
if flagCompareBase == "" && remoteBranch.IsMaster() {
utils.Check(fmt.Errorf("the branch to compare '%s' is the default branch", remoteBranch.ShortName()))
}
} else {
r = fmt.Sprintf("%s:%s", remoteProject.Owner, r)
}
if flagCompareBase == r {
utils.Check(fmt.Errorf("the branch to compare '%s' is the same as --base", r))
} else if flagCompareBase != "" {
r = fmt.Sprintf("%s...%s", flagCompareBase, r)
}
} else {
if flagCompareBase != "" {
utils.Check(command.UsageError(""))
} else {
r = parseCompareRange(args.RemoveParam(args.ParamsSize() - 1))
project, err = localRepo.CurrentProject()
if args.IsParamsEmpty() {
utils.Check(err)
} else {
projectName := ""
projectHost := ""
if err == nil {
projectName = project.Name
projectHost = project.Host
}
project = github.NewProject(args.RemoveParam(args.ParamsSize()-1), projectName, projectHost)
if project.Name == "" {
utils.Check(fmt.Errorf("error: missing project name (owner: %q)\n", project.Owner))
}
if !args.IsParamsEmpty() {
owner := args.RemoveParam(args.ParamsSize() - 1)
mainProject = github.NewProject(owner, mainProject.Name, mainProject.Host)
}
}
}
if project == nil {
project, err = localRepo.CurrentProject()
utils.Check(err)
}
subpage := utils.ConcatPaths("compare", rangeQueryEscape(r))
url := project.WebURL("", "", subpage)
url := mainProject.WebURL("", "", "compare/"+rangeQueryEscape(r))
args.NoForward()
flagCompareURLOnly := args.Flag.Bool("--url")

Просмотреть файл

@ -21,18 +21,14 @@ Feature: hub compare
Scenario: No args, no upstream
When I run `hub compare`
Then the exit status should be 1
And the stderr should contain:
"""
Usage: hub compare [-uc] [<USER>] [[<START>...]<END>]
hub compare [-uc] [-b <BASE>]
"""
And the stderr should contain exactly "the current branch 'master' doesn't seem pushed to a remote"
Scenario: Can't compare default branch to self
Given the default branch for "origin" is "develop"
And I am on the "develop" branch with upstream "origin/develop"
When I run `hub compare`
Then the exit status should be 1
And the stderr should contain "Usage: hub compare"
And the stderr should contain exactly "the branch to compare 'develop' is the default branch"
Scenario: No args, has upstream branch
Given I am on the "feature" branch with upstream "origin/experimental"
@ -48,6 +44,20 @@ Feature: hub compare
Then the output should not contain anything
And "open https://github.com/mislav/dotfiles/compare/my%23branch!with.special%2Bchars" should be run
Scenario: Current branch pushed to fork
Given I am "monalisa" on github.com with OAuth token "MONATOKEN"
And the "monalisa" remote has url "git@github.com:monalisa/dotfiles.git"
And I am on the "topic" branch pushed to "monalisa/topic"
When I successfully run `hub compare`
Then "open https://github.com/mislav/dotfiles/compare/monalisa:topic" should be run
Scenario: Current branch with full URL in upstream configuration
Given I am on the "local-topic" branch
When I successfully run `git config branch.local-topic.remote https://github.com/monalisa/dotfiles.git`
When I successfully run `git config branch.local-topic.merge refs/remotes/remote-topic`
When I successfully run `hub compare`
Then "open https://github.com/mislav/dotfiles/compare/monalisa:remote-topic" should be run
Scenario: Compare range
When I successfully run `hub compare 1.0...fix`
Then the output should not contain anything
@ -81,7 +91,7 @@ Feature: hub compare
When I run `hub compare -b experimental`
Then "open https://github.com/mislav/dotfiles/compare/experimental...experimental" should not be run
And the exit status should be 1
And the stderr should contain "Usage: hub compare"
And the stderr should contain exactly "the branch to compare 'experimental' is the same as --base\n"
Scenario: Compare base with parameters
Given I am on the "master" branch with upstream "origin/master"