Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,13 @@ public void ResolveReference_Packed()
using var temp = new TempRoot();

var gitDir = temp.CreateDirectory();
var commonDir = temp.CreateDirectory();

gitDir.CreateFile("packed-refs").WriteAllText(
commonDir.CreateFile("packed-refs").WriteAllText(
@"# pack-refs with: peeled fully-peeled sorted
1111111111111111111111111111111111111111 refs/heads/master
2222222222222222222222222222222222222222 refs/heads/br2
");
var commonDir = temp.CreateDirectory();
var refsHeadsDir = commonDir.CreateDirectory("refs").CreateDirectory("heads");

refsHeadsDir.CreateFile("br1").WriteAllText("ref: refs/heads/br2");
Expand All @@ -130,14 +130,14 @@ public void ResolveReference_Packed_SHA256()
using var temp = new TempRoot();

var gitDir = temp.CreateDirectory();
var commonDir = temp.CreateDirectory();

// Packed refs with SHA256 hashes (64 characters)
gitDir.CreateFile("packed-refs").WriteAllText(
commonDir.CreateFile("packed-refs").WriteAllText(
@"# pack-refs with: peeled fully-peeled sorted
1111111111111111111111111111111111111111111111111111111111111111 refs/heads/master
2222222222222222222222222222222222222222222222222222222222222222 refs/heads/br2
");
var commonDir = temp.CreateDirectory();
var refsHeadsDir = commonDir.CreateDirectory("refs").CreateDirectory("heads");

refsHeadsDir.CreateFile("br1").WriteAllText("ref: refs/heads/br2");
Expand Down Expand Up @@ -230,7 +230,7 @@ public void ResolveReference_RefTable()
var gitDir = temp.CreateDirectory();
var commonDir = temp.CreateDirectory();

var refTableDir = gitDir.CreateDirectory("reftable");
var refTableDir = commonDir.CreateDirectory("reftable");

refTableDir.CreateFile("tables.list").WriteAllText("""
2.ref
Expand Down
40 changes: 40 additions & 0 deletions src/Microsoft.Build.Tasks.Git.UnitTests/GitRepositoryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,46 @@ public void TryFindRepository_Worktree_Realistic()
Assert.Null(repository.WorkingDirectory);
}

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

var mainWorkingDir = temp.CreateDirectory();
var mainWorkingSubDir = mainWorkingDir.CreateDirectory("A");
var mainGitDir = mainWorkingDir.CreateDirectory(".git");
mainGitDir.CreateFile("HEAD");
mainGitDir.CreateFile("packed-refs").WriteAllText(
@"# pack-refs with: peeled fully-peeled sorted
1111111111111111111111111111111111111111 refs/heads/master
2222222222222222222222222222222222222222 refs/heads/br2
");

var worktreesDir = mainGitDir.CreateDirectory("worktrees");
var worktreeGitDir = worktreesDir.CreateDirectory("C");
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").WriteAllText("ref: refs/heads/br2\n");
worktreeGitDir.CreateFile("commondir").WriteAllText("../..\n");
worktreeGitDir.CreateFile("gitdir").WriteAllText(worktreeGitFile.Path + " \r\n\t\v");

// start under worktree directory:
Assert.True(GitRepository.TryFindRepository(worktreeSubDir.Path, out var location));
Assert.Equal(worktreeGitDir.Path, location.GitDirectory);
Assert.Equal(mainGitDir.Path, location.CommonDirectory);
Assert.Equal(worktreeDir.Path, location.WorkingDirectory);

var repository = GitRepository.OpenRepository(location, GitEnvironment.Empty);
Assert.Equal(location.GitDirectory, repository.GitDirectory);
Assert.Equal(location.WorkingDirectory, repository.WorkingDirectory);
Assert.Equal(location.CommonDirectory, repository.CommonDirectory);

Assert.Equal("2222222222222222222222222222222222222222", repository.GetHeadCommitSha());
}

[Fact]
public void LocateRepository_Submodule()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ public GitReferenceResolver(string gitDirectory, string commonDirectory, Referen
_commonDirectory = commonDirectory;
_storageFormat = storageFormat;
_objectNameFormat = objectNameFormat;
_lazyPackedReferences = new(() => ReadPackedReferences(_gitDirectory));
_lazyRefTableReferenceReaders = new(() => CreateRefTableReaders(_gitDirectory, _openedRefTableReaders));
_lazyPackedReferences = new(() => ReadPackedReferences(_commonDirectory));
_lazyRefTableReferenceReaders = new(() => CreateRefTableReaders(_commonDirectory, _openedRefTableReaders));
}

public void Dispose()
Expand All @@ -59,11 +59,15 @@ public void Dispose()
}
}

private ImmutableDictionary<string, string> ReadPackedReferences(string gitDirectory)
private ImmutableDictionary<string, string> ReadPackedReferences(string commonDirectory)
{
// https://git-scm.com/docs/git-pack-refs

var packedRefsPath = Path.Combine(gitDirectory, PackedRefsFileName);
// Although the above doc specifies 'packaged-refs' file is in GIT_DIR,
// it is actually in the common directory as specified in
// https://git-scm.com/docs/gitrepository-layout#Documentation/gitrepository-layout.txt-packed-refs

var packedRefsPath = Path.Combine(commonDirectory, PackedRefsFileName);
if (!File.Exists(packedRefsPath))
{
return ImmutableDictionary<string, string>.Empty;
Expand Down Expand Up @@ -174,9 +178,12 @@ internal ImmutableDictionary<string, string> ReadPackedReferences(TextReader rea

/// <exception cref="IOException"/>
/// <exception cref="InvalidDataException"/>
private static IEnumerable<GitRefTableReader> CreateRefTableReaders(string gitDirectory, List<GitRefTableReader> openReaders)
private static IEnumerable<GitRefTableReader> CreateRefTableReaders(string commonDirectory, List<GitRefTableReader> openReaders)
{
var refTableDirectory = Path.Combine(gitDirectory, RefTableDirectoryName);
// Although https://git-scm.com/docs/reftable#_layout specifies reftable to be in GIT_DIR,
// it is actually in the common directory. This is currently not documented.

var refTableDirectory = Path.Combine(commonDirectory, RefTableDirectoryName);
var tablesFilePath = Path.Combine(refTableDirectory, TablesListFileName);

// Create lazily-evaluated sequence of readers for each entry in the tables.list file (in reverse order).
Expand Down