Skip to content

Commit

Permalink
Normalize git commondir path.
Browse files Browse the repository at this point in the history
The constructor for GitRepositoryLocation asserts that this path is
normalized. On my machine, a git worktree created by git 2.22.0 has a
commondir file that contains "../..". This results in path that does not
satisfy this assert.
  • Loading branch information
AustinWise committed Nov 1, 2019
1 parent d5ae980 commit 0244a3a
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
50 changes: 50 additions & 0 deletions src/Microsoft.Build.Tasks.Git.UnitTests/GitRepositoryTests.cs
Expand Up @@ -58,6 +58,56 @@ public void TryFindRepository_Worktree()
Assert.Null(location.WorkingDirectory);
}

[Fact]
public void TryFindRepository_Worktree_Realistic()
{
using var temp = new TempRoot();

var mainWorkingDir = temp.CreateDirectory();
var mainWorkingSubDir = mainWorkingDir.CreateDirectory("A");
var mainGitDir = mainWorkingDir.CreateDirectory(".git");
mainGitDir.CreateFile("HEAD");

var worktreesDir = mainGitDir.CreateDirectory("worktrees");
var worktreeGitDir = worktreesDir.CreateDirectory("myworktree");
var worktreeGitSubDir = worktreeGitDir.CreateDirectory("B");
var worktreeDir = temp.CreateDirectory();
var worktreeSubDir = worktreeDir.CreateDirectory("C");
var worktreeGitFile = worktreeDir.CreateFile(".git").WriteAllText("gitdir: " + worktreeGitDir + " \r\n\t\v");

worktreeGitDir.CreateFile("HEAD");
worktreeGitDir.CreateFile("commondir").WriteAllText("../..\n");
worktreeGitDir.CreateFile("gitdir").WriteAllText(worktreeGitFile.Path + " \r\n\t\v");

// start under main repository directory:
Assert.True(GitRepository.TryFindRepository(mainWorkingSubDir.Path, out var location));

Assert.Equal(mainGitDir.Path, location.GitDirectory);
Assert.Equal(mainGitDir.Path, location.CommonDirectory);
Assert.Equal(mainWorkingDir.Path, location.WorkingDirectory);

// start at main git directory (git config works from this dir, but git status requires work dir):
Assert.True(GitRepository.TryFindRepository(mainGitDir.Path, out location));

Assert.Equal(mainGitDir.Path, location.GitDirectory);
Assert.Equal(mainGitDir.Path, location.CommonDirectory);
Assert.Null(location.WorkingDirectory);

// start under worktree directory:
Assert.True(GitRepository.TryFindRepository(worktreeSubDir.Path, out location));

Assert.Equal(worktreeGitDir.Path, location.GitDirectory);
Assert.Equal(mainGitDir.Path, location.CommonDirectory);
Assert.Equal(worktreeDir.Path, location.WorkingDirectory);

// start under worktree git directory (git config works from this dir, but git status requires work dir):
Assert.True(GitRepository.TryFindRepository(worktreeGitSubDir.Path, out location));

Assert.Equal(worktreeGitDir.Path, location.GitDirectory);
Assert.Equal(mainGitDir.Path, location.CommonDirectory);
Assert.Null(location.WorkingDirectory);
}

[Fact]
public void LocateRepository_Submodule()
{
Expand Down
2 changes: 2 additions & 0 deletions src/Microsoft.Build.Tasks.Git/GitDataReader/GitRepository.cs
Expand Up @@ -491,6 +491,8 @@ private static bool IsGitDirectory(string directory, out string commonDirectory)
try
{
commonDirectory = Path.Combine(directory, File.ReadAllText(commonLinkPath).TrimEnd(CharUtils.AsciiWhitespace));
// Normalize relative paths. For example, git worktrees typically have "../.." in this file.
commonDirectory = Path.GetFullPath(commonDirectory);
}
catch
{
Expand Down

0 comments on commit 0244a3a

Please sign in to comment.