fix(git): further fixes for submodule worktrees

filepath.Join() just concatenates paths. We have to check manually for
an absolute path and discard the first component to end up with the
correct path.

Also, fix the tests to demonstrate actual behaviour of git, not what
filepath.Join() was doing.

Additionally, note that on Windows git paths in gitdir use unix
separators, so search for `/worktrees/` instead of using system
separator, just like when processing all the other cases.
This commit is contained in:
Piotr Kalinowski 2022-07-20 18:37:22 +02:00 committed by Jan De Dobbeleer
parent d678265607
commit 3895210ab3
2 changed files with 14 additions and 12 deletions

View file

@ -196,11 +196,15 @@ func (g *Git) hasWorktree(gitdir *environment.FileInfo) bool {
// we need the parent folder to detect where the real .git folder is
ind = strings.LastIndex(g.workingFolder, "/.git/modules")
if ind > -1 {
if !filepath.IsAbs(g.workingFolder) {
g.rootFolder = filepath.Join(gitdir.ParentFolder, g.workingFolder)
} else {
g.rootFolder = g.workingFolder
}
// this might be both a worktree and a submodule, where the path would look like
// this: ../.git/modules/module/path/worktrees/location. We cannot distinguish
// this: path/.git/modules/module/path/worktrees/location. We cannot distinguish
// between worktree and a module path containing the word 'worktree,' however.
ind = strings.LastIndex(g.rootFolder, g.env.PathSeparator()+"worktrees"+g.env.PathSeparator())
ind = strings.LastIndex(g.rootFolder, "/worktrees/")
if ind > -1 && g.env.HasFilesInDir(g.rootFolder, "gitdir") {
gitDir := filepath.Join(g.rootFolder, "gitdir")
realGitFolder := filepath.Clean(g.env.FileContent(gitDir))

View file

@ -64,7 +64,6 @@ func TestEnabledInWorktree(t *testing.T) {
WorkingFolder string
WorkingFolderAddon string
WorkingFolderContent string
GitDirContent string
ExpectedRealFolder string
ExpectedWorkingFolder string
ExpectedRootFolder string
@ -93,17 +92,17 @@ func TestEnabledInWorktree(t *testing.T) {
Case: "submodule with root working folder",
ExpectedEnabled: true,
WorkingFolder: "/repo/.git/modules/submodule",
ExpectedWorkingFolder: "/dev/repo/.git/modules/submodule",
ExpectedRealFolder: "/dev/repo/.git/modules/submodule",
ExpectedRootFolder: "/dev/repo/.git/modules/submodule",
ExpectedWorkingFolder: "/repo/.git/modules/submodule",
ExpectedRealFolder: "/repo/.git/modules/submodule",
ExpectedRootFolder: "/repo/.git/modules/submodule",
WindowsPaths: true,
},
{
Case: "submodule with worktrees",
ExpectedEnabled: true,
WorkingFolder: "./.git/modules/module/path/worktrees/location",
WorkingFolderAddon: "/dev/",
GitDirContent: "/dev/worktree.git\n",
WorkingFolder: "/dev/.git/modules/module/path/worktrees/location",
WorkingFolderAddon: "gitdir",
WorkingFolderContent: "/dev/worktree.git\n",
ExpectedWorkingFolder: "/dev/.git/modules/module/path",
ExpectedRealFolder: "/dev/worktree",
ExpectedRootFolder: "/dev/.git/modules/module/path",
@ -126,9 +125,8 @@ func TestEnabledInWorktree(t *testing.T) {
env := new(mock.MockedEnvironment)
env.On("FileContent", "/dev/.git").Return(fmt.Sprintf("gitdir: %s", tc.WorkingFolder))
env.On("FileContent", filepath.Join(tc.WorkingFolder, tc.WorkingFolderAddon)).Return(tc.WorkingFolderContent)
env.On("HasFilesInDir", tc.WorkingFolder, tc.WorkingFolderAddon).Return(true)
env.On("HasFilesInDir", tc.WorkingFolder, "HEAD").Return(true)
env.On("HasFilesInDir", filepath.Join(tc.WorkingFolderAddon, tc.WorkingFolder), "gitdir").Return(true)
env.On("FileContent", filepath.Join(tc.WorkingFolderAddon, tc.WorkingFolder, "gitdir")).Return(tc.GitDirContent)
env.On("PathSeparator").Return(string(os.PathSeparator))
g := &Git{
scm: scm{