Add config git.autoStageResolvedConflicts

This commit is contained in:
Stefan Haller 2024-08-28 22:18:31 +02:00
parent 1191aca60f
commit 90b8fd242d
6 changed files with 124 additions and 23 deletions

View file

@ -305,6 +305,12 @@ git:
# If true, pass the --all arg to git fetch # If true, pass the --all arg to git fetch
fetchAll: true fetchAll: true
# If true, lazygit will automatically stage files that used to have merge
# conflicts but no longer do; and it will also ask you if you want to
# continue a merge or rebase if you've resolved all conflicts. If false, it
# won't do either of these things.
autoStageResolvedConflicts: true
# Command used when displaying the current branch git log in the main window # Command used when displaying the current branch git log in the main window
branchLogCmd: git log --graph --color=always --abbrev-commit --decorate --date=relative --pretty=medium {{branchName}} -- branchLogCmd: git log --graph --color=always --abbrev-commit --decorate --date=relative --pretty=medium {{branchName}} --

View file

@ -224,6 +224,11 @@ type GitConfig struct {
AutoRefresh bool `yaml:"autoRefresh"` AutoRefresh bool `yaml:"autoRefresh"`
// If true, pass the --all arg to git fetch // If true, pass the --all arg to git fetch
FetchAll bool `yaml:"fetchAll"` FetchAll bool `yaml:"fetchAll"`
// If true, lazygit will automatically stage files that used to have merge
// conflicts but no longer do; and it will also ask you if you want to
// continue a merge or rebase if you've resolved all conflicts. If false, it
// won't do either of these things.
AutoStageResolvedConflicts bool `yaml:"autoStageResolvedConflicts"`
// Command used when displaying the current branch git log in the main window // Command used when displaying the current branch git log in the main window
BranchLogCmd string `yaml:"branchLogCmd"` BranchLogCmd string `yaml:"branchLogCmd"`
// Command used to display git log of all branches in the main window. // Command used to display git log of all branches in the main window.
@ -753,6 +758,7 @@ func GetDefaultConfig() *UserConfig {
AutoFetch: true, AutoFetch: true,
AutoRefresh: true, AutoRefresh: true,
FetchAll: true, FetchAll: true,
AutoStageResolvedConflicts: true,
BranchLogCmd: "git log --graph --color=always --abbrev-commit --decorate --date=relative --pretty=medium {{branchName}} --", BranchLogCmd: "git log --graph --color=always --abbrev-commit --decorate --date=relative --pretty=medium {{branchName}} --",
AllBranchesLogCmd: "git log --graph --all --color=always --abbrev-commit --decorate --date=relative --pretty=medium", AllBranchesLogCmd: "git log --graph --all --color=always --abbrev-commit --decorate --date=relative --pretty=medium",
DisableForcePushing: false, DisableForcePushing: false,

View file

@ -546,6 +546,8 @@ func (self *RefreshHelper) refreshFilesAndSubmodules() error {
func (self *RefreshHelper) refreshStateFiles() error { func (self *RefreshHelper) refreshStateFiles() error {
fileTreeViewModel := self.c.Contexts().Files.FileTreeViewModel fileTreeViewModel := self.c.Contexts().Files.FileTreeViewModel
prevConflictFileCount := 0
if self.c.UserConfig().Git.AutoStageResolvedConflicts {
// If git thinks any of our files have inline merge conflicts, but they actually don't, // If git thinks any of our files have inline merge conflicts, but they actually don't,
// we stage them. // we stage them.
// Note that if files with merge conflicts have both arisen and have been resolved // Note that if files with merge conflicts have both arisen and have been resolved
@ -554,7 +556,6 @@ func (self *RefreshHelper) refreshStateFiles() error {
// Although this also means that at startup we won't be staging anything until // Although this also means that at startup we won't be staging anything until
// we call git status again. // we call git status again.
pathsToStage := []string{} pathsToStage := []string{}
prevConflictFileCount := 0
for _, file := range self.c.Model().Files { for _, file := range self.c.Model().Files {
if file.HasMergeConflicts { if file.HasMergeConflicts {
prevConflictFileCount++ prevConflictFileCount++
@ -575,6 +576,7 @@ func (self *RefreshHelper) refreshStateFiles() error {
return err return err
} }
} }
}
files := self.c.Git().Loaders.FileLoader. files := self.c.Git().Loaders.FileLoader.
GetStatusFiles(git_commands.GetStatusFileOptions{}) GetStatusFiles(git_commands.GetStatusFileOptions{})

View file

@ -0,0 +1,81 @@
package conflicts
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
"github.com/jesseduffield/lazygit/pkg/integration/tests/shared"
)
var ResolveNoAutoStage = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Resolving conflicts without auto-staging",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {
config.GetUserConfig().Git.AutoStageResolvedConflicts = false
},
SetupRepo: func(shell *Shell) {
shared.CreateMergeConflictFiles(shell)
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Files().
IsFocused().
Lines(
Contains("UU").Contains("file1").IsSelected(),
Contains("UU").Contains("file2"),
).
PressEnter()
t.Views().MergeConflicts().
IsFocused().
SelectedLines(
Contains("<<<<<<< HEAD"),
Contains("First Change"),
Contains("======="),
).
PressPrimaryAction()
t.Views().Files().
IsFocused().
// Resolving the conflict didn't auto-stage it
Lines(
Contains("UU").Contains("file1").IsSelected(),
Contains("UU").Contains("file2"),
).
// So do that manually
PressPrimaryAction().
Lines(
Contains("UU").Contains("file2").IsSelected(),
).
// Trying to stage a file that still has conflicts is not allowed:
PressPrimaryAction().
Tap(func() {
t.ExpectPopup().Alert().
Title(Equals("Error")).
Content(Contains("Cannot stage/unstage directory containing files with inline merge conflicts.")).
Confirm()
}).
PressEnter()
// coincidentally these files have the same conflict
t.Views().MergeConflicts().
IsFocused().
SelectedLines(
Contains("<<<<<<< HEAD"),
Contains("First Change"),
Contains("======="),
).
PressPrimaryAction()
t.Views().Files().
IsFocused().
// Again, resolving the conflict didn't auto-stage it
Lines(
Contains("UU").Contains("file2").IsSelected(),
).
// Doing that manually now works:
PressPrimaryAction().
Lines(
Contains("A").Contains("file3").IsSelected(),
)
},
})

View file

@ -115,6 +115,7 @@ var tests = []*components.IntegrationTest{
conflicts.Filter, conflicts.Filter,
conflicts.ResolveExternally, conflicts.ResolveExternally,
conflicts.ResolveMultipleFiles, conflicts.ResolveMultipleFiles,
conflicts.ResolveNoAutoStage,
conflicts.UndoChooseHunk, conflicts.UndoChooseHunk,
custom_commands.AccessCommitProperties, custom_commands.AccessCommitProperties,
custom_commands.BasicCommand, custom_commands.BasicCommand,

View file

@ -573,6 +573,11 @@
"description": "If true, pass the --all arg to git fetch", "description": "If true, pass the --all arg to git fetch",
"default": true "default": true
}, },
"autoStageResolvedConflicts": {
"type": "boolean",
"description": "If true, lazygit will automatically stage files that used to have merge\nconflicts but no longer do; and it will also ask you if you want to\ncontinue a merge or rebase if you've resolved all conflicts. If false, it\nwon't do either of these things.",
"default": true
},
"branchLogCmd": { "branchLogCmd": {
"type": "string", "type": "string",
"description": "Command used when displaying the current branch git log in the main window", "description": "Command used when displaying the current branch git log in the main window",