diff --git a/pkg/app/app.go b/pkg/app/app.go index 22f5913dd..602dffad2 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -97,6 +97,7 @@ func newLogger(config config.AppConfigurer) *logrus.Entry { // NewApp bootstrap a new application func NewApp(config config.AppConfigurer, filterPath string) (*App, error) { + app := &App{ closers: []io.Closer{}, Config: config, @@ -182,7 +183,7 @@ func (app *App) setupRepo() (bool, error) { } // if we are not in a git repo, we ask if we want to `git init` - if err := app.OSCommand.RunCommand("git status"); err != nil { + if err := commands.VerifyInGitRepo(app.OSCommand); err != nil { cwd, err := os.Getwd() if err != nil { return false, err @@ -225,6 +226,7 @@ func (app *App) setupRepo() (bool, error) { return false, err } } + return false, nil } diff --git a/pkg/commands/git.go b/pkg/commands/git.go index 0fc6e8739..0db74254e 100644 --- a/pkg/commands/git.go +++ b/pkg/commands/git.go @@ -54,10 +54,6 @@ func NewGitCommand(log *logrus.Entry, osCommand *oscommands.OSCommand, tr *i18n. pushToCurrent = strings.TrimSpace(output) == "current" } - if err := verifyInGitRepo(osCommand.RunCommand); err != nil { - return nil, err - } - if err := navigateToRepoRootDirectory(os.Stat, os.Chdir); err != nil { return nil, err } @@ -88,10 +84,6 @@ func NewGitCommand(log *logrus.Entry, osCommand *oscommands.OSCommand, tr *i18n. return gitCommand, nil } -func verifyInGitRepo(runCmd func(string, ...interface{}) error) error { - return runCmd("git status") -} - func navigateToRepoRootDirectory(stat func(string) (os.FileInfo, error), chdir func(string) error) error { gitDir := env.GetGitDirEnv() if gitDir != "" { @@ -120,6 +112,18 @@ func navigateToRepoRootDirectory(stat func(string) (os.FileInfo, error), chdir f if err = chdir(".."); err != nil { return utils.WrapError(err) } + + currentPath, err := os.Getwd() + if err != nil { + return err + } + + atRoot := currentPath == filepath.Dir(currentPath) + if atRoot { + // we should never really land here: the code that creates GitCommand should + // verify we're in a git directory + return errors.New("Must open lazygit in a git repository") + } } } @@ -189,3 +193,7 @@ func findDotGitDir(stat func(string) (os.FileInfo, error), readFile func(filenam } return strings.TrimSpace(strings.TrimPrefix(fileContent, "gitdir: ")), nil } + +func VerifyInGitRepo(osCommand *oscommands.OSCommand) error { + return osCommand.RunCommand("git rev-parse --git-dir") +} diff --git a/pkg/commands/git_test.go b/pkg/commands/git_test.go index 90c32c7dd..ab0f9c5ac 100644 --- a/pkg/commands/git_test.go +++ b/pkg/commands/git_test.go @@ -61,43 +61,6 @@ func (f fileInfoMock) Sys() interface{} { return f.sys } -// TestVerifyInGitRepo is a function. -func TestVerifyInGitRepo(t *testing.T) { - type scenario struct { - testName string - runCmd func(string, ...interface{}) error - test func(error) - } - - scenarios := []scenario{ - { - "Valid git repository", - func(string, ...interface{}) error { - return nil - }, - func(err error) { - assert.NoError(t, err) - }, - }, - { - "Not a valid git repository", - func(string, ...interface{}) error { - return fmt.Errorf("fatal: Not a git repository (or any of the parent directories): .git") - }, - func(err error) { - assert.Error(t, err) - assert.Regexp(t, `fatal: .ot a git repository \(or any of the parent directories\s?\/?\): \.git`, err.Error()) - }, - }, - } - - for _, s := range scenarios { - t.Run(s.testName, func(t *testing.T) { - s.test(verifyInGitRepo(s.runCmd)) - }) - } -} - // TestNavigateToRepoRootDirectory is a function. func TestNavigateToRepoRootDirectory(t *testing.T) { type scenario struct { @@ -233,7 +196,7 @@ func TestNewGitCommand(t *testing.T) { }, func(gitCmd *GitCommand, err error) { assert.Error(t, err) - assert.Regexp(t, `fatal: .ot a git repository ((\(or any of the parent directories\): \.git)|(\(or any parent up to mount point \/\)))`, err.Error()) + assert.Regexp(t, `Must open lazygit in a git repository`, err.Error()) }, }, { diff --git a/pkg/gui/recent_repos_panel.go b/pkg/gui/recent_repos_panel.go index 6fe038111..018098d23 100644 --- a/pkg/gui/recent_repos_panel.go +++ b/pkg/gui/recent_repos_panel.go @@ -48,9 +48,26 @@ func (gui *Gui) handleShowAllBranchLogs() error { func (gui *Gui) dispatchSwitchToRepo(path string) error { env.UnsetGitDirEnvs() + originalPath, err := os.Getwd() + if err != nil { + return nil + } + if err := os.Chdir(path); err != nil { + if os.IsNotExist(err) { + return gui.createErrorPanel(gui.Tr.ErrRepositoryMovedOrDeleted) + } return err } + + if err := commands.VerifyInGitRepo(gui.OSCommand); err != nil { + if err := os.Chdir(originalPath); err != nil { + return err + } + + return err + } + newGitCommand, err := commands.NewGitCommand(gui.Log, gui.OSCommand, gui.Tr, gui.Config) if err != nil { return err diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index f2211f8b1..372211069 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -438,6 +438,7 @@ type TranslationSet struct { LcCopiedToClipboard string ErrCannotEditDirectory string ErrStageDirWithInlineMergeConflicts string + ErrRepositoryMovedOrDeleted string } const englishReleaseNotes = `## lazygit 0.26 Release Notes @@ -999,5 +1000,6 @@ func englishTranslationSet() TranslationSet { LcCopiedToClipboard: "copied to clipboard", ErrCannotEditDirectory: "Cannot edit directory: you can only edit individual files", ErrStageDirWithInlineMergeConflicts: "Cannot stage/unstage directory containing files with inline merge conflicts. Please fix up the merge conflicts first", + ErrRepositoryMovedOrDeleted: "Cannot find repo. It might have been moved or deleted ¯\\_(ツ)_/¯", } }