diff --git a/GitVersionCore.Tests/Fixtures/RemoteRepositoryFixture.cs b/GitVersionCore.Tests/Fixtures/RemoteRepositoryFixture.cs index fa91302696..82588af506 100644 --- a/GitVersionCore.Tests/Fixtures/RemoteRepositoryFixture.cs +++ b/GitVersionCore.Tests/Fixtures/RemoteRepositoryFixture.cs @@ -20,6 +20,14 @@ public RemoteRepositoryFixture(Config configuration) CloneRepository(); } + /// + /// Simulates running on build server + /// + public void InitialiseRepo() + { + new GitPreparer(null, null, new Authentication(), null, false, LocalRepositoryPath).Initialise(true); + } + static IRepository CreateNewRepository(string path) { LibGit2Sharp.Repository.Init(path); diff --git a/GitVersionCore.Tests/GitVersionCore.Tests.csproj b/GitVersionCore.Tests/GitVersionCore.Tests.csproj index 417bf5f5f5..7c2c1f2bdf 100644 --- a/GitVersionCore.Tests/GitVersionCore.Tests.csproj +++ b/GitVersionCore.Tests/GitVersionCore.Tests.csproj @@ -85,6 +85,7 @@ + diff --git a/GitVersionCore.Tests/Helpers/GitTestExtensions.cs b/GitVersionCore.Tests/Helpers/GitTestExtensions.cs index 7cfb0ceffc..e83eedfae5 100644 --- a/GitVersionCore.Tests/Helpers/GitTestExtensions.cs +++ b/GitVersionCore.Tests/Helpers/GitTestExtensions.cs @@ -1,42 +1,13 @@ using System; -using System.Diagnostics; using System.IO; using System.Linq; -using System.Text; using GitVersion; -using GitVersion.Helpers; using LibGit2Sharp; public static class GitTestExtensions { static int pad = 1; - public static void DumpGraph(this IRepository repository) - { - var output = new StringBuilder(); - - try - { - ProcessHelper.Run( - o => output.AppendLine(o), - e => output.AppendLineFormat("ERROR: {0}", e), - null, - "git", - @"log --graph --abbrev-commit --decorate --date=relative --all --remotes=*", - repository.Info.Path); - } - catch (FileNotFoundException exception) - { - if (exception.FileName != "git") - throw; - - output.AppendLine("Could not execute 'git log' due to the following error:"); - output.AppendLine(exception.ToString()); - } - - Trace.Write(output.ToString()); - } - public static Commit MakeACommit(this IRepository repository) { return CreateFileAndCommit(repository, Guid.NewGuid().ToString()); diff --git a/GitVersionCore.Tests/IntegrationTests/OtherScenarios.cs b/GitVersionCore.Tests/IntegrationTests/OtherScenarios.cs new file mode 100644 index 0000000000..b3c7acf487 --- /dev/null +++ b/GitVersionCore.Tests/IntegrationTests/OtherScenarios.cs @@ -0,0 +1,53 @@ +namespace GitVersionCore.Tests.IntegrationTests +{ + using System.Linq; + using GitVersion; + using LibGit2Sharp; + using NUnit.Framework; + + [TestFixture] + public class OtherScenarios + { + // This is an attempt to automatically resolve the issue where you cannot build + // when multiple branches point at the same commit + // Current implementation favors master, then branches without - or / in their name + + [Test] + public void DoNotBlowUpWhenMasterAndDevelopPointAtSameCommit() + { + using (var fixture = new RemoteRepositoryFixture(new Config())) + { + fixture.Repository.MakeACommit(); + fixture.Repository.MakeATaggedCommit("1.0.0"); + fixture.Repository.MakeACommit(); + fixture.Repository.CreateBranch("develop"); + + fixture.LocalRepository.Network.Fetch(fixture.LocalRepository.Network.Remotes.First()); + fixture.LocalRepository.Checkout(fixture.Repository.Head.Tip); + fixture.LocalRepository.Branches.Remove("master"); + fixture.InitialiseRepo(); + fixture.AssertFullSemver("1.0.1+1"); + } + } + + [Test] + public void DoNotBlowUpWhenDevelopAndFeatureBranchPointAtSameCommit() + { + using (var fixture = new RemoteRepositoryFixture(new Config())) + { + fixture.Repository.MakeACommit(); + fixture.Repository.CreateBranch("develop").Checkout(); + fixture.Repository.MakeACommit(); + fixture.Repository.MakeATaggedCommit("1.0.0"); + fixture.Repository.MakeACommit(); + fixture.Repository.CreateBranch("feature/someFeature"); + + fixture.LocalRepository.Network.Fetch(fixture.LocalRepository.Network.Remotes.First()); + fixture.LocalRepository.Checkout(fixture.Repository.Head.Tip); + fixture.LocalRepository.Branches.Remove("master"); + fixture.InitialiseRepo(); + fixture.AssertFullSemver("1.1.0-unstable.1"); + } + } + } +} \ No newline at end of file diff --git a/GitVersionCore/BuildServers/GitHelper.cs b/GitVersionCore/BuildServers/GitHelper.cs index 10dd0ca3c7..1d47870e96 100644 --- a/GitVersionCore/BuildServers/GitHelper.cs +++ b/GitVersionCore/BuildServers/GitHelper.cs @@ -50,12 +50,33 @@ public static void NormalizeGitDirectory(string gitDirectory, Authentication aut if (localBranchesWhereCommitShaIsHead.Count > 1) { - var names = string.Join(", ", localBranchesWhereCommitShaIsHead.Select(r => r.CanonicalName)); - var message = string.Format("Found more than one local branch pointing at the commit '{0}'. Unable to determine which one to use ({1}).", headSha, names); - throw new WarningException(message); + var branchNames = localBranchesWhereCommitShaIsHead.Select(r => r.CanonicalName); + var csvNames = string.Join(", ", branchNames); + const string moveBranchMsg = "Move one of the branches along a commit to remove warning"; + + Logger.WriteWarning(string.Format("Found more than one local branch pointing at the commit '{0}' ({1}).", headSha, csvNames)); + var master = localBranchesWhereCommitShaIsHead.SingleOrDefault(n => n.Name == "master"); + if (master != null) + { + Logger.WriteWarning("Because one of the branches is 'master', will build master." + moveBranchMsg); + master.Checkout(); + } + else + { + var branchesWithoutSeparators = localBranchesWhereCommitShaIsHead.Where(b => !b.Name.Contains('/') && !b.Name.Contains('-')).ToList(); + if (branchesWithoutSeparators.Count == 1) + { + var branchWithoutSeparator = branchesWithoutSeparators[0]; + Logger.WriteWarning(string.Format("Choosing {0} as it is the only branch without / or - in it. " + moveBranchMsg, branchWithoutSeparator.CanonicalName)); + branchWithoutSeparator.Checkout(); + } + else + { + throw new WarningException("Failed to try and guess branch to use. " + moveBranchMsg); + } + } } - - if (localBranchesWhereCommitShaIsHead.Count == 0) + else if (localBranchesWhereCommitShaIsHead.Count == 0) { Logger.WriteInfo(string.Format("No local branch pointing at the commit '{0}'. Fake branch needs to be created.", headSha)); CreateFakeBranchPointingAtThePullRequestTip(repo, authentication); diff --git a/GitVersionCore/LibGitExtensions.cs b/GitVersionCore/LibGitExtensions.cs index 102d631902..c9f3668f65 100644 --- a/GitVersionCore/LibGitExtensions.cs +++ b/GitVersionCore/LibGitExtensions.cs @@ -2,8 +2,11 @@ namespace GitVersion { using System; using System.Collections.Generic; + using System.Diagnostics; using System.IO; using System.Linq; + using System.Text; + using GitVersion.Helpers; using LibGit2Sharp; static class LibGitExtensions @@ -174,5 +177,40 @@ public static void CheckoutFilesIfExist(this IRepository repository, params stri } } } + + public static void DumpGraph(this IRepository repository, Action writer = null, int? maxCommits = null) + { + DumpGraph(repository.Info.Path, writer, maxCommits); + } + + public static void DumpGraph(string workingDirectory, Action writer = null, int? maxCommits = null) + { + var output = new StringBuilder(); + + try + { + ProcessHelper.Run( + o => output.AppendLine(o), + e => output.AppendLineFormat("ERROR: {0}", e), + null, + "git", + @"log --graph --format=""%h %cr %d"" --decorate --date=relative --all --remotes=*" + (maxCommits != null ? string.Format(" -n {0}", maxCommits) : null), + //@"log --graph --abbrev-commit --decorate --date=relative --all --remotes=*", + workingDirectory); + } + catch (FileNotFoundException exception) + { + if (exception.FileName != "git") + { + throw; + } + + output.AppendLine("Could not execute 'git log' due to the following error:"); + output.AppendLine(exception.ToString()); + } + + if (writer != null) writer(output.ToString()); + else Trace.Write(output.ToString()); + } } } \ No newline at end of file diff --git a/GitVersionExe/Program.cs b/GitVersionExe/Program.cs index dd6bbc15b4..b800700cc9 100644 --- a/GitVersionExe/Program.cs +++ b/GitVersionExe/Program.cs @@ -32,11 +32,11 @@ static void Main() static int VerifyArgumentsAndRun() { + Arguments arguments = null; try { var fileSystem = new FileSystem(); - Arguments arguments; var argumentsWithoutExeName = GetArgumentsWithoutExeName(); try { @@ -99,6 +99,14 @@ static int VerifyArgumentsAndRun() { var error = string.Format("An unexpected error occurred:\r\n{0}", exception); Logger.WriteError(error); + + if (arguments != null) + { + Logger.WriteInfo(string.Empty); + Logger.WriteInfo("Here is the current git graph (please include in issue): "); + Logger.WriteInfo("Showing max of 100 commits"); + LibGitExtensions.DumpGraph(arguments.TargetPath, Logger.WriteInfo, 100); + } return 1; }