1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-08-08 22:36:49 +02:00

Bump minimum required git version to 2.32 (#4718)

This commit is contained in:
Stefan Haller
2025-07-09 13:14:24 +02:00
committed by GitHub
19 changed files with 32 additions and 220 deletions

View File

@ -49,10 +49,9 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
git-version: git-version:
- 2.22.0 # oldest supported version - 2.32.0 # oldest supported version
- 2.23.0 - 2.38.2 # first version that supports the rebase.updateRefs config
- 2.25.1 - 2.44.0
- 2.30.8
- latest # We rely on github to have the latest version installed on their VMs - latest # We rely on github to have the latest version installed on their VMs
runs-on: ubuntu-latest runs-on: ubuntu-latest
name: "Integration Tests - git ${{matrix.git-version}}" name: "Integration Tests - git ${{matrix.git-version}}"

View File

@ -148,7 +148,7 @@ func (app *App) validateGitVersion() (*git_commands.GitVersion, error) {
return nil, minVersionError return nil, minVersionError
} }
if version.IsOlderThan(2, 22, 0) { if version.IsOlderThan(2, 32, 0) {
return nil, minVersionError return nil, minVersionError
} }

View File

@ -249,8 +249,7 @@ func (self *CommitLoader) extractCommitFromLine(hashPool *utils.StringPool, line
} }
func (self *CommitLoader) getHydratedRebasingCommits(hashPool *utils.StringPool, addConflictingCommit bool) ([]*models.Commit, error) { func (self *CommitLoader) getHydratedRebasingCommits(hashPool *utils.StringPool, addConflictingCommit bool) ([]*models.Commit, error) {
todoFileHasShortHashes := self.version.IsOlderThan(2, 25, 2) return self.getHydratedTodoCommits(hashPool, self.getRebasingCommits(hashPool, addConflictingCommit), false)
return self.getHydratedTodoCommits(hashPool, self.getRebasingCommits(hashPool, addConflictingCommit), todoFileHasShortHashes)
} }
func (self *CommitLoader) getHydratedSequencerCommits(hashPool *utils.StringPool, workingTreeState models.WorkingTreeState) ([]*models.Commit, error) { func (self *CommitLoader) getHydratedSequencerCommits(hashPool *utils.StringPool, workingTreeState models.WorkingTreeState) ([]*models.Commit, error) {

View File

@ -218,7 +218,7 @@ func (self *RebaseCommands) PrepareInteractiveRebaseCommand(opts PrepareInteract
Arg("--interactive"). Arg("--interactive").
Arg("--autostash"). Arg("--autostash").
Arg("--keep-empty"). Arg("--keep-empty").
ArgIf(opts.keepCommitsThatBecomeEmpty && self.version.IsAtLeast(2, 26, 0), "--empty=keep"). ArgIf(opts.keepCommitsThatBecomeEmpty, "--empty=keep").
Arg("--no-autosquash"). Arg("--no-autosquash").
Arg("--rebase-merges"). Arg("--rebase-merges").
ArgIf(opts.onto != "", "--onto", opts.onto). ArgIf(opts.onto != "", "--onto", opts.onto).

View File

@ -21,8 +21,6 @@ type RepoPaths struct {
isBareRepo bool isBareRepo bool
} }
var gitPathFormatVersion = GitVersion{2, 31, 0, ""}
// Path to the current worktree. If we're in the main worktree, this will // Path to the current worktree. If we're in the main worktree, this will
// be the same as RepoPath() // be the same as RepoPath()
func (self *RepoPaths) WorktreePath() string { func (self *RepoPaths) WorktreePath() string {
@ -79,15 +77,14 @@ func GetRepoPaths(
if err != nil { if err != nil {
return nil, err return nil, err
} }
return GetRepoPathsForDir(cwd, cmd, version) return GetRepoPathsForDir(cwd, cmd)
} }
func GetRepoPathsForDir( func GetRepoPathsForDir(
dir string, dir string,
cmd oscommands.ICmdObjBuilder, cmd oscommands.ICmdObjBuilder,
version *GitVersion,
) (*RepoPaths, error) { ) (*RepoPaths, error) {
gitDirOutput, err := callGitRevParseWithDir(cmd, version, dir, "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--is-bare-repository", "--show-superproject-working-tree") gitDirOutput, err := callGitRevParseWithDir(cmd, dir, "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--is-bare-repository", "--show-superproject-working-tree")
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -96,12 +93,6 @@ func GetRepoPathsForDir(
worktreePath := gitDirResults[0] worktreePath := gitDirResults[0]
worktreeGitDirPath := gitDirResults[1] worktreeGitDirPath := gitDirResults[1]
repoGitDirPath := gitDirResults[2] repoGitDirPath := gitDirResults[2]
if version.IsOlderThanVersion(&gitPathFormatVersion) {
repoGitDirPath, err = filepath.Abs(repoGitDirPath)
if err != nil {
return nil, err
}
}
isBareRepo := gitDirResults[3] == "true" isBareRepo := gitDirResults[3] == "true"
// If we're in a submodule, --show-superproject-working-tree will return // If we're in a submodule, --show-superproject-working-tree will return
@ -131,11 +122,10 @@ func GetRepoPathsForDir(
func callGitRevParseWithDir( func callGitRevParseWithDir(
cmd oscommands.ICmdObjBuilder, cmd oscommands.ICmdObjBuilder,
version *GitVersion,
dir string, dir string,
gitRevArgs ...string, gitRevArgs ...string,
) (string, error) { ) (string, error) {
gitRevParse := NewGitCmd("rev-parse").ArgIf(version.IsAtLeastVersion(&gitPathFormatVersion), "--path-format=absolute").Arg(gitRevArgs...) gitRevParse := NewGitCmd("rev-parse").Arg("--path-format=absolute").Arg(gitRevArgs...)
if dir != "" { if dir != "" {
gitRevParse.Dir(dir) gitRevParse.Dir(dir)
} }

View File

@ -194,22 +194,13 @@ func TestGetRepoPaths(t *testing.T) {
runner := oscommands.NewFakeRunner(t) runner := oscommands.NewFakeRunner(t)
cmd := oscommands.NewDummyCmdObjBuilder(runner) cmd := oscommands.NewDummyCmdObjBuilder(runner)
version, err := GetGitVersion(oscommands.NewDummyOSCommand())
if err != nil {
t.Fatal(err)
}
getRevParseArgs := func() []string { getRevParseArgs := func() []string {
args := []string{"rev-parse"} return []string{"rev-parse", "--path-format=absolute"}
if version.IsAtLeast(2, 31, 0) {
args = append(args, "--path-format=absolute")
}
return args
} }
// prepare the filesystem for the scenario // prepare the filesystem for the scenario
s.BeforeFunc(runner, getRevParseArgs) s.BeforeFunc(runner, getRevParseArgs)
repoPaths, err := GetRepoPathsForDir("", cmd, version) repoPaths, err := GetRepoPathsForDir("", cmd)
// check the error and the paths // check the error and the paths
if s.Err != nil { if s.Err != nil {

View File

@ -59,7 +59,7 @@ func (self *SyncCommands) fetchCommandBuilder(fetchAll bool) *GitCommandBuilder
ArgIf(fetchAll, "--all"). ArgIf(fetchAll, "--all").
// avoid writing to .git/FETCH_HEAD; this allows running a pull // avoid writing to .git/FETCH_HEAD; this allows running a pull
// concurrently without getting errors // concurrently without getting errors
ArgIf(self.version.IsAtLeast(2, 29, 0), "--no-write-fetch-head") Arg("--no-write-fetch-head")
} }
func (self *SyncCommands) FetchCmdObj(task gocui.Task) *oscommands.CmdObj { func (self *SyncCommands) FetchCmdObj(task gocui.Task) *oscommands.CmdObj {

View File

@ -119,7 +119,7 @@ func TestSyncFetch(t *testing.T) {
test: func(cmdObj *oscommands.CmdObj) { test: func(cmdObj *oscommands.CmdObj) {
assert.True(t, cmdObj.ShouldLog()) assert.True(t, cmdObj.ShouldLog())
assert.Equal(t, cmdObj.GetCredentialStrategy(), oscommands.PROMPT) assert.Equal(t, cmdObj.GetCredentialStrategy(), oscommands.PROMPT)
assert.Equal(t, cmdObj.Args(), []string{"git", "fetch"}) assert.Equal(t, cmdObj.Args(), []string{"git", "fetch", "--no-write-fetch-head"})
}, },
}, },
{ {
@ -128,7 +128,7 @@ func TestSyncFetch(t *testing.T) {
test: func(cmdObj *oscommands.CmdObj) { test: func(cmdObj *oscommands.CmdObj) {
assert.True(t, cmdObj.ShouldLog()) assert.True(t, cmdObj.ShouldLog())
assert.Equal(t, cmdObj.GetCredentialStrategy(), oscommands.PROMPT) assert.Equal(t, cmdObj.GetCredentialStrategy(), oscommands.PROMPT)
assert.Equal(t, cmdObj.Args(), []string{"git", "fetch", "--all"}) assert.Equal(t, cmdObj.Args(), []string{"git", "fetch", "--all", "--no-write-fetch-head"})
}, },
}, },
} }
@ -157,7 +157,7 @@ func TestSyncFetchBackground(t *testing.T) {
test: func(cmdObj *oscommands.CmdObj) { test: func(cmdObj *oscommands.CmdObj) {
assert.False(t, cmdObj.ShouldLog()) assert.False(t, cmdObj.ShouldLog())
assert.Equal(t, cmdObj.GetCredentialStrategy(), oscommands.FAIL) assert.Equal(t, cmdObj.GetCredentialStrategy(), oscommands.FAIL)
assert.Equal(t, cmdObj.Args(), []string{"git", "fetch"}) assert.Equal(t, cmdObj.Args(), []string{"git", "fetch", "--no-write-fetch-head"})
}, },
}, },
{ {
@ -166,7 +166,7 @@ func TestSyncFetchBackground(t *testing.T) {
test: func(cmdObj *oscommands.CmdObj) { test: func(cmdObj *oscommands.CmdObj) {
assert.False(t, cmdObj.ShouldLog()) assert.False(t, cmdObj.ShouldLog())
assert.Equal(t, cmdObj.GetCredentialStrategy(), oscommands.FAIL) assert.Equal(t, cmdObj.GetCredentialStrategy(), oscommands.FAIL)
assert.Equal(t, cmdObj.Args(), []string{"git", "fetch", "--all"}) assert.Equal(t, cmdObj.Args(), []string{"git", "fetch", "--all", "--no-write-fetch-head"})
}, },
}, },
} }

View File

@ -82,7 +82,7 @@ func (self *WorktreeLoader) GetWorktrees() ([]*models.Worktree, error) {
if worktree.IsPathMissing { if worktree.IsPathMissing {
return return
} }
gitDir, err := callGitRevParseWithDir(self.cmd, self.version, worktree.Path, "--absolute-git-dir") gitDir, err := callGitRevParseWithDir(self.cmd, worktree.Path, "--absolute-git-dir")
if err != nil { if err != nil {
self.Log.Warnf("Could not find git dir for worktree %s: %v", worktree.Path, err) self.Log.Warnf("Could not find git dir for worktree %s: %v", worktree.Path, err)
return return

View File

@ -190,11 +190,7 @@ branch refs/heads/mybranch-worktree
} }
getRevParseArgs := func() []string { getRevParseArgs := func() []string {
args := []string{"rev-parse"} return []string{"rev-parse", "--path-format=absolute"}
if version.IsAtLeast(2, 31, 0) {
args = append(args, "--path-format=absolute")
}
return args
} }
s.before(runner, fs, getRevParseArgs) s.before(runner, fs, getRevParseArgs)

View File

@ -1709,7 +1709,7 @@ func EnglishTranslationSet() *TranslationSet {
CreateNewBranchFromCommit: "Create new branch off of commit", CreateNewBranchFromCommit: "Create new branch off of commit",
BuildingPatch: "Building patch", BuildingPatch: "Building patch",
ViewCommits: "View commits", ViewCommits: "View commits",
MinGitVersionError: "Git version must be at least 2.22 (i.e. from 2019 onwards). Please upgrade your git version. Alternatively raise an issue at https://github.com/jesseduffield/lazygit/issues for lazygit to be more backwards compatible.", MinGitVersionError: "Git version must be at least 2.32 (i.e. from 2021 onwards). Please upgrade your git version. Alternatively raise an issue at https://github.com/jesseduffield/lazygit/issues for lazygit to be more backwards compatible.",
RunningCustomCommandStatus: "Running custom command", RunningCustomCommandStatus: "Running custom command",
SubmoduleStashAndReset: "Stash uncommitted submodule changes and update", SubmoduleStashAndReset: "Stash uncommitted submodule changes and update",
AndResetSubmodules: "And reset submodules", AndResetSubmodules: "And reset submodules",

View File

@ -41,7 +41,6 @@ var CreateAmendCommit = NewIntegrationTest(NewIntegrationTestArgs{
Contains("commit 01"), Contains("commit 01"),
) )
if t.Git().Version().IsAtLeast(2, 32, 0) { // Support for auto-squashing "amend!" commits was added in git 2.32.0
t.Views().Commits(). t.Views().Commits().
Press(keys.Commits.SquashAboveCommits). Press(keys.Commits.SquashAboveCommits).
Tap(func() { Tap(func() {
@ -55,6 +54,5 @@ var CreateAmendCommit = NewIntegrationTest(NewIntegrationTestArgs{
Contains("commit 02 amended").IsSelected(), Contains("commit 02 amended").IsSelected(),
Contains("commit 01"), Contains("commit 01"),
) )
}
}, },
}) })

View File

@ -8,7 +8,6 @@ import (
var NegativeRefspec = NewIntegrationTest(NewIntegrationTestArgs{ var NegativeRefspec = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Having a config with a negative refspec", Description: "Having a config with a negative refspec",
ExtraCmdArgs: []string{}, ExtraCmdArgs: []string{},
GitVersion: AtLeast("2.29.0"),
SetupRepo: func(shell *Shell) { SetupRepo: func(shell *Shell) {
shell. shell.
SetConfig("remote.origin.fetch", "^refs/heads/test"). SetConfig("remote.origin.fetch", "^refs/heads/test").

View File

@ -9,7 +9,6 @@ var MoveToEarlierCommit = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Move a patch from a commit to an earlier commit", Description: "Move a patch from a commit to an earlier commit",
ExtraCmdArgs: []string{}, ExtraCmdArgs: []string{},
Skip: false, Skip: false,
GitVersion: AtLeast("2.26.0"),
SetupConfig: func(config *config.AppConfig) {}, SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) { SetupRepo: func(shell *Shell) {
shell.CreateDir("dir") shell.CreateDir("dir")

View File

@ -1,78 +0,0 @@
package patch_building
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var MoveToEarlierCommitNoKeepEmpty = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Move a patch from a commit to an earlier commit, for older git versions that don't keep the empty commit",
ExtraCmdArgs: []string{},
Skip: false,
GitVersion: Before("2.26.0"),
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {
shell.CreateDir("dir")
shell.CreateFileAndAdd("dir/file1", "file1 content")
shell.CreateFileAndAdd("dir/file2", "file2 content")
shell.Commit("first commit")
shell.CreateFileAndAdd("unrelated-file", "")
shell.Commit("destination commit")
shell.UpdateFileAndAdd("dir/file1", "file1 content with old changes")
shell.DeleteFileAndAdd("dir/file2")
shell.CreateFileAndAdd("dir/file3", "file3 content")
shell.Commit("commit to move from")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Commits().
Focus().
Lines(
Contains("commit to move from").IsSelected(),
Contains("destination commit"),
Contains("first commit"),
).
PressEnter()
t.Views().CommitFiles().
IsFocused().
Lines(
Contains("dir").IsSelected(),
Contains(" M file1"),
Contains(" D file2"),
Contains(" A file3"),
).
PressPrimaryAction().
PressEscape()
t.Views().Information().Content(Contains("Building patch"))
t.Views().Commits().
IsFocused().
SelectNextItem()
t.Common().SelectPatchOption(Contains("Move patch to selected commit"))
t.Views().Commits().
IsFocused().
Lines(
Contains("destination commit"),
Contains("first commit").IsSelected(),
).
SelectPreviousItem().
PressEnter()
t.Views().CommitFiles().
IsFocused().
Lines(
Equals("▼ /").IsSelected(),
Equals(" ▼ dir"),
Equals(" M file1"),
Equals(" D file2"),
Equals(" A file3"),
Equals(" A unrelated-file"),
).
PressEscape()
},
})

View File

@ -9,7 +9,6 @@ var MoveToNewCommitBefore = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Move a patch from a commit to a new commit before the original one", Description: "Move a patch from a commit to a new commit before the original one",
ExtraCmdArgs: []string{}, ExtraCmdArgs: []string{},
Skip: false, Skip: false,
GitVersion: AtLeast("2.26.0"),
SetupConfig: func(config *config.AppConfig) {}, SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) { SetupRepo: func(shell *Shell) {
shell.CreateDir("dir") shell.CreateDir("dir")

View File

@ -1,77 +0,0 @@
package patch_building
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var MoveToNewCommitBeforeNoKeepEmpty = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Move a patch from a commit to a new commit before the original one, for older git versions that don't keep the empty commit",
ExtraCmdArgs: []string{},
Skip: false,
GitVersion: Before("2.26.0"),
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {
shell.CreateDir("dir")
shell.CreateFileAndAdd("dir/file1", "file1 content")
shell.CreateFileAndAdd("dir/file2", "file2 content")
shell.Commit("first commit")
shell.UpdateFileAndAdd("dir/file1", "file1 content with old changes")
shell.DeleteFileAndAdd("dir/file2")
shell.CreateFileAndAdd("dir/file3", "file3 content")
shell.Commit("commit to move from")
shell.UpdateFileAndAdd("dir/file1", "file1 content with new changes")
shell.Commit("third commit")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Commits().
Focus().
Lines(
Contains("third commit").IsSelected(),
Contains("commit to move from"),
Contains("first commit"),
).
SelectNextItem().
PressEnter()
t.Views().CommitFiles().
IsFocused().
Lines(
Contains("dir").IsSelected(),
Contains(" M file1"),
Contains(" D file2"),
Contains(" A file3"),
).
PressPrimaryAction().
PressEscape()
t.Views().Information().Content(Contains("Building patch"))
t.Common().SelectPatchOption(Contains("Move patch into new commit before the original commit"))
t.ExpectPopup().CommitMessagePanel().
InitialText(Equals("")).
Type("new commit").Confirm()
t.Views().Commits().
IsFocused().
Lines(
Contains("third commit"),
Contains("new commit").IsSelected(),
Contains("first commit"),
).
PressEnter()
t.Views().CommitFiles().
IsFocused().
Lines(
Contains("dir").IsSelected(),
Contains(" M file1"),
Contains(" D file2"),
Contains(" A file3"),
).
PressEscape()
},
})

View File

@ -9,7 +9,6 @@ var ForcePushTriangular = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Push to a remote, requiring a force push because the branch is behind the remote push branch but not the upstream", Description: "Push to a remote, requiring a force push because the branch is behind the remote push branch but not the upstream",
ExtraCmdArgs: []string{}, ExtraCmdArgs: []string{},
Skip: false, Skip: false,
GitVersion: AtLeast("2.22.0"),
SetupConfig: func(config *config.AppConfig) {}, SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) { SetupRepo: func(shell *Shell) {
shell.SetConfig("push.default", "current") shell.SetConfig("push.default", "current")

View File

@ -306,7 +306,6 @@ var tests = []*components.IntegrationTest{
patch_building.MoveRangeToIndex, patch_building.MoveRangeToIndex,
patch_building.MoveToEarlierCommit, patch_building.MoveToEarlierCommit,
patch_building.MoveToEarlierCommitFromAddedFile, patch_building.MoveToEarlierCommitFromAddedFile,
patch_building.MoveToEarlierCommitNoKeepEmpty,
patch_building.MoveToIndex, patch_building.MoveToIndex,
patch_building.MoveToIndexFromAddedFileWithConflict, patch_building.MoveToIndexFromAddedFileWithConflict,
patch_building.MoveToIndexPartOfAdjacentAddedLines, patch_building.MoveToIndexPartOfAdjacentAddedLines,
@ -318,7 +317,6 @@ var tests = []*components.IntegrationTest{
patch_building.MoveToLaterCommitPartialHunk, patch_building.MoveToLaterCommitPartialHunk,
patch_building.MoveToNewCommit, patch_building.MoveToNewCommit,
patch_building.MoveToNewCommitBefore, patch_building.MoveToNewCommitBefore,
patch_building.MoveToNewCommitBeforeNoKeepEmpty,
patch_building.MoveToNewCommitFromAddedFile, patch_building.MoveToNewCommitFromAddedFile,
patch_building.MoveToNewCommitFromDeletedFile, patch_building.MoveToNewCommitFromDeletedFile,
patch_building.MoveToNewCommitInLastCommitOfStackedBranch, patch_building.MoveToNewCommitInLastCommitOfStackedBranch,