diff --git a/src/GitVersionCore.Tests/Core/GitVersionExecutorTests.cs b/src/GitVersionCore.Tests/Core/GitVersionExecutorTests.cs index 4de9768a77..affd588844 100644 --- a/src/GitVersionCore.Tests/Core/GitVersionExecutorTests.cs +++ b/src/GitVersionCore.Tests/Core/GitVersionExecutorTests.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Linq; using System.Text; using GitTools.Testing; using GitVersion; @@ -512,6 +513,37 @@ public void GetDotGitDirectoryWorktree() } } + [Test] + [Category("NoMono")] + [Description("LibGit2Sharp fails when running under Mono")] + public void CalculateVersionFromWorktreeHead() + { + // Setup + using var fixture = new EmptyRepositoryFixture(); + var repoDir = new DirectoryInfo(fixture.RepositoryPath); + var worktreePath = Path.Combine(repoDir.Parent.FullName, $"{repoDir.Name}-v1"); + + fixture.Repository.MakeATaggedCommit("v1.0.0"); + var branchV1 = fixture.Repository.CreateBranch("support/1.0"); + + fixture.Repository.MakeATaggedCommit("v2.0.0"); + + fixture.Repository.Worktrees.Add(branchV1.CanonicalName, "1.0", worktreePath, false); + using var worktreeFixture = new LocalRepositoryFixture(new Repository(worktreePath)); + + var gitVersionOptions = new GitVersionOptions { WorkingDirectory = worktreeFixture.RepositoryPath }; + + var sut = GetGitVersionCalculator(gitVersionOptions); + + // Execute + var version = sut.CalculateVersionVariables(); + + // Verify + version.SemVer.ShouldBe("1.0.0"); + var commits = worktreeFixture.Repository.Head.Commits; + version.Sha.ShouldBe(commits.First().Sha); + } + private IGitVersionTool GetGitVersionCalculator(GitVersionOptions gitVersionOptions, ILog logger = null, IRepository repository = null, IFileSystem fs = null) { sp = GetServiceProvider(gitVersionOptions, logger, repository, fs); diff --git a/src/GitVersionCore.Tests/Extensions/GitToolsTestingExtensions.cs b/src/GitVersionCore.Tests/Extensions/GitToolsTestingExtensions.cs index 4bf0270ec7..2679dd020a 100644 --- a/src/GitVersionCore.Tests/Extensions/GitToolsTestingExtensions.cs +++ b/src/GitVersionCore.Tests/Extensions/GitToolsTestingExtensions.cs @@ -29,7 +29,7 @@ public static VersionVariables GetVersion(this RepositoryFixtureBase fixture, Co var options = Options.Create(new GitVersionOptions { - WorkingDirectory = repository.GetRepositoryDirectory(), + WorkingDirectory = repository.Info.WorkingDirectory, ConfigInfo = { OverrideConfig = configuration }, RepositoryInfo = { diff --git a/src/GitVersionCore.Tests/IntegrationTests/WorktreeScenarios.cs b/src/GitVersionCore.Tests/IntegrationTests/WorktreeScenarios.cs new file mode 100644 index 0000000000..24843b5286 --- /dev/null +++ b/src/GitVersionCore.Tests/IntegrationTests/WorktreeScenarios.cs @@ -0,0 +1,35 @@ +using GitTools.Testing; +using LibGit2Sharp; +using NUnit.Framework; +using System.IO; +using GitVersionCore.Tests.Helpers; + +namespace GitVersionCore.Tests.IntegrationTests +{ + + [TestFixture] + public class WorktreeScenarios : TestBase + { + + [Test] + [Category("NoMono")] + [Description("LibGit2Sharp fails here when running under Mono")] + public void UseWorktreeRepositoryForVersion() + { + using var fixture = new EmptyRepositoryFixture(); + var repoDir = new DirectoryInfo(fixture.RepositoryPath); + var worktreePath = Path.Combine(repoDir.Parent.FullName, $"{repoDir.Name}-v1"); + + fixture.Repository.MakeATaggedCommit("v1.0.0"); + var branchV1 = fixture.Repository.CreateBranch("support/1.0"); + + fixture.Repository.MakeATaggedCommit("v2.0.0"); + fixture.AssertFullSemver("2.0.0"); + + fixture.Repository.Worktrees.Add(branchV1.CanonicalName, "1.0", worktreePath, false); + using var worktreeFixture = new LocalRepositoryFixture(new Repository(worktreePath)); + worktreeFixture.AssertFullSemver("1.0.0"); + } + + } +} diff --git a/src/GitVersionCore/Core/GitPreparer.cs b/src/GitVersionCore/Core/GitPreparer.cs index 5bb502edd0..fb8d1854f0 100644 --- a/src/GitVersionCore/Core/GitPreparer.cs +++ b/src/GitVersionCore/Core/GitPreparer.cs @@ -87,8 +87,7 @@ private string ResolveCurrentBranch() private void CleanupDuplicateOrigin() { var remoteToKeep = DefaultRemoteName; - - using var repo = new Repository(options.Value.DotGitDirectory); + using var repo = new Repository(options.Value.GitRootPath); // check that we have a remote that matches defaultRemoteName if not take the first remote if (!repo.Network.Remotes.Any(remote => remote.Name.Equals(DefaultRemoteName, StringComparison.InvariantCultureIgnoreCase))) diff --git a/src/GitVersionCore/Core/GitRepository.cs b/src/GitVersionCore/Core/GitRepository.cs index 27a5121280..878033780c 100644 --- a/src/GitVersionCore/Core/GitRepository.cs +++ b/src/GitVersionCore/Core/GitRepository.cs @@ -11,13 +11,13 @@ public class GitRepository : IGitRepository private IRepository repositoryInstance => repositoryLazy.Value; public GitRepository(IOptions options) - : this(() => options.Value.DotGitDirectory) + : this(() => options.Value.GitRootPath) { } - public GitRepository(Func getDotGitDirectory) + public GitRepository(Func getGitRootDirectory) { - repositoryLazy = new Lazy(() => new Repository(getDotGitDirectory())); + repositoryLazy = new Lazy(() => new Repository(getGitRootDirectory())); Commands = new GitRepositoryCommands(repositoryLazy); } diff --git a/src/GitVersionCore/Core/RepositoryMetadataProvider.cs b/src/GitVersionCore/Core/RepositoryMetadataProvider.cs index 5da1e859d1..11b6a14d02 100644 --- a/src/GitVersionCore/Core/RepositoryMetadataProvider.cs +++ b/src/GitVersionCore/Core/RepositoryMetadataProvider.cs @@ -183,10 +183,12 @@ public Branch GetTargetBranch(string targetBranch) { // In the case where HEAD is not the desired branch, try to find the branch with matching name desiredBranch = repository.Branches? - .SingleOrDefault(b => + .Where(b => b.CanonicalName.IsEquivalentTo(targetBranch) || b.FriendlyName.IsEquivalentTo(targetBranch) || - b.NameWithoutRemote().IsEquivalentTo(targetBranch)); + b.NameWithoutRemote().IsEquivalentTo(targetBranch)) + .OrderBy(b => b.IsRemote) + .FirstOrDefault(); // Failsafe in case the specified branch is invalid desiredBranch ??= repository.Head; diff --git a/src/GitVersionCore/Extensions/GitVersionOptionsExtensions.cs b/src/GitVersionCore/Extensions/GitVersionOptionsExtensions.cs index c8e161898b..3be5854eef 100644 --- a/src/GitVersionCore/Extensions/GitVersionOptionsExtensions.cs +++ b/src/GitVersionCore/Extensions/GitVersionOptionsExtensions.cs @@ -38,6 +38,14 @@ public static string GetProjectRootDirectory(this GitVersionOptions gitVersionOp return repository.Info.WorkingDirectory; } + public static string GetGitRootPath(this GitVersionOptions options) + { + var isDynamicRepo = !string.IsNullOrWhiteSpace(options.DynamicGitRepositoryPath); + var rootDirectory = isDynamicRepo ? options.DotGitDirectory : options.ProjectRootDirectory; + + return rootDirectory; + } + public static string GetDynamicGitRepositoryPath(this GitVersionOptions gitVersionOptions) { if (string.IsNullOrWhiteSpace(gitVersionOptions.RepositoryInfo.TargetUrl)) return null; diff --git a/src/GitVersionCore/Model/GitVersionOptions.cs b/src/GitVersionCore/Model/GitVersionOptions.cs index 2463c839ee..856bb604fc 100644 --- a/src/GitVersionCore/Model/GitVersionOptions.cs +++ b/src/GitVersionCore/Model/GitVersionOptions.cs @@ -11,12 +11,14 @@ public class GitVersionOptions private Lazy dotGitDirectory; private Lazy projectRootDirectory; private Lazy dynamicGitRepositoryPath; + private Lazy gitRootPath; public GitVersionOptions() { dotGitDirectory = new Lazy(this.GetDotGitDirectory); projectRootDirectory = new Lazy(this.GetProjectRootDirectory); dynamicGitRepositoryPath = new Lazy(this.GetDynamicGitRepositoryPath); + gitRootPath = new Lazy(this.GetGitRootPath); } public string WorkingDirectory { get; set; } @@ -24,6 +26,7 @@ public GitVersionOptions() public string DotGitDirectory => dotGitDirectory.Value; public string ProjectRootDirectory => projectRootDirectory.Value; public string DynamicGitRepositoryPath => dynamicGitRepositoryPath.Value; + public string GitRootPath => gitRootPath.Value; public AssemblyInfoData AssemblyInfo { get; } = new AssemblyInfoData(); public AuthenticationInfo Authentication { get; } = new AuthenticationInfo(); diff --git a/src/GitVersionCore/VersionCalculation/Cache/GitVersionCacheKeyFactory.cs b/src/GitVersionCore/VersionCalculation/Cache/GitVersionCacheKeyFactory.cs index fd33f7d128..2b05686e2e 100644 --- a/src/GitVersionCore/VersionCalculation/Cache/GitVersionCacheKeyFactory.cs +++ b/src/GitVersionCore/VersionCalculation/Cache/GitVersionCacheKeyFactory.cs @@ -141,7 +141,7 @@ private List CalculateDirectoryContents(string root) private string GetRepositorySnapshotHash() { - using var repo = new Repository(options.Value.DotGitDirectory); + using var repo = new Repository(options.Value.GitRootPath); var head = repo.Head; if (head.Tip == null)