/// <summary> /// Checks out the given commit on the given branch /// </summary> public void Checkout(IBranch branch, ICommit commit) { // Need to allow them to checkout the last created branch because that's how "create branch" works if (!EnabledVersionControls.Instance().CanCheckout&& !lastCreatedBranch.Equals(branch)) { Debug.Log("Can't Checkout branch; not enabled yet"); return; } LoadStateOfCommit(commit); activeCommit = commit; activeBranch = branch; if (!activeCommit.Equals(activeBranch.GetTip())) { this.isDetached = true; } else { this.isDetached = false; } if (checkoutTrigger != null) { checkoutTrigger.Trigger(); } UIController.Instance().UpdateOverlay(); }
// TODO I think we need to take a fresh approach to this.. it's getting really complex with heaps of edge cases private BranchConfig InheritBranchConfiguration(IBranch targetBranch, BranchConfig branchConfiguration, ICommit currentCommit, Config configuration, IList <IBranch> excludedInheritBranches) { using (log.IndentLog("Attempting to inherit branch configuration from parent branch")) { var excludedBranches = new[] { targetBranch }; // Check if we are a merge commit. If so likely we are a pull request var parentCount = currentCommit.Parents.Count(); if (parentCount == 2) { excludedBranches = CalculateWhenMultipleParents(currentCommit, ref targetBranch, excludedBranches); } excludedInheritBranches ??= repositoryMetadataProvider.GetExcludedInheritBranches(configuration).ToList(); excludedBranches = excludedBranches.Where(b => excludedInheritBranches.All(bte => !b.Equals(bte))).ToArray(); // Add new excluded branches. foreach (var excludedBranch in excludedBranches) { excludedInheritBranches.Add(excludedBranch); } var branchesToEvaluate = repositoryMetadataProvider.ExcludingBranches(excludedInheritBranches).ToList(); var branchPoint = repositoryMetadataProvider .FindCommitBranchWasBranchedFrom(targetBranch, configuration, excludedInheritBranches.ToArray()); List <IBranch> possibleParents; if (branchPoint == BranchCommit.Empty) { possibleParents = repositoryMetadataProvider.GetBranchesContainingCommit(targetBranch.Tip, branchesToEvaluate) // It fails to inherit Increment branch configuration if more than 1 parent; // therefore no point to get more than 2 parents .Take(2) .ToList(); } else { var branches = repositoryMetadataProvider.GetBranchesContainingCommit(branchPoint.Commit, branchesToEvaluate).ToList(); if (branches.Count > 1) { var currentTipBranches = repositoryMetadataProvider.GetBranchesContainingCommit(currentCommit, branchesToEvaluate).ToList(); possibleParents = branches.Except(currentTipBranches).ToList(); } else { possibleParents = branches; } } log.Info("Found possible parent branches: " + string.Join(", ", possibleParents.Select(p => p.ToString()))); if (possibleParents.Count == 1) { var branchConfig = GetBranchConfiguration(possibleParents[0], currentCommit, configuration, excludedInheritBranches); // If we have resolved a fallback config we should not return that we have got config if (branchConfig.Name != FallbackConfigName) { return(new BranchConfig(branchConfiguration) { Increment = branchConfig.Increment, PreventIncrementOfMergedBranchVersion = branchConfig.PreventIncrementOfMergedBranchVersion, // If we are inheriting from develop then we should behave like develop TracksReleaseBranches = branchConfig.TracksReleaseBranches }); } } // If we fail to inherit it is probably because the branch has been merged and we can't do much. So we will fall back to develop's config // if develop exists and master if not var errorMessage = possibleParents.Count == 0 ? "Failed to inherit Increment branch configuration, no branches found." : "Failed to inherit Increment branch configuration, ended up with: " + string.Join(", ", possibleParents.Select(p => p.ToString())); var chosenBranch = repositoryMetadataProvider.GetChosenBranch(configuration); if (chosenBranch == null) { // TODO We should call the build server to generate this exception, each build server works differently // for fetch issues and we could give better warnings. throw new InvalidOperationException("Could not find a 'develop' or 'master' branch, neither locally nor remotely."); } log.Warning($"{errorMessage}{System.Environment.NewLine}Falling back to {chosenBranch} branch config"); // To prevent infinite loops, make sure that a new branch was chosen. if (targetBranch.Equals(chosenBranch)) { var developOrMasterConfig = ChooseMasterOrDevelopIncrementStrategyIfTheChosenBranchIsOneOfThem( chosenBranch, branchConfiguration, configuration); if (developOrMasterConfig != null) { return(developOrMasterConfig); } log.Warning("Fallback branch wants to inherit Increment branch configuration from itself. Using patch increment instead."); return(new BranchConfig(branchConfiguration) { Increment = IncrementStrategy.Patch }); } var inheritingBranchConfig = GetBranchConfiguration(chosenBranch, currentCommit, configuration, excludedInheritBranches); var configIncrement = inheritingBranchConfig.Increment; if (inheritingBranchConfig.Name.IsEquivalentTo(FallbackConfigName) && configIncrement == IncrementStrategy.Inherit) { log.Warning("Fallback config inherits by default, dropping to patch increment"); configIncrement = IncrementStrategy.Patch; } return(new BranchConfig(branchConfiguration) { Increment = configIncrement, PreventIncrementOfMergedBranchVersion = inheritingBranchConfig.PreventIncrementOfMergedBranchVersion, // If we are inheriting from develop then we should behave like develop TracksReleaseBranches = inheritingBranchConfig.TracksReleaseBranches }); } }