Bump the minimum required git version to 2.22 (#4439)

- **PR Description**

For my current work on better cherry-picking/reverting, git versions
older than 2.22 cause considerable headache. Apparently they have issues
with `git cherry-pick --continue` and `git cherry-pick --skip` which I
would prefer not to have to work around.

The last time [we
discussed](https://github.com/jesseduffield/lazygit/issues/2457#issuecomment-1436767849)
the question of bumping the minimum version from 2.20 to 2.22, we
decided not to because 2.22 is 6 months newer. That was two years ago
though, so now it should be fine, I guess.
This commit is contained in:
Stefan Haller 2025-04-09 10:43:31 +02:00 committed by GitHub
commit e127a928fe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 15 additions and 44 deletions

View file

@ -49,8 +49,7 @@ jobs:
fail-fast: false
matrix:
git-version:
- 2.20.0 # oldest supported version
- 2.22.5
- 2.22.0 # oldest supported version
- 2.23.0
- 2.25.1
- 2.30.8

View file

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

View file

@ -72,7 +72,7 @@ func (self *BranchLoader) Load(reflogCommits []*models.Commit,
onWorker func(func() error),
renderFunc func(),
) ([]*models.Branch, error) {
branches := self.obtainBranches(self.version.IsAtLeast(2, 22, 0))
branches := self.obtainBranches()
if self.AppState.LocalBranchSortOrder == "recency" {
reflogBranches := self.obtainReflogBranches(reflogCommits)
@ -232,7 +232,7 @@ func (self *BranchLoader) GetBaseBranch(branch *models.Branch, mainBranches *Mai
return split[0], nil
}
func (self *BranchLoader) obtainBranches(canUsePushTrack bool) []*models.Branch {
func (self *BranchLoader) obtainBranches() []*models.Branch {
output, err := self.getRawBranches()
if err != nil {
panic(err)
@ -255,7 +255,7 @@ func (self *BranchLoader) obtainBranches(canUsePushTrack bool) []*models.Branch
}
storeCommitDateAsRecency := self.AppState.LocalBranchSortOrder != "recency"
return obtainBranch(split, storeCommitDateAsRecency, canUsePushTrack), true
return obtainBranch(split, storeCommitDateAsRecency), true
})
}
@ -298,7 +298,7 @@ var branchFields = []string{
}
// Obtain branch information from parsed line output of getRawBranches()
func obtainBranch(split []string, storeCommitDateAsRecency bool, canUsePushTrack bool) *models.Branch {
func obtainBranch(split []string, storeCommitDateAsRecency bool) *models.Branch {
headMarker := split[0]
fullName := split[1]
upstreamName := split[2]
@ -310,12 +310,7 @@ func obtainBranch(split []string, storeCommitDateAsRecency bool, canUsePushTrack
name := strings.TrimPrefix(fullName, "heads/")
aheadForPull, behindForPull, gone := parseUpstreamInfo(upstreamName, track)
var aheadForPush, behindForPush string
if canUsePushTrack {
aheadForPush, behindForPush, _ = parseUpstreamInfo(upstreamName, pushTrack)
} else {
aheadForPush, behindForPush = aheadForPull, behindForPull
}
aheadForPush, behindForPush, _ := parseUpstreamInfo(upstreamName, pushTrack)
recency := ""
if storeCommitDateAsRecency {

View file

@ -119,7 +119,7 @@ func TestObtainBranch(t *testing.T) {
for _, s := range scenarios {
t.Run(s.testName, func(t *testing.T) {
branch := obtainBranch(s.input, s.storeCommitDateAsRecency, true)
branch := obtainBranch(s.input, s.storeCommitDateAsRecency)
assert.EqualValues(t, s.expectedBranch, branch)
})
}

View file

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

View file

@ -54,16 +54,6 @@ func TestRebaseRebaseBranch(t *testing.T) {
assert.NoError(t, err)
},
},
{
testName: "successful rebase (< 2.22.0)",
arg: "master",
gitVersion: &GitVersion{2, 21, 9, ""},
runner: oscommands.NewFakeRunner(t).
ExpectGitArgs([]string{"rebase", "--interactive", "--autostash", "--keep-empty", "--no-autosquash", "master"}, "", nil),
test: func(err error) {
assert.NoError(t, err)
},
},
}
for _, s := range scenarios {

View file

@ -1714,7 +1714,7 @@ func EnglishTranslationSet() *TranslationSet {
CreateNewBranchFromCommit: "Create new branch off of commit",
BuildingPatch: "Building patch",
ViewCommits: "View commits",
MinGitVersionError: "Git version must be at least 2.20 (i.e. from 2018 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.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.",
RunningCustomCommandStatus: "Running custom command",
SubmoduleStashAndReset: "Stash uncommitted submodule changes and update",
AndResetSubmodules: "And reset submodules",

View file

@ -10,7 +10,6 @@ var DropMergeCommit = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Drops a merge commit outside of an interactive rebase",
ExtraCmdArgs: []string{},
Skip: false,
GitVersion: AtLeast("2.22.0"), // first version that supports the --rebase-merges option
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {
shared.CreateMergeCommit(shell)

View file

@ -10,7 +10,6 @@ var EditRangeSelectDownToMergeOutsideRebase = NewIntegrationTest(NewIntegrationT
Description: "Select a range of commits (the last one being a merge commit) to edit outside of a rebase",
ExtraCmdArgs: []string{},
Skip: false,
GitVersion: AtLeast("2.22.0"), // first version that supports the --rebase-merges option
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {
shared.CreateMergeCommit(shell)

View file

@ -10,7 +10,6 @@ var EditRangeSelectOutsideRebase = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Select a range of commits to edit outside of a rebase",
ExtraCmdArgs: []string{},
Skip: false,
GitVersion: AtLeast("2.22.0"), // first version that supports the --rebase-merges option
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {
shared.CreateMergeCommit(shell)

View file

@ -29,11 +29,7 @@ var Enter = NewIntegrationTest(NewIntegrationTestArgs{
t.Views().Status().Content(Contains("repo"))
}
assertInSubmodule := func() {
if t.Git().Version().IsAtLeast(2, 22, 0) {
t.Views().Status().Content(Contains("my_submodule_path(my_submodule_name)"))
} else {
t.Views().Status().Content(Contains("my_submodule_path"))
}
t.Views().Status().Content(Contains("my_submodule_path(my_submodule_name)"))
}
assertInParentRepo()

View file

@ -37,11 +37,7 @@ var EnterNested = NewIntegrationTest(NewIntegrationTestArgs{
// enter the nested submodule
PressEnter()
if t.Git().Version().IsAtLeast(2, 22, 0) {
t.Views().Status().Content(Contains("innerSubPath(innerSubName)"))
} else {
t.Views().Status().Content(Contains("innerSubPath"))
}
t.Views().Status().Content(Contains("innerSubPath(innerSubName)"))
t.Views().Commits().ContainsLines(
Contains("initial inner commit"),
)

View file

@ -31,11 +31,7 @@ var Reset = NewIntegrationTest(NewIntegrationTestArgs{
t.Views().Status().Content(Contains("repo"))
}
assertInSubmodule := func() {
if t.Git().Version().IsAtLeast(2, 22, 0) {
t.Views().Status().Content(Contains("my_submodule_path(my_submodule_name)"))
} else {
t.Views().Status().Content(Contains("my_submodule_path"))
}
t.Views().Status().Content(Contains("my_submodule_path(my_submodule_name)"))
}
assertInParentRepo()

View file

@ -1,5 +1,7 @@
#!/bin/sh
echo "Running integration tests with $(git --version)"
# This is ugly, but older versions of git don't support the GIT_CONFIG_GLOBAL
# env var; the only way to run tests for these old versions is to copy our test
# config file to the actual global location. Move an existing file out of the