mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-07-30 03:23:08 +03:00
Refactor repo_paths.go to use git rev-parse
This changes GetRepoPaths() to pull information from `git rev-parse` instead of effectively reimplementing git's logic for pathfinding. This change fixes issues with bare repos, esp. versioned homedir use cases, by aligning lazygit's path handling to what git itself does. This change also enables lazygit to run from arbitrary subdirectories of a repository, including correct handling of symlinks, including "deep" symlinks into a repo, worktree, a repo's submodules, etc. Integration tests are now resilient against unintended side effects from the host's environment variables. Of necessity, $PATH and $TERM are the only env vars allowed through now.
This commit is contained in:
committed by
Stefan Haller
parent
74d937881e
commit
3d9f1e02e5
92
pkg/integration/tests/worktree/bare_repo_worktree_config.go
Normal file
92
pkg/integration/tests/worktree/bare_repo_worktree_config.go
Normal file
@ -0,0 +1,92 @@
|
||||
package worktree
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||
)
|
||||
|
||||
// This case is identical to dotfile_bare_repo.go, except
|
||||
// that it invokes lazygit with $GIT_DIR set but not
|
||||
// $GIT_WORK_TREE. Instead, the repo uses the core.worktree
|
||||
// config to identify the main worktre.
|
||||
|
||||
var BareRepoWorktreeConfig = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
Description: "Open lazygit in the worktree of a vcsh-style bare repo and add a file and commit",
|
||||
ExtraCmdArgs: []string{"--git-dir={{.actualPath}}/.bare"},
|
||||
Skip: false,
|
||||
SetupConfig: func(config *config.AppConfig) {
|
||||
config.UserConfig.Gui.ShowFileTree = false
|
||||
},
|
||||
SetupRepo: func(shell *Shell) {
|
||||
// we're going to have a directory structure like this:
|
||||
// project
|
||||
// - .bare
|
||||
// - . (a worktree at the same path as .bare)
|
||||
//
|
||||
//
|
||||
// 'repo' is the repository/directory that all lazygit tests start in
|
||||
|
||||
shell.CreateFileAndAdd("a/b/c/blah", "blah\n")
|
||||
shell.Commit("initial commit")
|
||||
|
||||
shell.CreateFileAndAdd(".gitignore", ".bare/\n/repo\n")
|
||||
shell.Commit("add .gitignore")
|
||||
|
||||
shell.Chdir("..")
|
||||
|
||||
// configure this "fake bare"" repo using the vcsh convention
|
||||
// of core.bare=false and core.worktree set to the actual
|
||||
// worktree path (a homedir root). This allows $GIT_DIR
|
||||
// alone to make this repo "self worktree identifying"
|
||||
shell.RunCommand([]string{"git", "--git-dir=./.bare", "init", "--shared=false"})
|
||||
shell.RunCommand([]string{"git", "--git-dir=./.bare", "config", "core.bare", "false"})
|
||||
shell.RunCommand([]string{"git", "--git-dir=./.bare", "config", "core.worktree", ".."})
|
||||
shell.RunCommand([]string{"git", "--git-dir=./.bare", "remote", "add", "origin", "./repo"})
|
||||
shell.RunCommand([]string{"git", "--git-dir=./.bare", "checkout", "-b", "main"})
|
||||
shell.RunCommand([]string{"git", "--git-dir=./.bare", "config", "branch.main.remote", "origin"})
|
||||
shell.RunCommand([]string{"git", "--git-dir=./.bare", "config", "branch.main.merge", "refs/heads/master"})
|
||||
shell.RunCommand([]string{"git", "--git-dir=./.bare", "fetch", "origin", "master"})
|
||||
shell.RunCommand([]string{"git", "--git-dir=./.bare", "-c", "merge.ff=true", "merge", "origin/master"})
|
||||
|
||||
// we no longer need the original repo so remove it
|
||||
shell.DeleteFile("repo")
|
||||
|
||||
shell.UpdateFile("a/b/c/blah", "updated content\n")
|
||||
shell.Chdir("a/b/c")
|
||||
},
|
||||
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
||||
t.Views().Branches().
|
||||
Lines(
|
||||
Contains("main"),
|
||||
)
|
||||
|
||||
t.Views().Commits().
|
||||
Lines(
|
||||
Contains("add .gitignore"),
|
||||
Contains("initial commit"),
|
||||
)
|
||||
|
||||
t.Views().Files().
|
||||
IsFocused().
|
||||
Lines(
|
||||
Contains(" M a/b/c/blah"), // shows as modified
|
||||
).
|
||||
PressPrimaryAction().
|
||||
Press(keys.Files.CommitChanges)
|
||||
|
||||
t.ExpectPopup().CommitMessagePanel().
|
||||
Title(Equals("Commit summary")).
|
||||
Type("Add blah").
|
||||
Confirm()
|
||||
|
||||
t.Views().Files().
|
||||
IsEmpty()
|
||||
|
||||
t.Views().Commits().
|
||||
Lines(
|
||||
Contains("Add blah"),
|
||||
Contains("add .gitignore"),
|
||||
Contains("initial commit"),
|
||||
)
|
||||
},
|
||||
})
|
@ -0,0 +1,93 @@
|
||||
package worktree
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||
)
|
||||
|
||||
// Even though this involves submodules, it's a worktree test since
|
||||
// it's really exercising lazygit's ability to correctly do pathfinding
|
||||
// in a complex use case.
|
||||
var DoubleNestedLinkedSubmodule = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
Description: "Open lazygit in a link to a repo's double nested submodules",
|
||||
ExtraCmdArgs: []string{},
|
||||
Skip: false,
|
||||
SetupConfig: func(config *config.AppConfig) {
|
||||
config.UserConfig.Gui.ShowFileTree = false
|
||||
},
|
||||
SetupRepo: func(shell *Shell) {
|
||||
// we're going to have a directory structure like this:
|
||||
// project
|
||||
// - repo/outerSubmodule/innerSubmodule/a/b/c
|
||||
// - link (symlink to repo/outerSubmodule/innerSubmodule/a/b/c)
|
||||
//
|
||||
shell.CreateFileAndAdd("rootFile", "rootStuff")
|
||||
shell.Commit("initial repo commit")
|
||||
|
||||
shell.Chdir("..")
|
||||
shell.CreateDir("innerSubmodule")
|
||||
shell.Chdir("innerSubmodule")
|
||||
shell.Init()
|
||||
shell.CreateFileAndAdd("a/b/c/blah", "blah\n")
|
||||
shell.Commit("initial inner commit")
|
||||
|
||||
shell.Chdir("..")
|
||||
shell.CreateDir("outerSubmodule")
|
||||
shell.Chdir("outerSubmodule")
|
||||
shell.Init()
|
||||
shell.CreateFileAndAdd("foo", "foo")
|
||||
shell.Commit("initial outer commit")
|
||||
// the git config (-c) parameter below is required
|
||||
// to let git create a file-protocol/path submodule
|
||||
shell.RunCommand([]string{"git", "-c", "protocol.file.allow=always", "submodule", "add", "../innerSubmodule"})
|
||||
shell.Commit("add dependency as innerSubmodule")
|
||||
|
||||
shell.Chdir("../repo")
|
||||
shell.RunCommand([]string{"git", "-c", "protocol.file.allow=always", "submodule", "add", "../outerSubmodule"})
|
||||
shell.Commit("add dependency as outerSubmodule")
|
||||
shell.Chdir("outerSubmodule")
|
||||
shell.RunCommand([]string{"git", "-c", "protocol.file.allow=always", "submodule", "update", "--init", "--recursive"})
|
||||
|
||||
shell.Chdir("innerSubmodule")
|
||||
shell.UpdateFile("a/b/c/blah", "updated content\n")
|
||||
|
||||
shell.Chdir("../../..")
|
||||
shell.RunCommand([]string{"ln", "-s", "repo/outerSubmodule/innerSubmodule/a/b/c", "link"})
|
||||
|
||||
shell.Chdir("link")
|
||||
},
|
||||
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
||||
t.Views().Branches().
|
||||
Lines(
|
||||
Contains("HEAD detached"),
|
||||
Contains("master"),
|
||||
)
|
||||
|
||||
t.Views().Commits().
|
||||
Lines(
|
||||
Contains("initial inner commit"),
|
||||
)
|
||||
|
||||
t.Views().Files().
|
||||
IsFocused().
|
||||
Lines(
|
||||
Contains(" M a/b/c/blah"), // shows as modified
|
||||
).
|
||||
PressPrimaryAction().
|
||||
Press(keys.Files.CommitChanges)
|
||||
|
||||
t.ExpectPopup().CommitMessagePanel().
|
||||
Title(Equals("Commit summary")).
|
||||
Type("Update blah").
|
||||
Confirm()
|
||||
|
||||
t.Views().Files().
|
||||
IsEmpty()
|
||||
|
||||
t.Views().Commits().
|
||||
Lines(
|
||||
Contains("Update blah"),
|
||||
Contains("initial inner commit"),
|
||||
)
|
||||
},
|
||||
})
|
63
pkg/integration/tests/worktree/symlink_into_repo_subdir.go
Normal file
63
pkg/integration/tests/worktree/symlink_into_repo_subdir.go
Normal file
@ -0,0 +1,63 @@
|
||||
package worktree
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||
)
|
||||
|
||||
var SymlinkIntoRepoSubdir = NewIntegrationTest(NewIntegrationTestArgs{
|
||||
Description: "Open lazygit in a symlink into a repo's subdirectory",
|
||||
ExtraCmdArgs: []string{},
|
||||
Skip: false,
|
||||
SetupConfig: func(config *config.AppConfig) {
|
||||
config.UserConfig.Gui.ShowFileTree = false
|
||||
},
|
||||
SetupRepo: func(shell *Shell) {
|
||||
// we're going to have a directory structure like this:
|
||||
// project
|
||||
// - repo/a/b/c (main worktree with subdirs)
|
||||
// - link (symlink to repo/a/b/c)
|
||||
//
|
||||
shell.CreateFileAndAdd("a/b/c/blah", "blah\n")
|
||||
shell.Commit("initial commit")
|
||||
shell.UpdateFile("a/b/c/blah", "updated content\n")
|
||||
|
||||
shell.Chdir("..")
|
||||
shell.RunCommand([]string{"ln", "-s", "repo/a/b/c", "link"})
|
||||
|
||||
shell.Chdir("link")
|
||||
},
|
||||
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
||||
t.Views().Branches().
|
||||
Lines(
|
||||
Contains("master"),
|
||||
)
|
||||
|
||||
t.Views().Commits().
|
||||
Lines(
|
||||
Contains("initial commit"),
|
||||
)
|
||||
|
||||
t.Views().Files().
|
||||
IsFocused().
|
||||
Lines(
|
||||
Contains(" M a/b/c/blah"), // shows as modified
|
||||
).
|
||||
PressPrimaryAction().
|
||||
Press(keys.Files.CommitChanges)
|
||||
|
||||
t.ExpectPopup().CommitMessagePanel().
|
||||
Title(Equals("Commit summary")).
|
||||
Type("Add blah").
|
||||
Confirm()
|
||||
|
||||
t.Views().Files().
|
||||
IsEmpty()
|
||||
|
||||
t.Views().Commits().
|
||||
Lines(
|
||||
Contains("Add blah"),
|
||||
Contains("initial commit"),
|
||||
)
|
||||
},
|
||||
})
|
Reference in New Issue
Block a user