Skip to content

Commit 5595ca5

Browse files
committed
Improve getting .git directory
When using worktrees we want to get the .git directory of the main repo (main working tree). This fixes calculating system hashs and the location of the GitVersion cache. When determining the root directory we have to use the .git directory of the linked working tree. Fixes #1063.
1 parent 4d30873 commit 5595ca5

File tree

2 files changed

+68
-11
lines changed

2 files changed

+68
-11
lines changed

src/GitVersionCore.Tests/ExecuteCoreTests.cs

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ public void WorkingDirectoryWithoutGit()
299299
[Test]
300300
[Category("NoMono")]
301301
[Description("LibGit2Sharp fails when running under Mono")]
302-
public void WorkingDirectoryWithWorktree()
302+
public void GetProjectRootDirectory_WorkingDirectoryWithWorktree()
303303
{
304304
var versionAndBranchFinder = new ExecuteCore(fileSystem);
305305

@@ -323,6 +323,20 @@ public void WorkingDirectoryWithWorktree()
323323
});
324324
}
325325

326+
[Test]
327+
public void GetProjectRootDirectory_NoWorktree()
328+
{
329+
var versionAndBranchFinder = new ExecuteCore(fileSystem);
330+
331+
RepositoryScope(versionAndBranchFinder, (fixture, vv) =>
332+
{
333+
var targetUrl = "https://github.com/GitTools/GitVersion.git";
334+
var gitPreparer = new GitPreparer(targetUrl, null, new Authentication(), false, fixture.RepositoryPath);
335+
var expectedPath = fixture.RepositoryPath.TrimEnd('/', '\\');
336+
gitPreparer.GetProjectRootDirectory().TrimEnd('/', '\\').ShouldBe(expectedPath);
337+
});
338+
}
339+
326340
[Test]
327341
public void DynamicRepositoriesShouldNotErrorWithFailedToFindGitDirectory()
328342
{
@@ -334,6 +348,48 @@ public void DynamicRepositoriesShouldNotErrorWithFailedToFindGitDirectory()
334348
});
335349
}
336350

351+
[Test]
352+
public void GetDotGitDirectory_NoWorktree()
353+
{
354+
var versionAndBranchFinder = new ExecuteCore(fileSystem);
355+
356+
RepositoryScope(versionAndBranchFinder, (fixture, vv) =>
357+
{
358+
var targetUrl = "https://github.com/GitTools/GitVersion.git";
359+
var gitPreparer = new GitPreparer(targetUrl, null, new Authentication(), false, fixture.RepositoryPath);
360+
var expectedPath = Path.Combine(fixture.RepositoryPath, ".git");
361+
gitPreparer.GetDotGitDirectory().ShouldBe(expectedPath);
362+
});
363+
}
364+
365+
[Test]
366+
[Category("NoMono")]
367+
[Description("LibGit2Sharp fails when running under Mono")]
368+
public void GetDotGitDirectory_Worktree()
369+
{
370+
var versionAndBranchFinder = new ExecuteCore(fileSystem);
371+
372+
RepositoryScope(versionAndBranchFinder, (fixture, vv) =>
373+
{
374+
var worktreePath = Path.Combine(Directory.GetParent(fixture.RepositoryPath).FullName, Guid.NewGuid().ToString());
375+
try
376+
{
377+
// create a branch and a new worktree for it
378+
var repo = new Repository(fixture.RepositoryPath);
379+
repo.Worktrees.Add("worktree", worktreePath, false);
380+
381+
var targetUrl = "https://github.com/GitTools/GitVersion.git";
382+
var gitPreparer = new GitPreparer(targetUrl, null, new Authentication(), false, worktreePath);
383+
var expectedPath = Path.Combine(fixture.RepositoryPath, ".git");
384+
gitPreparer.GetDotGitDirectory().ShouldBe(expectedPath);
385+
}
386+
finally
387+
{
388+
DirectoryHelper.DeleteDirectory(worktreePath);
389+
}
390+
});
391+
}
392+
337393
LogMessages RepositoryScope(ExecuteCore executeCore = null, Action<EmptyRepositoryFixture, VersionVariables> fixtureAction = null)
338394
{
339395
// Make sure GitVersion doesn't trigger build server mode when we are running the tests

src/GitVersionCore/GitPreparer.cs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -135,17 +135,14 @@ static bool GitRepoHasMatchingRemote(string possiblePath, string targetUrl)
135135

136136
public string GetDotGitDirectory()
137137
{
138-
if (IsDynamicGitRepository)
139-
return DynamicGitRepositoryPath;
140-
141-
var dotGitDirectory = Repository.Discover(targetPath);
138+
var dotGitDirectory = IsDynamicGitRepository ? DynamicGitRepositoryPath : Repository.Discover(targetPath);
142139

140+
dotGitDirectory = dotGitDirectory?.TrimEnd('/', '\\');
143141
if (string.IsNullOrEmpty(dotGitDirectory))
144142
throw new DirectoryNotFoundException("Can't find the .git directory in " + targetPath);
145143

146-
dotGitDirectory = dotGitDirectory.TrimEnd('/', '\\');
147-
if (string.IsNullOrEmpty(dotGitDirectory))
148-
throw new DirectoryNotFoundException("Can't find the .git directory in " + targetPath);
144+
if (dotGitDirectory.Contains(Path.Combine(".git", "worktrees")))
145+
return Directory.GetParent(Directory.GetParent(dotGitDirectory).FullName).FullName;
149146

150147
return dotGitDirectory;
151148
}
@@ -159,11 +156,15 @@ public string GetProjectRootDirectory()
159156
return targetPath;
160157
}
161158

162-
var dotGetGitDirectory = GetDotGitDirectory();
163-
using (var repo = new Repository(dotGetGitDirectory))
159+
var dotGitDirectory = Repository.Discover(targetPath);
160+
161+
if (string.IsNullOrEmpty(dotGitDirectory))
162+
throw new DirectoryNotFoundException($"Can't find the .git directory in {targetPath}");
163+
164+
using (var repo = new Repository(dotGitDirectory))
164165
{
165166
var result = repo.Info.WorkingDirectory;
166-
Logger.WriteInfo($"Returning Project Root from DotGitDirectory: {dotGetGitDirectory} - {result}");
167+
Logger.WriteInfo($"Returning Project Root from DotGitDirectory: {dotGitDirectory} - {result}");
167168
return result;
168169
}
169170
}

0 commit comments

Comments
 (0)