diff --git a/src/GitVersionCore.Tests/ExecuteCoreTests.cs b/src/GitVersionCore.Tests/ExecuteCoreTests.cs index 04ad8fc674..4b3e251ff4 100644 --- a/src/GitVersionCore.Tests/ExecuteCoreTests.cs +++ b/src/GitVersionCore.Tests/ExecuteCoreTests.cs @@ -8,6 +8,8 @@ using System.IO; using System.Text; +using LibGit2Sharp; + [TestFixture] [Parallelizable(ParallelScope.None)] public class ExecuteCoreTests : TestBase @@ -40,6 +42,34 @@ public void CacheKeySameAfterReNormalizing() }); } + [Test] + [Category("NoMono")] + [Description("LibGit2Sharp fails here when running under Mono")] + public void CacheKeyForWorktree() { + var versionAndBranchFinder = new ExecuteCore(fileSystem); + + RepositoryScope(versionAndBranchFinder, (fixture, vv) => + { + var worktreePath = Path.Combine(Path.GetTempPath(), "TestRepositories", Guid.NewGuid().ToString()); + try + { + // create a branch and a new worktree for it + var repo = new Repository(fixture.RepositoryPath); + repo.Worktrees.Add("worktree", worktreePath, false); + + var targetUrl = "https://github.com/GitTools/GitVersion.git"; + var gitPreparer = new GitPreparer(targetUrl, null, new Authentication(), false, worktreePath); + var configFileLocator = new DefaultConfigFileLocator(); + var cacheKey = GitVersionCacheKeyFactory.Create(fileSystem, gitPreparer, null, configFileLocator); + cacheKey.Value.ShouldNotBeEmpty(); + } + finally + { + DirectoryHelper.DeleteDirectory(worktreePath); + } + }); + } + [Test] public void CacheFileExistsOnDisk() { diff --git a/src/GitVersionCore/GitVersionCacheKeyFactory.cs b/src/GitVersionCore/GitVersionCacheKeyFactory.cs index dfd917ac2d..3d79591310 100644 --- a/src/GitVersionCore/GitVersionCacheKeyFactory.cs +++ b/src/GitVersionCore/GitVersionCacheKeyFactory.cs @@ -25,12 +25,30 @@ static string GetGitSystemHash(GitPreparer gitPreparer) { var dotGitDirectory = gitPreparer.GetDotGitDirectory(); + // get repo .git directory -- not the worktree gitdir + dotGitDirectory = GetWorktreeParentDotGetDirectory(dotGitDirectory); + // traverse the directory and get a list of files, use that for GetHash var contents = CalculateDirectoryContents(Path.Combine(dotGitDirectory, "refs")); return GetHash(contents.ToArray()); } + static string GetWorktreeParentDotGetDirectory(string path) + { + if (string.IsNullOrEmpty(path)) return path; + + var parentPath = Path.GetDirectoryName(path); + if (string.IsNullOrEmpty(parentPath)) return path; + + var worktreesPath = Path.Combine(".git", "worktrees"); + + if (!parentPath.EndsWith(worktreesPath, StringComparison.Ordinal)) + return path; + + return parentPath.Substring(0, parentPath.Length - 10); + } + // based on https://msdn.microsoft.com/en-us/library/bb513869.aspx static List CalculateDirectoryContents(string root) { @@ -42,7 +60,7 @@ static List CalculateDirectoryContents(string root) if (!Directory.Exists(root)) { - throw new ArgumentException(); + throw new ArgumentException($"Root directory does not exist: {root}"); } dirs.Push(root);