private void ShowMergeBranchHelper(bool fromMenu) { var branchesList = TypicalMergeBranchesWithOrigin .Where(branch => WorkBranches.Any(b => b.StartsWith(branch, StringComparison.OrdinalIgnoreCase))) .Select(branch => branch + "*") .ToList(); if (branchesList.Count == 0) { if (fromMenu) { Utils.ShowMessage("There are no branches in the Work list that we would consider as belonging in the Merge list.\r\nIf you want to make changes, you can use the Right-Click Popup menu from each list or selecting a branch + Ctrl/Arrow keys to move branches between lists."); } } else { var introText = WorkBranches.Count > 0 && MergeBranches.Count == 0 ? "This project is new for WhatsMerged. Please select how you want to treat the branches that it contains.\r\n" + "We recognized some popular branch names, please tell us if these are Merge branches or not.\r\n\r\n" : ""; introText += "What we call Work branches (the left list) is where you implement your changes and fixes.\r\n" + "What we call Merge branches (the middle list) is where those changes are then merged, typically using PRs.\r\n\r\n" + "Note: these settings are stored in '" + Path.Combine(UserHomePath, UserSettingsFilename) + "'.\r\n\r\n" + "Please check/uncheck which groups of branches to set as Merge branches, with * meaning a wildcard that matches all text:"; var frm = new CheckboxListForm { Intro = introText, Items = branchesList, StartPosition = FormStartPosition.CenterParent }; frm.ShowDialog(this); if (frm.Items.Count > 0) { branchesList.Clear(); for (var i = 0; i < frm.Items.Count; i++) { var branch = frm.Items[i].RemoveAtEnd("*"); branchesList.AddRange(WorkBranches.Where(b => b.StartsWith(branch))); } WorkBranches.RemoveRange(branchesList); MergeBranches.AddRange(branchesList); WMEngine.SortByCommitDate(MergeBranches); // Workbranches always gets sorted on load, so no need to do that again. lstMergeBranches.SelectedIndex = -1; SaveUserSettings(); } } }
private void ShowMergeStatusInGrid(string title, bool fromWork = false, bool fromMerge = false, bool toWork = false, bool toMerge = false) { Status($"Gathering data for {title} overview..."); SetEnabled(busy: true); try { ClearError(); ClearGrid(); if ((fromWork || toWork) && WorkBranches.IsNullOrEmpty()) { ShowError($"{title}: {lblWorkBranches.Text} list is empty."); return; } if ((fromMerge || toMerge) && MergeBranches.IsNullOrEmpty()) { ShowError($"{title}: {lblMergeBranches.Text} list is empty."); return; } var mergeTable = WMEngine.GetMergeTable(title, fromWork, fromMerge, toWork, toMerge); if (HasError() || mergeTable == null) { return; } LoadGrid(mergeTable); StatusAdd("Done."); } catch (Exception ex) { ShowError("Exception: " + ex.Message); StatusAdd("Error occurred."); } finally { SetEnabled(busy: false); } }
/// <summary> /// Produce a MergeTable using branch info from Git, according to the specified from- and to-branches as kept in ProjectSettings. /// </summary> /// <param name="title"></param> /// <param name="fromWork"></param> /// <param name="fromMerge"></param> /// <param name="toWork"></param> /// <param name="toMerge"></param> /// <returns></returns> public MergeTable GetMergeTable(string title, bool fromWork = false, bool fromMerge = false, bool toWork = false, bool toMerge = false) { if (!fromWork && !fromMerge) { Reporter.ShowError("No 'From' collections specified."); return(null); } if (!toWork && !toMerge) { Reporter.ShowError("No 'To' collections specified."); return(null); } var from = fromWork && fromMerge?WorkBranches.Concat(MergeBranches).ToBindingList() : fromWork ? WorkBranches : MergeBranches; var to = toWork && toMerge?SortByCommitDate(WorkBranches.Concat(MergeBranches)).ToBindingList() : toWork ? WorkBranches : MergeBranches; if (from.IsNullOrEmpty() || to.IsNullOrEmpty()) { Reporter.ShowError("Both 'From' and 'To' must have at least 1 branch."); return(null); } var ignore = IgnoreBranches; if (!fromWork) { ignore = ignore.Concat(WorkBranches).ToBindingList(); } if (!fromMerge) { ignore = ignore.Concat(MergeBranches).ToBindingList(); } // Check for each entry in mergeBranches what branches have been merged into it, and which haven't. // The results are shown as grid rows. We make no rows for the branchesToHide, e.g. because these branches are merge // targets (meaning if all is well then no work is done in them), or because they are not of interest (e.g. very old). var merged = new List <string[]>(); var notMerged = new List <string[]>(); for (int i = 0; i < to.Count; i++) { merged.Add(GitGetter.MergedBranches(to[i], ignore, ProjectPath, Reporter)); notMerged.Add(GitGetter.NotMergedBranches(to[i], ignore, ProjectPath, Reporter)); } // Construct a distinct list of all work branches. We start with what we found for the last branch (it will contain the least merged work // branches), and then we proceed back to the first branch (it will contain the most merged work branches). This makes workBranches sorted // more or less from oldest-that-has-been-merged to newest-that-has-been-merged, followed by all branches that have not been merged. var fromBranchesOrderedByMergeStatus = new List <string>(); for (int i = to.Count - 1; i >= 0; i--) { fromBranchesOrderedByMergeStatus.AddRange(merged[i].Where(b => !fromBranchesOrderedByMergeStatus.Contains(b))); } for (int i = to.Count - 1; i >= 0; i--) { fromBranchesOrderedByMergeStatus.AddRange(notMerged[i].Where(b => !fromBranchesOrderedByMergeStatus.Contains(b))); } var table = GetMergeTable(title, to, fromBranchesOrderedByMergeStatus, merged); return(table); }