Fix #5302: Create .git/info directory before writing exclude file

When .git/info directory does not exist (can happen with bare clones
or manual deletion), the Exclude function failed with 'no such file
or directory'. Added os.MkdirAll to create the directory before
opening the exclude file.

Added integration test exclude_without_info_dir that removes .git/info
before attempting to exclude a file.
This commit is contained in:
cobyfrombrooklyn-bot 2026-02-26 10:42:24 -05:00 committed by Stefan Haller
parent 9b74805d2d
commit 30154aa9c5
3 changed files with 38 additions and 1 deletions

View file

@ -246,7 +246,11 @@ func (self *WorkingTreeCommands) Ignore(filename string) error {
// Exclude adds a file to the .git/info/exclude for the repo
func (self *WorkingTreeCommands) Exclude(filename string) error {
excludeFile := filepath.Join(self.repoPaths.repoGitDirPath, "info", "exclude")
infoDir := filepath.Join(self.repoPaths.repoGitDirPath, "info")
if err := os.MkdirAll(infoDir, 0o755); err != nil {
return err
}
excludeFile := filepath.Join(infoDir, "exclude")
return self.os.AppendLineToFile(excludeFile, escapeFilename(filename))
}

View file

@ -0,0 +1,32 @@
package file
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var ExcludeWithoutInfoDir = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Exclude a file when .git/info directory does not exist",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {
},
SetupRepo: func(shell *Shell) {
// Remove .git/info directory to reproduce #5302
shell.RunCommand([]string{"rm", "-rf", ".git/info"})
shell.CreateFile("toExclude", "")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Files().
IsFocused().
Focus().
NavigateToLine(Contains("toExclude")).
Press(keys.Files.IgnoreFile).
Tap(func() {
t.ExpectPopup().Menu().Title(Equals("Ignore or exclude file")).Select(Contains("Add to .git/info/exclude")).Confirm()
// Should succeed without error, creating .git/info/ directory automatically
t.FileSystem().FileContent(".git/info/exclude", Contains("/toExclude"))
})
},
})

View file

@ -221,6 +221,7 @@ var tests = []*components.IntegrationTest{
file.DiscardUnstagedRangeSelect,
file.DiscardVariousChanges,
file.DiscardVariousChangesRangeSelect,
file.ExcludeWithoutInfoDir,
file.Gitignore,
file.GitignoreSpecialCharacters,
file.RememberCommitMessageAfterFail,