Skip to content

Commit

Permalink
Normalize git commondir path. (#463)
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 authored and tmat committed Nov 2, 2019
1 parent 751d216 commit 16fa3ff
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 16fa3ff

Please sign in to comment.