mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-28 18:26:03 -04:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
307d051ec2 | ||
|
|
3a668011fa | ||
|
|
14c8b80494 | ||
|
|
10dde518bc | ||
|
|
1e1c90c92e | ||
|
|
4954791443 | ||
|
|
c471f4927a | ||
|
|
9eba98302e | ||
|
|
250fe740b2 | ||
|
|
70eda031dc | ||
|
|
86f296a898 | ||
|
|
71ff18318d |
@@ -49,6 +49,7 @@ Default path for the config file:
|
||||
autoFetch: true
|
||||
branchLogCmd: "git log --graph --color=always --abbrev-commit --decorate --date=relative --pretty=medium {{branchName}} --"
|
||||
overrideGpg: false # prevents lazygit from spawning a separate process when using GPG
|
||||
disableForcePushing: false
|
||||
update:
|
||||
method: prompt # can be: prompt | background | never
|
||||
days: 14 # how often an update is checked for
|
||||
|
||||
@@ -39,7 +39,7 @@ func main() {
|
||||
flaggy.Bool(&debuggingFlag, "d", "debug", "Run in debug mode with logging")
|
||||
|
||||
configFlag := false
|
||||
flaggy.Bool(&configFlag, "c", "config", "Print the current default config")
|
||||
flaggy.Bool(&configFlag, "c", "config", "Print the default config")
|
||||
|
||||
flaggy.Parse()
|
||||
|
||||
|
||||
+26
-11
@@ -8,6 +8,7 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -138,19 +139,33 @@ func (app *App) validateGitVersion() error {
|
||||
if err != nil {
|
||||
return minVersionError
|
||||
}
|
||||
// output should be something like: 'git version 2.23.0'
|
||||
// first number in the string should be greater than 0
|
||||
split := strings.Split(output, " ")
|
||||
gitVersion := split[len(split)-1]
|
||||
majorVersion, err := strconv.Atoi(gitVersion[0:1])
|
||||
if err != nil {
|
||||
return minVersionError
|
||||
}
|
||||
if majorVersion < 2 {
|
||||
return minVersionError
|
||||
|
||||
if isGitVersionValid(output) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
return minVersionError
|
||||
}
|
||||
|
||||
func isGitVersionValid(versionStr string) bool {
|
||||
// output should be something like: 'git version 2.23.0 (blah)'
|
||||
re := regexp.MustCompile(`[^\d]+([\d\.]+)`)
|
||||
matches := re.FindStringSubmatch(versionStr)
|
||||
|
||||
if len(matches) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
gitVersion := matches[1]
|
||||
majorVersion, err := strconv.Atoi(gitVersion[0:1])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if majorVersion < 2 {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (app *App) setupRepo() (bool, error) {
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestIsGitVersionValid(t *testing.T) {
|
||||
type scenario struct {
|
||||
versionStr string
|
||||
expectedResult bool
|
||||
}
|
||||
|
||||
scenarios := []scenario{
|
||||
{
|
||||
"",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"git version 1.9.0",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"git version 1.9.0 (Apple Git-128)",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"git version 2.4.0",
|
||||
true,
|
||||
},
|
||||
{
|
||||
"git version 2.24.3 (Apple Git-128)",
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
t.Run(s.versionStr, func(t *testing.T) {
|
||||
result := isGitVersionValid(s.versionStr)
|
||||
assert.Equal(t, result, s.expectedResult)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -172,7 +172,7 @@ func (c *CommitListBuilder) GetCommits(opts GetCommitsOptions) ([]*Commit, error
|
||||
currentCommit.Name = fmt.Sprintf("%s %s", youAreHere, currentCommit.Name)
|
||||
}
|
||||
|
||||
commits, err = c.setCommitMergedStatuses(commits)
|
||||
commits, err = c.setCommitMergedStatuses(opts.RefName, commits)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -290,8 +290,8 @@ func (c *CommitListBuilder) commitFromPatch(content string) (*Commit, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *CommitListBuilder) setCommitMergedStatuses(commits []*Commit) ([]*Commit, error) {
|
||||
ancestor, err := c.getMergeBase()
|
||||
func (c *CommitListBuilder) setCommitMergedStatuses(refName string, commits []*Commit) ([]*Commit, error) {
|
||||
ancestor, err := c.getMergeBase(refName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -313,7 +313,7 @@ func (c *CommitListBuilder) setCommitMergedStatuses(commits []*Commit) ([]*Commi
|
||||
return commits, nil
|
||||
}
|
||||
|
||||
func (c *CommitListBuilder) getMergeBase() (string, error) {
|
||||
func (c *CommitListBuilder) getMergeBase(refName string) (string, error) {
|
||||
currentBranch, _, err := c.GitCommand.CurrentBranchName()
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -325,8 +325,18 @@ func (c *CommitListBuilder) getMergeBase() (string, error) {
|
||||
}
|
||||
|
||||
// swallowing error because it's not a big deal; probably because there are no commits yet
|
||||
output, _ := c.OSCommand.RunCommandWithOutput("git merge-base HEAD %s", baseBranch)
|
||||
return output, nil
|
||||
output, _ := c.OSCommand.RunCommandWithOutput("git merge-base %s %s", refName, baseBranch)
|
||||
return ignoringWarnings(output), nil
|
||||
}
|
||||
|
||||
func ignoringWarnings(commandOutput string) string {
|
||||
trimmedOutput := strings.TrimSpace(commandOutput)
|
||||
split := strings.Split(trimmedOutput, "\n")
|
||||
// need to get last line in case the first line is a warning about how the error is ambiguous.
|
||||
// At some point we should find a way to make it unambiguous
|
||||
lastLine := split[len(split)-1]
|
||||
|
||||
return lastLine
|
||||
}
|
||||
|
||||
// getFirstPushedCommit returns the first commit SHA which has been pushed to the ref's upstream.
|
||||
@@ -336,7 +346,8 @@ func (c *CommitListBuilder) getFirstPushedCommit(refName string) (string, error)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return strings.TrimSpace(output), nil
|
||||
|
||||
return ignoringWarnings(output), nil
|
||||
}
|
||||
|
||||
// getLog gets the git log.
|
||||
|
||||
@@ -66,7 +66,7 @@ func TestCommitListBuilderGetMergeBase(t *testing.T) {
|
||||
},
|
||||
func(output string, err error) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "blah\n", output)
|
||||
assert.Equal(t, "blah", output)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -86,7 +86,7 @@ func TestCommitListBuilderGetMergeBase(t *testing.T) {
|
||||
},
|
||||
func(output string, err error) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "blah\n", output)
|
||||
assert.Equal(t, "blah", output)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -105,7 +105,7 @@ func TestCommitListBuilderGetMergeBase(t *testing.T) {
|
||||
t.Run(s.testName, func(t *testing.T) {
|
||||
c := NewDummyCommitListBuilder()
|
||||
c.OSCommand.SetCommand(s.command)
|
||||
s.test(c.getMergeBase())
|
||||
s.test(c.getMergeBase("HEAD"))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,6 +276,7 @@ git:
|
||||
autoFetch: true
|
||||
branchLogCmd: "git log --graph --color=always --abbrev-commit --decorate --date=relative --pretty=medium {{branchName}} --"
|
||||
overrideGpg: false # prevents lazygit from spawning a separate process when using GPG
|
||||
disableForcePushing: false
|
||||
update:
|
||||
method: prompt # can be: prompt | background | never
|
||||
days: 14 # how often a update is checked for
|
||||
|
||||
@@ -318,7 +318,7 @@ func (gui *Gui) handleCommitMoveDown(g *gocui.Gui, v *gocui.View) error {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
gui.State.Panels.Commits.SelectedLineIdx++
|
||||
return gui.refreshSidePanels(refreshOptions{mode: BLOCK_UI, scope: []int{COMMITS, BRANCHES}})
|
||||
return gui.refreshRebaseCommits()
|
||||
}
|
||||
|
||||
return gui.WithWaitingStatus(gui.Tr.SLocalize("MovingStatus"), func() error {
|
||||
@@ -345,7 +345,7 @@ func (gui *Gui) handleCommitMoveUp(g *gocui.Gui, v *gocui.View) error {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
gui.State.Panels.Commits.SelectedLineIdx--
|
||||
return gui.refreshSidePanels(refreshOptions{mode: BLOCK_UI, scope: []int{COMMITS, BRANCHES}})
|
||||
return gui.refreshRebaseCommits()
|
||||
}
|
||||
|
||||
return gui.WithWaitingStatus(gui.Tr.SLocalize("MovingStatus"), func() error {
|
||||
|
||||
+20
-9
@@ -332,15 +332,17 @@ func (gui *Gui) handleAmendCommitPress() error {
|
||||
title: strings.Title(gui.Tr.SLocalize("AmendLastCommit")),
|
||||
prompt: gui.Tr.SLocalize("SureToAmend"),
|
||||
handleConfirm: func() error {
|
||||
ok, err := gui.runSyncOrAsyncCommand(gui.GitCommand.AmendHead())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return gui.WithWaitingStatus(gui.Tr.SLocalize("AmendingStatus"), func() error {
|
||||
ok, err := gui.runSyncOrAsyncCommand(gui.GitCommand.AmendHead())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
|
||||
return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -517,6 +519,11 @@ func (gui *Gui) pushWithForceFlag(v *gocui.View, force bool, upstream string, ar
|
||||
branchName := gui.getCheckedOutBranch().Name
|
||||
err := gui.GitCommand.Push(branchName, force, upstream, args, gui.promptUserForCredential)
|
||||
if err != nil && !force && strings.Contains(err.Error(), "Updates were rejected") {
|
||||
forcePushDisabled := gui.Config.GetUserConfig().GetBool("git.disableForcePushing")
|
||||
if forcePushDisabled {
|
||||
gui.createErrorPanel(gui.Tr.SLocalize("UpdatesRejectedAndForcePushDisabled"))
|
||||
return
|
||||
}
|
||||
gui.ask(askOpts{
|
||||
title: gui.Tr.SLocalize("ForcePush"),
|
||||
prompt: gui.Tr.SLocalize("ForcePushPrompt"),
|
||||
@@ -524,7 +531,6 @@ func (gui *Gui) pushWithForceFlag(v *gocui.View, force bool, upstream string, ar
|
||||
return gui.pushWithForceFlag(v, true, upstream, args)
|
||||
},
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
gui.handleCredentialsPopup(err)
|
||||
@@ -564,6 +570,11 @@ func (gui *Gui) pushFiles(g *gocui.Gui, v *gocui.View) error {
|
||||
return gui.pushWithForceFlag(v, false, "", "")
|
||||
}
|
||||
|
||||
forcePushDisabled := gui.Config.GetUserConfig().GetBool("git.disableForcePushing")
|
||||
if forcePushDisabled {
|
||||
return gui.createErrorPanel(gui.Tr.SLocalize("ForcePushDisabled"))
|
||||
}
|
||||
|
||||
return gui.ask(askOpts{
|
||||
title: gui.Tr.SLocalize("ForcePush"),
|
||||
prompt: gui.Tr.SLocalize("ForcePushPrompt"),
|
||||
|
||||
+7
-1
@@ -418,6 +418,12 @@ func addDutch(i18nObject *i18n.Bundle) error {
|
||||
}, &i18n.Message{
|
||||
ID: "ForcePushPrompt",
|
||||
Other: "Jouw branch is afgeweken van de remote branch. Druk 'esc' om te annuleren, of 'enter' om geforceert te pushen.",
|
||||
}, &i18n.Message{
|
||||
ID: "ForcePushDisabled",
|
||||
Other: "Your branch has diverged from the remote branch and you've disabled force pushing",
|
||||
}, &i18n.Message{
|
||||
ID: "UpdatesRejectedAndForcePushDisabled",
|
||||
Other: "Updates were rejected and you have disabled force pushing",
|
||||
}, &i18n.Message{
|
||||
ID: "checkForUpdate",
|
||||
Other: "check voor updates",
|
||||
@@ -446,7 +452,7 @@ func addDutch(i18nObject *i18n.Bundle) error {
|
||||
1) Als je meer van lazygit zijn features wilt leren bekijk dan deze video:
|
||||
https://youtu.be/CPLdltN7wgE
|
||||
|
||||
3) Als je git gebruikt, ben je een programmeur! Met jouw hulp kunnen we lazygit verbeteren, dus overweeg om een donateur te worden en mee te doen aan het plezier op
|
||||
2) Als je git gebruikt, ben je een programmeur! Met jouw hulp kunnen we lazygit verbeteren, dus overweeg om een donateur te worden en mee te doen aan het plezier op
|
||||
https://github.com/jesseduffield/lazygit`,
|
||||
}, &i18n.Message{
|
||||
ID: "GitconfigParseErr",
|
||||
|
||||
+7
-1
@@ -426,6 +426,12 @@ func addEnglish(i18nObject *i18n.Bundle) error {
|
||||
}, &i18n.Message{
|
||||
ID: "ForcePushPrompt",
|
||||
Other: "Your branch has diverged from the remote branch. Press 'esc' to cancel, or 'enter' to force push.",
|
||||
}, &i18n.Message{
|
||||
ID: "ForcePushDisabled",
|
||||
Other: "Your branch has diverged from the remote branch and you've disabled force pushing",
|
||||
}, &i18n.Message{
|
||||
ID: "UpdatesRejectedAndForcePushDisabled",
|
||||
Other: "Updates were rejected and you have disabled force pushing",
|
||||
}, &i18n.Message{
|
||||
ID: "checkForUpdate",
|
||||
Other: "check for update",
|
||||
@@ -454,7 +460,7 @@ func addEnglish(i18nObject *i18n.Bundle) error {
|
||||
1) If you want to learn about lazygit's features, watch this vid:
|
||||
https://youtu.be/CPLdltN7wgE
|
||||
|
||||
3) If you're using git, that makes you a programmer! With your help we can make lazygit better, so consider becoming a contributor and joining the fun at
|
||||
2) If you're using git, that makes you a programmer! With your help we can make lazygit better, so consider becoming a contributor and joining the fun at
|
||||
https://github.com/jesseduffield/lazygit`,
|
||||
}, &i18n.Message{
|
||||
ID: "GitconfigParseErr",
|
||||
|
||||
@@ -338,6 +338,12 @@ func addPolish(i18nObject *i18n.Bundle) error {
|
||||
}, &i18n.Message{
|
||||
ID: "ForcePushPrompt",
|
||||
Other: "Twoja gałąź rozeszła się z gałęzią zdalną. Wciśnij 'esc' aby anulować lub 'enter' aby wymusić wypchnięcie.",
|
||||
}, &i18n.Message{
|
||||
ID: "ForcePushDisabled",
|
||||
Other: "Your branch has diverged from the remote branch and you've disabled force pushing",
|
||||
}, &i18n.Message{
|
||||
ID: "UpdatesRejectedAndForcePushDisabled",
|
||||
Other: "Updates were rejected and you have disabled force pushing",
|
||||
}, &i18n.Message{
|
||||
ID: "checkForUpdate",
|
||||
Other: "sprawdź aktualizacje",
|
||||
|
||||
Reference in New Issue
Block a user