1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2024-11-24 08:52:21 +02:00

use cached git config

This commit is contained in:
Jesse Duffield 2021-10-23 09:52:19 +11:00
parent 5011cac7ea
commit b6a5e9d615
145 changed files with 596 additions and 290 deletions

View File

@ -4,15 +4,6 @@ import (
"bufio"
"errors"
"fmt"
"github.com/aybabtme/humanlog"
"github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/env"
"github.com/jesseduffield/lazygit/pkg/gui"
"github.com/jesseduffield/lazygit/pkg/i18n"
"github.com/jesseduffield/lazygit/pkg/updates"
"github.com/sirupsen/logrus"
"io"
"io/ioutil"
"log"
@ -21,6 +12,17 @@ import (
"regexp"
"strconv"
"strings"
"github.com/aybabtme/humanlog"
"github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/git_config"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/env"
"github.com/jesseduffield/lazygit/pkg/gui"
"github.com/jesseduffield/lazygit/pkg/i18n"
"github.com/jesseduffield/lazygit/pkg/updates"
"github.com/sirupsen/logrus"
)
// App struct
@ -125,7 +127,7 @@ func NewApp(config config.AppConfigurer, filterPath string) (*App, error) {
return app, err
}
app.GitCommand, err = commands.NewGitCommand(app.Log, app.OSCommand, app.Tr, app.Config)
app.GitCommand, err = commands.NewGitCommand(app.Log, app.OSCommand, app.Tr, app.Config, git_config.NewStdCachedGitConfig(app.Log))
if err != nil {
return app, err
}

View File

@ -15,12 +15,8 @@ func (c *GitCommand) ConfiguredPager() string {
if os.Getenv("PAGER") != "" {
return os.Getenv("PAGER")
}
output, err := c.RunCommandWithOutput("git config --get-all core.pager")
if err != nil {
return ""
}
trimmedOutput := strings.TrimSpace(output)
return strings.Split(trimmedOutput, "\n")[0]
output := c.GitConfig.Get("core.pager")
return strings.Split(output, "\n")[0]
}
func (c *GitCommand) GetPager(width int) string {
@ -42,11 +38,6 @@ func (c *GitCommand) colorArg() string {
return c.Config.GetUserConfig().Git.Paging.ColorArg
}
func (c *GitCommand) GetConfigValue(key string) string {
output, _ := c.getGitConfigValue(key)
return output
}
// UsingGpg tells us whether the user has gpg enabled so that we can know
// whether we need to run a subprocess to allow them to enter their password
func (c *GitCommand) UsingGpg() bool {
@ -55,8 +46,5 @@ func (c *GitCommand) UsingGpg() bool {
return false
}
gpgsign := c.GetConfigValue("commit.gpgsign")
value := strings.ToLower(gpgsign)
return value == "true" || value == "1" || value == "yes" || value == "on"
return c.GitConfig.GetBool("commit.gpgsign")
}

View File

@ -1,70 +0,0 @@
package commands
import (
"testing"
"github.com/stretchr/testify/assert"
)
// TestGitCommandUsingGpg is a function.
func TestGitCommandUsingGpg(t *testing.T) {
type scenario struct {
testName string
getGitConfigValue func(string) (string, error)
test func(bool)
}
scenarios := []scenario{
{
"Option global and local config commit.gpgsign is not set",
func(string) (string, error) { return "", nil },
func(gpgEnabled bool) {
assert.False(t, gpgEnabled)
},
},
{
"Option commit.gpgsign is true",
func(string) (string, error) {
return "True", nil
},
func(gpgEnabled bool) {
assert.True(t, gpgEnabled)
},
},
{
"Option commit.gpgsign is on",
func(string) (string, error) {
return "ON", nil
},
func(gpgEnabled bool) {
assert.True(t, gpgEnabled)
},
},
{
"Option commit.gpgsign is yes",
func(string) (string, error) {
return "YeS", nil
},
func(gpgEnabled bool) {
assert.True(t, gpgEnabled)
},
},
{
"Option commit.gpgsign is 1",
func(string) (string, error) {
return "1", nil
},
func(gpgEnabled bool) {
assert.True(t, gpgEnabled)
},
},
}
for _, s := range scenarios {
t.Run(s.testName, func(t *testing.T) {
gitCmd := NewDummyGitCommand()
gitCmd.getGitConfigValue = s.getGitConfigValue
s.test(gitCmd.UsingGpg())
})
}
}

View File

@ -1,6 +1,7 @@
package commands
import (
"github.com/jesseduffield/lazygit/pkg/commands/git_config"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/i18n"
@ -16,10 +17,10 @@ func NewDummyGitCommand() *GitCommand {
func NewDummyGitCommandWithOSCommand(osCommand *oscommands.OSCommand) *GitCommand {
newAppConfig := config.NewDummyAppConfig()
return &GitCommand{
Log: utils.NewDummyLog(),
OSCommand: osCommand,
Tr: i18n.NewTranslationSet(utils.NewDummyLog(), newAppConfig.GetUserConfig().Gui.Language),
Config: newAppConfig,
getGitConfigValue: func(string) (string, error) { return "", nil },
Log: utils.NewDummyLog(),
OSCommand: osCommand,
Tr: i18n.NewTranslationSet(utils.NewDummyLog(), newAppConfig.GetUserConfig().Gui.Language),
Config: newAppConfig,
GitConfig: git_config.NewFakeGitConfig(map[string]string{}),
}
}

View File

@ -331,7 +331,7 @@ func (c *GitCommand) EditFileCmdStr(filename string, lineNumber int) (string, er
editor := c.Config.GetUserConfig().OS.EditCommand
if editor == "" {
editor = c.GetConfigValue("core.editor")
editor = c.GitConfig.Get("core.editor")
}
if editor == "" {

View File

@ -6,6 +6,7 @@ import (
"os/exec"
"testing"
"github.com/jesseduffield/lazygit/pkg/commands/git_config"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/secureexec"
"github.com/jesseduffield/lazygit/pkg/test"
@ -523,24 +524,21 @@ func TestGitCommandApplyPatch(t *testing.T) {
}
}
// TestGitCommandDiscardOldFileChanges is a function.
func TestGitCommandDiscardOldFileChanges(t *testing.T) {
type scenario struct {
testName string
getGitConfigValue func(string) (string, error)
commits []*models.Commit
commitIndex int
fileName string
command func(string, ...string) *exec.Cmd
test func(error)
testName string
gitConfigMockResponses map[string]string
commits []*models.Commit
commitIndex int
fileName string
command func(string, ...string) *exec.Cmd
test func(error)
}
scenarios := []scenario{
{
"returns error when index outside of range of commits",
func(string) (string, error) {
return "", nil
},
nil,
[]*models.Commit{},
0,
"test999.txt",
@ -551,9 +549,7 @@ func TestGitCommandDiscardOldFileChanges(t *testing.T) {
},
{
"returns error when using gpg",
func(string) (string, error) {
return "true", nil
},
map[string]string{"commit.gpgsign": "true"},
[]*models.Commit{{Name: "commit", Sha: "123456"}},
0,
"test999.txt",
@ -564,9 +560,7 @@ func TestGitCommandDiscardOldFileChanges(t *testing.T) {
},
{
"checks out file if it already existed",
func(string) (string, error) {
return "", nil
},
nil,
[]*models.Commit{
{Name: "commit", Sha: "123456"},
{Name: "commit2", Sha: "abcdef"},
@ -608,7 +602,7 @@ func TestGitCommandDiscardOldFileChanges(t *testing.T) {
for _, s := range scenarios {
t.Run(s.testName, func(t *testing.T) {
gitCmd.OSCommand.Command = s.command
gitCmd.getGitConfigValue = s.getGitConfigValue
gitCmd.GitConfig = git_config.NewFakeGitConfig(s.gitConfigMockResponses)
s.test(gitCmd.DiscardOldFileChanges(s.commits, s.commitIndex, s.fileName))
})
}
@ -725,7 +719,7 @@ func TestEditFileCmdStr(t *testing.T) {
configEditCommandTemplate string
command func(string, ...string) *exec.Cmd
getenv func(string) string
getGitConfigValue func(string) (string, error)
gitConfigMockResponses map[string]string
test func(string, error)
}
@ -740,9 +734,7 @@ func TestEditFileCmdStr(t *testing.T) {
func(env string) string {
return ""
},
func(cf string) (string, error) {
return "", nil
},
nil,
func(cmdStr string, err error) {
assert.EqualError(t, err, "No editor defined in config file, $GIT_EDITOR, $VISUAL, $EDITOR, or git config")
},
@ -758,9 +750,7 @@ func TestEditFileCmdStr(t *testing.T) {
func(env string) string {
return ""
},
func(cf string) (string, error) {
return "", nil
},
nil,
func(cmdStr string, err error) {
assert.NoError(t, err)
assert.Equal(t, "nano "+gitCmd.OSCommand.Quote("test"), cmdStr)
@ -777,9 +767,7 @@ func TestEditFileCmdStr(t *testing.T) {
func(env string) string {
return ""
},
func(cf string) (string, error) {
return "nano", nil
},
map[string]string{"core.editor": "nano"},
func(cmdStr string, err error) {
assert.NoError(t, err)
assert.Equal(t, "nano "+gitCmd.OSCommand.Quote("test"), cmdStr)
@ -800,9 +788,7 @@ func TestEditFileCmdStr(t *testing.T) {
return ""
},
func(cf string) (string, error) {
return "", nil
},
nil,
func(cmdStr string, err error) {
assert.NoError(t, err)
},
@ -822,9 +808,7 @@ func TestEditFileCmdStr(t *testing.T) {
return ""
},
func(cf string) (string, error) {
return "", nil
},
nil,
func(cmdStr string, err error) {
assert.NoError(t, err)
assert.Equal(t, "emacs "+gitCmd.OSCommand.Quote("test"), cmdStr)
@ -841,9 +825,7 @@ func TestEditFileCmdStr(t *testing.T) {
func(env string) string {
return ""
},
func(cf string) (string, error) {
return "", nil
},
nil,
func(cmdStr string, err error) {
assert.NoError(t, err)
assert.Equal(t, "vi "+gitCmd.OSCommand.Quote("test"), cmdStr)
@ -860,9 +842,7 @@ func TestEditFileCmdStr(t *testing.T) {
func(env string) string {
return ""
},
func(cf string) (string, error) {
return "", nil
},
nil,
func(cmdStr string, err error) {
assert.NoError(t, err)
assert.Equal(t, "vi "+gitCmd.OSCommand.Quote("file/with space"), cmdStr)
@ -879,9 +859,7 @@ func TestEditFileCmdStr(t *testing.T) {
func(env string) string {
return ""
},
func(cf string) (string, error) {
return "", nil
},
nil,
func(cmdStr string, err error) {
assert.NoError(t, err)
assert.Equal(t, "vim +1 "+gitCmd.OSCommand.Quote("open file/at line"), cmdStr)
@ -894,7 +872,7 @@ func TestEditFileCmdStr(t *testing.T) {
gitCmd.Config.GetUserConfig().OS.EditCommandTemplate = s.configEditCommandTemplate
gitCmd.OSCommand.Command = s.command
gitCmd.OSCommand.Getenv = s.getenv
gitCmd.getGitConfigValue = s.getGitConfigValue
gitCmd.GitConfig = git_config.NewFakeGitConfig(s.gitConfigMockResponses)
s.test(gitCmd.EditFileCmdStr(s.filename, 1))
}
}

View File

@ -10,6 +10,7 @@ import (
"github.com/go-errors/errors"
gogit "github.com/jesseduffield/go-git/v5"
"github.com/jesseduffield/lazygit/pkg/commands/git_config"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/commands/patch"
"github.com/jesseduffield/lazygit/pkg/config"
@ -32,32 +33,32 @@ type GitCommand struct {
Repo *gogit.Repository
Tr *i18n.TranslationSet
Config config.AppConfigurer
getGitConfigValue func(string) (string, error)
DotGitDir string
onSuccessfulContinue func() error
PatchManager *patch.PatchManager
GitConfig git_config.IGitConfig
// 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
}
// NewGitCommand it runs git commands
func NewGitCommand(log *logrus.Entry, osCommand *oscommands.OSCommand, tr *i18n.TranslationSet, config config.AppConfigurer) (*GitCommand, error) {
func NewGitCommand(
log *logrus.Entry,
osCommand *oscommands.OSCommand,
tr *i18n.TranslationSet,
config config.AppConfigurer,
gitConfig git_config.IGitConfig,
) (*GitCommand, error) {
var repo *gogit.Repository
// see what our default push behaviour is
output, err := osCommand.RunCommandWithOutput("git config --get push.default")
pushToCurrent := false
if err != nil {
log.Errorf("error reading git config: %v", err)
} else {
pushToCurrent = strings.TrimSpace(output) == "current"
}
pushToCurrent := gitConfig.Get("push.default") == "current"
if err := navigateToRepoRootDirectory(os.Stat, os.Chdir); err != nil {
return nil, err
}
var err error
if repo, err = setupRepository(gogit.PlainOpen, tr.GitconfigParseErr); err != nil {
return nil, err
}
@ -68,14 +69,14 @@ func NewGitCommand(log *logrus.Entry, osCommand *oscommands.OSCommand, tr *i18n.
}
gitCommand := &GitCommand{
Log: log,
OSCommand: osCommand,
Tr: tr,
Repo: repo,
Config: config,
getGitConfigValue: getGitConfigValue,
DotGitDir: dotGitDir,
PushToCurrent: pushToCurrent,
Log: log,
OSCommand: osCommand,
Tr: tr,
Repo: repo,
Config: config,
DotGitDir: dotGitDir,
PushToCurrent: pushToCurrent,
GitConfig: gitConfig,
}
gitCommand.PatchManager = patch.NewPatchManager(log, gitCommand.ApplyPatch, gitCommand.ShowFileDiff)

View File

@ -0,0 +1,59 @@
package git_config
import (
"strings"
"github.com/sirupsen/logrus"
)
type IGitConfig interface {
Get(string) string
GetBool(string) bool
}
type CachedGitConfig struct {
cache map[string]string
getKey func(string) (string, error)
log *logrus.Entry
}
func NewStdCachedGitConfig(log *logrus.Entry) *CachedGitConfig {
return NewCachedGitConfig(getGitConfigValue, log)
}
func NewCachedGitConfig(getKey func(string) (string, error), log *logrus.Entry) *CachedGitConfig {
return &CachedGitConfig{
cache: make(map[string]string),
getKey: getKey,
log: log,
}
}
func (self *CachedGitConfig) Get(key string) string {
if value, ok := self.cache[key]; ok {
self.log.Debugf("using cache for key " + key)
return value
}
value := self.getAux(key)
self.cache[key] = value
return value
}
func (self *CachedGitConfig) getAux(key string) string {
value, err := self.getKey(key)
if err != nil {
self.log.Debugf("Error getting git config value for key: " + key + ". Error: " + err.Error())
return ""
}
return strings.TrimSpace(value)
}
func (self *CachedGitConfig) GetBool(key string) bool {
return isTruthy(self.Get(key))
}
func isTruthy(value string) bool {
lcValue := strings.ToLower(value)
return lcValue == "true" || lcValue == "1" || lcValue == "yes" || lcValue == "on"
}

View File

@ -0,0 +1,116 @@
package git_config
import (
"testing"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/stretchr/testify/assert"
)
func TestGetBool(t *testing.T) {
type scenario struct {
testName string
mockResponses map[string]string
expected bool
}
scenarios := []scenario{
{
"Option global and local config commit.gpgsign is not set",
map[string]string{},
false,
},
{
"Some other random key is set",
map[string]string{"blah": "blah"},
false,
},
{
"Option commit.gpgsign is true",
map[string]string{"commit.gpgsign": "True"},
true,
},
{
"Option commit.gpgsign is on",
map[string]string{"commit.gpgsign": "ON"},
true,
},
{
"Option commit.gpgsign is yes",
map[string]string{"commit.gpgsign": "YeS"},
true,
},
{
"Option commit.gpgsign is 1",
map[string]string{"commit.gpgsign": "1"},
true,
},
}
for _, s := range scenarios {
s := s
t.Run(s.testName, func(t *testing.T) {
fake := NewFakeGitConfig(s.mockResponses)
real := NewCachedGitConfig(
func(key string) (string, error) {
return fake.Get(key), nil
},
utils.NewDummyLog(),
)
result := real.GetBool("commit.gpgsign")
assert.Equal(t, s.expected, result)
})
}
}
func TestGet(t *testing.T) {
type scenario struct {
testName string
mockResponses map[string]string
expected string
}
scenarios := []scenario{
{
"not set",
map[string]string{},
"",
},
{
"is set",
map[string]string{"commit.gpgsign": "blah"},
"blah",
},
}
for _, s := range scenarios {
s := s
t.Run(s.testName, func(t *testing.T) {
fake := NewFakeGitConfig(s.mockResponses)
real := NewCachedGitConfig(
func(key string) (string, error) {
return fake.Get(key), nil
},
utils.NewDummyLog(),
)
result := real.Get("commit.gpgsign")
assert.Equal(t, s.expected, result)
})
}
// verifying that the cache is used
count := 0
real := NewCachedGitConfig(
func(key string) (string, error) {
count++
assert.Equal(t, "commit.gpgsign", key)
return "blah", nil
},
utils.NewDummyLog(),
)
result := real.Get("commit.gpgsign")
assert.Equal(t, "blah", result)
result = real.Get("commit.gpgsign")
assert.Equal(t, "blah", result)
assert.Equal(t, 1, count)
}

View File

@ -0,0 +1,22 @@
package git_config
type FakeGitConfig struct {
mockResponses map[string]string
}
func NewFakeGitConfig(mockResponses map[string]string) *FakeGitConfig {
return &FakeGitConfig{
mockResponses: mockResponses,
}
}
func (self *FakeGitConfig) Get(key string) string {
if self.mockResponses == nil {
return ""
}
return self.mockResponses[key]
}
func (self *FakeGitConfig) GetBool(key string) bool {
return isTruthy(self.Get(key))
}

View File

@ -1,4 +1,4 @@
package commands
package git_config
import (
"bytes"

View File

@ -8,6 +8,7 @@ import (
"github.com/go-errors/errors"
gogit "github.com/jesseduffield/go-git/v5"
"github.com/jesseduffield/lazygit/pkg/commands/git_config"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/i18n"
@ -210,7 +211,7 @@ func TestNewGitCommand(t *testing.T) {
t.Run(s.testName, func(t *testing.T) {
s.setup()
newAppConfig := config.NewDummyAppConfig()
s.test(NewGitCommand(utils.NewDummyLog(), oscommands.NewDummyOSCommand(), i18n.NewTranslationSet(utils.NewDummyLog(), newAppConfig.GetUserConfig().Gui.Language), newAppConfig))
s.test(NewGitCommand(utils.NewDummyLog(), oscommands.NewDummyOSCommand(), i18n.NewTranslationSet(utils.NewDummyLog(), newAppConfig.GetUserConfig().Gui.Language), newAppConfig, git_config.NewFakeGitConfig(nil)))
})
}
}

View File

@ -15,7 +15,7 @@ type GetStatusFileOptions struct {
func (c *GitCommand) GetStatusFiles(opts GetStatusFileOptions) []*models.File {
// check if config wants us ignoring untracked files
untrackedFilesSetting := c.GetConfigValue("status.showUntrackedFiles")
untrackedFilesSetting := c.GitConfig.Get("status.showUntrackedFiles")
if untrackedFilesSetting == "" {
untrackedFilesSetting = "all"

View File

@ -8,6 +8,7 @@ import (
"strings"
"testing"
"github.com/jesseduffield/lazygit/pkg/commands/git_config"
"github.com/jesseduffield/lazygit/pkg/secureexec"
"github.com/stretchr/testify/assert"
)
@ -247,10 +248,7 @@ func TestCreatePullRequest(t *testing.T) {
"invalid.work.com": "noservice:invalid.work.com",
"noservice.work.com": "noservice.work.com",
}
gitCommand.getGitConfigValue = func(path string) (string, error) {
assert.Equal(t, path, "remote.origin.url")
return s.remoteUrl, nil
}
gitCommand.GitConfig = git_config.NewFakeGitConfig(map[string]string{"remote.origin.url": s.remoteUrl})
dummyPullRequest := NewPullRequest(gitCommand)
s.test(dummyPullRequest.Create(s.from, s.to))
})

View File

@ -8,6 +8,7 @@ import (
"strings"
"testing"
"github.com/jesseduffield/lazygit/pkg/commands/git_config"
"github.com/jesseduffield/lazygit/pkg/secureexec"
"github.com/stretchr/testify/assert"
)
@ -247,10 +248,7 @@ func TestCreatePullRequestOnWindows(t *testing.T) {
"invalid.work.com": "noservice:invalid.work.com",
"noservice.work.com": "noservice.work.com",
}
gitCommand.getGitConfigValue = func(path string) (string, error) {
assert.Equal(t, path, "remote.origin.url")
return s.remoteUrl, nil
}
gitCommand.GitConfig = git_config.NewFakeGitConfig(map[string]string{"remote.origin.url": s.remoteUrl})
dummyPullRequest := NewPullRequest(gitCommand)
s.test(dummyPullRequest.Create(s.from, s.to))
})

View File

@ -38,5 +38,5 @@ func (c *GitCommand) CheckRemoteBranchExists(branchName string) bool {
// GetRemoteURL returns current repo remote url
func (c *GitCommand) GetRemoteURL() string {
return c.GetConfigValue("remote.origin.url")
return c.GitConfig.Get("remote.origin.url")
}

View File

@ -18,10 +18,6 @@ type PushOpts struct {
func (c *GitCommand) Push(opts PushOpts) error {
cmdStr := "git push"
if c.GetConfigValue("push.followTags") != "false" {
cmdStr += " --follow-tags"
}
if opts.Force {
cmdStr += " --force-with-lease"
}

View File

@ -11,11 +11,10 @@ import (
// TestGitCommandPush is a function.
func TestGitCommandPush(t *testing.T) {
type scenario struct {
testName string
getGitConfigValue func(string) (string, error)
command func(string, ...string) *exec.Cmd
opts PushOpts
test func(error)
testName string
command func(string, ...string) *exec.Cmd
opts PushOpts
test func(error)
}
prompt := func(passOrUname string) string {
@ -24,42 +23,7 @@ func TestGitCommandPush(t *testing.T) {
scenarios := []scenario{
{
"Push with force disabled, follow-tags on",
func(string) (string, error) {
return "", nil
},
func(cmd string, args ...string) *exec.Cmd {
assert.EqualValues(t, "git", cmd)
assert.EqualValues(t, []string{"push", "--follow-tags"}, args)
return secureexec.Command("echo")
},
PushOpts{Force: false, PromptUserForCredential: prompt},
func(err error) {
assert.NoError(t, err)
},
},
{
"Push with force enabled, follow-tags on",
func(string) (string, error) {
return "", nil
},
func(cmd string, args ...string) *exec.Cmd {
assert.EqualValues(t, "git", cmd)
assert.EqualValues(t, []string{"push", "--follow-tags", "--force-with-lease"}, args)
return secureexec.Command("echo")
},
PushOpts{Force: true, PromptUserForCredential: prompt},
func(err error) {
assert.NoError(t, err)
},
},
{
"Push with force disabled, follow-tags off",
func(string) (string, error) {
return "false", nil
},
"Push with force disabled",
func(cmd string, args ...string) *exec.Cmd {
assert.EqualValues(t, "git", cmd)
assert.EqualValues(t, []string{"push"}, args)
@ -72,13 +36,23 @@ func TestGitCommandPush(t *testing.T) {
},
},
{
"Push with an error occurring, follow-tags on",
func(string) (string, error) {
return "", nil
},
"Push with force enabled",
func(cmd string, args ...string) *exec.Cmd {
assert.EqualValues(t, "git", cmd)
assert.EqualValues(t, []string{"push", "--follow-tags"}, args)
assert.EqualValues(t, []string{"push", "--force-with-lease"}, args)
return secureexec.Command("echo")
},
PushOpts{Force: true, PromptUserForCredential: prompt},
func(err error) {
assert.NoError(t, err)
},
},
{
"Push with an error occurring",
func(cmd string, args ...string) *exec.Cmd {
assert.EqualValues(t, "git", cmd)
assert.EqualValues(t, []string{"push"}, args)
return secureexec.Command("test")
},
PushOpts{Force: false, PromptUserForCredential: prompt},
@ -87,10 +61,7 @@ func TestGitCommandPush(t *testing.T) {
},
},
{
"Push with force disabled, follow-tags off, upstream supplied",
func(string) (string, error) {
return "false", nil
},
"Push with force disabled, upstream supplied",
func(cmd string, args ...string) *exec.Cmd {
assert.EqualValues(t, "git", cmd)
assert.EqualValues(t, []string{"push", "origin", "master"}, args)
@ -108,10 +79,7 @@ func TestGitCommandPush(t *testing.T) {
},
},
{
"Push with force disabled, follow-tags off, setting upstream",
func(string) (string, error) {
return "false", nil
},
"Push with force disabled, setting upstream",
func(cmd string, args ...string) *exec.Cmd {
assert.EqualValues(t, "git", cmd)
assert.EqualValues(t, []string{"push", "--set-upstream", "origin", "master"}, args)
@ -130,10 +98,7 @@ func TestGitCommandPush(t *testing.T) {
},
},
{
"Push with force enabled, follow-tags off, setting upstream",
func(string) (string, error) {
return "false", nil
},
"Push with force enabled, setting upstream",
func(cmd string, args ...string) *exec.Cmd {
assert.EqualValues(t, "git", cmd)
assert.EqualValues(t, []string{"push", "--force-with-lease", "--set-upstream", "origin", "master"}, args)
@ -153,9 +118,6 @@ func TestGitCommandPush(t *testing.T) {
},
{
"Push with remote branch but no origin",
func(string) (string, error) {
return "false", nil
},
func(cmd string, args ...string) *exec.Cmd {
return nil
},
@ -172,10 +134,7 @@ func TestGitCommandPush(t *testing.T) {
},
},
{
"Push with force disabled, follow-tags off, upstream supplied",
func(string) (string, error) {
return "false", nil
},
"Push with force disabled, upstream supplied",
func(cmd string, args ...string) *exec.Cmd {
assert.EqualValues(t, "git", cmd)
assert.EqualValues(t, []string{"push", "origin", "master"}, args)
@ -192,57 +151,12 @@ func TestGitCommandPush(t *testing.T) {
assert.NoError(t, err)
},
},
{
"Push with force disabled, follow-tags off, setting upstream",
func(string) (string, error) {
return "false", nil
},
func(cmd string, args ...string) *exec.Cmd {
assert.EqualValues(t, "git", cmd)
assert.EqualValues(t, []string{"push", "--set-upstream", "origin", "master"}, args)
return secureexec.Command("echo")
},
PushOpts{
Force: false,
UpstreamRemote: "origin",
UpstreamBranch: "master",
PromptUserForCredential: prompt,
SetUpstream: true,
},
func(err error) {
assert.NoError(t, err)
},
},
{
"Push with force enabled, follow-tags off, setting upstream",
func(string) (string, error) {
return "false", nil
},
func(cmd string, args ...string) *exec.Cmd {
assert.EqualValues(t, "git", cmd)
assert.EqualValues(t, []string{"push", "--force-with-lease", "--set-upstream", "origin", "master"}, args)
return secureexec.Command("echo")
},
PushOpts{
Force: true,
UpstreamRemote: "origin",
UpstreamBranch: "master",
PromptUserForCredential: prompt,
SetUpstream: true,
},
func(err error) {
assert.NoError(t, err)
},
},
}
for _, s := range scenarios {
t.Run(s.testName, func(t *testing.T) {
gitCmd := NewDummyGitCommand()
gitCmd.OSCommand.Command = s.command
gitCmd.getGitConfigValue = s.getGitConfigValue
err := gitCmd.Push(s.opts)
s.test(err)
})

View File

@ -6,6 +6,7 @@ import (
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/git_config"
"github.com/jesseduffield/lazygit/pkg/env"
"github.com/jesseduffield/lazygit/pkg/gui/style"
"github.com/jesseduffield/lazygit/pkg/utils"
@ -72,7 +73,7 @@ func (gui *Gui) dispatchSwitchToRepo(path string, reuse bool) error {
return err
}
newGitCommand, err := commands.NewGitCommand(gui.Log, gui.OSCommand, gui.Tr, gui.Config)
newGitCommand, err := commands.NewGitCommand(gui.Log, gui.OSCommand, gui.Tr, gui.Config, git_config.NewStdCachedGitConfig(gui.Log))
if err != nil {
return err
}

View File

@ -0,0 +1 @@
myfile3

View File

@ -0,0 +1 @@
d0d3bfe09c1a5a9631f3041a184d6b9c6d927c83 branch 'master' of ../actual_remote

View File

@ -0,0 +1 @@
ref: refs/heads/master

View File

@ -0,0 +1,18 @@
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[user]
email = CI@example.com
name = CI
[remote "origin"]
url = ../actual_remote
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
[push]
followTags = true

View File

@ -0,0 +1 @@
Unnamed repository; edit this file 'description' to name the repository.

View File

@ -0,0 +1,7 @@
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
.DS_Store

View File

@ -0,0 +1,3 @@
0000000000000000000000000000000000000000 f27af92910b10e6ddf592fae975337355579464b CI <CI@example.com> 1634944096 +1100 commit (initial): myfile1
f27af92910b10e6ddf592fae975337355579464b d0d3bfe09c1a5a9631f3041a184d6b9c6d927c83 CI <CI@example.com> 1634944096 +1100 commit: myfile2
d0d3bfe09c1a5a9631f3041a184d6b9c6d927c83 aea6b2960cc3e7a2453ce3490ca09d090d7ce223 CI <CI@example.com> 1634944096 +1100 commit: myfile3

View File

@ -0,0 +1,3 @@
0000000000000000000000000000000000000000 f27af92910b10e6ddf592fae975337355579464b CI <CI@example.com> 1634944096 +1100 commit (initial): myfile1
f27af92910b10e6ddf592fae975337355579464b d0d3bfe09c1a5a9631f3041a184d6b9c6d927c83 CI <CI@example.com> 1634944096 +1100 commit: myfile2
d0d3bfe09c1a5a9631f3041a184d6b9c6d927c83 aea6b2960cc3e7a2453ce3490ca09d090d7ce223 CI <CI@example.com> 1634944096 +1100 commit: myfile3

View File

@ -0,0 +1,2 @@
0000000000000000000000000000000000000000 d0d3bfe09c1a5a9631f3041a184d6b9c6d927c83 CI <CI@example.com> 1634944096 +1100 fetch origin: storing head
d0d3bfe09c1a5a9631f3041a184d6b9c6d927c83 aea6b2960cc3e7a2453ce3490ca09d090d7ce223 CI <CI@example.com> 1634944097 +1100 update by push

View File

@ -0,0 +1,4 @@
xЌОA
В0@QЧ9Eц‚d’ЙДЎ«#if°РШR"иннЬ~ЮвOkks·Аx껈Н) дИкjQ&b-ик‰ЄчЕ©G іе]^ЭЄOYЩ3ёNЁVЌм5 §B
1ЖДHXL~чзєЫaґ·a|И'·m‘Лґ¶»
И€ЋЙћњ3G=¦єьЙMыкј€7?љS9і

View File

@ -0,0 +1,2 @@
x█мA
┐0@я╝s┼ый▄NгJ\y▄≤L╗Ю░")╢╥в#tШyПS5[к╔М╙─*╘`■eЙ3Ё▓≈Л╘▀T^╦об%╕{ГБ╖╫Йс ▐iУМ╫И-U{Iо│┐ю∙я²У°4Щ⌠;Ш∙uSr3m,у

View File

@ -0,0 +1 @@
aea6b2960cc3e7a2453ce3490ca09d090d7ce223

View File

@ -0,0 +1 @@
aea6b2960cc3e7a2453ce3490ca09d090d7ce223

View File

@ -0,0 +1 @@
3410e6811881ccede9ff762c875f9b99a3e6eaef

View File

@ -0,0 +1 @@
test1

View File

@ -0,0 +1 @@
test2

View File

@ -0,0 +1 @@
test3

View File

@ -0,0 +1 @@
ref: refs/heads/master

View File

@ -0,0 +1,8 @@
[core]
repositoryformatversion = 0
filemode = true
bare = true
ignorecase = true
precomposeunicode = true
[remote "origin"]
url = /Users/jesseduffieldduffield/go/src/github.com/jesseduffield/lazygit/test/integration/pushFollowTags/./actual

View File

@ -0,0 +1 @@
Unnamed repository; edit this file 'description' to name the repository.

View File

@ -0,0 +1,7 @@
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
.DS_Store

View File

@ -0,0 +1,4 @@
xЌОA
В0@QЧ9Eц‚d’ЙДЎ«#if°РШR"иннЬ~ЮвOkks·Аx껈Н) дИкjQ&b-ик‰ЄчЕ©G іе]^ЭЄOYЩ3ёNЁVЌм5 §B
1ЖДHXL~чзєЫaґ·a|И'·m‘Лґ¶»
И€ЋЙћњ3G=¦єьЙMыкј€7?љS9і

View File

@ -0,0 +1,2 @@
x█мA
┐0@я╝s┼ый▄NгJ\y▄≤L╗Ю░")╢╥в#tШyПS5[к╔М╙─*╘`■eЙ3Ё▓≈Л╘▀T^╦об%╕{ГБ╖╫Йс ▐iУМ╫И-U{Iо│┐ю∙я²У°4Щ⌠;Ш∙uSr3m,у

View File

@ -0,0 +1,2 @@
# pack-refs with: peeled fully-peeled sorted
d0d3bfe09c1a5a9631f3041a184d6b9c6d927c83 refs/heads/master

View File

@ -0,0 +1 @@
aea6b2960cc3e7a2453ce3490ca09d090d7ce223

View File

@ -0,0 +1 @@
3410e6811881ccede9ff762c875f9b99a3e6eaef

View File

@ -0,0 +1 @@
{"KeyEvents":[{"Timestamp":682,"Mod":0,"Key":256,"Ch":80},{"Timestamp":1641,"Mod":0,"Key":256,"Ch":113}],"ResizeEvents":[{"Timestamp":0,"Width":272,"Height":74}]}

View File

@ -0,0 +1,32 @@
#!/bin/sh
set -e
cd $1
git init
git config user.email "CI@example.com"
git config user.name "CI"
echo test1 > myfile1
git add .
git commit -am "myfile1"
echo test2 > myfile2
git add .
git commit -am "myfile2"
cd ..
git clone --bare ./actual actual_remote
cd actual
echo test3 > myfile3
git add .
git commit -am "myfile3"
git remote add origin ../actual_remote
git fetch origin
git branch --set-upstream-to=origin/master master
git config push.followTags true
git tag -a v1.0 -m "my version 1.0"

View File

@ -0,0 +1 @@
{ "description": "push changes to the remote, when --follow-tags is configured", "speed": 10 }

View File

@ -0,0 +1 @@
myfile3

View File

@ -0,0 +1 @@
8f99b05bf3462e1a797335475bff5fabe3ae9ec5 branch 'master' of ../actual_remote

View File

@ -0,0 +1 @@
ref: refs/heads/master

View File

@ -0,0 +1,16 @@
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[user]
email = CI@example.com
name = CI
[remote "origin"]
url = ../actual_remote
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master

View File

@ -0,0 +1 @@
Unnamed repository; edit this file 'description' to name the repository.

View File

@ -0,0 +1,7 @@
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
.DS_Store

View File

@ -0,0 +1,3 @@
0000000000000000000000000000000000000000 fb20b9e96648c61699f9faf3a4383340fefd5f91 CI <CI@example.com> 1634944114 +1100 commit (initial): myfile1
fb20b9e96648c61699f9faf3a4383340fefd5f91 8f99b05bf3462e1a797335475bff5fabe3ae9ec5 CI <CI@example.com> 1634944114 +1100 commit: myfile2
8f99b05bf3462e1a797335475bff5fabe3ae9ec5 03009ca2af4be2a9bb49206974ce9c97eaa2da23 CI <CI@example.com> 1634944114 +1100 commit: myfile3

View File

@ -0,0 +1,3 @@
0000000000000000000000000000000000000000 fb20b9e96648c61699f9faf3a4383340fefd5f91 CI <CI@example.com> 1634944114 +1100 commit (initial): myfile1
fb20b9e96648c61699f9faf3a4383340fefd5f91 8f99b05bf3462e1a797335475bff5fabe3ae9ec5 CI <CI@example.com> 1634944114 +1100 commit: myfile2
8f99b05bf3462e1a797335475bff5fabe3ae9ec5 03009ca2af4be2a9bb49206974ce9c97eaa2da23 CI <CI@example.com> 1634944114 +1100 commit: myfile3

View File

@ -0,0 +1,2 @@
0000000000000000000000000000000000000000 8f99b05bf3462e1a797335475bff5fabe3ae9ec5 CI <CI@example.com> 1634944115 +1100 fetch origin: storing head
8f99b05bf3462e1a797335475bff5fabe3ae9ec5 03009ca2af4be2a9bb49206974ce9c97eaa2da23 CI <CI@example.com> 1634944115 +1100 update by push

View File

@ -0,0 +1,3 @@
x�ÎA
Â0@Q×9ÅìÉ$Ó±"BW=FÒÌ`¡±¥DÐÛÛ#¸ý¼ÅŸÖZç(tj»*¤k$L�˜/EÕ„EY,sä>0—²·@ÈnK»¾X>‹
3õ#‹˜X²˜(ö1’7µÒ™ Kïö\wF¸ ãC?©n‹^¦µÞ9’!œ½wG=¦šþÉ]ýÚ¼hp?Ö::

View File

@ -0,0 +1,3 @@
x█мA
б0Faв9еЛиъ▌сD└╝z▄4≥`║C╓Dпшш#╦}|ПR5[│ЕтvUР*╘Ь(к0jхл┼ 9═▀(/эgАс╣sЯщ·u╖i╕ш4?ТМ╣И%U╩╓Г▒`:ч╩ё⌠╕rgъ╡n
В0┬,ц

View File

@ -0,0 +1 @@
03009ca2af4be2a9bb49206974ce9c97eaa2da23

View File

@ -0,0 +1 @@
03009ca2af4be2a9bb49206974ce9c97eaa2da23

View File

@ -0,0 +1 @@
e19bd88e6b3a0d7e4ffc1de39b34d5a312fb9b77

View File

@ -0,0 +1 @@
test1

View File

@ -0,0 +1 @@
test2

View File

@ -0,0 +1 @@
test3

View File

@ -0,0 +1 @@
ref: refs/heads/master

View File

@ -0,0 +1,8 @@
[core]
repositoryformatversion = 0
filemode = true
bare = true
ignorecase = true
precomposeunicode = true
[remote "origin"]
url = /Users/jesseduffieldduffield/go/src/github.com/jesseduffield/lazygit/test/integration/pushNoFollowTags/./actual

View File

@ -0,0 +1 @@
Unnamed repository; edit this file 'description' to name the repository.

View File

@ -0,0 +1,7 @@
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
.DS_Store

View File

@ -0,0 +1,3 @@
x�ÎA
Â0@Q×9ÅìÉ$Ó±"BW=FÒÌ`¡±¥DÐÛÛ#¸ý¼ÅŸÖZç(tj»*¤k$L�˜/EÕ„EY,sä>0—²·@ÈnK»¾X>‹
3õ#‹˜X²˜(ö1’7µÒ™ Kïö\wF¸ ãC?©n‹^¦µÞ9’!œ½wG=¦šþÉ]ýÚ¼hp?Ö::

Some files were not shown because too many files have changed in this diff Show More