mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-10 07:36:27 -04:00
Don't load or migrate the user config when running in daemon mode
When git invokes lazygit as a daemon during a rebase (e.g. as the
GIT_SEQUENCE_EDITOR), the child instance loaded the user config on
startup. If the config still had a pre-migration schema, it was
auto-migrated and written back to disk in the middle of the git
operation. With the config file checked in (e.g. a dotfiles repo),
this dirties the working tree mid-rebase and git aborts:
error: Your local changes to the following files would be
overwritten by merge: config.yml
The daemon doesn't need the user config for anything, so skip loading
it entirely in daemon mode: build the app config from defaults without
touching any config files, and handle the daemon instruction right
away. Normal (non-daemon) startup is unchanged.
Fixes #5998
This commit is contained in:
parent
c07f4d381b
commit
0bfa987b7a
|
|
@ -136,6 +136,25 @@ func Start(buildInfo *BuildInfo, integrationTest integrationTypes.IntegrationTes
|
|||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// When git invokes lazygit as a daemon (e.g. as the editor of a rebase todo
|
||||
// file), skip loading and migrating the user config entirely; the daemon
|
||||
// doesn't need it, and migrating the config here would dirty the working
|
||||
// tree in the middle of the git operation (see #5998).
|
||||
if daemon.InDaemonMode() {
|
||||
appConfig, err := config.NewAppConfigForDaemon("lazygit", buildInfo.Version, buildInfo.Commit, buildInfo.Date, buildInfo.BuildSource, cliArgs.Debug, tempDir)
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
|
||||
common, err := NewCommon(appConfig)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
daemon.Handle(common)
|
||||
return
|
||||
}
|
||||
|
||||
appConfig, err := config.NewAppConfig("lazygit", buildInfo.Version, buildInfo.Commit, buildInfo.Date, buildInfo.BuildSource, cliArgs.Debug, tempDir)
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
|
|
@ -159,11 +178,6 @@ func Start(buildInfo *BuildInfo, integrationTest integrationTypes.IntegrationTes
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if daemon.InDaemonMode() {
|
||||
daemon.Handle(common)
|
||||
return
|
||||
}
|
||||
|
||||
if cliArgs.Profile {
|
||||
go func() {
|
||||
if err := http.ListenAndServe("localhost:6060", nil); err != nil {
|
||||
|
|
|
|||
|
|
@ -130,6 +130,45 @@ func NewAppConfig(
|
|||
return appConfig, nil
|
||||
}
|
||||
|
||||
// NewAppConfigForDaemon makes a new app config for running lazygit in daemon
|
||||
// mode, i.e. when git invokes lazygit as e.g. the editor of a rebase todo
|
||||
// file. The daemon doesn't need the user config for anything, so it is neither
|
||||
// loaded nor migrated here: migrating the config from within a git operation
|
||||
// would modify the working tree mid-operation, aborting e.g. a rebase with
|
||||
// "error: Your local changes to the following files would be overwritten by
|
||||
// merge" when the config file is checked in (see #5998).
|
||||
func NewAppConfigForDaemon(
|
||||
name string,
|
||||
version,
|
||||
commit,
|
||||
date string,
|
||||
buildSource string,
|
||||
debuggingFlag bool,
|
||||
tempDir string,
|
||||
) (*AppConfig, error) {
|
||||
configDir, err := findOrCreateConfigDir()
|
||||
if err != nil && !os.IsPermission(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
appState, err := loadAppState()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &AppConfig{
|
||||
name: name,
|
||||
version: version,
|
||||
buildDate: date,
|
||||
debug: debuggingFlag,
|
||||
buildSource: buildSource,
|
||||
userConfig: GetDefaultConfigForPlatform(KeybindingPlatform()),
|
||||
userConfigDir: configDir,
|
||||
tempDir: tempDir,
|
||||
appState: appState,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ConfigDir() string {
|
||||
_, filePath := findConfigFile(ConfigFilename)
|
||||
|
||||
|
|
|
|||
41
pkg/config/app_config_daemon_test.go
Normal file
41
pkg/config/app_config_daemon_test.go
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// Invoking lazygit as a daemon (e.g. as the editor of a rebase todo file) must
|
||||
// not load or migrate the user config: writing a migrated config back to disk
|
||||
// dirties the working tree in the middle of the git operation, aborting a
|
||||
// rebase whose repo has the config file checked in (see #5998).
|
||||
func TestNewAppConfigForDaemonDoesNotTouchUserConfig(t *testing.T) {
|
||||
stateDir := t.TempDir()
|
||||
t.Setenv("CONFIG_DIR", stateDir)
|
||||
|
||||
configPath := filepath.Join(stateDir, ConfigFilename)
|
||||
preMigrationConfig := "git:\n pagers:\n - pager: less\n"
|
||||
if err := os.WriteFile(configPath, []byte(preMigrationConfig), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
appConfig, err := NewAppConfigForDaemon("lazygit", "test-version", "test-commit", "test-date", "test-build", false, t.TempDir())
|
||||
assert.NoError(t, err)
|
||||
if appConfig == nil {
|
||||
t.Fatal("expected non-nil app config")
|
||||
}
|
||||
|
||||
// The config file must be untouched (not created, not migrated, not
|
||||
// rewritten).
|
||||
content, err := os.ReadFile(configPath)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, preMigrationConfig, string(content))
|
||||
|
||||
// The daemon still gets a usable config object with defaults, and usable
|
||||
// app state.
|
||||
assert.NotNil(t, appConfig.GetUserConfig())
|
||||
assert.NotNil(t, appConfig.GetAppState())
|
||||
}
|
||||
Loading…
Reference in a new issue