public static KeyValuePair<string, BranchConfig> GetBranchConfiguration(Commit currentCommit, IRepository repository, bool onlyEvaluateTrackedBranches, Config config, Branch currentBranch, IList<Branch> excludedInheritBranches = null) { var matchingBranches = LookupBranchConfiguration(config, currentBranch); if (matchingBranches.Length == 0) { var branchConfig = new BranchConfig(); ConfigurationProvider.ApplyBranchDefaults(config, branchConfig); return new KeyValuePair<string, BranchConfig>(string.Empty, branchConfig); } if (matchingBranches.Length == 1) { var keyValuePair = matchingBranches[0]; var branchConfiguration = keyValuePair.Value; if (branchConfiguration.Increment == IncrementStrategy.Inherit) { return InheritBranchConfiguration(onlyEvaluateTrackedBranches, repository, currentCommit, currentBranch, keyValuePair, branchConfiguration, config, excludedInheritBranches); } return keyValuePair; } const string format = "Multiple branch configurations match the current branch branchName of '{0}'. Matching configurations: '{1}'"; throw new Exception(string.Format(format, currentBranch.Name, string.Join(", ", matchingBranches.Select(b => b.Key)))); }
/// <summary> /// Gets the <see cref="BranchConfig"/> for the current commit. /// </summary> public static BranchConfig GetBranchConfiguration(GitVersionContext context, Branch targetBranch, IList<Branch> excludedInheritBranches = null) { var matchingBranches = LookupBranchConfiguration(context.FullConfiguration, targetBranch).ToArray(); BranchConfig branchConfiguration; if (matchingBranches.Length > 0) { branchConfiguration = matchingBranches[0]; if (matchingBranches.Length > 1) { Logger.WriteWarning(string.Format( "Multiple branch configurations match the current branch branchName of '{0}'. Using the first matching configuration, '{1}'. Matching configurations include: '{2}'", targetBranch.FriendlyName, branchConfiguration.Name, string.Join("', '", matchingBranches.Select(b => b.Name)))); } } else { Logger.WriteInfo(string.Format( "No branch configuration found for branch {0}, falling back to default configuration", targetBranch.FriendlyName)); branchConfiguration = new BranchConfig { Name = string.Empty }; ConfigurationProvider.ApplyBranchDefaults(context.FullConfiguration, branchConfiguration, ""); } return branchConfiguration.Increment == IncrementStrategy.Inherit ? InheritBranchConfiguration(context, targetBranch, branchConfiguration, excludedInheritBranches) : branchConfiguration; }
public BranchConfig(BranchConfig branchConfiguration) { VersioningMode = branchConfiguration.VersioningMode; Tag = branchConfiguration.Tag; Increment = branchConfiguration.Increment; PreventIncrementOfMergedBranchVersion = branchConfiguration.PreventIncrementOfMergedBranchVersion; TagNumberPattern = branchConfiguration.TagNumberPattern; TrackMergeTarget = branchConfiguration.TrackMergeTarget; }
public BranchConfig(BranchConfig branchConfiguration) { VersioningMode = branchConfiguration.VersioningMode; Tag = branchConfiguration.Tag; Increment = branchConfiguration.Increment; PreventIncrementOfMergedBranchVersion = branchConfiguration.PreventIncrementOfMergedBranchVersion; TagNumberPattern = branchConfiguration.TagNumberPattern; TrackMergeTarget = branchConfiguration.TrackMergeTarget; CommitMessageIncrementing = branchConfiguration.CommitMessageIncrementing; DisableMergeMessageStrategy = branchConfiguration.DisableMergeMessageStrategy; }
public BranchConfig(BranchConfig branchConfiguration) { VersioningMode = branchConfiguration.VersioningMode; Tag = branchConfiguration.Tag; Increment = branchConfiguration.Increment; PreventIncrementOfMergedBranchVersion = branchConfiguration.PreventIncrementOfMergedBranchVersion; TagNumberPattern = branchConfiguration.TagNumberPattern; TrackMergeTarget = branchConfiguration.TrackMergeTarget; CommitMessageIncrementing = branchConfiguration.CommitMessageIncrementing; IsDevelop = branchConfiguration.IsDevelop; IsReleaseBranch = branchConfiguration.IsReleaseBranch; }
/// <summary> /// Creates a clone of the given <paramref name="branchConfiguration"/>. /// </summary> public BranchConfig(BranchConfig branchConfiguration) { VersioningMode = branchConfiguration.VersioningMode; Tag = branchConfiguration.Tag; Increment = branchConfiguration.Increment; PreventIncrementOfMergedBranchVersion = branchConfiguration.PreventIncrementOfMergedBranchVersion; TagNumberPattern = branchConfiguration.TagNumberPattern; TrackMergeTarget = branchConfiguration.TrackMergeTarget; CommitMessageIncrementing = branchConfiguration.CommitMessageIncrementing; TracksReleaseBranches = branchConfiguration.TracksReleaseBranches; Regex = branchConfiguration.Regex; IsReleaseBranch = branchConfiguration.IsReleaseBranch; IsMainline = branchConfiguration.IsMainline; Name = branchConfiguration.Name; }
public static void ApplyBranchDefaults(Config config, BranchConfig branchConfig, string defaultTag = "useBranchName", IncrementStrategy defaultIncrementStrategy = IncrementStrategy.Patch, bool defaultPreventIncrement = false, VersioningMode? defaultVersioningMode = null, // Looked up from main config bool defaultTrackMergeTarget = false, string defaultTagNumberPattern = null) { branchConfig.Tag = branchConfig.Tag ?? defaultTag; branchConfig.TagNumberPattern = branchConfig.TagNumberPattern ?? defaultTagNumberPattern; branchConfig.Increment = branchConfig.Increment ?? defaultIncrementStrategy; branchConfig.PreventIncrementOfMergedBranchVersion = branchConfig.PreventIncrementOfMergedBranchVersion ?? defaultPreventIncrement; branchConfig.TrackMergeTarget = branchConfig.TrackMergeTarget ?? defaultTrackMergeTarget; branchConfig.VersioningMode = branchConfig.VersioningMode ?? defaultVersioningMode ?? config.VersioningMode; }
public static void ApplyBranchDefaults(Config config, BranchConfig branchConfig, string branchRegex, string defaultTag = "useBranchName", IncrementStrategy? defaultIncrementStrategy = null, // Looked up from main config bool defaultPreventIncrement = false, VersioningMode? defaultVersioningMode = null, // Looked up from main config bool defaultTrackMergeTarget = false, string defaultTagNumberPattern = null, bool tracksReleaseBranches = false, bool isReleaseBranch = false, bool isMainline = false) { branchConfig.Regex = string.IsNullOrEmpty(branchConfig.Regex) ? branchRegex : branchConfig.Regex; branchConfig.Tag = branchConfig.Tag ?? defaultTag; branchConfig.TagNumberPattern = branchConfig.TagNumberPattern ?? defaultTagNumberPattern; branchConfig.Increment = branchConfig.Increment ?? defaultIncrementStrategy ?? config.Increment ?? DefaultIncrementStrategy; branchConfig.PreventIncrementOfMergedBranchVersion = branchConfig.PreventIncrementOfMergedBranchVersion ?? defaultPreventIncrement; branchConfig.TrackMergeTarget = branchConfig.TrackMergeTarget ?? defaultTrackMergeTarget; branchConfig.VersioningMode = branchConfig.VersioningMode ?? defaultVersioningMode ?? config.VersioningMode; branchConfig.TracksReleaseBranches = branchConfig.TracksReleaseBranches ?? tracksReleaseBranches; branchConfig.IsReleaseBranch = branchConfig.IsReleaseBranch ?? isReleaseBranch; branchConfig.IsMainline = branchConfig.IsMainline ?? isMainline; }
static BranchConfig GetOrCreateBranchDefaults(Config config, string branch) { if (!config.Branches.ContainsKey(branch)) { var branchConfig = new BranchConfig(); config.Branches.Add(branch, branchConfig); return branchConfig; } return config.Branches[branch]; }
public SetBranchTag(string name, BranchConfig branchConfig) { this.name = name; this.branchConfig = branchConfig; }
static BranchConfig InheritBranchConfiguration(GitVersionContext context, Branch targetBranch, BranchConfig branchConfiguration, IList <Branch> excludedInheritBranches) { var repository = context.Repository; var config = context.FullConfiguration; using (Logger.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 = context.CurrentCommit.Parents.Count(); if (parentCount == 2) { excludedBranches = CalculateWhenMultipleParents(repository, context.CurrentCommit, ref targetBranch, excludedBranches); } if (excludedInheritBranches == null) { excludedInheritBranches = repository.Branches.Where(b => { var branchConfig = LookupBranchConfiguration(config, b).ToArray(); // NOTE: if length is 0 we couldn't find the configuration for the branch e.g. "origin/master" // NOTE: if the length is greater than 1 we cannot decide which merge strategy to pick return((branchConfig.Length != 1) || (branchConfig.Length == 1 && branchConfig[0].Increment == IncrementStrategy.Inherit)); }).ToList(); } // Add new excluded branches. foreach (var excludedBranch in excludedBranches.ExcludingBranches(excludedInheritBranches)) { excludedInheritBranches.Add(excludedBranch); } var branchesToEvaluate = repository.Branches.Except(excludedInheritBranches).ToList(); var branchPoint = context.RepositoryMetadataProvider .FindCommitBranchWasBranchedFrom(targetBranch, excludedInheritBranches.ToArray()); List <Branch> possibleParents; if (branchPoint == BranchCommit.Empty) { possibleParents = context.RepositoryMetadataProvider.GetBranchesContainingCommit(context.CurrentCommit, branchesToEvaluate, true) // 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 = context.RepositoryMetadataProvider .GetBranchesContainingCommit(branchPoint.Commit, branchesToEvaluate, true).ToList(); if (branches.Count > 1) { var currentTipBranches = context.RepositoryMetadataProvider .GetBranchesContainingCommit(context.CurrentCommit, branchesToEvaluate, true).ToList(); possibleParents = branches.Except(currentTipBranches).ToList(); } else { possibleParents = branches; } } Logger.WriteInfo("Found possible parent branches: " + string.Join(", ", possibleParents.Select(p => p.FriendlyName))); if (possibleParents.Count == 1) { var branchConfig = GetBranchConfiguration(context, possibleParents[0], excludedInheritBranches); 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 string errorMessage; if (possibleParents.Count == 0) { errorMessage = "Failed to inherit Increment branch configuration, no branches found."; } else { errorMessage = "Failed to inherit Increment branch configuration, ended up with: " + string.Join(", ", possibleParents.Select(p => p.FriendlyName)); } var chosenBranch = repository.Branches.FirstOrDefault(b => Regex.IsMatch(b.FriendlyName, "^develop", RegexOptions.IgnoreCase) || Regex.IsMatch(b.FriendlyName, "master$", RegexOptions.IgnoreCase)); 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."); } var branchName = chosenBranch.FriendlyName; Logger.WriteWarning(errorMessage + Environment.NewLine + Environment.NewLine + "Falling back to " + branchName + " branch config"); // To prevent infinite loops, make sure that a new branch was chosen. if (targetBranch.IsSameBranch(chosenBranch)) { Logger.WriteWarning("Fallback branch wants to inherit Increment branch configuration from itself. Using patch increment instead."); return(new BranchConfig(branchConfiguration) { Increment = IncrementStrategy.Patch }); } var inheritingBranchConfig = GetBranchConfiguration(context, chosenBranch, excludedInheritBranches); return(new BranchConfig(branchConfiguration) { Increment = inheritingBranchConfig.Increment, PreventIncrementOfMergedBranchVersion = inheritingBranchConfig.PreventIncrementOfMergedBranchVersion, // If we are inheriting from develop then we should behave like develop TracksReleaseBranches = inheritingBranchConfig.TracksReleaseBranches }); } }
static KeyValuePair<string, BranchConfig> InheritBranchConfiguration(bool onlyEvaluateTrackedBranches, IRepository repository, Commit currentCommit, Branch currentBranch, KeyValuePair<string, BranchConfig> keyValuePair, BranchConfig branchConfiguration, Config config, IList<Branch> excludedInheritBranches) { using (Logger.IndentLog("Attempting to inherit branch configuration from parent branch")) { var excludedBranches = new[] { currentBranch }; // Check if we are a merge commit. If so likely we are a pull request var parentCount = currentCommit.Parents.Count(); if (parentCount == 2) { var parents = currentCommit.Parents.ToArray(); var branch = repository.Branches.SingleOrDefault(b => !b.IsRemote && b.Tip == parents[1]); if (branch != null) { excludedBranches = new[] { currentBranch, branch }; currentBranch = branch; } else { var possibleTargetBranches = repository.Branches.Where(b => !b.IsRemote && b.Tip == parents[0]).ToList(); if (possibleTargetBranches.Count() > 1) { currentBranch = possibleTargetBranches.FirstOrDefault(b => b.Name == "master") ?? possibleTargetBranches.First(); } else { currentBranch = possibleTargetBranches.FirstOrDefault() ?? currentBranch; } } Logger.WriteInfo("HEAD is merge commit, this is likely a pull request using " + currentBranch.Name + " as base"); } if (excludedInheritBranches == null) { excludedInheritBranches = repository.Branches.Where(b => { var branchConfig = LookupBranchConfiguration(config, b); return branchConfig.Length == 1 && branchConfig[0].Value.Increment == IncrementStrategy.Inherit; }).ToList(); } excludedBranches.ToList().ForEach(excludedInheritBranches.Add); var branchPoint = currentBranch.FindCommitBranchWasBranchedFrom(repository, excludedInheritBranches.ToArray()); List<Branch> possibleParents; if (branchPoint == null) { possibleParents = currentCommit.GetBranchesContainingCommit(repository, true).Except(excludedInheritBranches).ToList(); } else { var branches = branchPoint.GetBranchesContainingCommit(repository, true).Except(excludedInheritBranches).ToList(); if (branches.Count > 1) { var currentTipBranches = currentCommit.GetBranchesContainingCommit(repository, true).Except(excludedInheritBranches).ToList(); possibleParents = branches.Except(currentTipBranches).ToList(); } else { possibleParents = branches; } } Logger.WriteInfo("Found possible parent branches: " + string.Join(", ", possibleParents.Select(p => p.Name))); if (possibleParents.Count == 1) { var branchConfig = GetBranchConfiguration(currentCommit, repository, onlyEvaluateTrackedBranches, config, possibleParents[0], excludedInheritBranches).Value; return new KeyValuePair<string, BranchConfig>( keyValuePair.Key, new BranchConfig(branchConfiguration) { Increment = branchConfig.Increment, PreventIncrementOfMergedBranchVersion = branchConfig.PreventIncrementOfMergedBranchVersion }); } // 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 string errorMessage; if (possibleParents.Count == 0) errorMessage = "Failed to inherit Increment branch configuration, no branches found."; else errorMessage = "Failed to inherit Increment branch configuration, ended up with: " + string.Join(", ", possibleParents.Select(p => p.Name)); var developBranch = repository.Branches.FirstOrDefault(b => Regex.IsMatch(b.Name, "^develop", RegexOptions.IgnoreCase)); var branchName = developBranch != null ? developBranch.Name : "master"; Logger.WriteWarning(errorMessage + Environment.NewLine + Environment.NewLine + "Falling back to " + branchName + " branch config"); var value = GetBranchConfiguration(currentCommit, repository, onlyEvaluateTrackedBranches, config, repository.Branches[branchName]).Value; return new KeyValuePair<string, BranchConfig>( keyValuePair.Key, new BranchConfig(branchConfiguration) { Increment = value.Increment, PreventIncrementOfMergedBranchVersion = value.PreventIncrementOfMergedBranchVersion }); } }
static BranchConfig GetOrCreateBranchDefaults(Config config, string branchKey) { if (!config.Branches.ContainsKey(branchKey)) { var branchConfig = new BranchConfig {Name = branchKey}; config.Branches.Add(branchKey, branchConfig); return branchConfig; } return config.Branches[branchKey]; }
static KeyValuePair <string, BranchConfig> InheritBranchConfiguration(bool onlyEvaluateTrackedBranches, IRepository repository, Commit currentCommit, Branch currentBranch, KeyValuePair <string, BranchConfig> keyValuePair, BranchConfig branchConfiguration, Config config, IList <Branch> excludedInheritBranches) { Logger.WriteInfo("Attempting to inherit branch configuration from parent branch"); var excludedBranches = new [] { currentBranch }; // Check if we are a merge commit. If so likely we are a pull request var parentCount = currentCommit.Parents.Count(); if (parentCount == 2) { var parents = currentCommit.Parents.ToArray(); var branch = repository.Branches.SingleOrDefault(b => !b.IsRemote && b.Tip == parents[1]); if (branch != null) { excludedBranches = new[] { currentBranch, branch }; currentBranch = branch; } else { var possibleTargetBranches = repository.Branches.Where(b => !b.IsRemote && b.Tip == parents[0]).ToList(); if (possibleTargetBranches.Count() > 1) { currentBranch = possibleTargetBranches.FirstOrDefault(b => b.Name == "master") ?? possibleTargetBranches.First(); } else { currentBranch = possibleTargetBranches.FirstOrDefault() ?? currentBranch; } } Logger.WriteInfo("HEAD is merge commit, this is likely a pull request using " + currentBranch.Name + " as base"); } if (excludedInheritBranches == null) { excludedInheritBranches = repository.Branches.Where(b => { var branchConfig = LookupBranchConfiguration(config, b); return(branchConfig.Length == 1 && branchConfig[0].Value.Increment == IncrementStrategy.Inherit); }).ToList(); } excludedBranches.ToList().ForEach(excludedInheritBranches.Add); var branchPoint = currentBranch.FindCommitBranchWasBranchedFrom(repository, excludedInheritBranches.ToArray()); List <Branch> possibleParents; if (branchPoint == null) { possibleParents = currentCommit.GetBranchesContainingCommit(repository, true).Except(excludedInheritBranches).ToList(); } else { var branches = branchPoint.GetBranchesContainingCommit(repository, true).Except(excludedInheritBranches).ToList(); if (branches.Count > 1) { var currentTipBranches = currentCommit.GetBranchesContainingCommit(repository, true).Except(excludedInheritBranches).ToList(); possibleParents = branches.Except(currentTipBranches).ToList(); } else { possibleParents = branches; } } Logger.WriteInfo("Found possible parent branches: " + string.Join(", ", possibleParents.Select(p => p.Name))); if (possibleParents.Count == 1) { var branchConfig = GetBranchConfiguration(currentCommit, repository, onlyEvaluateTrackedBranches, config, possibleParents[0], excludedInheritBranches).Value; return(new KeyValuePair <string, BranchConfig>( keyValuePair.Key, new BranchConfig(branchConfiguration) { Increment = branchConfig.Increment, PreventIncrementOfMergedBranchVersion = branchConfig.PreventIncrementOfMergedBranchVersion })); } // 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 string errorMessage; if (possibleParents.Count == 0) { errorMessage = "Failed to inherit Increment branch configuration, no branches found."; } else { errorMessage = "Failed to inherit Increment branch configuration, ended up with: " + string.Join(", ", possibleParents.Select(p => p.Name)); } var developBranch = repository.Branches.FirstOrDefault(b => Regex.IsMatch(b.Name, "^develop", RegexOptions.IgnoreCase)); var branchName = developBranch != null ? developBranch.Name : "master"; Logger.WriteWarning(errorMessage + Environment.NewLine + Environment.NewLine + "Falling back to " + branchName + " branch config"); var value = GetBranchConfiguration(currentCommit, repository, onlyEvaluateTrackedBranches, config, repository.Branches[branchName]).Value; return(new KeyValuePair <string, BranchConfig>( keyValuePair.Key, new BranchConfig(branchConfiguration) { Increment = value.Increment, PreventIncrementOfMergedBranchVersion = value.PreventIncrementOfMergedBranchVersion })); }
static KeyValuePair<string, BranchConfig> InheritBranchConfiguration( bool onlyEvaluateTrackedBranches, IRepository repository, Commit currentCommit, Branch currentBranch, KeyValuePair<string, BranchConfig> keyValuePair, BranchConfig branchConfiguration, Config config) { Logger.WriteInfo("Attempting to inherit branch configuration from parent branch"); var excludedBranches = new [] { currentBranch }; // Check if we are a merge commit. If so likely we are a pull request var parentCount = currentCommit.Parents.Count(); if (parentCount == 2) { var parents = currentCommit.Parents.ToArray(); var branch = repository.Branches.SingleOrDefault(b => !b.IsRemote && b.Tip == parents[1]); if (branch != null) { excludedBranches = new[] { currentBranch, branch }; currentBranch = branch; } else { currentBranch = repository.Branches.SingleOrDefault(b => !b.IsRemote && b.Tip == parents[0]) ?? currentBranch; } Logger.WriteInfo("HEAD is merge commit, this is likely a pull request using " + currentBranch.Name + " as base"); } var branchPoint = currentBranch.FindCommitBranchWasBranchedFrom(repository, onlyEvaluateTrackedBranches, excludedBranches); List<Branch> possibleParents; if (branchPoint.Sha == currentCommit.Sha) { possibleParents = currentCommit.GetBranchesContainingCommit(repository, true).Except(excludedBranches).ToList(); } else { var branches = branchPoint.GetBranchesContainingCommit(repository, true).Except(excludedBranches).ToList(); var currentTipBranches = currentCommit.GetBranchesContainingCommit(repository, true).Except(excludedBranches).ToList(); possibleParents = branches .Except(currentTipBranches) .ToList(); } Logger.WriteInfo("Found possible parent branches: " + string.Join(", ", possibleParents.Select(p => p.Name))); // If it comes down to master and something, master is always first so we pick other branch if (possibleParents.Count == 2 && possibleParents.Any(p => p.Name == "master")) { possibleParents.Remove(possibleParents.Single(p => p.Name == "master")); } if (possibleParents.Count == 1) { var branchConfig = GetBranchConfiguration(currentCommit, repository, onlyEvaluateTrackedBranches, config, possibleParents[0]).Value; return new KeyValuePair<string, BranchConfig>( keyValuePair.Key, new BranchConfig(branchConfiguration) { Increment = branchConfig.Increment, PreventIncrementOfMergedBranchVersion = branchConfig.PreventIncrementOfMergedBranchVersion }); } // 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 string errorMessage; if (possibleParents.Count == 0) errorMessage = "Failed to inherit Increment branch configuration, no branches found."; else errorMessage = "Failed to inherit Increment branch configuration, ended up with: " + string.Join(", ", possibleParents.Select(p => p.Name)); var hasDevelop = repository.FindBranch("develop") != null; var branchName = hasDevelop ? "develop" : "master"; Logger.WriteWarning(errorMessage + Environment.NewLine + Environment.NewLine + "Falling back to " + branchName + " branch config"); var value = GetBranchConfiguration(currentCommit, repository, onlyEvaluateTrackedBranches, config, repository.Branches[branchName]).Value; return new KeyValuePair<string, BranchConfig>( keyValuePair.Key, new BranchConfig(branchConfiguration) { Increment = value.Increment, PreventIncrementOfMergedBranchVersion = value.PreventIncrementOfMergedBranchVersion }); }
public ConfigureBranch(string name, BranchConfig branchConfig) { this.branchConfig = branchConfig; this.name = name; }
static KeyValuePair <string, BranchConfig> InheritBranchConfiguration(bool onlyEvaluateTrackedBranches, IRepository repository, Commit currentCommit, Branch currentBranch, KeyValuePair <string, BranchConfig> keyValuePair, BranchConfig branchConfiguration, Config config, IList <Branch> excludedInheritBranches) { using (Logger.IndentLog("Attempting to inherit branch configuration from parent branch")) { var excludedBranches = new[] { currentBranch }; // 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(repository, currentCommit, ref currentBranch, excludedBranches); } if (excludedInheritBranches == null) { excludedInheritBranches = repository.Branches.Where(b => { var branchConfig = LookupBranchConfiguration(config, b); // NOTE: if length is 0 we couldn't find the configuration for the branch e.g. "origin/master" // NOTE: if the length is greater than 1 we cannot decide which merge strategy to pick return((branchConfig.Length != 1) || (branchConfig.Length == 1 && branchConfig[0].Value.Increment == IncrementStrategy.Inherit)); }).ToList(); } excludedBranches.ToList().ForEach(excludedInheritBranches.Add); var branchesToEvaluate = repository.Branches.Except(excludedInheritBranches).ToList(); var branchPoint = currentBranch.FindCommitBranchWasBranchedFrom(repository, excludedInheritBranches.ToArray()); List <Branch> possibleParents; if (branchPoint == null) { possibleParents = currentCommit.GetBranchesContainingCommit(repository, branchesToEvaluate, true).ToList(); } else { var branches = branchPoint.GetBranchesContainingCommit(repository, branchesToEvaluate, true).ToList(); if (branches.Count > 1) { var currentTipBranches = currentCommit.GetBranchesContainingCommit(repository, branchesToEvaluate, true).ToList(); possibleParents = branches.Except(currentTipBranches).ToList(); } else { possibleParents = branches; } } Logger.WriteInfo("Found possible parent branches: " + string.Join(", ", possibleParents.Select(p => p.Name))); if (possibleParents.Count == 1) { var branchConfig = GetBranchConfiguration(currentCommit, repository, onlyEvaluateTrackedBranches, config, possibleParents[0], excludedInheritBranches).Value; return(new KeyValuePair <string, BranchConfig>( keyValuePair.Key, new BranchConfig(branchConfiguration) { Increment = branchConfig.Increment, PreventIncrementOfMergedBranchVersion = branchConfig.PreventIncrementOfMergedBranchVersion })); } // 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 string errorMessage; if (possibleParents.Count == 0) { errorMessage = "Failed to inherit Increment branch configuration, no branches found."; } else { errorMessage = "Failed to inherit Increment branch configuration, ended up with: " + string.Join(", ", possibleParents.Select(p => p.Name)); } var chosenBranch = repository.Branches.FirstOrDefault(b => Regex.IsMatch(b.Name, "^develop", RegexOptions.IgnoreCase) || Regex.IsMatch(b.Name, "master$", RegexOptions.IgnoreCase)); if (chosenBranch == null) { throw new InvalidOperationException("Could not find a 'develop' or 'master' branch, neither locally nor remotely."); } var branchName = chosenBranch.Name; Logger.WriteWarning(errorMessage + Environment.NewLine + Environment.NewLine + "Falling back to " + branchName + " branch config"); var value = GetBranchConfiguration(currentCommit, repository, onlyEvaluateTrackedBranches, config, chosenBranch).Value; return(new KeyValuePair <string, BranchConfig>( keyValuePair.Key, new BranchConfig(branchConfiguration) { Increment = value.Increment, PreventIncrementOfMergedBranchVersion = value.PreventIncrementOfMergedBranchVersion })); } }
static KeyValuePair <string, BranchConfig> InheritBranchConfiguration( bool onlyEvaluateTrackedBranches, IRepository repository, Commit currentCommit, Branch currentBranch, KeyValuePair <string, BranchConfig> keyValuePair, BranchConfig branchConfiguration, Config config) { Logger.WriteInfo("Attempting to inherit branch configuration from parent branch"); var excludedBranches = new [] { currentBranch }; // Check if we are a merge commit. If so likely we are a pull request var parentCount = currentCommit.Parents.Count(); if (parentCount == 2) { var parents = currentCommit.Parents.ToArray(); var branch = repository.Branches.SingleOrDefault(b => !b.IsRemote && b.Tip == parents[1]); if (branch != null) { excludedBranches = new[] { currentBranch, branch }; currentBranch = branch; } else { currentBranch = repository.Branches.SingleOrDefault(b => !b.IsRemote && b.Tip == parents[0]) ?? currentBranch; } Logger.WriteInfo("HEAD is merge commit, this is likely a pull request using " + currentBranch.Name + " as base"); } var branchPoint = currentBranch.FindCommitBranchWasBranchedFrom(repository, onlyEvaluateTrackedBranches, excludedBranches); List <Branch> possibleParents; if (branchPoint.Sha == currentCommit.Sha) { possibleParents = currentCommit.GetBranchesContainingCommit(repository, true).Except(excludedBranches).ToList(); } else { var branches = branchPoint.GetBranchesContainingCommit(repository, true).Except(excludedBranches).ToList(); var currentTipBranches = currentCommit.GetBranchesContainingCommit(repository, true).Except(excludedBranches).ToList(); possibleParents = branches .Except(currentTipBranches) .ToList(); } Logger.WriteInfo("Found possible parent branches: " + string.Join(", ", possibleParents.Select(p => p.Name))); // If it comes down to master and something, master is always first so we pick other branch if (possibleParents.Count == 2 && possibleParents.Any(p => p.Name == "master")) { possibleParents.Remove(possibleParents.Single(p => p.Name == "master")); } if (possibleParents.Count == 1) { var branchConfig = GetBranchConfiguration(currentCommit, repository, onlyEvaluateTrackedBranches, config, possibleParents[0]).Value; return(new KeyValuePair <string, BranchConfig>( keyValuePair.Key, new BranchConfig(branchConfiguration) { Increment = branchConfig.Increment, PreventIncrementOfMergedBranchVersion = branchConfig.PreventIncrementOfMergedBranchVersion })); } // 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 string errorMessage; if (possibleParents.Count == 0) { errorMessage = "Failed to inherit Increment branch configuration, no branches found."; } else { errorMessage = "Failed to inherit Increment branch configuration, ended up with: " + string.Join(", ", possibleParents.Select(p => p.Name)); } var hasDevelop = repository.FindBranch("develop") != null; var branchName = hasDevelop ? "develop" : "master"; Logger.WriteWarning(errorMessage + Environment.NewLine + Environment.NewLine + "Falling back to " + branchName + " branch config"); var value = GetBranchConfiguration(currentCommit, repository, onlyEvaluateTrackedBranches, config, repository.Branches[branchName]).Value; return(new KeyValuePair <string, BranchConfig>( keyValuePair.Key, new BranchConfig(branchConfiguration) { Increment = value.Increment, PreventIncrementOfMergedBranchVersion = value.PreventIncrementOfMergedBranchVersion })); }
static KeyValuePair<string, BranchConfig> InheritBranchConfiguration(bool onlyEvaluateTrackedBranches, IRepository repository, Commit currentCommit, Branch currentBranch, KeyValuePair<string, BranchConfig> keyValuePair, BranchConfig branchConfiguration, Config config, IList<Branch> excludedInheritBranches) { using (Logger.IndentLog("Attempting to inherit branch configuration from parent branch")) { var excludedBranches = new[] { currentBranch }; // 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(repository, currentCommit, ref currentBranch, excludedBranches); } if (excludedInheritBranches == null) { excludedInheritBranches = repository.Branches.Where(b => { var branchConfig = LookupBranchConfiguration(config, b); // NOTE: if length is 0 we couldn't find the configuration for the branch e.g. "origin/master" // NOTE: if the length is greater than 1 we cannot decide which merge strategy to pick return (branchConfig.Length != 1) || (branchConfig.Length == 1 && branchConfig[0].Value.Increment == IncrementStrategy.Inherit); }).ToList(); } excludedBranches.ToList().ForEach(excludedInheritBranches.Add); var branchesToEvaluate = repository.Branches.Except(excludedInheritBranches).ToList(); var branchPoint = currentBranch.FindCommitBranchWasBranchedFrom(repository, excludedInheritBranches.ToArray()); List<Branch> possibleParents; if (branchPoint == null) { possibleParents = currentCommit.GetBranchesContainingCommit(repository, branchesToEvaluate, true).ToList(); } else { var branches = branchPoint.GetBranchesContainingCommit(repository, branchesToEvaluate, true).ToList(); if (branches.Count > 1) { var currentTipBranches = currentCommit.GetBranchesContainingCommit(repository, branchesToEvaluate, true).ToList(); possibleParents = branches.Except(currentTipBranches).ToList(); } else { possibleParents = branches; } } Logger.WriteInfo("Found possible parent branches: " + string.Join(", ", possibleParents.Select(p => p.Name))); if (possibleParents.Count == 1) { var branchConfig = GetBranchConfiguration(currentCommit, repository, onlyEvaluateTrackedBranches, config, possibleParents[0], excludedInheritBranches).Value; return new KeyValuePair<string, BranchConfig>( keyValuePair.Key, new BranchConfig(branchConfiguration) { Increment = branchConfig.Increment, PreventIncrementOfMergedBranchVersion = branchConfig.PreventIncrementOfMergedBranchVersion }); } // 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 string errorMessage; if (possibleParents.Count == 0) errorMessage = "Failed to inherit Increment branch configuration, no branches found."; else errorMessage = "Failed to inherit Increment branch configuration, ended up with: " + string.Join(", ", possibleParents.Select(p => p.Name)); var chosenBranch = repository.Branches.FirstOrDefault(b => Regex.IsMatch(b.Name, "^develop", RegexOptions.IgnoreCase) || Regex.IsMatch(b.Name, "master$", RegexOptions.IgnoreCase)); if (chosenBranch == null) throw new InvalidOperationException("Could not find a 'develop' or 'master' branch, neither locally nor remotely."); var branchName = chosenBranch.Name; Logger.WriteWarning(errorMessage + Environment.NewLine + Environment.NewLine + "Falling back to " + branchName + " branch config"); var value = GetBranchConfiguration(currentCommit, repository, onlyEvaluateTrackedBranches, config, chosenBranch).Value; return new KeyValuePair<string, BranchConfig>( keyValuePair.Key, new BranchConfig(branchConfiguration) { Increment = value.Increment, PreventIncrementOfMergedBranchVersion = value.PreventIncrementOfMergedBranchVersion }); } }
static BranchConfig InheritBranchConfiguration(GitVersionContext context, Branch targetBranch, BranchConfig branchConfiguration, IList<Branch> excludedInheritBranches) { var repository = context.Repository; var config = context.FullConfiguration; using (Logger.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 = context.CurrentCommit.Parents.Count(); if (parentCount == 2) { excludedBranches = CalculateWhenMultipleParents(repository, context.CurrentCommit, ref targetBranch, excludedBranches); } if (excludedInheritBranches == null) { excludedInheritBranches = repository.Branches.Where(b => { var branchConfig = LookupBranchConfiguration(config, b).ToArray(); // NOTE: if length is 0 we couldn't find the configuration for the branch e.g. "origin/master" // NOTE: if the length is greater than 1 we cannot decide which merge strategy to pick return (branchConfig.Length != 1) || (branchConfig.Length == 1 && branchConfig[0].Increment == IncrementStrategy.Inherit); }).ToList(); } // Add new excluded branches. foreach (var excludedBranch in excludedBranches.ExcludingBranches(excludedInheritBranches)) { excludedInheritBranches.Add(excludedBranch); } var branchesToEvaluate = repository.Branches.Except(excludedInheritBranches).ToList(); var branchPoint = context.RepositoryMetadataProvider .FindCommitBranchWasBranchedFrom(targetBranch, excludedInheritBranches.ToArray()); List<Branch> possibleParents; if (branchPoint == BranchCommit.Empty) { possibleParents = context.RepositoryMetadataProvider.GetBranchesContainingCommit(context.CurrentCommit, branchesToEvaluate, true) // 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 = context.RepositoryMetadataProvider .GetBranchesContainingCommit(branchPoint.Commit, branchesToEvaluate, true).ToList(); if (branches.Count > 1) { var currentTipBranches = context.RepositoryMetadataProvider .GetBranchesContainingCommit(context.CurrentCommit, branchesToEvaluate, true).ToList(); possibleParents = branches.Except(currentTipBranches).ToList(); } else { possibleParents = branches; } } Logger.WriteInfo("Found possible parent branches: " + string.Join(", ", possibleParents.Select(p => p.FriendlyName))); if (possibleParents.Count == 1) { var branchConfig = GetBranchConfiguration(context, possibleParents[0], excludedInheritBranches); 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 string errorMessage; if (possibleParents.Count == 0) errorMessage = "Failed to inherit Increment branch configuration, no branches found."; else errorMessage = "Failed to inherit Increment branch configuration, ended up with: " + string.Join(", ", possibleParents.Select(p => p.FriendlyName)); var chosenBranch = repository.Branches.FirstOrDefault(b => Regex.IsMatch(b.FriendlyName, "^develop", RegexOptions.IgnoreCase) || Regex.IsMatch(b.FriendlyName, "master$", RegexOptions.IgnoreCase)); 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."); } var branchName = chosenBranch.FriendlyName; Logger.WriteWarning(errorMessage + Environment.NewLine + Environment.NewLine + "Falling back to " + branchName + " branch config"); // To prevent infinite loops, make sure that a new branch was chosen. if (targetBranch.IsSameBranch(chosenBranch)) { Logger.WriteWarning("Fallback branch wants to inherit Increment branch configuration from itself. Using patch increment instead."); return new BranchConfig(branchConfiguration) { Increment = IncrementStrategy.Patch }; } var inheritingBranchConfig = GetBranchConfiguration(context, chosenBranch, excludedInheritBranches); return new BranchConfig(branchConfiguration) { Increment = inheritingBranchConfig.Increment, PreventIncrementOfMergedBranchVersion = inheritingBranchConfig.PreventIncrementOfMergedBranchVersion, // If we are inheriting from develop then we should behave like develop TracksReleaseBranches = inheritingBranchConfig.TracksReleaseBranches }; } }