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 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/Microsoft.Build.Tasks.Git.UnitTests/GitRepositoryTests.cs
Expand Up @@ -356,5 +356,25 @@ public void GetSubmoduleHeadCommitSha()
var repository = new GitRepository(GitEnvironment.Empty, GitConfig.Empty, gitDir.Path, gitDir.Path, workingDir.Path);
Assert.Equal("0000000000000000000000000000000000000000", repository.ReadSubmoduleHeadCommitSha(submoduleWorkingDir.Path));
}

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

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

// 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("1111111111111111111111111111111111111111", repository.ReadSubmoduleHeadCommitSha(oldStyleSubmoduleWorkingDir.Path));
}
}
}
15 changes: 13 additions & 2 deletions src/Microsoft.Build.Tasks.Git/GitDataReader/GitRepository.cs
Expand Up @@ -209,8 +209,19 @@ public static GitRepository OpenRepository(GitRepositoryLocation location, GitEn
/// <returns>Null if the HEAD tip reference can't be resolved.</returns>
internal string? ReadSubmoduleHeadCommitSha(string submoduleWorkingDirectoryFullPath)
{
var gitDirectory = ReadDotGitFile(Path.Combine(submoduleWorkingDirectoryFullPath, GitDirName));
if (!IsGitDirectory(gitDirectory, out var commonDirectory))
// 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

var gitDirectory =
Directory.Exists(dotGitPath) ? dotGitPath :
File.Exists(dotGitPath) ? ReadDotGitFile(dotGitPath) :
Copy link
Member

@tmat tmat Aug 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A test is failing - looking at it I think we should keep throwing if the file can't be read, rather then returning null.

var gitDirectory = Directory.Exists(dotGitPath) ? dotGitPath : ReadDotGitFile(dotGitPath);

if (!IsGitDirectory(gitDirectory, out var commonDirectory))
{
    return null;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this change you'd still need to update the Submodules_Errors test - remove case S6:

[submodule ""S6""]             # sub6/.git is a directory, but should be a file
  path = sub6
  url = http://github.com

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or rather update it - since in this case the directory is not a valid git directory (it's empty) so failure is expected of some sort

null;

if (gitDirectory == null || !IsGitDirectory(gitDirectory, out var commonDirectory))
{
return null;
}
Expand Down