mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-13 05:15:53 +02:00
show github pr number in branches list
This commit is contained in:
parent
de5133ff90
commit
c295deaa81
23 changed files with 360 additions and 101 deletions
|
@ -39,8 +39,8 @@
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<kbd>space</kbd>: checkout
|
<kbd>space</kbd>: checkout
|
||||||
<kbd>o</kbd>: create pull request
|
<kbd>o</kbd>: create / show pull request
|
||||||
<kbd>O</kbd>: create pull request options
|
<kbd>O</kbd>: create / show pull request options
|
||||||
<kbd>ctrl+y</kbd>: copy pull request URL to clipboard
|
<kbd>ctrl+y</kbd>: copy pull request URL to clipboard
|
||||||
<kbd>c</kbd>: checkout by name
|
<kbd>c</kbd>: checkout by name
|
||||||
<kbd>F</kbd>: force checkout
|
<kbd>F</kbd>: force checkout
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
<kbd>space</kbd>: uitchecken
|
<kbd>space</kbd>: uitchecken
|
||||||
<kbd>o</kbd>: maak een pull-request
|
<kbd>o</kbd>: maak of laat een pull-request zien
|
||||||
<kbd>O</kbd>: bekijk opties voor pull-aanvraag
|
<kbd>O</kbd>: bekijk opties voor pull-aanvraag
|
||||||
<kbd>ctrl+y</kbd>: kopieer de URL van het pull-verzoek naar het klembord
|
<kbd>ctrl+y</kbd>: kopieer de URL van het pull-verzoek naar het klembord
|
||||||
<kbd>c</kbd>: uitchecken bij naam
|
<kbd>c</kbd>: uitchecken bij naam
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/go-errors/errors"
|
"github.com/go-errors/errors"
|
||||||
|
|
||||||
gogit "github.com/jesseduffield/go-git/v5"
|
gogit "github.com/jesseduffield/go-git/v5"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/patch"
|
"github.com/jesseduffield/lazygit/pkg/commands/patch"
|
||||||
"github.com/jesseduffield/lazygit/pkg/config"
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
|
@ -39,6 +40,8 @@ type GitCommand struct {
|
||||||
|
|
||||||
// Push to current determines whether the user has configured to push to the remote branch of the same name as the current or not
|
// Push to current determines whether the user has configured to push to the remote branch of the same name as the current or not
|
||||||
PushToCurrent bool
|
PushToCurrent bool
|
||||||
|
|
||||||
|
GithubRecentPRs map[string]models.GithubPullRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGitCommand it runs git commands
|
// NewGitCommand it runs git commands
|
||||||
|
|
65
pkg/commands/github.go
Normal file
65
pkg/commands/github.go
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
package commands
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *GitCommand) GithubMostRecentPRs() map[string]models.GithubPullRequest {
|
||||||
|
commandOutput, err := c.OSCommand.RunCommandWithOutput("gh pr list --limit 50 --state all --json state,url,number,headRefName,headRepositoryOwner")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(1, err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
prs := []models.GithubPullRequest{}
|
||||||
|
err = json.Unmarshal([]byte(commandOutput), &prs)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(2, err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
res := map[string]models.GithubPullRequest{}
|
||||||
|
for _, pr := range prs {
|
||||||
|
res[pr.HeadRepositoryOwner.Login+":"+pr.HeadRefName] = pr
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *GitCommand) InjectGithubPullRequests(prs map[string]models.GithubPullRequest, branches []*models.Branch) bool {
|
||||||
|
if len(prs) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
remotesToOwnersMap, _ := c.GetRemotesToOwnersMap()
|
||||||
|
if len(remotesToOwnersMap) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
foundBranchWithGithubPullRequest := false
|
||||||
|
|
||||||
|
for _, branch := range branches {
|
||||||
|
if branch.UpstreamName == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
remoteAndName := strings.SplitN(branch.UpstreamName, "/", 2)
|
||||||
|
owner, foundRemoteOwner := remotesToOwnersMap[remoteAndName[0]]
|
||||||
|
if len(remoteAndName) != 2 || !foundRemoteOwner {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
pr, hasPr := prs[owner+":"+remoteAndName[1]]
|
||||||
|
if !hasPr {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
foundBranchWithGithubPullRequest = true
|
||||||
|
branch.PR = &pr
|
||||||
|
}
|
||||||
|
|
||||||
|
return foundBranchWithGithubPullRequest
|
||||||
|
}
|
75
pkg/commands/github_test.go
Normal file
75
pkg/commands/github_test.go
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
package commands
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os/exec"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/secureexec"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGithubMostRecentPRs(t *testing.T) {
|
||||||
|
scenarios := []struct {
|
||||||
|
testName string
|
||||||
|
response string
|
||||||
|
expect map[string]models.GithubPullRequest
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"no response",
|
||||||
|
"",
|
||||||
|
nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"error response",
|
||||||
|
"none of the git remotes configured for this repository point to a known GitHub host. To tell gh about a new GitHub host, please use `gh auth login`",
|
||||||
|
nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"empty response",
|
||||||
|
"[]",
|
||||||
|
map[string]models.GithubPullRequest{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"response with data",
|
||||||
|
`[{
|
||||||
|
"headRefName": "command-log-2",
|
||||||
|
"number": 1249,
|
||||||
|
"state": "MERGED",
|
||||||
|
"url": "https://github.com/jesseduffield/lazygit/pull/1249",
|
||||||
|
"headRepositoryOwner": {
|
||||||
|
"id": "MDQ6VXNlcjg0NTY2MzM=",
|
||||||
|
"name": "Jesse Duffield",
|
||||||
|
"login": "jesseduffield"
|
||||||
|
}
|
||||||
|
}]`,
|
||||||
|
map[string]models.GithubPullRequest{
|
||||||
|
"jesseduffield:command-log-2": {
|
||||||
|
HeadRefName: "command-log-2",
|
||||||
|
Number: 1249,
|
||||||
|
State: "MERGED",
|
||||||
|
Url: "https://github.com/jesseduffield/lazygit/pull/1249",
|
||||||
|
HeadRepositoryOwner: models.GithubRepositoryOwner{
|
||||||
|
ID: "MDQ6VXNlcjg0NTY2MzM=",
|
||||||
|
Name: "Jesse Duffield",
|
||||||
|
Login: "jesseduffield",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range scenarios {
|
||||||
|
t.Run(s.testName, func(t *testing.T) {
|
||||||
|
gitCmd := NewDummyGitCommand()
|
||||||
|
gitCmd.OSCommand.Command = func(cmd string, args ...string) *exec.Cmd {
|
||||||
|
assert.EqualValues(t, "gh", cmd)
|
||||||
|
assert.EqualValues(t, []string{"pr", "list", "--limit", "50", "--state", "all", "--json", "state,url,number,headRefName,headRepositoryOwner"}, args)
|
||||||
|
return secureexec.Command("echo", s.response)
|
||||||
|
}
|
||||||
|
|
||||||
|
res := gitCmd.GithubMostRecentPRs()
|
||||||
|
assert.Equal(t, s.expect, res)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -99,8 +99,8 @@ func (b *BranchListBuilder) obtainBranches() []*models.Branch {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the list of branches for the current repo
|
// Build the list of branches for the current repo
|
||||||
func (b *BranchListBuilder) Build() []*models.Branch {
|
func (b *BranchListBuilder) Build() (branches []*models.Branch, branchesWithGithubPullRequests bool) {
|
||||||
branches := b.obtainBranches()
|
branches = b.obtainBranches()
|
||||||
|
|
||||||
reflogBranches := b.obtainReflogBranches()
|
reflogBranches := b.obtainReflogBranches()
|
||||||
|
|
||||||
|
@ -138,9 +138,17 @@ outer:
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
branches = append([]*models.Branch{{Name: currentBranchName, DisplayName: currentBranchDisplayName, Head: true, Recency: " *"}}, branches...)
|
branches = append([]*models.Branch{{
|
||||||
|
Name: currentBranchName,
|
||||||
|
DisplayName: currentBranchDisplayName,
|
||||||
|
Head: true,
|
||||||
|
Recency: " *",
|
||||||
|
}}, branches...)
|
||||||
}
|
}
|
||||||
return branches
|
|
||||||
|
branchesWithGithubPullRequests = b.GitCommand.InjectGithubPullRequests(b.GitCommand.GithubRecentPRs, branches)
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: only look at the new reflog commits, and otherwise store the recencies in
|
// TODO: only look at the new reflog commits, and otherwise store the recencies in
|
||||||
|
|
|
@ -11,6 +11,7 @@ type Branch struct {
|
||||||
Pullables string
|
Pullables string
|
||||||
UpstreamName string
|
UpstreamName string
|
||||||
Head bool
|
Head bool
|
||||||
|
PR *GithubPullRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Branch) RefName() string {
|
func (b *Branch) RefName() string {
|
||||||
|
|
15
pkg/commands/models/github.go
Normal file
15
pkg/commands/models/github.go
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
package models
|
||||||
|
|
||||||
|
type GithubPullRequest struct {
|
||||||
|
HeadRefName string `json:"headRefName"`
|
||||||
|
Number int `json:"number"`
|
||||||
|
State string `json:"state"` // "MERGED", "OPEN", "CLOSED"
|
||||||
|
Url string `json:"url"`
|
||||||
|
HeadRepositoryOwner GithubRepositoryOwner `json:"headRepositoryOwner"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GithubRepositoryOwner struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Login string `json:"login"`
|
||||||
|
}
|
|
@ -153,34 +153,9 @@ func (pr *PullRequest) getPullRequestURL(from string, to string) (string, error)
|
||||||
return "", errors.New(pr.GitCommand.Tr.UnsupportedGitService)
|
return "", errors.New(pr.GitCommand.Tr.UnsupportedGitService)
|
||||||
}
|
}
|
||||||
|
|
||||||
repoInfo := getRepoInfoFromURL(repoURL)
|
repoInfo := GetRepoInfoFromURL(repoURL)
|
||||||
|
|
||||||
pullRequestURL := gitService.PullRequestURL(repoInfo.Owner, repoInfo.Repository, from, to)
|
pullRequestURL := gitService.PullRequestURL(repoInfo.Owner, repoInfo.Repository, from, to)
|
||||||
|
|
||||||
return pullRequestURL, nil
|
return pullRequestURL, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRepoInfoFromURL(url string) *RepoInformation {
|
|
||||||
isHTTP := strings.HasPrefix(url, "http")
|
|
||||||
|
|
||||||
if isHTTP {
|
|
||||||
splits := strings.Split(url, "/")
|
|
||||||
owner := strings.Join(splits[3:len(splits)-1], "/")
|
|
||||||
repo := strings.TrimSuffix(splits[len(splits)-1], ".git")
|
|
||||||
|
|
||||||
return &RepoInformation{
|
|
||||||
Owner: owner,
|
|
||||||
Repository: repo,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tmpSplit := strings.Split(url, ":")
|
|
||||||
splits := strings.Split(tmpSplit[1], "/")
|
|
||||||
owner := strings.Join(splits[0:len(splits)-1], "/")
|
|
||||||
repo := strings.TrimSuffix(splits[len(splits)-1], ".git")
|
|
||||||
|
|
||||||
return &RepoInformation{
|
|
||||||
Owner: owner,
|
|
||||||
Repository: repo,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ func TestGetRepoInfoFromURL(t *testing.T) {
|
||||||
|
|
||||||
for _, s := range scenarios {
|
for _, s := range scenarios {
|
||||||
t.Run(s.testName, func(t *testing.T) {
|
t.Run(s.testName, func(t *testing.T) {
|
||||||
s.test(getRepoInfoFromURL(s.repoURL))
|
s.test(GetRepoInfoFromURL(s.repoURL))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package commands
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *GitCommand) AddRemote(name string, url string) error {
|
func (c *GitCommand) AddRemote(name string, url string) error {
|
||||||
|
@ -39,3 +40,66 @@ func (c *GitCommand) CheckRemoteBranchExists(branchName string) bool {
|
||||||
func (c *GitCommand) GetRemoteURL() string {
|
func (c *GitCommand) GetRemoteURL() string {
|
||||||
return c.GetConfigValue("remote.origin.url")
|
return c.GetConfigValue("remote.origin.url")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *GitCommand) GetRemoteURLs() (map[string]string, error) {
|
||||||
|
res := map[string]string{}
|
||||||
|
out, err := c.OSCommand.RunCommandWithOutput("git remote -v")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
lines := strings.Split(strings.TrimSpace(out), "\n")
|
||||||
|
for _, line := range lines {
|
||||||
|
lineParts := strings.Split(line, "\t")
|
||||||
|
if len(lineParts) < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
name := lineParts[0] // "origin"
|
||||||
|
for _, mightBeUrl := range lineParts[1:] {
|
||||||
|
if len(mightBeUrl) > 0 {
|
||||||
|
// mightBeUrl = "git@github.com:jesseduffield/lazygit.git (fetch)"
|
||||||
|
res[name] = strings.SplitN(mightBeUrl, " ", 2)[0]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetRepoInfoFromURL(url string) *RepoInformation {
|
||||||
|
isHTTP := strings.HasPrefix(url, "http")
|
||||||
|
|
||||||
|
if isHTTP {
|
||||||
|
splits := strings.Split(url, "/")
|
||||||
|
owner := strings.Join(splits[3:len(splits)-1], "/")
|
||||||
|
repo := strings.TrimSuffix(splits[len(splits)-1], ".git")
|
||||||
|
|
||||||
|
return &RepoInformation{
|
||||||
|
Owner: owner,
|
||||||
|
Repository: repo,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpSplit := strings.Split(url, ":")
|
||||||
|
splits := strings.Split(tmpSplit[1], "/")
|
||||||
|
owner := strings.Join(splits[0:len(splits)-1], "/")
|
||||||
|
repo := strings.TrimSuffix(splits[len(splits)-1], ".git")
|
||||||
|
|
||||||
|
return &RepoInformation{
|
||||||
|
Owner: owner,
|
||||||
|
Repository: repo,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *GitCommand) GetRemotesToOwnersMap() (map[string]string, error) {
|
||||||
|
remotes, err := c.GetRemoteURLs()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res := map[string]string{}
|
||||||
|
for remoteName, remoteUrl := range remotes {
|
||||||
|
res[remoteName] = GetRepoInfoFromURL(remoteUrl).Owner
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
|
@ -192,19 +192,19 @@ type KeybindingFilesConfig struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type KeybindingBranchesConfig struct {
|
type KeybindingBranchesConfig struct {
|
||||||
CreatePullRequest string `yaml:"createPullRequest"`
|
CreateOrShowPullRequest string `yaml:"createPullRequest"`
|
||||||
ViewPullRequestOptions string `yaml:"viewPullRequestOptions"`
|
ViewPullRequestOptions string `yaml:"viewPullRequestOptions"`
|
||||||
CopyPullRequestURL string `yaml:"copyPullRequestURL"`
|
CopyPullRequestURL string `yaml:"copyPullRequestURL"`
|
||||||
CheckoutBranchByName string `yaml:"checkoutBranchByName"`
|
CheckoutBranchByName string `yaml:"checkoutBranchByName"`
|
||||||
ForceCheckoutBranch string `yaml:"forceCheckoutBranch"`
|
ForceCheckoutBranch string `yaml:"forceCheckoutBranch"`
|
||||||
RebaseBranch string `yaml:"rebaseBranch"`
|
RebaseBranch string `yaml:"rebaseBranch"`
|
||||||
RenameBranch string `yaml:"renameBranch"`
|
RenameBranch string `yaml:"renameBranch"`
|
||||||
MergeIntoCurrentBranch string `yaml:"mergeIntoCurrentBranch"`
|
MergeIntoCurrentBranch string `yaml:"mergeIntoCurrentBranch"`
|
||||||
ViewGitFlowOptions string `yaml:"viewGitFlowOptions"`
|
ViewGitFlowOptions string `yaml:"viewGitFlowOptions"`
|
||||||
FastForward string `yaml:"fastForward"`
|
FastForward string `yaml:"fastForward"`
|
||||||
PushTag string `yaml:"pushTag"`
|
PushTag string `yaml:"pushTag"`
|
||||||
SetUpstream string `yaml:"setUpstream"`
|
SetUpstream string `yaml:"setUpstream"`
|
||||||
FetchRemote string `yaml:"fetchRemote"`
|
FetchRemote string `yaml:"fetchRemote"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type KeybindingCommitsConfig struct {
|
type KeybindingCommitsConfig struct {
|
||||||
|
@ -436,19 +436,19 @@ func GetDefaultConfig() *UserConfig {
|
||||||
OpenMergeTool: "M",
|
OpenMergeTool: "M",
|
||||||
},
|
},
|
||||||
Branches: KeybindingBranchesConfig{
|
Branches: KeybindingBranchesConfig{
|
||||||
CopyPullRequestURL: "<c-y>",
|
CopyPullRequestURL: "<c-y>",
|
||||||
CreatePullRequest: "o",
|
CreateOrShowPullRequest: "o",
|
||||||
ViewPullRequestOptions: "O",
|
ViewPullRequestOptions: "O",
|
||||||
CheckoutBranchByName: "c",
|
CheckoutBranchByName: "c",
|
||||||
ForceCheckoutBranch: "F",
|
ForceCheckoutBranch: "F",
|
||||||
RebaseBranch: "r",
|
RebaseBranch: "r",
|
||||||
RenameBranch: "R",
|
RenameBranch: "R",
|
||||||
MergeIntoCurrentBranch: "M",
|
MergeIntoCurrentBranch: "M",
|
||||||
ViewGitFlowOptions: "i",
|
ViewGitFlowOptions: "i",
|
||||||
FastForward: "f",
|
FastForward: "f",
|
||||||
PushTag: "P",
|
PushTag: "P",
|
||||||
SetUpstream: "u",
|
SetUpstream: "u",
|
||||||
FetchRemote: "f",
|
FetchRemote: "f",
|
||||||
},
|
},
|
||||||
Commits: KeybindingCommitsConfig{
|
Commits: KeybindingCommitsConfig{
|
||||||
SquashDown: "s",
|
SquashDown: "s",
|
||||||
|
|
|
@ -68,7 +68,7 @@ func (gui *Gui) refreshBranches() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = gui.surfaceError(err)
|
_ = gui.surfaceError(err)
|
||||||
}
|
}
|
||||||
gui.State.Branches = builder.Build()
|
gui.State.Branches, gui.State.BranchesWithGithubPullRequests = builder.Build()
|
||||||
|
|
||||||
if err := gui.postRefreshUpdate(gui.State.Contexts.Branches); err != nil {
|
if err := gui.postRefreshUpdate(gui.State.Contexts.Branches); err != nil {
|
||||||
gui.Log.Error(err)
|
gui.Log.Error(err)
|
||||||
|
@ -77,6 +77,13 @@ func (gui *Gui) refreshBranches() {
|
||||||
gui.refreshStatus()
|
gui.refreshStatus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) refreshGithubPullRequests() {
|
||||||
|
prs := gui.GitCommand.GithubMostRecentPRs()
|
||||||
|
if len(prs) > 0 {
|
||||||
|
gui.GitCommand.GithubRecentPRs = prs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// specific functions
|
// specific functions
|
||||||
|
|
||||||
func (gui *Gui) handleBranchPress() error {
|
func (gui *Gui) handleBranchPress() error {
|
||||||
|
@ -90,19 +97,22 @@ func (gui *Gui) handleBranchPress() error {
|
||||||
return gui.handleCheckoutRef(branch.Name, handleCheckoutRefOptions{span: gui.Tr.Spans.CheckoutBranch})
|
return gui.handleCheckoutRef(branch.Name, handleCheckoutRefOptions{span: gui.Tr.Spans.CheckoutBranch})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleCreatePullRequestPress() error {
|
func (gui *Gui) handleCreateOrShowPullRequestPress() error {
|
||||||
branch := gui.getSelectedBranch()
|
branch := gui.getSelectedBranch()
|
||||||
|
if branch.PR != nil {
|
||||||
|
return gui.OSCommand.OpenLink(branch.PR.Url)
|
||||||
|
}
|
||||||
return gui.createPullRequest(branch.Name, "")
|
return gui.createPullRequest(branch.Name, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleCreatePullRequestMenu() error {
|
func (gui *Gui) handleCreateOrOpenPullRequestMenu() error {
|
||||||
selectedBranch := gui.getSelectedBranch()
|
selectedBranch := gui.getSelectedBranch()
|
||||||
if selectedBranch == nil {
|
if selectedBranch == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
checkedOutBranch := gui.getCheckedOutBranch()
|
checkedOutBranch := gui.getCheckedOutBranch()
|
||||||
|
|
||||||
return gui.createPullRequestMenu(selectedBranch, checkedOutBranch)
|
return gui.createOrOpenPullRequestMenu(selectedBranch, checkedOutBranch)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleCopyPullRequestURLPress() error {
|
func (gui *Gui) handleCopyPullRequestURLPress() error {
|
||||||
|
|
|
@ -61,12 +61,23 @@ func (gui *Gui) handleCommitSelect() error {
|
||||||
func (gui *Gui) refreshReflogCommitsConsideringStartup() {
|
func (gui *Gui) refreshReflogCommitsConsideringStartup() {
|
||||||
switch gui.State.StartupStage {
|
switch gui.State.StartupStage {
|
||||||
case INITIAL:
|
case INITIAL:
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(1)
|
||||||
|
|
||||||
go utils.Safe(func() {
|
go utils.Safe(func() {
|
||||||
_ = gui.refreshReflogCommits()
|
_ = gui.refreshReflogCommits()
|
||||||
gui.refreshBranches()
|
gui.refreshBranches()
|
||||||
gui.State.StartupStage = COMPLETE
|
gui.State.StartupStage = COMPLETE
|
||||||
|
wg.Done()
|
||||||
|
})
|
||||||
|
go utils.Safe(func() {
|
||||||
|
// The github cli can be quite slow so we load the github PRs sparately
|
||||||
|
gui.refreshGithubPullRequests()
|
||||||
|
wg.Wait()
|
||||||
|
gui.State.BranchesWithGithubPullRequests = gui.GitCommand.InjectGithubPullRequests(gui.GitCommand.GithubRecentPRs, gui.State.Branches)
|
||||||
|
_ = gui.postRefreshUpdate(gui.State.Contexts.Branches)
|
||||||
|
gui.refreshStatus()
|
||||||
})
|
})
|
||||||
|
|
||||||
case COMPLETE:
|
case COMPLETE:
|
||||||
_ = gui.refreshReflogCommits()
|
_ = gui.refreshReflogCommits()
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,12 +289,13 @@ type guiMutexes struct {
|
||||||
type guiState struct {
|
type guiState struct {
|
||||||
// the file panels (files and commit files) can render as a tree, so we have
|
// the file panels (files and commit files) can render as a tree, so we have
|
||||||
// managers for them which handle rendering a flat list of files in tree form
|
// managers for them which handle rendering a flat list of files in tree form
|
||||||
FileManager *filetree.FileManager
|
FileManager *filetree.FileManager
|
||||||
CommitFileManager *filetree.CommitFileManager
|
CommitFileManager *filetree.CommitFileManager
|
||||||
Submodules []*models.SubmoduleConfig
|
Submodules []*models.SubmoduleConfig
|
||||||
Branches []*models.Branch
|
Branches []*models.Branch
|
||||||
Commits []*models.Commit
|
BranchesWithGithubPullRequests bool
|
||||||
StashEntries []*models.StashEntry
|
Commits []*models.Commit
|
||||||
|
StashEntries []*models.StashEntry
|
||||||
// Suggestions will sometimes appear when typing into a prompt
|
// Suggestions will sometimes appear when typing into a prompt
|
||||||
Suggestions []*types.Suggestion
|
Suggestions []*types.Suggestion
|
||||||
// FilteredReflogCommits are the ones that appear in the reflog panel.
|
// FilteredReflogCommits are the ones that appear in the reflog panel.
|
||||||
|
|
|
@ -541,16 +541,16 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
||||||
{
|
{
|
||||||
ViewName: "branches",
|
ViewName: "branches",
|
||||||
Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)},
|
Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)},
|
||||||
Key: gui.getKey(config.Branches.CreatePullRequest),
|
Key: gui.getKey(config.Branches.CreateOrShowPullRequest),
|
||||||
Handler: gui.handleCreatePullRequestPress,
|
Handler: gui.handleCreateOrShowPullRequestPress,
|
||||||
Description: gui.Tr.LcCreatePullRequest,
|
Description: gui.Tr.LcCreateOrShowPullRequest,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "branches",
|
ViewName: "branches",
|
||||||
Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)},
|
Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)},
|
||||||
Key: gui.getKey(config.Branches.ViewPullRequestOptions),
|
Key: gui.getKey(config.Branches.ViewPullRequestOptions),
|
||||||
Handler: gui.handleCreatePullRequestMenu,
|
Handler: gui.handleCreateOrOpenPullRequestMenu,
|
||||||
Description: gui.Tr.LcCreatePullRequestOptions,
|
Description: gui.Tr.LcCreateOrOpenPullRequestOptions,
|
||||||
OpensMenu: true,
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -70,7 +70,12 @@ func (gui *Gui) branchesListContext() *ListContext {
|
||||||
Gui: gui,
|
Gui: gui,
|
||||||
ResetMainViewOriginOnFocus: true,
|
ResetMainViewOriginOnFocus: true,
|
||||||
GetDisplayStrings: func() [][]string {
|
GetDisplayStrings: func() [][]string {
|
||||||
return presentation.GetBranchListDisplayStrings(gui.State.Branches, gui.State.ScreenMode != SCREEN_NORMAL, gui.State.Modes.Diffing.Ref)
|
return presentation.GetBranchListDisplayStrings(
|
||||||
|
gui.State.Branches,
|
||||||
|
gui.State.ScreenMode != SCREEN_NORMAL,
|
||||||
|
gui.State.Modes.Diffing.Ref,
|
||||||
|
gui.State.BranchesWithGithubPullRequests,
|
||||||
|
)
|
||||||
},
|
},
|
||||||
SelectedItem: func() (ListItem, bool) {
|
SelectedItem: func() (ListItem, bool) {
|
||||||
item := gui.getSelectedBranch()
|
item := gui.getSelectedBranch()
|
||||||
|
|
|
@ -2,6 +2,7 @@ package presentation
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
|
@ -10,19 +11,19 @@ import (
|
||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetBranchListDisplayStrings(branches []*models.Branch, fullDescription bool, diffName string) [][]string {
|
func GetBranchListDisplayStrings(branches []*models.Branch, fullDescription bool, diffName string, showGithub bool) [][]string {
|
||||||
lines := make([][]string, len(branches))
|
lines := make([][]string, len(branches))
|
||||||
|
|
||||||
for i := range branches {
|
for i := range branches {
|
||||||
diffed := branches[i].Name == diffName
|
diffed := branches[i].Name == diffName
|
||||||
lines[i] = getBranchDisplayStrings(branches[i], fullDescription, diffed)
|
lines[i] = getBranchDisplayStrings(branches[i], fullDescription, diffed, showGithub)
|
||||||
}
|
}
|
||||||
|
|
||||||
return lines
|
return lines
|
||||||
}
|
}
|
||||||
|
|
||||||
// getBranchDisplayStrings returns the display string of branch
|
// getBranchDisplayStrings returns the display string of branch
|
||||||
func getBranchDisplayStrings(b *models.Branch, fullDescription bool, diffed bool) []string {
|
func getBranchDisplayStrings(b *models.Branch, fullDescription bool, diffed, showGithub bool) []string {
|
||||||
displayName := b.Name
|
displayName := b.Name
|
||||||
if b.DisplayName != "" {
|
if b.DisplayName != "" {
|
||||||
displayName = b.DisplayName
|
displayName = b.DisplayName
|
||||||
|
@ -42,11 +43,26 @@ func getBranchDisplayStrings(b *models.Branch, fullDescription bool, diffed bool
|
||||||
recencyColor = color.FgGreen
|
recencyColor = color.FgGreen
|
||||||
}
|
}
|
||||||
|
|
||||||
if fullDescription {
|
res := []string{utils.ColoredString(b.Recency, recencyColor)}
|
||||||
return []string{utils.ColoredString(b.Recency, recencyColor), coloredName, utils.ColoredString(b.UpstreamName, color.FgYellow)}
|
if showGithub {
|
||||||
|
if b.PR != nil {
|
||||||
|
colour := color.FgMagenta // = state MERGED
|
||||||
|
switch b.PR.State {
|
||||||
|
case "OPEN":
|
||||||
|
colour = color.FgGreen
|
||||||
|
case "CLOSED":
|
||||||
|
colour = color.FgRed
|
||||||
|
}
|
||||||
|
res = append(res, utils.ColoredString("#"+strconv.Itoa(b.PR.Number), colour))
|
||||||
|
} else {
|
||||||
|
res = append(res, "")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return []string{utils.ColoredString(b.Recency, recencyColor), coloredName}
|
if fullDescription {
|
||||||
|
return append(res, coloredName, utils.ColoredString(b.UpstreamName, color.FgYellow))
|
||||||
|
}
|
||||||
|
return append(res, coloredName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBranchColor branch color
|
// GetBranchColor branch color
|
||||||
|
|
|
@ -2,13 +2,14 @@ package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (gui *Gui) createPullRequestMenu(selectedBranch *models.Branch, checkedOutBranch *models.Branch) error {
|
func (gui *Gui) createOrOpenPullRequestMenu(selectedBranch *models.Branch, checkedOutBranch *models.Branch) error {
|
||||||
menuItems := make([]*menuItem, 0, 4)
|
menuItems := make([]*menuItem, 0, 4)
|
||||||
|
|
||||||
fromToDisplayStrings := func(from string, to string) []string {
|
fromToDisplayStrings := func(from string, to string) []string {
|
||||||
|
@ -38,6 +39,15 @@ func (gui *Gui) createPullRequestMenu(selectedBranch *models.Branch, checkedOutB
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if selectedBranch.PR != nil {
|
||||||
|
menuItems = append(menuItems, &menuItem{
|
||||||
|
displayString: "open #" + strconv.Itoa(selectedBranch.PR.Number),
|
||||||
|
onPress: func() error {
|
||||||
|
return gui.OSCommand.OpenLink(selectedBranch.PR.Url)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if selectedBranch != checkedOutBranch {
|
if selectedBranch != checkedOutBranch {
|
||||||
menuItems = append(menuItems,
|
menuItems = append(menuItems,
|
||||||
&menuItem{
|
&menuItem{
|
||||||
|
@ -52,7 +62,7 @@ func (gui *Gui) createPullRequestMenu(selectedBranch *models.Branch, checkedOutB
|
||||||
|
|
||||||
menuItems = append(menuItems, menuItemsForBranch(selectedBranch)...)
|
menuItems = append(menuItems, menuItemsForBranch(selectedBranch)...)
|
||||||
|
|
||||||
return gui.createMenu(fmt.Sprintf(gui.Tr.CreatePullRequestOptions), menuItems, createMenuOptions{showCancel: true})
|
return gui.createMenu(fmt.Sprintf(gui.Tr.CreateOrOpenPullRequestOptions), menuItems, createMenuOptions{showCancel: true})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) createPullRequest(from string, to string) error {
|
func (gui *Gui) createPullRequest(from string, to string) error {
|
||||||
|
@ -61,7 +71,7 @@ func (gui *Gui) createPullRequest(from string, to string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gui.surfaceError(err)
|
return gui.surfaceError(err)
|
||||||
}
|
}
|
||||||
gui.OnRunCommand(oscommands.NewCmdLogEntry(fmt.Sprintf(gui.Tr.CreatingPullRequestAtUrl, url), gui.Tr.CreatePullRequest, false))
|
gui.OnRunCommand(oscommands.NewCmdLogEntry(fmt.Sprintf(gui.Tr.CreatingPullRequestAtUrl, url), gui.Tr.CreateOrShowPullRequest, false))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,7 +176,7 @@ func chineseTranslationSet() TranslationSet {
|
||||||
SwitchRepo: `切换到最近的仓库`,
|
SwitchRepo: `切换到最近的仓库`,
|
||||||
LcAllBranchesLogGraph: `显示所有分支日志`,
|
LcAllBranchesLogGraph: `显示所有分支日志`,
|
||||||
UnsupportedGitService: `不支持的git服务`,
|
UnsupportedGitService: `不支持的git服务`,
|
||||||
LcCreatePullRequest: `创建pull请求`,
|
LcCreateOrShowPullRequest: `创建pull请求`,
|
||||||
LcCopyPullRequestURL: `将拉取请求URL复制到剪贴板`,
|
LcCopyPullRequestURL: `将拉取请求URL复制到剪贴板`,
|
||||||
NoBranchOnRemote: `该分支在远程上不存在。您需要先将其推送到远程.`,
|
NoBranchOnRemote: `该分支在远程上不存在。您需要先将其推送到远程.`,
|
||||||
LcFetch: `fetch`,
|
LcFetch: `fetch`,
|
||||||
|
|
|
@ -154,7 +154,7 @@ func dutchTranslationSet() TranslationSet {
|
||||||
SwitchRepo: "wissel naar een recente repo",
|
SwitchRepo: "wissel naar een recente repo",
|
||||||
LcAllBranchesLogGraph: `alle logs van de branch laten zien`,
|
LcAllBranchesLogGraph: `alle logs van de branch laten zien`,
|
||||||
UnsupportedGitService: `Niet-ondersteunde git-service`,
|
UnsupportedGitService: `Niet-ondersteunde git-service`,
|
||||||
LcCreatePullRequest: `maak een pull-request`,
|
LcCreateOrShowPullRequest: `maak of laat een pull-request zien`,
|
||||||
LcCopyPullRequestURL: `kopieer de URL van het pull-verzoek naar het klembord`,
|
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.`,
|
NoBranchOnRemote: `Deze branch bestaat niet op de remote. U moet het eerst naar de remote pushen.`,
|
||||||
LcFetch: `fetch`,
|
LcFetch: `fetch`,
|
||||||
|
@ -396,7 +396,7 @@ func dutchTranslationSet() TranslationSet {
|
||||||
LcInitSubmodule: "initialiseer submodule",
|
LcInitSubmodule: "initialiseer submodule",
|
||||||
LcViewBulkSubmoduleOptions: "bekijk bulk submodule opties",
|
LcViewBulkSubmoduleOptions: "bekijk bulk submodule opties",
|
||||||
LcViewStashFiles: "bekijk bestanden van stash entry",
|
LcViewStashFiles: "bekijk bestanden van stash entry",
|
||||||
CreatePullRequestOptions: "Bekijk opties voor pull-aanvraag",
|
CreateOrOpenPullRequestOptions: "Bekijk opties voor pull-aanvraag",
|
||||||
LcCreatePullRequestOptions: "bekijk opties voor pull-aanvraag",
|
LcCreateOrOpenPullRequestOptions: "bekijk opties voor pull-aanvraag",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,7 +169,7 @@ type TranslationSet struct {
|
||||||
SwitchRepo string
|
SwitchRepo string
|
||||||
LcAllBranchesLogGraph string
|
LcAllBranchesLogGraph string
|
||||||
UnsupportedGitService string
|
UnsupportedGitService string
|
||||||
LcCreatePullRequest string
|
LcCreateOrShowPullRequest string
|
||||||
LcCopyPullRequestURL string
|
LcCopyPullRequestURL string
|
||||||
NoBranchOnRemote string
|
NoBranchOnRemote string
|
||||||
LcFetch string
|
LcFetch string
|
||||||
|
@ -454,11 +454,11 @@ type TranslationSet struct {
|
||||||
ToggleWhitespaceInDiffView string
|
ToggleWhitespaceInDiffView string
|
||||||
IgnoringWhitespaceInDiffView string
|
IgnoringWhitespaceInDiffView string
|
||||||
ShowingWhitespaceInDiffView string
|
ShowingWhitespaceInDiffView string
|
||||||
CreatePullRequestOptions string
|
CreateOrOpenPullRequestOptions string
|
||||||
LcCreatePullRequestOptions string
|
LcCreateOrOpenPullRequestOptions string
|
||||||
LcDefaultBranch string
|
LcDefaultBranch string
|
||||||
LcSelectBranch string
|
LcSelectBranch string
|
||||||
CreatePullRequest string
|
CreateOrShowPullRequest string
|
||||||
CreatingPullRequestAtUrl string
|
CreatingPullRequestAtUrl string
|
||||||
Spans Spans
|
Spans Spans
|
||||||
}
|
}
|
||||||
|
@ -720,7 +720,7 @@ func englishTranslationSet() TranslationSet {
|
||||||
SwitchRepo: `switch to a recent repo`,
|
SwitchRepo: `switch to a recent repo`,
|
||||||
LcAllBranchesLogGraph: `show all branch logs`,
|
LcAllBranchesLogGraph: `show all branch logs`,
|
||||||
UnsupportedGitService: `Unsupported git service`,
|
UnsupportedGitService: `Unsupported git service`,
|
||||||
LcCreatePullRequest: `create pull request`,
|
LcCreateOrShowPullRequest: `create / show pull request`,
|
||||||
LcCopyPullRequestURL: `copy pull request URL to clipboard`,
|
LcCopyPullRequestURL: `copy pull request URL to clipboard`,
|
||||||
NoBranchOnRemote: `This branch doesn't exist on remote. You need to push it to remote first.`,
|
NoBranchOnRemote: `This branch doesn't exist on remote. You need to push it to remote first.`,
|
||||||
LcFetch: `fetch`,
|
LcFetch: `fetch`,
|
||||||
|
@ -1007,9 +1007,9 @@ func englishTranslationSet() TranslationSet {
|
||||||
ToggleWhitespaceInDiffView: "Toggle whether or not whitespace changes are shown in the diff view",
|
ToggleWhitespaceInDiffView: "Toggle whether or not whitespace changes are shown in the diff view",
|
||||||
IgnoringWhitespaceInDiffView: "Whitespace will be ignored in the diff view",
|
IgnoringWhitespaceInDiffView: "Whitespace will be ignored in the diff view",
|
||||||
ShowingWhitespaceInDiffView: "Whitespace will be shown in the diff view",
|
ShowingWhitespaceInDiffView: "Whitespace will be shown in the diff view",
|
||||||
CreatePullRequest: "Create pull request",
|
CreateOrShowPullRequest: "Create / show pull request",
|
||||||
CreatePullRequestOptions: "Create pull request options",
|
CreateOrOpenPullRequestOptions: "Create / show pull request options",
|
||||||
LcCreatePullRequestOptions: "create pull request options",
|
LcCreateOrOpenPullRequestOptions: "create / show pull request options",
|
||||||
LcDefaultBranch: "default branch",
|
LcDefaultBranch: "default branch",
|
||||||
LcSelectBranch: "select branch",
|
LcSelectBranch: "select branch",
|
||||||
CreatingPullRequestAtUrl: "Creating pull request at URL: %s",
|
CreatingPullRequestAtUrl: "Creating pull request at URL: %s",
|
||||||
|
|
|
@ -127,7 +127,7 @@ func polishTranslationSet() TranslationSet {
|
||||||
ConfirmQuit: `Na pewno chcesz wyjść z programu?`,
|
ConfirmQuit: `Na pewno chcesz wyjść z programu?`,
|
||||||
LcAllBranchesLogGraph: `pokazywać wszystkie logi branżowe`,
|
LcAllBranchesLogGraph: `pokazywać wszystkie logi branżowe`,
|
||||||
UnsupportedGitService: `Nieobsługiwana usługa git`,
|
UnsupportedGitService: `Nieobsługiwana usługa git`,
|
||||||
LcCreatePullRequest: `utwórz żądanie wyciągnięcia`,
|
LcCreateOrShowPullRequest: `utwórz żądanie wyciągnięcia`,
|
||||||
LcCopyPullRequestURL: `skopiuj adres URL żądania ściągnięcia do schowka`,
|
LcCopyPullRequestURL: `skopiuj adres URL żądania ściągnięcia do schowka`,
|
||||||
NoBranchOnRemote: `Ta gałąź nie istnieje na zdalnym. Najpierw musisz go odepchnąć na odległość.`,
|
NoBranchOnRemote: `Ta gałąź nie istnieje na zdalnym. Najpierw musisz go odepchnąć na odległość.`,
|
||||||
LcFetch: `fetch`,
|
LcFetch: `fetch`,
|
||||||
|
@ -255,7 +255,7 @@ func polishTranslationSet() TranslationSet {
|
||||||
PullRequestURLCopiedToClipboard: "URL żądania ściągnięcia skopiowany do schowka",
|
PullRequestURLCopiedToClipboard: "URL żądania ściągnięcia skopiowany do schowka",
|
||||||
CommitMessageCopiedToClipboard: "Commit message skopiowany do schowka",
|
CommitMessageCopiedToClipboard: "Commit message skopiowany do schowka",
|
||||||
LcCopiedToClipboard: "skopiowany do schowka",
|
LcCopiedToClipboard: "skopiowany do schowka",
|
||||||
CreatePullRequestOptions: "Utwórz opcje żądania ściągnięcia",
|
CreateOrOpenPullRequestOptions: "Utwórz opcje żądania ściągnięcia",
|
||||||
LcCreatePullRequestOptions: "utwórz opcje żądania ściągnięcia",
|
LcCreateOrOpenPullRequestOptions: "utwórz opcje żądania ściągnięcia",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue