diff --git a/src/Models/CommitGraph.cs b/src/Models/CommitGraph.cs index 8557f271d..f2c821c36 100644 --- a/src/Models/CommitGraph.cs +++ b/src/Models/CommitGraph.cs @@ -13,6 +13,7 @@ public enum CommitGraphHighlighting All = 0, CurrentBranchOnly, SelectedCommitsOnly, + SelectedCommitsOnlyFirstParent, CurrentBranchAndSelectedCommits, } @@ -70,7 +71,7 @@ public class Dot public List Links { get; } = []; public List Dots { get; } = []; - public static CommitGraph Generate(List commits, bool recalculateMergeState, bool firstParentOnlyEnabled, CommitGraphHighlighting highlighting, HashSet highlightExtraCommits) + public static CommitGraph Generate(List commits, bool firstParentOnlyEnabled, CommitGraphHighlighting highlighting, HashSet highlightExtraCommits) { const double unitWidth = 12; const double halfWidth = 6; @@ -82,29 +83,11 @@ public static CommitGraph Generate(List commits, bool recalculateMergeSt var ended = new List(); var offsetY = -halfHeight; var colorPicker = new ColorPicker(); - var merged = new HashSet(); foreach (var commit in commits) { PathHelper major = null; - // Update merge state of this commit. - if (recalculateMergeState) - { - if (commit.IsMerged) - { - merged.Remove(commit.SHA); - foreach (var p in commit.Parents) - merged.Add(p); - } - else if (merged.Remove(commit.SHA)) - { - commit.IsMerged = true; - foreach (var p in commit.Parents) - merged.Add(p); - } - } - // Update current y offset offsetY += unitHeight; @@ -164,31 +147,23 @@ public static CommitGraph Generate(List commits, bool recalculateMergeSt { isHighlighted = true; } - else if (highlighting == CommitGraphHighlighting.CurrentBranchOnly) + + if (!isHighlighted && + (highlighting == CommitGraphHighlighting.CurrentBranchOnly || + highlighting == CommitGraphHighlighting.CurrentBranchAndSelectedCommits)) { isHighlighted = commit.IsMerged; } - else if (highlighting == CommitGraphHighlighting.SelectedCommitsOnly) + + if (!isHighlighted && + (highlighting == CommitGraphHighlighting.SelectedCommitsOnly || + highlighting == CommitGraphHighlighting.SelectedCommitsOnlyFirstParent || + highlighting == CommitGraphHighlighting.CurrentBranchAndSelectedCommits)) { isHighlighted = highlightExtraCommits.Remove(commit.SHA); - if (isHighlighted) - { - foreach (var p in commit.Parents) - highlightExtraCommits.Add(p); - } - } - else - { - if (commit.IsMerged) - { - isHighlighted = true; - } - else if (highlightExtraCommits.Remove(commit.SHA)) - { - isHighlighted = true; - foreach (var p in commit.Parents) - highlightExtraCommits.Add(p); - } + // Highlight first parent, other parents are dealt with later + if (isHighlighted && commit.Parents.Count > 0) + highlightExtraCommits.Add(commit.Parents[0]); } } commit.IsHighlightedInGraph = isHighlighted; @@ -227,6 +202,9 @@ public static CommitGraph Generate(List commits, bool recalculateMergeSt // Deal with other parents (the first parent has been processed) if (!firstParentOnlyEnabled) { + if (highlighting == CommitGraphHighlighting.SelectedCommitsOnlyFirstParent) + isHighlighted = false; + for (int j = 1; j < commit.Parents.Count; j++) { var parentHash = commit.Parents[j]; diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 2d589bbec..6932a0c02 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -518,6 +518,7 @@ Current Branch Only Current Branch & Selected Commits Selected Commits Only + Selected Commits (only first-parent) SELECTED {0} COMMITS SHOW COLUMNS Hold 'Ctrl' or 'Shift' to select multiple commits. diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs index 15cf15748..a4a52e116 100644 --- a/src/ViewModels/Histories.cs +++ b/src/ViewModels/Histories.cs @@ -75,7 +75,8 @@ public List Commits get => _commits; set { - GenerateGraph(value, true); + RecalculateMergeState(value); + GenerateGraph(value); if (SetProperty(ref _commits, value)) PostCommitsChanged(); } @@ -510,7 +511,24 @@ private void PostSelectedCommitsChanged() GenerateGraph(_commits); } - private void GenerateGraph(List commits, bool commitsChanged = false) + private void RecalculateMergeState(List commits) + { + var merged = new HashSet(); + + foreach (var commit in commits) + { + if (merged.Remove(commit.SHA)) + commit.IsMerged = true; + + if (commit.IsMerged) + { + foreach (var p in commit.Parents) + merged.Add(p); + } + } + } + + private void GenerateGraph(List commits) { var firstParentOnly = _repo.UIStates.HistoryShowFlags.HasFlag(Models.HistoryShowFlags.FirstParentOnly); var highlighting = _repo.UIStates.GraphHighlighting; @@ -522,7 +540,7 @@ private void GenerateGraph(List commits, bool commitsChanged = fa extraHeads.Add(c.SHA); } - Graph = Models.CommitGraph.Generate(commits, commitsChanged, firstParentOnly, highlighting, extraHeads); + Graph = Models.CommitGraph.Generate(commits, firstParentOnly, highlighting, extraHeads); } private Repository _repo = null; diff --git a/src/Views/Repository.axaml.cs b/src/Views/Repository.axaml.cs index f5bac41d8..ecee53c52 100644 --- a/src/Views/Repository.axaml.cs +++ b/src/Views/Repository.axaml.cs @@ -487,6 +487,16 @@ private void OnOpenAdvancedHistoriesOption(object sender, RoutedEventArgs e) ev.Handled = true; }; + var selectedCommitsOnlyFirstParent = new MenuItem(); + selectedCommitsOnlyFirstParent.Header = App.Text("Histories.HighlightsInGraph.SelectedCommitsOnlyFirstParent"); + if (histories.GraphHighlighting == Models.CommitGraphHighlighting.SelectedCommitsOnlyFirstParent) + selectedCommitsOnlyFirstParent.Icon = this.CreateMenuIcon("Icons.Check"); + selectedCommitsOnlyFirstParent.Click += (_, ev) => + { + histories.GraphHighlighting = Models.CommitGraphHighlighting.SelectedCommitsOnlyFirstParent; + ev.Handled = true; + }; + var currentBranchAndSelectedCommits = new MenuItem(); currentBranchAndSelectedCommits.Header = App.Text("Histories.HighlightsInGraph.CurrentBranchAndSelectedCommits"); if (histories.GraphHighlighting == Models.CommitGraphHighlighting.CurrentBranchAndSelectedCommits) @@ -516,6 +526,7 @@ private void OnOpenAdvancedHistoriesOption(object sender, RoutedEventArgs e) menu.Items.Add(all); menu.Items.Add(currentBranchOnly); menu.Items.Add(selectedCommitsOnly); + menu.Items.Add(selectedCommitsOnlyFirstParent); menu.Items.Add(currentBranchAndSelectedCommits); menu.Open(button); }