Skip to content

Commit

Permalink
Support bare worktrees where worktree does not have its own .git file
Browse files Browse the repository at this point in the history
This was on oversight on my part: I assumed that the --work-tree arg was
always intended for use with linked worktrees which have a .git file
pointing back to the repo.

I'm honestly confused now: seems like there are three kinds of worktrees:
* the main worktree of a non-bare repo
* a linked worktree (with its own gitdir in the repo's worktrees/ dir)
* a random folder which you specify as a worktree with the --work-tree arg

I'm pretty sure the --work-tree arg is only intended to be used with this
third kind or workree
  • Loading branch information
jesseduffield committed Aug 7, 2023
1 parent 0551f29 commit 595e28d
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 22 deletions.
24 changes: 10 additions & 14 deletions pkg/app/entry_point.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,17 @@ func Start(buildInfo *BuildInfo, integrationTest integrationTypes.IntegrationTes
log.Fatal(absRepoPath + " is not a valid git repository.")
}

cliArgs.WorkTree = absRepoPath
cliArgs.GitDir = filepath.Join(absRepoPath, ".git")
err = os.Chdir(absRepoPath)
if err != nil {
log.Fatalf("Failed to change directory to %s: %v", absRepoPath, err)
}
} else if cliArgs.WorkTree != "" {
env.SetWorkTreeEnv(cliArgs.WorkTree)

if err := os.Chdir(cliArgs.WorkTree); err != nil {
log.Fatalf("Failed to change directory to %s: %v", cliArgs.WorkTree, err)
}
}

if cliArgs.CustomConfigFile != "" {
Expand All @@ -75,13 +84,6 @@ func Start(buildInfo *BuildInfo, integrationTest integrationTypes.IntegrationTes
os.Setenv("CONFIG_DIR", cliArgs.UseConfigDir)
}

if cliArgs.WorkTree != "" {
err := os.Chdir(cliArgs.WorkTree)
if err != nil {
log.Fatalf("Failed to change directory to %s: %v", cliArgs.WorkTree, err)
}
}

if cliArgs.GitDir != "" {
env.SetGitDirEnv(cliArgs.GitDir)
}
Expand Down Expand Up @@ -118,12 +120,6 @@ func Start(buildInfo *BuildInfo, integrationTest integrationTypes.IntegrationTes
os.Exit(0)
}

if cliArgs.WorkTree != "" {
if err := os.Chdir(cliArgs.WorkTree); err != nil {
log.Fatal(err.Error())
}
}

tempDir, err := os.MkdirTemp("", "lazygit-*")
if err != nil {
log.Fatal(err.Error())
Expand Down
22 changes: 18 additions & 4 deletions pkg/commands/git_commands/repo_paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,24 @@ func getRepoPathsAux(
if err != nil {
return nil, errors.Errorf("failed to get repo git dir path: %v", err)
}
worktreeGitDirPath, err := worktreeGitDirPath(fs, currentPath)
if err != nil {
return nil, errors.Errorf("failed to get worktree git dir path: %v", err)

var worktreeGitDirPath string
if env.GetWorkTreeEnv() != "" {
// This env is set when you pass --work-tree to lazygit. In that case,
// we're not dealing with a linked work-tree, we're dealing with a 'specified'
// worktree (for lack of a better term). In this case, the worktree has no
// .git file and it just contains a bunch of files: it has no idea it's
// pointed to by a bare repo. As such it does not have its own git dir within
// the bare repo's git dir. Instead, we just use the bare repo's git dir.
worktreeGitDirPath = repoGitDirPath
} else {
var err error
worktreeGitDirPath, err = getWorktreeGitDirPath(fs, currentPath)
if err != nil {
return nil, errors.Errorf("failed to get worktree git dir path: %v", err)
}
}

repoName := path.Base(repoPath)

return &RepoPaths{
Expand All @@ -110,7 +124,7 @@ func getRepoPathsAux(
// Returns the path of the git-dir for the worktree. For linked worktrees, the worktree has
// a .git file that points to the git-dir (which itself lives in the git-dir
// of the repo)
func worktreeGitDirPath(fs afero.Fs, worktreePath string) (string, error) {
func getWorktreeGitDirPath(fs afero.Fs, worktreePath string) (string, error) {
// if .git is a file, we're in a linked worktree, otherwise we're in
// the main worktree
dotGitPath := path.Join(worktreePath, ".git")
Expand Down
2 changes: 1 addition & 1 deletion pkg/commands/git_commands/worktree_loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (self *WorktreeLoader) GetWorktrees() ([]*models.Worktree, error) {
isPathMissing := self.pathExists(path)

var gitDir string
gitDir, err := worktreeGitDirPath(self.Fs, path)
gitDir, err := getWorktreeGitDirPath(self.Fs, path)
if err != nil {
self.Log.Warnf("Could not find git dir for worktree %s: %v", path, err)
}
Expand Down
11 changes: 10 additions & 1 deletion pkg/env/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ func SetGitDirEnv(value string) {
os.Setenv("GIT_DIR", value)
}

func UnsetGitDirEnv() {
func GetWorkTreeEnv() string {
return os.Getenv("GIT_WORK_TREE")
}

func SetWorkTreeEnv(value string) {
os.Setenv("GIT_WORK_TREE", value)
}

func UnsetGitLocationEnvVars() {
_ = os.Unsetenv("GIT_DIR")
_ = os.Unsetenv("GIT_WORK_TREE")
}
2 changes: 1 addition & 1 deletion pkg/gui/controllers/helpers/repos_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ func (self *ReposHelper) DispatchSwitchToRepo(path string, contextKey types.Cont

func (self *ReposHelper) DispatchSwitchTo(path string, errMsg string, contextKey types.ContextKey) error {
return self.c.WithWaitingStatus(self.c.Tr.Switching, func(gocui.Task) error {
env.UnsetGitDirEnv()
env.UnsetGitLocationEnvVars()
originalPath, err := os.Getwd()
if err != nil {
return nil
Expand Down
2 changes: 1 addition & 1 deletion pkg/integration/tests/worktree/dotfile_bare_repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
var DotfileBareRepo = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Open lazygit in the worktree of a dotfile bare repo and add a file and commit",
ExtraCmdArgs: []string{"--git-dir={{.actualPath}}/.bare", "--work-tree={{.actualPath}}/repo"},
Skip: true,
Skip: false,
// passing this because we're explicitly passing --git-dir and --work-tree args
UseCustomPath: true,
SetupConfig: func(config *config.AppConfig) {},
Expand Down

0 comments on commit 595e28d

Please sign in to comment.