fix conflict

This commit is contained in:
Yuki Osaki
2022-08-16 22:07:42 +09:00
parent 4a31f3fd50
commit f277ea2350
18 changed files with 181 additions and 448 deletions
+1 -69
View File
@@ -41,75 +41,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
<kbd>[</kbd>: previous tab
</pre>
## Branches Panel (Branches Tab)
<pre>
<kbd>space</kbd>: checkout
<kbd>o</kbd>: create pull request
<kbd>O</kbd>: create pull request options
<kbd>ctrl+y</kbd>: copy pull request URL to clipboard
<kbd>c</kbd>: checkout by name
<kbd>F</kbd>: force checkout
<kbd>n</kbd>: new branch
<kbd>d</kbd>: delete branch
<kbd>r</kbd>: rebase checked-out branch onto this branch
<kbd>M</kbd>: merge into currently checked out branch
<kbd>i</kbd>: show git-flow options
<kbd>f</kbd>: fast-forward this branch from its upstream
<kbd>g</kbd>: view reset options
<kbd>R</kbd>: rename branch
<kbd>ctrl+o</kbd>: copy branch name to clipboard
<kbd>enter</kbd>: view commits
</pre>
## Branches Panel (Remote Branches (in Remotes tab))
<pre>
<kbd>esc</kbd>: Return to remotes list
<kbd>g</kbd>: view reset options
<kbd>enter</kbd>: view commits
<kbd>space</kbd>: checkout
<kbd>n</kbd>: new branch
<kbd>M</kbd>: merge into currently checked out branch
<kbd>d</kbd>: delete branch
<kbd>r</kbd>: rebase checked-out branch onto this branch
<kbd>u</kbd>: set as upstream of checked-out branch
</pre>
## Branches Panel (Remotes Tab)
<pre>
<kbd>f</kbd>: fetch remote
<kbd>n</kbd>: add new remote
<kbd>d</kbd>: remove remote
<kbd>e</kbd>: edit remote
</pre>
## Branches Panel (Sub-commits)
<pre>
<kbd>enter</kbd>: view commit's files
<kbd>space</kbd>: checkout commit
<kbd>g</kbd>: view reset options
<kbd>n</kbd>: new branch
<kbd>c</kbd>: copy commit (cherry-pick)
<kbd>C</kbd>: copy commit range (cherry-pick)
<kbd>ctrl+r</kbd>: reset cherry-picked (copied) commits selection
<kbd>ctrl+o</kbd>: copy commit SHA to clipboard
</pre>
## Branches Panel (Tags Tab)
<pre>
<kbd>space</kbd>: checkout
<kbd>d</kbd>: delete tag
<kbd>P</kbd>: push tag
<kbd>n</kbd>: create tag
<kbd>g</kbd>: view reset options
<kbd>enter</kbd>: view commits
</pre>
## Commit Files Panel
## Commit Files
<pre>
<kbd>ctrl+o</kbd>: copy the committed file name to the clipboard
+1 -1
View File
@@ -64,7 +64,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
<kbd>space</kbd>: 检出
<kbd>n</kbd>: 新分支
<kbd>o</kbd>: 创建抓取请求
<kbd>O</kbd>: 创建抓取请求
<kbd>O</kbd>: 创建抓取请求选项
<kbd>ctrl+y</kbd>: 将抓取请求 URL 复制到剪贴板
<kbd>c</kbd>: 按名称检出
<kbd>F</kbd>: 强制检出
+23
View File
@@ -136,6 +136,29 @@ func (app *App) validateGhVersion() error {
return minVersionError
}
func isGhVersionValid(versionStr string) bool {
// output should be something like:
// gh version 2.0.0 (2021-08-23)
// https://github.com/cli/cli/releases/tag/v2.0.0
re := regexp.MustCompile(`[^\d]+([\d\.]+)`)
matches := re.FindStringSubmatch(versionStr)
if len(matches) == 0 {
return false
}
ghVersion := matches[1]
majorVersion, err := strconv.Atoi(ghVersion[0:1])
if err != nil {
return false
}
if majorVersion < 2 {
return false
}
return true
}
func (app *App) validateGitVersion() error {
output, err := app.OSCommand.Cmd.New("git --version").RunWithOutput()
// if we get an error anywhere here we'll show the same status
+18 -15
View File
@@ -5,7 +5,6 @@ import (
"fmt"
"strings"
"github.com/jesseduffield/lazygit/pkg/commands/hosting_service"
"github.com/jesseduffield/lazygit/pkg/commands/models"
)
@@ -21,17 +20,16 @@ func NewGhCommand(gitCommon *GitCommon) *GhCommands {
// https://github.com/cli/cli/issues/2300
func (self *GhCommands) BaseRepo() error {
return self.cmd.New("git config --local --get-regexp .gh-resolved").StreamOutput().Run()
return self.cmd.New("git config --local --get-regexp .gh-resolved").Run()
}
// Ex: git config --local --add "remote.origin.gh-resolved" "jesseduffield/lazygit"
func (self *GhCommands) SetBaseRepo(repository string) (string, error) {
return self.cmd.NewShell(fmt.Sprintf("git config --local --add \"remote.origin.gh-resolved\" \"%s\"", repository)).RunWithOutput()
return self.cmd.New(fmt.Sprintf("git config --local --add \"remote.origin.gh-resolved\" \"%s\"", repository)).RunWithOutput()
}
func (self *GhCommands) prList() (string, error) {
return self.cmd.NewShell("gh pr list --limit 100 --state all --json state,url,number,headRefName,headRepositoryOwner").RunWithOutput()
return self.cmd.New("gh pr list --limit 500 --state all --json state,url,number,headRefName,headRepositoryOwner").RunWithOutput()
}
func (self *GhCommands) GithubMostRecentPRs() ([]*models.GithubPullRequest, error) {
@@ -49,17 +47,17 @@ func (self *GhCommands) GithubMostRecentPRs() ([]*models.GithubPullRequest, erro
return prs, nil
}
func GenerateGithubPullRequestMap(prs []*models.GithubPullRequest, branches []*models.Branch, remotes []*models.Remote) (map[*models.Branch]*models.GithubPullRequest, error) {
func GenerateGithubPullRequestMap(prs []*models.GithubPullRequest, branches []*models.Branch, remotes []*models.Remote) map[*models.Branch]*models.GithubPullRequest {
res := map[*models.Branch]*models.GithubPullRequest{}
if len(prs) == 0 {
return res, nil
return res
}
remotesToOwnersMap, err := getRemotesToOwnersMap(remotes)
remotesToOwnersMap := getRemotesToOwnersMap(remotes)
if len(remotesToOwnersMap) == 0 {
return res, err
return res
}
prWithStringKey := map[string]models.GithubPullRequest{}
@@ -87,10 +85,10 @@ func GenerateGithubPullRequestMap(prs []*models.GithubPullRequest, branches []*m
res[branch] = &pr
}
return res, nil
return res
}
func GetRepoInfoFromURL(url string) hosting_service.RepoInformation {
func GetRepoInfoFromURL(url string) RepoInformation {
isHTTP := strings.HasPrefix(url, "http")
if isHTTP {
@@ -98,7 +96,7 @@ func GetRepoInfoFromURL(url string) hosting_service.RepoInformation {
owner := strings.Join(splits[3:len(splits)-1], "/")
repo := strings.TrimSuffix(splits[len(splits)-1], ".git")
return hosting_service.RepoInformation{
return RepoInformation{
Owner: owner,
Repository: repo,
}
@@ -109,13 +107,13 @@ func GetRepoInfoFromURL(url string) hosting_service.RepoInformation {
owner := strings.Join(splits[0:len(splits)-1], "/")
repo := strings.TrimSuffix(splits[len(splits)-1], ".git")
return hosting_service.RepoInformation{
return RepoInformation{
Owner: owner,
Repository: repo,
}
}
func getRemotesToOwnersMap(remotes []*models.Remote) (map[string]string, error) {
func getRemotesToOwnersMap(remotes []*models.Remote) map[string]string {
res := map[string]string{}
for _, remote := range remotes {
if len(remote.Urls) == 0 {
@@ -124,5 +122,10 @@ func getRemotesToOwnersMap(remotes []*models.Remote) (map[string]string, error)
res[remote.Name] = GetRepoInfoFromURL(remote.Urls[0]).Owner
}
return res, nil
return res
}
type RepoInformation struct {
Owner string
Repository string
}
+26 -26
View File
@@ -224,19 +224,19 @@ type KeybindingFilesConfig struct {
}
type KeybindingBranchesConfig struct {
CreateOrShowPullRequest string `yaml:"createPullRequest"`
ViewPullRequestOptions string `yaml:"viewPullRequestOptions"`
CopyPullRequestURL string `yaml:"copyPullRequestURL"`
CheckoutBranchByName string `yaml:"checkoutBranchByName"`
ForceCheckoutBranch string `yaml:"forceCheckoutBranch"`
RebaseBranch string `yaml:"rebaseBranch"`
RenameBranch string `yaml:"renameBranch"`
MergeIntoCurrentBranch string `yaml:"mergeIntoCurrentBranch"`
ViewGitFlowOptions string `yaml:"viewGitFlowOptions"`
FastForward string `yaml:"fastForward"`
PushTag string `yaml:"pushTag"`
SetUpstream string `yaml:"setUpstream"`
FetchRemote string `yaml:"fetchRemote"`
CreatePullRequest string `yaml:"createPullRequest"`
ViewPullRequestOptions string `yaml:"viewPullRequestOptions"`
CopyPullRequestURL string `yaml:"copyPullRequestURL"`
CheckoutBranchByName string `yaml:"checkoutBranchByName"`
ForceCheckoutBranch string `yaml:"forceCheckoutBranch"`
RebaseBranch string `yaml:"rebaseBranch"`
RenameBranch string `yaml:"renameBranch"`
MergeIntoCurrentBranch string `yaml:"mergeIntoCurrentBranch"`
ViewGitFlowOptions string `yaml:"viewGitFlowOptions"`
FastForward string `yaml:"fastForward"`
PushTag string `yaml:"pushTag"`
SetUpstream string `yaml:"setUpstream"`
FetchRemote string `yaml:"fetchRemote"`
}
type KeybindingCommitsConfig struct {
@@ -505,19 +505,19 @@ func GetDefaultConfig() *UserConfig {
OpenStatusFilter: "<c-b>",
},
Branches: KeybindingBranchesConfig{
CopyPullRequestURL: "<c-y>",
CreateOrShowPullRequest: "o",
ViewPullRequestOptions: "O",
CheckoutBranchByName: "c",
ForceCheckoutBranch: "F",
RebaseBranch: "r",
RenameBranch: "R",
MergeIntoCurrentBranch: "M",
ViewGitFlowOptions: "i",
FastForward: "f",
PushTag: "P",
SetUpstream: "u",
FetchRemote: "f",
CopyPullRequestURL: "<c-y>",
CreatePullRequest: "o",
ViewPullRequestOptions: "O",
CheckoutBranchByName: "c",
ForceCheckoutBranch: "F",
RebaseBranch: "r",
RenameBranch: "R",
MergeIntoCurrentBranch: "M",
ViewGitFlowOptions: "i",
FastForward: "f",
PushTag: "P",
SetUpstream: "u",
FetchRemote: "f",
},
Commits: KeybindingCommitsConfig{
SquashDown: "s",
+44 -1
View File
@@ -1,6 +1,8 @@
package gui
import "github.com/jesseduffield/lazygit/pkg/gui/types"
import (
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
func (gui *Gui) branchesRenderToMain() error {
var task types.UpdateTask
@@ -21,3 +23,44 @@ func (gui *Gui) branchesRenderToMain() error {
},
})
}
func (gui *Gui) refreshGithubPullRequests() {
if err := gui.git.Gh.BaseRepo(); err == nil {
_ = gui.setGithubPullRequests()
return
}
// when config not exits
_ = gui.refreshRemotes()
_ = gui.c.Prompt(types.PromptOpts{
Title: gui.c.Tr.SelectRemoteRepository,
InitialContent: "",
FindSuggestionsFunc: gui.helpers.Suggestions.GetRemoteRepoSuggestionsFunc(),
HandleConfirm: func(repository string) error {
return gui.c.WithWaitingStatus(gui.c.Tr.LcSelectingRemote, func() error {
_, err := gui.git.Gh.SetBaseRepo(repository)
if err != nil {
return err
}
err = gui.setGithubPullRequests()
if err != nil {
return err
}
_ = gui.postRefreshUpdate(gui.State.Contexts.Branches)
return nil
})
},
})
}
func (gui *Gui) setGithubPullRequests() error {
prs, err := gui.git.Gh.GithubMostRecentPRs()
if err != nil {
return gui.c.Error(err)
}
gui.State.Model.PullRequests = prs
return nil
}
@@ -5,6 +5,7 @@ import (
"os"
"github.com/jesseduffield/generics/slices"
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
"github.com/jesseduffield/lazygit/pkg/gui/types"
@@ -80,6 +81,26 @@ func (self *SuggestionsHelper) getBranchNames() []string {
})
}
func (self *SuggestionsHelper) GetRemoteRepoSuggestionsFunc() func(string) []*types.Suggestion {
remotesNames := self.getRemoteRepoNames()
return FuzzySearchFunc(remotesNames)
}
func (self *SuggestionsHelper) getRemoteRepoNames() []string {
remotes := self.model.Remotes
result := make([]string, 0, len(remotes))
for _, remote := range remotes {
if len(remote.Urls) == 0 {
continue
}
info := git_commands.GetRepoInfoFromURL(remote.Urls[0])
result = append(result, fmt.Sprintf("%s/%s", info.Owner, info.Repository))
}
return result
}
func (self *SuggestionsHelper) GetBranchNameSuggestionsFunc() func(string) []*types.Suggestion {
branchNames := self.getBranchNames()
-211
View File
@@ -1,211 +0,0 @@
package gui
import (
"fmt"
"os"
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/jesseduffield/minimal/gitignore"
"gopkg.in/ozeidan/fuzzy-patricia.v3/patricia"
)
// Thinking out loud: I'm typically a staunch advocate of organising code by feature rather than type,
// because colocating code that relates to the same feature means far less effort
// to get all the context you need to work on any particular feature. But the one
// major benefit of grouping by type is that it makes it makes it less likely that
// somebody will re-implement the same logic twice, because they can quickly see
// if a certain method has been used for some use case, given that as a starting point
// they know about the type. In that vein, I'm including all our functions for
// finding suggestions in this file, so that it's easy to see if a function already
// exists for fetching a particular model.
func (gui *Gui) getRemoteNames() []string {
result := make([]string, len(gui.State.Remotes))
for i, remote := range gui.State.Remotes {
result[i] = remote.Name
}
return result
}
func matchesToSuggestions(matches []string) []*types.Suggestion {
suggestions := make([]*types.Suggestion, len(matches))
for i, match := range matches {
suggestions[i] = &types.Suggestion{
Value: match,
Label: match,
}
}
return suggestions
}
func (gui *Gui) getRemoteSuggestionsFunc() func(string) []*types.Suggestion {
remoteNames := gui.getRemoteNames()
return fuzzySearchFunc(remoteNames)
}
func (gui *Gui) getRemoteRepoSuggestionsFunc() func(string) []*types.Suggestion {
remotesNames := gui.getRemoteRepoNames()
return fuzzySearchFunc(remotesNames)
}
func (gui *Gui) getRemoteRepoNames() []string {
remotes := gui.State.Remotes
result := make([]string, 0, len(remotes))
for _, remote := range remotes {
if len(remote.Urls) == 0 {
continue
}
info := git_commands.GetRepoInfoFromURL(remote.Urls[0])
result = append(result, fmt.Sprintf("%s/%s", info.Owner, info.Repository))
}
return result
}
func (gui *Gui) getBranchNames() []string {
result := make([]string, len(gui.State.Branches))
for i, branch := range gui.State.Branches {
result[i] = branch.Name
}
return result
}
func (gui *Gui) getBranchNameSuggestionsFunc() func(string) []*types.Suggestion {
branchNames := gui.getBranchNames()
return func(input string) []*types.Suggestion {
var matchingBranchNames []string
if input == "" {
matchingBranchNames = branchNames
} else {
matchingBranchNames = utils.FuzzySearch(input, branchNames)
}
suggestions := make([]*types.Suggestion, len(matchingBranchNames))
for i, branchName := range matchingBranchNames {
suggestions[i] = &types.Suggestion{
Value: branchName,
Label: presentation.GetBranchTextStyle(branchName).Sprint(branchName),
}
}
return suggestions
}
}
// here we asynchronously fetch the latest set of paths in the repo and store in
// gui.State.FilesTrie. On the main thread we'll be doing a fuzzy search via
// gui.State.FilesTrie. So if we've looked for a file previously, we'll start with
// the old trie and eventually it'll be swapped out for the new one.
// Notably, unlike other suggestion functions we're not showing all the options
// if nothing has been typed because there'll be too much to display efficiently
func (gui *Gui) getFilePathSuggestionsFunc() func(string) []*types.Suggestion {
_ = gui.WithWaitingStatus(gui.Tr.LcLoadingFileSuggestions, func() error {
trie := patricia.NewTrie()
// load every non-gitignored file in the repo
ignore, err := gitignore.FromGit()
if err != nil {
return err
}
err = ignore.Walk(".",
func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
trie.Insert(patricia.Prefix(path), path)
return nil
})
// cache the trie for future use
gui.State.FilesTrie = trie
// refresh the selections view
gui.suggestionsAsyncHandler.Do(func() func() {
// assuming here that the confirmation view is what we're typing into.
// This assumption may prove false over time
suggestions := gui.findSuggestions(gui.Views.Confirmation.TextArea.GetContent())
return func() { gui.setSuggestions(suggestions) }
})
return err
})
return func(input string) []*types.Suggestion {
matchingNames := []string{}
_ = gui.State.FilesTrie.VisitFuzzy(patricia.Prefix(input), true, func(prefix patricia.Prefix, item patricia.Item, skipped int) error {
matchingNames = append(matchingNames, item.(string))
return nil
})
// doing another fuzzy search for good measure
matchingNames = utils.FuzzySearch(input, matchingNames)
suggestions := make([]*types.Suggestion, len(matchingNames))
for i, name := range matchingNames {
suggestions[i] = &types.Suggestion{
Value: name,
Label: name,
}
}
return suggestions
}
}
func (gui *Gui) getRemoteBranchNames(separator string) []string {
result := []string{}
for _, remote := range gui.State.Remotes {
for _, branch := range remote.Branches {
result = append(result, fmt.Sprintf("%s%s%s", remote.Name, separator, branch.Name))
}
}
return result
}
func (gui *Gui) getRemoteBranchesSuggestionsFunc(separator string) func(string) []*types.Suggestion {
return fuzzySearchFunc(gui.getRemoteBranchNames(separator))
}
func (gui *Gui) getTagNames() []string {
result := make([]string, len(gui.State.Tags))
for i, tag := range gui.State.Tags {
result[i] = tag.Name
}
return result
}
func (gui *Gui) getRefsSuggestionsFunc() func(string) []*types.Suggestion {
remoteBranchNames := gui.getRemoteBranchNames("/")
localBranchNames := gui.getBranchNames()
tagNames := gui.getTagNames()
additionalRefNames := []string{"HEAD", "FETCH_HEAD", "MERGE_HEAD", "ORIG_HEAD"}
refNames := append(append(append(remoteBranchNames, localBranchNames...), tagNames...), additionalRefNames...)
return fuzzySearchFunc(refNames)
}
func (gui *Gui) getCustomCommandsHistorySuggestionsFunc() func(string) []*types.Suggestion {
// reversing so that we display the latest command first
history := utils.Reverse(gui.Config.GetAppState().CustomCommandsHistory)
return fuzzySearchFunc(history)
}
func fuzzySearchFunc(options []string) func(string) []*types.Suggestion {
return func(input string) []*types.Suggestion {
var matches []string
if input == "" {
matches = options
} else {
matches = utils.FuzzySearch(input, options)
}
return matchesToSuggestions(matches)
}
}
+13 -4
View File
@@ -238,10 +238,6 @@ func (gui *Gui) onNewRepo(startArgs appTypes.StartArgs, reuseState bool) error {
return nil
}
type GithubState struct {
RecentPRs []*models.GithubPullRequest
}
// reuseState determines if we pull the repo state from our repo state map or
// just re-initialize it. For now we're only re-using state when we're going
// in and out of submodules, for the sake of having the cursor back on the submodule
@@ -290,6 +286,7 @@ func (gui *Gui) resetState(startArgs appTypes.StartArgs, reuseState bool) {
ReflogCommits: make([]*models.Commit, 0),
BisectInfo: git_commands.NewNullBisectInfo(),
FilesTrie: patricia.NewTrie(),
PullRequests: make([]*models.GithubPullRequest, 0),
},
Modes: &types.Modes{
Filtering: filtering.New(startArgs.FilterPath),
@@ -777,3 +774,15 @@ func (gui *Gui) onUIThread(f func() error) {
return f()
})
}
func (gui *Gui) GetPr(branch *models.Branch) (*models.GithubPullRequest, bool, error) {
prs := git_commands.GenerateGithubPullRequestMap(
gui.State.Model.PullRequests,
[]*models.Branch{branch},
gui.State.Model.Remotes,
)
pr, hasPr := prs[branch]
return pr, hasPr, nil
}
+2 -1
View File
@@ -45,7 +45,8 @@ func (gui *Gui) branchesListContext() *context.BranchesContext {
func() []*models.Branch { return gui.State.Model.Branches },
gui.Views.Branches,
func(startIdx int, length int) [][]string {
return presentation.GetBranchListDisplayStrings(gui.State.Model.Branches, gui.State.ScreenMode != SCREEN_NORMAL, gui.State.Modes.Diffing.Ref, gui.Tr)
prs := git_commands.GenerateGithubPullRequestMap(gui.State.Model.PullRequests, gui.State.Model.Branches, gui.State.Model.Remotes)
return presentation.GetBranchListDisplayStrings(gui.State.Model.Branches, prs, gui.State.ScreenMode != SCREEN_NORMAL, gui.State.Modes.Diffing.Ref, gui.Tr)
},
nil,
gui.withDiffModeCheck(gui.branchesRenderToMain),
+14 -4
View File
@@ -16,15 +16,17 @@ import (
var branchPrefixColorCache = make(map[string]style.TextStyle)
func GetBranchListDisplayStrings(branches []*models.Branch, fullDescription bool, diffName string, tr *i18n.TranslationSet) [][]string {
func GetBranchListDisplayStrings(branches []*models.Branch, prs map[*models.Branch]*models.GithubPullRequest, fullDescription bool, diffName string, tr *i18n.TranslationSet) [][]string {
return slices.Map(branches, func(branch *models.Branch) []string {
diffed := branch.Name == diffName
return getBranchDisplayStrings(branch, fullDescription, diffed, tr)
return getBranchDisplayStrings(branch, prs, fullDescription, diffed, tr)
})
}
// getBranchDisplayStrings returns the display string of branch
func getBranchDisplayStrings(b *models.Branch, fullDescription bool, diffed bool, tr *i18n.TranslationSet) []string {
func getBranchDisplayStrings(b *models.Branch,
prs map[*models.Branch]*models.GithubPullRequest, fullDescription bool, diffed bool, tr *i18n.TranslationSet,
) []string {
displayName := b.Name
if b.DisplayName != "" {
displayName = b.DisplayName
@@ -49,7 +51,15 @@ func getBranchDisplayStrings(b *models.Branch, fullDescription bool, diffed bool
if icons.IsIconEnabled() {
res = append(res, nameTextStyle.Sprint(icons.IconForBranch(b)))
}
res = append(res, coloredName)
pr, hasPr := prs[b]
if hasPr {
res = append(res, coloredPrNumber(pr, hasPr), coloredName)
} else {
res = append(res, coloredName)
}
if fullDescription {
res = append(
res,
-94
View File
@@ -1,94 +0,0 @@
package gui
import (
"fmt"
"strconv"
"github.com/jesseduffield/lazygit/pkg/commands/hosting_service"
"github.com/jesseduffield/lazygit/pkg/commands/models"
)
func (gui *Gui) createOrOpenPullRequestMenu(selectedBranch *models.Branch, checkedOutBranch *models.Branch) error {
menuItems := make([]*menuItem, 0, 4)
fromToDisplayStrings := func(from string, to string) []string {
return []string{fmt.Sprintf("%s → %s", from, to)}
}
menuItemsForBranch := func(branch *models.Branch) []*menuItem {
return []*menuItem{
{
displayStrings: fromToDisplayStrings(branch.Name, gui.Tr.LcDefaultBranch),
onPress: func() error {
return gui.createPullRequest(branch.Name, "")
},
},
{
displayStrings: fromToDisplayStrings(branch.Name, gui.Tr.LcSelectBranch),
onPress: func() error {
return gui.prompt(promptOpts{
title: branch.Name + " →",
findSuggestionsFunc: gui.getBranchNameSuggestionsFunc(),
handleConfirm: func(targetBranchName string) error {
return gui.createPullRequest(branch.Name, targetBranchName)
}},
)
},
},
}
}
pr, hasPr, err := gui.GetPr(selectedBranch)
if err != nil {
return err
}
if hasPr {
menuItems = append(menuItems, &menuItem{
displayString: gui.Git.Gh.Tr.MustSpecifyOriginError + strconv.Itoa(pr.Number),
onPress: func() error {
return gui.OSCommand.OpenLink(pr.Url)
},
})
}
if selectedBranch != checkedOutBranch {
menuItems = append(menuItems,
&menuItem{
displayStrings: fromToDisplayStrings(checkedOutBranch.Name, selectedBranch.Name),
onPress: func() error {
return gui.createPullRequest(checkedOutBranch.Name, selectedBranch.Name)
},
},
)
menuItems = append(menuItems, menuItemsForBranch(checkedOutBranch)...)
}
menuItems = append(menuItems, menuItemsForBranch(selectedBranch)...)
return gui.createMenu(fmt.Sprintf(gui.Tr.CreateOrOpenPullRequestOptions), menuItems, createMenuOptions{showCancel: true})
}
func (gui *Gui) createPullRequest(from string, to string) error {
hostingServiceMgr := gui.getHostingServiceMgr()
url, err := hostingServiceMgr.GetPullRequestURL(from, to)
if err != nil {
return gui.surfaceError(err)
}
// gui.OnRunCommand(oscommands.NewCmdLogEntry(fmt.Sprintf(gui.Tr.CreatingPullRequestAtUrl, url), gui.Tr.CreateOrShowPullRequest, false))
gui.logAction(gui.Tr.Actions.OpenPullRequest)
if err := gui.OSCommand.OpenLink(url); err != nil {
return gui.surfaceError(err)
}
return nil
}
func (gui *Gui) getHostingServiceMgr() *hosting_service.HostingServiceMgr {
remoteUrl := gui.Git.Config.GetRemoteURL()
configServices := gui.UserConfig.Services
return hosting_service.NewHostingServiceMgr(gui.Log, gui.Tr, remoteUrl, configServices)
}
+4
View File
@@ -237,6 +237,10 @@ func (gui *Gui) refreshCommitsWithLimit() error {
}
gui.State.Model.Commits = commits
if gui.Config.GetUserConfig().Git.EnableGhCommand {
gui.refreshGithubPullRequests()
}
return gui.c.PostRefreshUpdate(gui.State.Contexts.LocalCommits)
}
+1
View File
@@ -145,6 +145,7 @@ type Model struct {
StashEntries []*models.StashEntry
SubCommits []*models.Commit
Remotes []*models.Remote
PullRequests []*models.GithubPullRequest
// FilteredReflogCommits are the ones that appear in the reflog panel.
// when in filtering mode we only include the ones that match the given path
+3 -1
View File
@@ -163,7 +163,7 @@ func chineseTranslationSet() TranslationSet {
SwitchRepo: `切换到最近的仓库`,
LcAllBranchesLogGraph: `显示所有分支的日志`,
UnsupportedGitService: `不支持的 git 服务`,
LcCreateOrOpenPullRequestOptions: `创建抓取请求`,
LcCreatePullRequest: `创建抓取请求`,
LcCopyPullRequestURL: `将抓取请求 URL 复制到剪贴板`,
NoBranchOnRemote: `该分支在远程上不存在. 您需要先将其推送到远程.`,
LcFetch: `抓取`,
@@ -436,6 +436,8 @@ func chineseTranslationSet() TranslationSet {
LcCopiedToClipboard: "复制到剪贴板",
ErrCannotEditDirectory: "无法编辑目录:您只能编辑单个文件",
ErrStageDirWithInlineMergeConflicts: "无法 暂存/取消暂存 包含具有内联合并冲突的文件的目录。请先解决合并冲突",
SelectRemoteRepository: "选择存储库",
LcSelectingRemote: "选择遥控器",
ErrRepositoryMovedOrDeleted: "找不到仓库。它可能已被移动或删除 ¯\\_(ツ)_/¯",
CommandLog: "命令日志",
ToggleShowCommandLog: "切换 显示/隐藏 命令日志",
+1 -1
View File
@@ -128,7 +128,7 @@ func dutchTranslationSet() TranslationSet {
SwitchRepo: "wissel naar een recente repo",
LcAllBranchesLogGraph: `alle logs van de branch laten zien`,
UnsupportedGitService: `Niet-ondersteunde git-service`,
LcCreateOrShowPullRequest: `maak of laat een pull-request zien`,
LcCreatePullRequest: `maak een pull-request`,
LcCopyPullRequestURL: `kopieer de URL van het pull-verzoek naar het klembord`,
NoBranchOnRemote: `Deze branch bestaat niet op de remote. U moet het eerst naar de remote pushen.`,
LcFetch: `fetch`,
+8 -17
View File
@@ -162,7 +162,7 @@ type TranslationSet struct {
SwitchRepo string
LcAllBranchesLogGraph string
UnsupportedGitService string
LcCreateOrShowPullRequest string
LcCreatePullRequest string
LcCopyPullRequestURL string
NoBranchOnRemote string
LcFetch string
@@ -355,6 +355,8 @@ type TranslationSet struct {
LcNextScreenMode string
LcPrevScreenMode string
LcStartSearch string
SelectRemoteRepository string
LcSelectingRemote string
Panel string
Keybindings string
LcRenameBranch string
@@ -472,16 +474,12 @@ type TranslationSet struct {
ToggleWhitespaceInDiffView string
IgnoringWhitespaceInDiffView string
ShowingWhitespaceInDiffView string
CreateOrOpenPullRequestOptions string
LcCreateOrOpenPullRequestOptions string
LcDefaultBranch string
LcSelectBranch string
CreateOrShowPullRequest string
CreatingPullRequestAtUrl string
IncreaseContextInDiffView string
DecreaseContextInDiffView string
CreatePullRequestOptions string
LcCreatePullRequestOptions string
LcDefaultBranch string
LcSelectBranch string
CreatePullRequest string
SelectConfigFile string
NoConfigFileFoundErr string
@@ -490,11 +488,8 @@ type TranslationSet struct {
MustSpecifyOriginError string
GitOutput string
GitCommandFailed string
OpenPr string
AbortTitle string
AbortPrompt string
SelectRemoteRepository string
LcSelectingRemote string
LcOpenLogMenu string
LogMenuTitle string
ToggleShowGitGraphAll string
@@ -808,7 +803,7 @@ func EnglishTranslationSet() TranslationSet {
SwitchRepo: `switch to a recent repo`,
LcAllBranchesLogGraph: `show all branch logs`,
UnsupportedGitService: `Unsupported git service`,
LcCreateOrShowPullRequest: `create / open pull request`,
LcCreatePullRequest: `create pull request`,
LcCopyPullRequestURL: `copy pull request URL to clipboard`,
NoBranchOnRemote: `This branch doesn't exist on remote. You need to push it to remote first.`,
LcFetch: `fetch`,
@@ -1002,6 +997,8 @@ func EnglishTranslationSet() TranslationSet {
LcNextScreenMode: "next screen mode (normal/half/fullscreen)",
LcPrevScreenMode: "prev screen mode",
LcStartSearch: "start search",
LcSelectingRemote: "selecting remote",
SelectRemoteRepository: "select base remote repository",
Panel: "Panel",
Keybindings: "Keybindings",
LcRenameBranch: "rename branch",
@@ -1100,8 +1097,6 @@ func EnglishTranslationSet() TranslationSet {
SuggestionsTitle: "Suggestions (press %s to focus)",
ExtrasTitle: "Command Log",
PushingTagStatus: "pushing tag",
SelectRemoteRepository: "select base remote repository",
LcSelectingRemote: "selecting remote",
PullRequestURLCopiedToClipboard: "Pull request URL copied to clipboard",
CommitDiffCopiedToClipboard: "Commit diff copied to clipboard",
CommitSHACopiedToClipboard: "Commit SHA copied to clipboard",
@@ -1121,9 +1116,6 @@ 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",
CreateOrShowPullRequest: "create / open pull request",
CreateOrOpenPullRequestOptions: "create / open pull request options",
LcCreateOrOpenPullRequestOptions: "create / open pull request options",
IncreaseContextInDiffView: "Increase the size of the context shown around changes in the diff view",
DecreaseContextInDiffView: "Decrease the size of the context shown around changes in the diff view",
CreatePullRequest: "Create pull request",
@@ -1138,7 +1130,6 @@ func EnglishTranslationSet() TranslationSet {
MustSpecifyOriginError: "Must specify a remote if specifying a branch",
GitOutput: "Git output:",
GitCommandFailed: "Git command failed. Check command log for details (open with %s)",
OpenPr: "Open PR #",
AbortTitle: "Abort %s",
AbortPrompt: "Are you sure you want to abort the current %s?",
LcOpenLogMenu: "open log menu",
+1 -3
View File
@@ -102,7 +102,7 @@ func polishTranslationSet() TranslationSet {
ConfirmQuit: "Na pewno chcesz wyjść z programu?",
LcAllBranchesLogGraph: "pokaż wszystkie logi gałęzi",
UnsupportedGitService: "Nieobsługiwana usługa git",
LcCreateOrShowPullRequest: `maak of laat een pull-request zien`,
LcCreatePullRequest: "utwórz żądanie pobrania",
LcCopyPullRequestURL: "skopiuj adres URL żądania pobrania do schowka",
NoBranchOnRemote: "Ta gałąź nie istnieje w zdalnym repo. Najpierw musisz ją wysłać.",
LcFetch: "pobierz",
@@ -225,8 +225,6 @@ func polishTranslationSet() TranslationSet {
PullRequestURLCopiedToClipboard: "URL żądania ściągnięcia skopiowany do schowka",
CommitMessageCopiedToClipboard: "Komunikat commita skopiowany do schowka",
LcCopiedToClipboard: "skopiowany do schowka",
CreateOrOpenPullRequestOptions: "Utwórz opcje żądania ściągnięcia",
LcCreateOrOpenPullRequestOptions: "utwórz opcje żądania",
CreatePullRequestOptions: "Utwórz opcje żądania ściągnięcia",
LcCreatePullRequestOptions: "utwórz opcje żądania ściągnięcia",
ConfirmRevertCommit: "Czy na pewno chcesz obrócić {{.selectedCommit}}?",