diff options
-rw-r--r-- | pkg/commands/pull_request.go | 51 | ||||
-rw-r--r-- | pkg/config/user_config.go | 2 | ||||
-rw-r--r-- | pkg/gui/branches_panel.go | 18 | ||||
-rw-r--r-- | pkg/gui/keybindings.go | 7 | ||||
-rw-r--r-- | pkg/gui/pull_request_menu_panel.go | 52 | ||||
-rw-r--r-- | pkg/i18n/english.go | 2 |
6 files changed, 109 insertions, 23 deletions
diff --git a/pkg/commands/pull_request.go b/pkg/commands/pull_request.go index ac60af536..9a29ae17a 100644 --- a/pkg/commands/pull_request.go +++ b/pkg/commands/pull_request.go @@ -37,24 +37,39 @@ func NewService(typeName string, repositoryDomain string, siteDomain string) *Se service = &Service{ Name: repositoryDomain, PullRequestURL: func(owner string, repository string, from string, to string) string { - urlFormat := fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/compare/%s?expand=1") - return fmt.Sprintf(urlFormat, owner, repository, from) + if to == "" { + urlFormat := fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/compare/%s?expand=1") + return fmt.Sprintf(urlFormat, owner, repository, from) + } else { + urlFormat := fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/compare/%s...%s?expand=1") + return fmt.Sprintf(urlFormat, owner, repository, to, from) + } }, } case "bitbucket": service = &Service{ - Name: repositoryDomain, + Name: repositoryDomain, PullRequestURL: func(owner string, repository string, from string, to string) string { - urlFormat := fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/pull-requests/new?source=%s&t=1") - return fmt.Sprintf(urlFormat, owner, repository, from) + if to == "" { + urlFormat := fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/pull-requests/new?source=%s&t=1") + return fmt.Sprintf(urlFormat, owner, repository, from) + } else { + urlFormat := fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/pull-requests/new?source=%s&dest=%s&t=1") + return fmt.Sprintf(urlFormat, owner, repository, from, to) + } }, } case "gitlab": service = &Service{ - Name: repositoryDomain, + Name: repositoryDomain, PullRequestURL: func(owner string, repository string, from string, to string) string { - urlFormat := fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/merge_requests/new?merge_request[source_branch]=%s") - return fmt.Sprintf(urlFormat, owner, repository, from) + if to == "" { + urlFormat := fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/merge_requests/new?merge_request[source_branch]=%s") + return fmt.Sprintf(urlFormat, owner, repository, from) + } else { + urlFormat := fmt.Sprintf("https://%s%s", siteDomain, "/%s/%s/merge_requests/new?merge_request[source_branch]=%s&merge_request[target_branch]=%s") + return fmt.Sprintf(urlFormat, owner, repository, from, to) + } }, } } @@ -99,8 +114,8 @@ func NewPullRequest(gitCommand *GitCommand) *PullRequest { } // Create opens link to new pull request in browser -func (pr *PullRequest) Create(branch *models.Branch) (string, error) { - pullRequestURL, err := pr.getPullRequestURL(branch) +func (pr *PullRequest) Create(from *models.Branch, to *models.Branch) (string, error) { + pullRequestURL, err := pr.getPullRequestURL(from, to) if err != nil { return "", err } @@ -109,8 +124,8 @@ func (pr *PullRequest) Create(branch *models.Branch) (string, error) { } // CopyURL copies the pull request URL to the clipboard -func (pr *PullRequest) CopyURL(branch *models.Branch) (string, error) { - pullRequestURL, err := pr.getPullRequestURL(branch) +func (pr *PullRequest) CopyURL(from *models.Branch, to *models.Branch) (string, error) { + pullRequestURL, err := pr.getPullRequestURL(from, to) if err != nil { return "", err } @@ -118,8 +133,8 @@ func (pr *PullRequest) CopyURL(branch *models.Branch) (string, error) { return pullRequestURL, pr.GitCommand.OSCommand.CopyToClipboard(pullRequestURL) } -func (pr *PullRequest) getPullRequestURL(branch *models.Branch) (string, error) { - branchExistsOnRemote := pr.GitCommand.CheckRemoteBranchExists(branch) +func (pr *PullRequest) getPullRequestURL(from *models.Branch, to *models.Branch) (string, error) { + branchExistsOnRemote := pr.GitCommand.CheckRemoteBranchExists(from) if !branchExistsOnRemote { return "", errors.New(pr.GitCommand.Tr.NoBranchOnRemote) @@ -140,7 +155,13 @@ func (pr *PullRequest) getPullRequestURL(branch *models.Branch) (string, error) } repoInfo := getRepoInfoFromURL(repoURL) - pullRequestURL := gitService.PullRequestURL(repoInfo.Owner, repoInfo.Repository, branch.Name, "") + var toBranchName string + if to == nil { + toBranchName = "" + } else { + toBranchName = to.Name + } + pullRequestURL := gitService.PullRequestURL(repoInfo.Owner, repoInfo.Repository, from.Name, toBranchName) return pullRequestURL, nil } diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index d373b74f1..38259f6f2 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -193,6 +193,7 @@ type KeybindingFilesConfig struct { type KeybindingBranchesConfig struct { CreatePullRequest string `yaml:"createPullRequest"` + ViewPullRequestOptions string `yaml:"viewPullRequestOptions"` CopyPullRequestURL string `yaml:"copyPullRequestURL"` CheckoutBranchByName string `yaml:"checkoutBranchByName"` ForceCheckoutBranch string `yaml:"forceCheckoutBranch"` @@ -437,6 +438,7 @@ func GetDefaultConfig() *UserConfig { Branches: KeybindingBranchesConfig{ CopyPullRequestURL: "<c-y>", CreatePullRequest: "o", + ViewPullRequestOptions: "O", CheckoutBranchByName: "c", ForceCheckoutBranch: "F", RebaseBranch: "r", diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go index 863622f94..da55c9df8 100644 --- a/pkg/gui/branches_panel.go +++ b/pkg/gui/branches_panel.go @@ -91,23 +91,25 @@ func (gui *Gui) handleBranchPress() error { } func (gui *Gui) handleCreatePullRequestPress() error { - pullRequest := commands.NewPullRequest(gui.GitCommand) - branch := gui.getSelectedBranch() - url, err := pullRequest.Create(branch) - if err != nil { - return gui.surfaceError(err) + return createPullRequest(branch, nil, gui) +} + +func (gui *Gui) handleCreatePullRequestMenu() error { + selectedBranch := gui.getSelectedBranch() + if selectedBranch == nil { + return nil } - gui.OnRunCommand(oscommands.NewCmdLogEntry(fmt.Sprintf("Creating pull request at URL: %s", url), "Create pull request", false)) + checkedOutBranch := gui.getCheckedOutBranch() - return nil + return gui.createPullRequestMenu(selectedBranch, checkedOutBranch) } func (gui *Gui) handleCopyPullRequestURLPress() error { pullRequest := commands.NewPullRequest(gui.GitCommand) branch := gui.getSelectedBranch() - url, err := pullRequest.CopyURL(branch) + url, err := pullRequest.CopyURL(branch, nil) if err != nil { return gui.surfaceError(err) } diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 2e690a1e4..5519f1954 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -548,6 +548,13 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { { ViewName: "branches", Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)}, + Key: gui.getKey(config.Branches.ViewPullRequestOptions), + Handler: gui.handleCreatePullRequestMenu, + Description: gui.Tr.LcCreatePullRequest, + }, + { + ViewName: "branches", + Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Branches.CopyPullRequestURL), Handler: gui.handleCopyPullRequestURLPress, Description: gui.Tr.LcCopyPullRequestURL, diff --git a/pkg/gui/pull_request_menu_panel.go b/pkg/gui/pull_request_menu_panel.go new file mode 100644 index 000000000..088cae2eb --- /dev/null +++ b/pkg/gui/pull_request_menu_panel.go @@ -0,0 +1,52 @@ +package gui + +import ( + "fmt" + "github.com/jesseduffield/lazygit/pkg/commands" + "github.com/jesseduffield/lazygit/pkg/commands/models" + "github.com/jesseduffield/lazygit/pkg/commands/oscommands" +) + +func (gui *Gui) createPullRequestMenu(selectedBranch *models.Branch, checkedOutBranch *models.Branch) error { + menuItems := make([]*menuItem, 0, 2) + + if selectedBranch != checkedOutBranch { + menuItems = append(menuItems, &menuItem{ + displayStrings: []string{ + fmt.Sprintf("%s -> default branch", selectedBranch.Name), + }, + onPress: func() error { + return createPullRequest(selectedBranch, nil, gui) + }, + }, &menuItem{ + displayStrings: []string{ + fmt.Sprintf("%s -> %s", checkedOutBranch.Name, selectedBranch.Name), + }, + onPress: func() error { + return createPullRequest(checkedOutBranch, selectedBranch, gui) + }, + }) + } + + menuItems = append(menuItems, &menuItem{ + displayStrings: []string{ + fmt.Sprintf("%s -> default branch", checkedOutBranch.Name), + }, + onPress: func() error { + return createPullRequest(checkedOutBranch, nil, gui) + }, + }) + + return gui.createMenu(fmt.Sprintf(gui.Tr.CreatePullRequest), menuItems, createMenuOptions{showCancel: true}) +} + +func createPullRequest(checkedOutBranch *models.Branch, selectedBranch *models.Branch, gui *Gui) error { + pullRequest := commands.NewPullRequest(gui.GitCommand) + url, err := pullRequest.Create(checkedOutBranch, selectedBranch) + if err != nil { + return gui.surfaceError(err) + } + gui.OnRunCommand(oscommands.NewCmdLogEntry(fmt.Sprintf("Creating pull request at URL: %s", url), "Create pull request", false)) + + return nil +} diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index a7c26b7f9..b0e333bd5 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -454,6 +454,7 @@ type TranslationSet struct { ToggleWhitespaceInDiffView string IgnoringWhitespaceInDiffView string ShowingWhitespaceInDiffView string + CreatePullRequest string Spans Spans } @@ -1001,6 +1002,7 @@ func englishTranslationSet() TranslationSet { ToggleWhitespaceInDiffView: "Toggle whether or not whitespace changes are shown in the diff view", IgnoringWhitespaceInDiffView: "Whitespace will be ignored in the diff view", ShowingWhitespaceInDiffView: "Whitespace will be shown in the diff view", + CreatePullRequest: "Create pull request", Spans: Spans{ // TODO: combine this with the original keybinding descriptions (those are all in lowercase atm) CheckoutCommit: "Checkout commit", |