From 9009083f55ffe1c380d79aa9c61de9089e1bed66 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Mon, 12 Oct 2026 18:45:43 +0200 Subject: [PATCH] Don't stage nested repositories when committing with nothing staged If nothing is staged, committing offers to stage all files first, or stages them without asking if gui.skipNoStagedFilesWarning is set. Like staging all files in the files panel, this adds a nested repository as an embedded repository. Show why the nested repository can't be staged instead, as staging all files in the files panel does. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../helpers/working_tree_helper.go | 4 ++ .../commit_all_with_nested_repository.go | 52 +++++++++++++++++++ pkg/integration/tests/test_list.go | 1 + 3 files changed, 57 insertions(+) create mode 100644 pkg/integration/tests/commit/commit_all_with_nested_repository.go diff --git a/pkg/gui/controllers/helpers/working_tree_helper.go b/pkg/gui/controllers/helpers/working_tree_helper.go index a4b8c6cae..a11830649 100644 --- a/pkg/gui/controllers/helpers/working_tree_helper.go +++ b/pkg/gui/controllers/helpers/working_tree_helper.go @@ -266,6 +266,10 @@ func (self *WorkingTreeHelper) WithEnsureCommittableFiles(handler func() error) } if !self.AnyStagedFiles() { + if nestedRepository, ok := lo.Find(self.c.Model().Files, (*models.File).IsNestedRepository); ok { + return errors.New(self.CantStageNestedRepository(nestedRepository).Text) + } + if self.c.UserConfig().Gui.SkipNoStagedFilesWarning { self.c.LogAction(self.c.Tr.Actions.StageAllFiles) if err := self.c.Git().WorkingTree.StageAll(false); err != nil { diff --git a/pkg/integration/tests/commit/commit_all_with_nested_repository.go b/pkg/integration/tests/commit/commit_all_with_nested_repository.go new file mode 100644 index 000000000..497498d68 --- /dev/null +++ b/pkg/integration/tests/commit/commit_all_with_nested_repository.go @@ -0,0 +1,52 @@ +package commit + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var CommitAllWithNestedRepository = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Committing with nothing staged doesn't offer to stage all files if that would stage a nested repository", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) { + config.GetUserConfig().Gui.ShowFileTree = false + }, + SetupRepo: func(shell *Shell) { + shell.EmptyCommit("first commit") + shell.CreateFile("file", "content") + shell.RunCommand([]string{"git", "init", "nested"}) + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Files(). + IsFocused(). + Lines( + Equals("?? file").IsSelected(), + Equals("?? nested (nested repository)"), + ). + Press(keys.Files.CommitChanges). + Tap(func() { + t.ExpectPopup().Alert(). + Title(Equals("Error")). + Content(Equals("Can't stage 'nested' because it is a git repository of its own. Discard it with d, or ignore it with i.")). + Confirm() + }). + // Once something is staged, committing works as usual + PressPrimaryAction(). + Press(keys.Files.CommitChanges). + Tap(func() { + t.ExpectPopup().CommitMessagePanel(). + Type("add file"). + Confirm() + }). + Lines( + Equals("?? nested (nested repository)").IsSelected(), + ) + + t.Views().Commits(). + Lines( + Contains("add file"), + Contains("first commit"), + ) + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index 1975e07dc..0736fecf6 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -114,6 +114,7 @@ var tests = []*components.IntegrationTest{ commit.CheckoutFileFromRangeSelectionOfCommits, commit.CheckoutFileWithLocalModifications, commit.Commit, + commit.CommitAllWithNestedRepository, commit.CommitMultiline, commit.CommitSkipHooks, commit.CommitSwitchToEditor,