Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow using .git directory instead of gitdir redirect in submodules. #653

Merged
merged 6 commits into from
Aug 12, 2021
Merged
Show file tree
Hide file tree
Changes from 4 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
23 changes: 16 additions & 7 deletions src/Microsoft.Build.Tasks.Git.UnitTests/GitRepositoryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -344,17 +344,26 @@ public void GetSubmoduleHeadCommitSha()
var gitDir = temp.CreateDirectory();
var workingDir = temp.CreateDirectory();

var submoduleGitDir = temp.CreateDirectory();
var basicSubmoduleGitDir = temp.CreateDirectory();

var submoduleWorkingDir = workingDir.CreateDirectory("sub").CreateDirectory("abc");
submoduleWorkingDir.CreateFile(".git").WriteAllText("gitdir: " + submoduleGitDir.Path + "\t \v\f\r\n\n\r");
var basicSubmoduleWorkingDir = workingDir.CreateDirectory("sub").CreateDirectory("abc");
basicSubmoduleWorkingDir.CreateFile(".git").WriteAllText("gitdir: " + basicSubmoduleGitDir.Path + "\t \v\f\r\n\n\r");

var submoduleRefsHeadsDir = submoduleGitDir.CreateDirectory("refs").CreateDirectory("heads");
submoduleRefsHeadsDir.CreateFile("master").WriteAllText("0000000000000000000000000000000000000000");
submoduleGitDir.CreateFile("HEAD").WriteAllText("ref: refs/heads/master");
var basicSubmoduleRefsHeadsDir = basicSubmoduleGitDir.CreateDirectory("refs").CreateDirectory("heads");
basicSubmoduleRefsHeadsDir.CreateFile("master").WriteAllText("0000000000000000000000000000000000000000");
basicSubmoduleGitDir.CreateFile("HEAD").WriteAllText("ref: refs/heads/master");

// this is a unusual but legal case which can occur with older versions of Git or other tools.
// see https://git-scm.com/docs/gitsubmodules#_forms for more details.
var oldStyleSubmoduleWorkingDir = workingDir.CreateDirectory("old-style-submodule");
var oldStyleSubmoduleGitDir = oldStyleSubmoduleWorkingDir.CreateDirectory(".git");
var oldStyleSubmoduleRefsHeadDir = oldStyleSubmoduleGitDir.CreateDirectory("refs").CreateDirectory("heads");
oldStyleSubmoduleRefsHeadDir.CreateFile("branch1").WriteAllText("1111111111111111111111111111111111111111");
oldStyleSubmoduleGitDir.CreateFile("HEAD").WriteAllText("ref: refs/heads/branch1");
crummel marked this conversation as resolved.
Show resolved Hide resolved

var repository = new GitRepository(GitEnvironment.Empty, GitConfig.Empty, gitDir.Path, gitDir.Path, workingDir.Path);
Assert.Equal("0000000000000000000000000000000000000000", repository.ReadSubmoduleHeadCommitSha(submoduleWorkingDir.Path));
Assert.Equal("0000000000000000000000000000000000000000", repository.ReadSubmoduleHeadCommitSha(basicSubmoduleWorkingDir.Path));
Assert.Equal("1111111111111111111111111111111111111111", repository.ReadSubmoduleHeadCommitSha(oldStyleSubmoduleWorkingDir.Path));
}
}
}
12 changes: 12 additions & 0 deletions src/Microsoft.Build.Tasks.Git/GitDataReader/GitRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,18 @@ public static GitRepository OpenRepository(GitRepositoryLocation location, GitEn
/// <returns>Null if the HEAD tip reference can't be resolved.</returns>
internal string? ReadSubmoduleHeadCommitSha(string submoduleWorkingDirectoryFullPath)
{
// Submodules don't usually have their own .git directories but this is still legal.
// This can occur with older versions of Git or other tools, or when a user clones one
// repo into another's source tree (but it was not yet registered as a submodule).
// See https://git-scm.com/docs/gitsubmodules#_forms for more details.
// Handle this case first since the other case throws.
var dotGitPath = Path.Combine(submoduleWorkingDirectoryFullPath, GitDirName);
crummel marked this conversation as resolved.
Show resolved Hide resolved
if (IsGitDirectory(dotGitPath, out var directSubmoduleGitDirectory))
{
var submoduleGitDirResolver = new GitReferenceResolver(directSubmoduleGitDirectory, directSubmoduleGitDirectory);
return submoduleGitDirResolver.ResolveHeadReference();
}

var gitDirectory = ReadDotGitFile(Path.Combine(submoduleWorkingDirectoryFullPath, GitDirName));
if (!IsGitDirectory(gitDirectory, out var commonDirectory))
{
Expand Down