Skip to content

Commit 09ab27e

Browse files
committed
enhance: improve commit graph highlighting performance
This commit also changes the behaviour of `Selected Commits Only` and `Current Branch & Selected Commits`. Now, if we select a commit which is already highlighted, the graph will not be re-generated. Signed-off-by: leo <longshuang@msn.cn>
1 parent 425b570 commit 09ab27e

3 files changed

Lines changed: 83 additions & 58 deletions

File tree

src/Models/CommitGraph.cs

Lines changed: 49 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public class Dot
7070
public List<Link> Links { get; } = [];
7171
public List<Dot> Dots { get; } = [];
7272

73-
public static CommitGraph Generate(List<Commit> commits, bool firstParentOnlyEnabled, CommitGraphHighlighting highlighting, HashSet<string> highlightExtraCommits)
73+
public static CommitGraph Generate(List<Commit> commits, bool recalculateMergeState, bool firstParentOnlyEnabled, CommitGraphHighlighting highlighting, HashSet<string> highlightExtraCommits)
7474
{
7575
const double unitWidth = 12;
7676
const double halfWidth = 6;
@@ -89,60 +89,29 @@ public static CommitGraph Generate(List<Commit> commits, bool firstParentOnlyEna
8989
PathHelper major = null;
9090

9191
// Update merge state of this commit.
92-
if (commit.IsMerged)
93-
{
94-
merged.Remove(commit.SHA);
95-
foreach (var p in commit.Parents)
96-
merged.Add(p);
97-
}
98-
else if (merged.Remove(commit.SHA))
99-
{
100-
commit.IsMerged = true;
101-
foreach (var p in commit.Parents)
102-
merged.Add(p);
103-
}
104-
105-
// Calculate highlighted state
106-
var isHighlighted = false;
107-
if (highlighting == CommitGraphHighlighting.All)
108-
{
109-
isHighlighted = true;
110-
}
111-
else if (highlighting == CommitGraphHighlighting.CurrentBranchOnly)
112-
{
113-
isHighlighted = commit.IsMerged;
114-
}
115-
else if (highlighting == CommitGraphHighlighting.SelectedCommitsOnly)
116-
{
117-
isHighlighted = highlightExtraCommits.Remove(commit.SHA);
118-
if (isHighlighted)
119-
{
120-
commit.IsHighlightedInGraph = true;
121-
foreach (var p in commit.Parents)
122-
highlightExtraCommits.Add(p);
123-
}
124-
}
125-
else
92+
if (recalculateMergeState)
12693
{
12794
if (commit.IsMerged)
12895
{
129-
isHighlighted = true;
96+
merged.Remove(commit.SHA);
97+
foreach (var p in commit.Parents)
98+
merged.Add(p);
13099
}
131-
else if (highlightExtraCommits.Remove(commit.SHA))
100+
else if (merged.Remove(commit.SHA))
132101
{
133-
isHighlighted = true;
102+
commit.IsMerged = true;
134103
foreach (var p in commit.Parents)
135-
highlightExtraCommits.Add(p);
104+
merged.Add(p);
136105
}
137106
}
138-
commit.IsHighlightedInGraph = isHighlighted;
139107

140108
// Update current y offset
141109
offsetY += unitHeight;
142110

143111
// Find first curves that links to this commit and marks others that links to this commit ended.
144112
var offsetX = 4 - halfWidth;
145113
var maxOffsetOld = unsolved.Count > 0 ? unsolved[^1].LastX : offsetX + unitWidth;
114+
var isHighlighted = false;
146115
foreach (var l in unsolved)
147116
{
148117
if (l.Next.Equals(commit.SHA, StringComparison.Ordinal))
@@ -151,6 +120,7 @@ public static CommitGraph Generate(List<Commit> commits, bool firstParentOnlyEna
151120
{
152121
offsetX += unitWidth;
153122
major = l;
123+
isHighlighted = major.IsHighlighted;
154124

155125
if (commit.Parents.Count > 0)
156126
{
@@ -167,6 +137,9 @@ public static CommitGraph Generate(List<Commit> commits, bool firstParentOnlyEna
167137
{
168138
l.End(major.LastX, offsetY, halfHeight);
169139
ended.Add(l);
140+
141+
if (!isHighlighted && l.IsHighlighted)
142+
isHighlighted = true;
170143
}
171144
}
172145
else
@@ -184,6 +157,42 @@ public static CommitGraph Generate(List<Commit> commits, bool firstParentOnlyEna
184157
}
185158
ended.Clear();
186159

160+
// Calculate highlighted state
161+
if (!isHighlighted)
162+
{
163+
if (highlighting == CommitGraphHighlighting.All)
164+
{
165+
isHighlighted = true;
166+
}
167+
else if (highlighting == CommitGraphHighlighting.CurrentBranchOnly)
168+
{
169+
isHighlighted = commit.IsMerged;
170+
}
171+
else if (highlighting == CommitGraphHighlighting.SelectedCommitsOnly)
172+
{
173+
isHighlighted = highlightExtraCommits.Remove(commit.SHA);
174+
if (isHighlighted)
175+
{
176+
foreach (var p in commit.Parents)
177+
highlightExtraCommits.Add(p);
178+
}
179+
}
180+
else
181+
{
182+
if (commit.IsMerged)
183+
{
184+
isHighlighted = true;
185+
}
186+
else if (highlightExtraCommits.Remove(commit.SHA))
187+
{
188+
isHighlighted = true;
189+
foreach (var p in commit.Parents)
190+
highlightExtraCommits.Add(p);
191+
}
192+
}
193+
}
194+
commit.IsHighlightedInGraph = isHighlighted;
195+
187196
// If no path found, create new curve for branch head
188197
// Otherwise, create new curve for new merged commit
189198
if (major == null)

src/ViewModels/Histories.cs

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ public List<Models.Commit> Commits
6262
get => _commits;
6363
set
6464
{
65+
GenerateGraph(value, true);
6566
if (SetProperty(ref _commits, value))
6667
PostCommitsChanged();
6768
}
@@ -91,7 +92,8 @@ public List<Models.Commit> SelectedCommits
9192
get => _selectedCommits;
9293
set
9394
{
94-
if (SetProperty(ref _selectedCommits, value))
95+
var oldCount = _selectedCommits.Count;
96+
if (SetProperty(ref _selectedCommits, value) && oldCount + value.Count > 0)
9597
PostSelectedCommitsChanged();
9698
}
9799
}
@@ -179,21 +181,6 @@ public void NotifyCurrentBranchChanged()
179181
OnPropertyChanged(nameof(CurrentBranch));
180182
}
181183

182-
public void GenerateGraph(List<Models.Commit> commits)
183-
{
184-
var firstParentOnly = _repo.UIStates.HistoryShowFlags.HasFlag(Models.HistoryShowFlags.FirstParentOnly);
185-
var highlighting = _repo.UIStates.GraphHighlighting;
186-
var extraHeads = new HashSet<string>();
187-
188-
if (highlighting >= Models.CommitGraphHighlighting.SelectedCommitsOnly)
189-
{
190-
foreach (var c in _selectedCommits)
191-
extraHeads.Add(c.SHA);
192-
}
193-
194-
Graph = Models.CommitGraph.Generate(commits, firstParentOnly, highlighting, extraHeads);
195-
}
196-
197184
public Models.BisectState UpdateBisectInfo()
198185
{
199186
var test = Path.Combine(_repo.GitDir, "BISECT_START");
@@ -481,7 +468,37 @@ private void PostSelectedCommitsChanged()
481468
}
482469

483470
if (_repo.UIStates.GraphHighlighting >= Models.CommitGraphHighlighting.SelectedCommitsOnly)
484-
GenerateGraph(_commits);
471+
{
472+
if (_selectedCommits.Count == 0)
473+
{
474+
GenerateGraph(_commits);
475+
return;
476+
}
477+
478+
foreach (var c in _selectedCommits)
479+
{
480+
if (!c.IsHighlightedInGraph)
481+
{
482+
GenerateGraph(_commits);
483+
return;
484+
}
485+
}
486+
}
487+
}
488+
489+
private void GenerateGraph(List<Models.Commit> commits, bool commitsChanged = false)
490+
{
491+
var firstParentOnly = _repo.UIStates.HistoryShowFlags.HasFlag(Models.HistoryShowFlags.FirstParentOnly);
492+
var highlighting = _repo.UIStates.GraphHighlighting;
493+
var extraHeads = new HashSet<string>();
494+
495+
if (highlighting >= Models.CommitGraphHighlighting.SelectedCommitsOnly)
496+
{
497+
foreach (var c in _selectedCommits)
498+
extraHeads.Add(c.SHA);
499+
}
500+
501+
Graph = Models.CommitGraph.Generate(commits, commitsChanged, firstParentOnly, highlighting, extraHeads);
485502
}
486503

487504
private Repository _repo = null;

src/ViewModels/Repository.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1218,7 +1218,6 @@ public void RefreshCommits()
12181218
if (_histories != null)
12191219
{
12201220
_histories.IsLoading = false;
1221-
_histories.GenerateGraph(commits);
12221221
_histories.Commits = commits;
12231222
BisectState = _histories.UpdateBisectInfo();
12241223

0 commit comments

Comments
 (0)