diff --git a/src/Stack.Tests/Commands/Branch/NewBranchCommandHandlerTests.cs b/src/Stack.Tests/Commands/Branch/NewBranchCommandHandlerTests.cs index b587912..aec5421 100644 --- a/src/Stack.Tests/Commands/Branch/NewBranchCommandHandlerTests.cs +++ b/src/Stack.Tests/Commands/Branch/NewBranchCommandHandlerTests.cs @@ -7,7 +7,7 @@ using Stack.Infrastructure; using Stack.Tests.Helpers; -namespace Stack.Tests.Commands.Stack; +namespace Stack.Tests.Commands.Branch; public class NewBranchCommandHandlerTests { @@ -15,22 +15,24 @@ public class NewBranchCommandHandlerTests public async Task WhenNoInputsProvided_AsksForStackAndBranchAndConfirms_CreatesAndAddsBranchToStackAndSwitchesToBranch() { // Arrange - var gitOperations = Substitute.For(); + var sourceBranch = Some.BranchName(); + var anotherBranch = Some.BranchName(); + var newBranch = Some.BranchName(); + using var repo = new TestGitRepositoryBuilder() + .WithBranch(sourceBranch) + .WithBranch(anotherBranch) + .Build(); + var stackConfig = Substitute.For(); var inputProvider = Substitute.For(); var outputProvider = Substitute.For(); + var gitOperations = new GitOperations(outputProvider, repo.GitOperationSettings); var handler = new NewBranchCommandHandler(inputProvider, outputProvider, gitOperations, stackConfig); - var remoteUri = Some.HttpsUri().ToString(); - - gitOperations.GetRemoteUri().Returns(remoteUri); - gitOperations.GetCurrentBranch().Returns("branch-1"); - gitOperations.DoesLocalBranchExist("branch-5").Returns(false); - var stacks = new List( [ - new("Stack1", remoteUri, "branch-1", ["branch-3"]), - new("Stack2", remoteUri, "branch-2", ["branch-4"]) + new("Stack1", repo.RemoteUri, sourceBranch, [anotherBranch]), + new("Stack2", repo.RemoteUri, sourceBranch, []) ]); stackConfig.Load().Returns(stacks); stackConfig @@ -38,7 +40,7 @@ public async Task WhenNoInputsProvided_AsksForStackAndBranchAndConfirms_CreatesA .Do(ci => stacks = ci.ArgAt>(0)); inputProvider.Select(Questions.SelectStack, Arg.Any()).Returns("Stack1"); - inputProvider.Text(Questions.BranchName, Arg.Any()).Returns("branch-5"); + inputProvider.Text(Questions.BranchName, Arg.Any()).Returns(newBranch); inputProvider.Confirm(Questions.ConfirmSwitchToBranch).Returns(true); // Act @@ -47,32 +49,34 @@ public async Task WhenNoInputsProvided_AsksForStackAndBranchAndConfirms_CreatesA // Assert stacks.Should().BeEquivalentTo(new List { - new("Stack1", remoteUri, "branch-1", ["branch-3", "branch-5"]), - new("Stack2", remoteUri, "branch-2", ["branch-4"]) + new("Stack1", repo.RemoteUri, sourceBranch, [anotherBranch, newBranch]), + new("Stack2", repo.RemoteUri, sourceBranch, []) }); - gitOperations.Received().ChangeBranch("branch-5"); + gitOperations.GetCurrentBranch().Should().Be(newBranch); } [Fact] - public async Task WhenSwitchBranchIsFalse_CreatsAndAddsBranchToStackButDoesNotSwitchToBranch() + public async Task WhenSwitchBranchIsFalse_CreatesAndAddsBranchToStackButDoesNotSwitchToBranch() { // Arrange - var gitOperations = Substitute.For(); + var sourceBranch = Some.BranchName(); + var anotherBranch = Some.BranchName(); + var newBranch = Some.BranchName(); + using var repo = new TestGitRepositoryBuilder() + .WithBranch(sourceBranch) + .WithBranch(anotherBranch) + .Build(); + var stackConfig = Substitute.For(); var inputProvider = Substitute.For(); var outputProvider = Substitute.For(); + var gitOperations = new GitOperations(outputProvider, repo.GitOperationSettings); var handler = new NewBranchCommandHandler(inputProvider, outputProvider, gitOperations, stackConfig); - var remoteUri = Some.HttpsUri().ToString(); - - gitOperations.GetRemoteUri().Returns(remoteUri); - gitOperations.GetCurrentBranch().Returns("branch-1"); - gitOperations.DoesLocalBranchExist("branch-5").Returns(false); - var stacks = new List( [ - new("Stack1", remoteUri, "branch-1", ["branch-3"]), - new("Stack2", remoteUri, "branch-2", ["branch-4"]) + new("Stack1", repo.RemoteUri, sourceBranch, [anotherBranch]), + new("Stack2", repo.RemoteUri, sourceBranch, []) ]); stackConfig.Load().Returns(stacks); stackConfig @@ -80,7 +84,7 @@ public async Task WhenSwitchBranchIsFalse_CreatsAndAddsBranchToStackButDoesNotSw .Do(ci => stacks = ci.ArgAt>(0)); inputProvider.Select(Questions.SelectStack, Arg.Any()).Returns("Stack1"); - inputProvider.Text(Questions.BranchName, Arg.Any()).Returns("branch-5"); + inputProvider.Text(Questions.BranchName, Arg.Any()).Returns(newBranch); inputProvider.Confirm(Questions.ConfirmSwitchToBranch).Returns(false); // Act @@ -89,39 +93,41 @@ public async Task WhenSwitchBranchIsFalse_CreatsAndAddsBranchToStackButDoesNotSw // Assert stacks.Should().BeEquivalentTo(new List { - new("Stack1", remoteUri, "branch-1", ["branch-3", "branch-5"]), - new("Stack2", remoteUri, "branch-2", ["branch-4"]) + new("Stack1", repo.RemoteUri, sourceBranch, [anotherBranch, newBranch]), + new("Stack2", repo.RemoteUri, sourceBranch, []) }); - gitOperations.DidNotReceive().ChangeBranch("branch-5"); + gitOperations.GetCurrentBranch().Should().NotBe(newBranch); } [Fact] public async Task WhenStackNameProvided_DoesNotAskForStackName_CreatesAndAddsBranchFromStack() { // Arrange - var gitOperations = Substitute.For(); + var sourceBranch = Some.BranchName(); + var anotherBranch = Some.BranchName(); + var newBranch = Some.BranchName(); + using var repo = new TestGitRepositoryBuilder() + .WithBranch(sourceBranch) + .WithBranch(anotherBranch) + .Build(); + var stackConfig = Substitute.For(); var inputProvider = Substitute.For(); var outputProvider = Substitute.For(); + var gitOperations = new GitOperations(outputProvider, repo.GitOperationSettings); var handler = new NewBranchCommandHandler(inputProvider, outputProvider, gitOperations, stackConfig); - var remoteUri = Some.HttpsUri().ToString(); - - gitOperations.GetRemoteUri().Returns(remoteUri); - gitOperations.GetCurrentBranch().Returns("branch-1"); - gitOperations.DoesLocalBranchExist("branch-5").Returns(false); - var stacks = new List( [ - new("Stack1", remoteUri, "branch-1", ["branch-3"]), - new("Stack2", remoteUri, "branch-2", ["branch-4"]) + new("Stack1", repo.RemoteUri, sourceBranch, [anotherBranch]), + new("Stack2", repo.RemoteUri, sourceBranch, []) ]); stackConfig.Load().Returns(stacks); stackConfig .WhenForAnyArgs(s => s.Save(Arg.Any>())) .Do(ci => stacks = ci.ArgAt>(0)); - inputProvider.Text(Questions.BranchName, Arg.Any()).Returns("branch-5"); + inputProvider.Text(Questions.BranchName, Arg.Any()).Returns(newBranch); // Act await handler.Handle(new NewBranchCommandInputs("Stack1", null, false)); @@ -130,8 +136,8 @@ public async Task WhenStackNameProvided_DoesNotAskForStackName_CreatesAndAddsBra inputProvider.DidNotReceive().Select(Questions.SelectStack, Arg.Any()); stacks.Should().BeEquivalentTo(new List { - new("Stack1", remoteUri, "branch-1", ["branch-3", "branch-5"]), - new("Stack2", remoteUri, "branch-2", ["branch-4"]) + new("Stack1", repo.RemoteUri, sourceBranch, [anotherBranch, newBranch]), + new("Stack2", repo.RemoteUri, sourceBranch, []) }); } @@ -139,28 +145,30 @@ public async Task WhenStackNameProvided_DoesNotAskForStackName_CreatesAndAddsBra public async Task WhenOnlyOneStackExists_DoesNotAskForStackName_CreatesAndAddsBranchFromStack() { // Arrange - var gitOperations = Substitute.For(); + var sourceBranch = Some.BranchName(); + var anotherBranch = Some.BranchName(); + var newBranch = Some.BranchName(); + using var repo = new TestGitRepositoryBuilder() + .WithBranch(sourceBranch) + .WithBranch(anotherBranch) + .Build(); + var stackConfig = Substitute.For(); var inputProvider = Substitute.For(); var outputProvider = Substitute.For(); + var gitOperations = new GitOperations(outputProvider, repo.GitOperationSettings); var handler = new NewBranchCommandHandler(inputProvider, outputProvider, gitOperations, stackConfig); - var remoteUri = Some.HttpsUri().ToString(); - - gitOperations.GetRemoteUri().Returns(remoteUri); - gitOperations.GetCurrentBranch().Returns("branch-1"); - gitOperations.DoesLocalBranchExist("branch-5").Returns(false); - var stacks = new List( [ - new("Stack1", remoteUri, "branch-1", ["branch-3"]) + new("Stack1", repo.RemoteUri, sourceBranch, [anotherBranch]) ]); stackConfig.Load().Returns(stacks); stackConfig .WhenForAnyArgs(s => s.Save(Arg.Any>())) .Do(ci => stacks = ci.ArgAt>(0)); - inputProvider.Text(Questions.BranchName, Arg.Any()).Returns("branch-5"); + inputProvider.Text(Questions.BranchName, Arg.Any()).Returns(newBranch); // Act await handler.Handle(new NewBranchCommandInputs(null, null, false)); @@ -169,7 +177,7 @@ public async Task WhenOnlyOneStackExists_DoesNotAskForStackName_CreatesAndAddsBr inputProvider.DidNotReceive().Select(Questions.SelectStack, Arg.Any()); stacks.Should().BeEquivalentTo(new List { - new("Stack1", remoteUri, "branch-1", ["branch-3", "branch-5"]) + new("Stack1", repo.RemoteUri, sourceBranch, [anotherBranch, newBranch]), }); } @@ -177,21 +185,24 @@ public async Task WhenOnlyOneStackExists_DoesNotAskForStackName_CreatesAndAddsBr public async Task WhenStackNameProvided_ButStackDoesNotExist_Throws() { // Arrange - var gitOperations = Substitute.For(); + var sourceBranch = Some.BranchName(); + var anotherBranch = Some.BranchName(); + var newBranch = Some.BranchName(); + using var repo = new TestGitRepositoryBuilder() + .WithBranch(sourceBranch) + .WithBranch(anotherBranch) + .Build(); + var stackConfig = Substitute.For(); var inputProvider = Substitute.For(); var outputProvider = Substitute.For(); + var gitOperations = new GitOperations(outputProvider, repo.GitOperationSettings); var handler = new NewBranchCommandHandler(inputProvider, outputProvider, gitOperations, stackConfig); - var remoteUri = Some.HttpsUri().ToString(); - - gitOperations.GetRemoteUri().Returns(remoteUri); - gitOperations.GetCurrentBranch().Returns("branch-1"); - var stacks = new List( [ - new("Stack1", remoteUri, "branch-1", ["branch-3", "branch-5"]), - new("Stack2", remoteUri, "branch-2", ["branch-4"]) + new("Stack1", repo.RemoteUri, sourceBranch, [anotherBranch]), + new("Stack2", repo.RemoteUri, sourceBranch, []) ]); stackConfig.Load().Returns(stacks); @@ -207,22 +218,24 @@ await handler.Invoking(async h => await h.Handle(new NewBranchCommandInputs(inva public async Task WhenBranchNameProvided_DoesNotAskForBranchName_CreatesAndAddsBranchFromStack() { // Arrange - var gitOperations = Substitute.For(); + var sourceBranch = Some.BranchName(); + var anotherBranch = Some.BranchName(); + var newBranch = Some.BranchName(); + using var repo = new TestGitRepositoryBuilder() + .WithBranch(sourceBranch) + .WithBranch(anotherBranch) + .Build(); + var stackConfig = Substitute.For(); var inputProvider = Substitute.For(); var outputProvider = Substitute.For(); + var gitOperations = new GitOperations(outputProvider, repo.GitOperationSettings); var handler = new NewBranchCommandHandler(inputProvider, outputProvider, gitOperations, stackConfig); - var remoteUri = Some.HttpsUri().ToString(); - - gitOperations.GetRemoteUri().Returns(remoteUri); - gitOperations.GetCurrentBranch().Returns("branch-1"); - gitOperations.DoesLocalBranchExist("branch-5").Returns(false); - var stacks = new List( [ - new("Stack1", remoteUri, "branch-1", ["branch-3"]), - new("Stack2", remoteUri, "branch-2", ["branch-4"]) + new("Stack1", repo.RemoteUri, sourceBranch, [anotherBranch]), + new("Stack2", repo.RemoteUri, sourceBranch, []) ]); stackConfig.Load().Returns(stacks); stackConfig @@ -232,13 +245,13 @@ public async Task WhenBranchNameProvided_DoesNotAskForBranchName_CreatesAndAddsB inputProvider.Select(Questions.SelectStack, Arg.Any()).Returns("Stack1"); // Act - await handler.Handle(new NewBranchCommandInputs(null, "branch-5", false)); + await handler.Handle(new NewBranchCommandInputs(null, newBranch, false)); // Assert stacks.Should().BeEquivalentTo(new List { - new("Stack1", remoteUri, "branch-1", ["branch-3", "branch-5"]), - new("Stack2", remoteUri, "branch-2", ["branch-4"]) + new("Stack1", repo.RemoteUri, sourceBranch, [anotherBranch, newBranch]), + new("Stack2", repo.RemoteUri, sourceBranch, []) }); inputProvider.DidNotReceive().Text(Questions.BranchName); } @@ -247,22 +260,23 @@ public async Task WhenBranchNameProvided_DoesNotAskForBranchName_CreatesAndAddsB public async Task WhenBranchNameProvided_ButBranchAlreadyExistLocally_Throws() { // Arrange - var gitOperations = Substitute.For(); + var sourceBranch = Some.BranchName(); + var anotherBranch = Some.BranchName(); + using var repo = new TestGitRepositoryBuilder() + .WithBranch(sourceBranch) + .WithBranch(anotherBranch) + .Build(); + var stackConfig = Substitute.For(); var inputProvider = Substitute.For(); var outputProvider = Substitute.For(); + var gitOperations = new GitOperations(outputProvider, repo.GitOperationSettings); var handler = new NewBranchCommandHandler(inputProvider, outputProvider, gitOperations, stackConfig); - var remoteUri = Some.HttpsUri().ToString(); - - gitOperations.GetRemoteUri().Returns(remoteUri); - gitOperations.GetCurrentBranch().Returns("branch-1"); - gitOperations.DoesLocalBranchExist("branch-5").Returns(true); - var stacks = new List( [ - new("Stack1", remoteUri, "branch-1", ["branch-3"]), - new("Stack2", remoteUri, "branch-2", ["branch-4"]) + new("Stack1", repo.RemoteUri, sourceBranch, []), + new("Stack2", repo.RemoteUri, sourceBranch, []) ]); stackConfig.Load().Returns(stacks); @@ -270,64 +284,68 @@ public async Task WhenBranchNameProvided_ButBranchAlreadyExistLocally_Throws() // Act and assert var invalidBranchName = Some.Name(); - await handler.Invoking(async h => await h.Handle(new NewBranchCommandInputs(null, "branch-5", false))) + await handler.Invoking(async h => await h.Handle(new NewBranchCommandInputs(null, anotherBranch, false))) .Should() .ThrowAsync() - .WithMessage($"Branch 'branch-5' already exists locally."); + .WithMessage($"Branch '{anotherBranch}' already exists locally."); } [Fact] public async Task WhenBranchNameProvided_ButBranchAlreadyExistsInStack_Throws() { // Arrange - var gitOperations = Substitute.For(); + var sourceBranch = Some.BranchName(); + var anotherBranch = Some.BranchName(); + var newBranch = Some.BranchName(); + using var repo = new TestGitRepositoryBuilder() + .WithBranch(sourceBranch) + .WithBranch(anotherBranch) + .Build(); + var stackConfig = Substitute.For(); var inputProvider = Substitute.For(); var outputProvider = Substitute.For(); + var gitOperations = new GitOperations(outputProvider, repo.GitOperationSettings); var handler = new NewBranchCommandHandler(inputProvider, outputProvider, gitOperations, stackConfig); - var remoteUri = Some.HttpsUri().ToString(); - - gitOperations.GetRemoteUri().Returns(remoteUri); - gitOperations.GetCurrentBranch().Returns("branch-1"); - gitOperations.DoesLocalBranchExist("branch-5").Returns(false); - var stacks = new List( [ - new("Stack1", remoteUri, "branch-1", ["branch-3", "branch-5"]), - new("Stack2", remoteUri, "branch-2", ["branch-4"]) + new("Stack1", repo.RemoteUri, sourceBranch, [anotherBranch, newBranch]), + new("Stack2", repo.RemoteUri, sourceBranch, []) ]); stackConfig.Load().Returns(stacks); inputProvider.Select(Questions.SelectStack, Arg.Any()).Returns("Stack1"); // Act and assert - await handler.Invoking(async h => await h.Handle(new NewBranchCommandInputs(null, "branch-5", false))) + await handler.Invoking(async h => await h.Handle(new NewBranchCommandInputs(null, newBranch, false))) .Should() .ThrowAsync() - .WithMessage($"Branch 'branch-5' already exists in stack 'Stack1'."); + .WithMessage($"Branch '{newBranch}' already exists in stack 'Stack1'."); } [Fact] public async Task WhenAllInputsProvided_DoesNotAskForAnything_CreatesAndAddsBranchFromStackAndChangesToBranch() { // Arrange - var gitOperations = Substitute.For(); + var sourceBranch = Some.BranchName(); + var anotherBranch = Some.BranchName(); + var newBranch = Some.BranchName(); + using var repo = new TestGitRepositoryBuilder() + .WithBranch(sourceBranch) + .WithBranch(anotherBranch) + .Build(); + var stackConfig = Substitute.For(); var inputProvider = Substitute.For(); var outputProvider = Substitute.For(); + var gitOperations = new GitOperations(outputProvider, repo.GitOperationSettings); var handler = new NewBranchCommandHandler(inputProvider, outputProvider, gitOperations, stackConfig); - var remoteUri = Some.HttpsUri().ToString(); - - gitOperations.GetRemoteUri().Returns(remoteUri); - gitOperations.GetCurrentBranch().Returns("branch-1"); - gitOperations.DoesLocalBranchExist("branch-5").Returns(false); - var stacks = new List( [ - new("Stack1", remoteUri, "branch-1", ["branch-3"]), - new("Stack2", remoteUri, "branch-2", ["branch-4"]) + new("Stack1", repo.RemoteUri, sourceBranch, [anotherBranch]), + new("Stack2", repo.RemoteUri, sourceBranch, []) ]); stackConfig.Load().Returns(stacks); stackConfig @@ -335,13 +353,13 @@ public async Task WhenAllInputsProvided_DoesNotAskForAnything_CreatesAndAddsBran .Do(ci => stacks = ci.ArgAt>(0)); // Act - await handler.Handle(new NewBranchCommandInputs("Stack1", "branch-5", true)); + await handler.Handle(new NewBranchCommandInputs("Stack1", newBranch, true)); // Assert stacks.Should().BeEquivalentTo(new List { - new("Stack1", remoteUri, "branch-1", ["branch-3", "branch-5"]), - new("Stack2", remoteUri, "branch-2", ["branch-4"]) + new("Stack1", repo.RemoteUri, sourceBranch, [anotherBranch, newBranch]), + new("Stack2", repo.RemoteUri, sourceBranch, []) }); inputProvider.ReceivedCalls().Should().BeEmpty(); } @@ -350,22 +368,24 @@ public async Task WhenAllInputsProvided_DoesNotAskForAnything_CreatesAndAddsBran public async Task WhenStackHasANameWithMultipleWords_SuggestsAGoodDefaultNewBranchName() { // Arrange - var gitOperations = Substitute.For(); + var sourceBranch = Some.BranchName(); + var anotherBranch = Some.BranchName(); + var newBranch = Some.BranchName(); + using var repo = new TestGitRepositoryBuilder() + .WithBranch(sourceBranch) + .WithBranch(anotherBranch) + .Build(); + var stackConfig = Substitute.For(); var inputProvider = Substitute.For(); var outputProvider = Substitute.For(); + var gitOperations = new GitOperations(outputProvider, repo.GitOperationSettings); var handler = new NewBranchCommandHandler(inputProvider, outputProvider, gitOperations, stackConfig); - var remoteUri = Some.HttpsUri().ToString(); - - gitOperations.GetRemoteUri().Returns(remoteUri); - gitOperations.GetCurrentBranch().Returns("branch-1"); - gitOperations.DoesLocalBranchExist("branch-5").Returns(false); - var stacks = new List( [ - new("A stack with multiple words", remoteUri, "branch-1", ["branch-3"]), - new("Stack2", remoteUri, "branch-2", ["branch-4"]) + new("A stack with multiple words", repo.RemoteUri, sourceBranch, [anotherBranch]), + new("Stack2", repo.RemoteUri, sourceBranch, []) ]); stackConfig.Load().Returns(stacks); stackConfig @@ -373,7 +393,7 @@ public async Task WhenStackHasANameWithMultipleWords_SuggestsAGoodDefaultNewBran .Do(ci => stacks = ci.ArgAt>(0)); inputProvider.Select(Questions.SelectStack, Arg.Any()).Returns("A stack with multiple words"); - inputProvider.Text(Questions.BranchName, "a-stack-with-multiple-words-2").Returns("branch-5"); + inputProvider.Text(Questions.BranchName, "a-stack-with-multiple-words-2").Returns(newBranch); inputProvider.Confirm(Questions.ConfirmSwitchToBranch).Returns(true); // Act @@ -382,9 +402,9 @@ public async Task WhenStackHasANameWithMultipleWords_SuggestsAGoodDefaultNewBran // Assert stacks.Should().BeEquivalentTo(new List { - new("A stack with multiple words", remoteUri, "branch-1", ["branch-3", "branch-5"]), - new("Stack2", remoteUri, "branch-2", ["branch-4"]) + new("A stack with multiple words", repo.RemoteUri, sourceBranch, [anotherBranch, newBranch]), + new("Stack2", repo.RemoteUri, sourceBranch, []) }); - gitOperations.Received().ChangeBranch("branch-5"); + gitOperations.GetCurrentBranch().Should().Be(newBranch); } } diff --git a/src/Stack/Commands/Branch/NewBranchCommand.cs b/src/Stack/Commands/Branch/NewBranchCommand.cs index 00f9c96..d9601b6 100644 --- a/src/Stack/Commands/Branch/NewBranchCommand.cs +++ b/src/Stack/Commands/Branch/NewBranchCommand.cs @@ -61,7 +61,6 @@ public async Task Handle(NewBranchCommandInputs inputs { await Task.CompletedTask; - var defaultBranch = gitOperations.GetDefaultBranch(); var remoteUri = gitOperations.GetRemoteUri(); var currentBranch = gitOperations.GetCurrentBranch(); var branches = gitOperations.GetLocalBranchesOrderedByMostRecentCommitterDate(); diff --git a/src/Stack/Git/GitOperations.cs b/src/Stack/Git/GitOperations.cs index 27be14a..60c9b5a 100644 --- a/src/Stack/Git/GitOperations.cs +++ b/src/Stack/Git/GitOperations.cs @@ -24,7 +24,6 @@ public interface IGitOperations void DeleteLocalBranch(string branchName); void MergeFromLocalSourceBranch(string sourceBranchName); string GetCurrentBranch(); - string GetDefaultBranch(); bool DoesLocalBranchExist(string branchName); bool DoesRemoteBranchExist(string branchName); string[] GetBranchesThatExistLocally(string[] branches); @@ -97,11 +96,6 @@ public string GetCurrentBranch() return ExecuteGitCommandAndReturnOutput("branch --show-current").Trim(); } - public string GetDefaultBranch() - { - return ExecuteGitCommandAndReturnOutput("symbolic-ref refs/remotes/origin/HEAD").Trim().Replace("refs/remotes/origin/", ""); - } - public bool DoesRemoteBranchExist(string branchName) { return ExecuteGitCommandAndReturnOutput($"ls-remote --heads origin {branchName}").Trim().Length > 0;