mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-22 20:37:19 -08:00
enhance: only store subject in commits.
It has several advantages: * reduce the memory costed by histories * higher performance while parsing commits * no need to calculate subject every time, which is invoked most frequently to render histories
This commit is contained in:
parent
6426da3289
commit
9e45a8a77d
12 changed files with 67 additions and 65 deletions
19
src/Commands/QueryCommitFullMessage.cs
Normal file
19
src/Commands/QueryCommitFullMessage.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
namespace SourceGit.Commands
|
||||
{
|
||||
public class QueryCommitFullMessage : Command
|
||||
{
|
||||
public QueryCommitFullMessage(string repo, string sha)
|
||||
{
|
||||
WorkingDirectory = repo;
|
||||
Context = repo;
|
||||
Args = $"show --no-show-signature --pretty=format:%B -s {sha}";
|
||||
}
|
||||
|
||||
public string Result()
|
||||
{
|
||||
var rs = ReadToEnd();
|
||||
if (rs.IsSuccess) return rs.StdOut.TrimEnd();
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,11 +7,9 @@ namespace SourceGit.Commands
|
|||
{
|
||||
public QueryCommits(string repo, string limits, bool needFindHead = true)
|
||||
{
|
||||
_endOfBodyToken = $"----- END OF BODY {Guid.NewGuid()} -----";
|
||||
|
||||
WorkingDirectory = repo;
|
||||
Context = repo;
|
||||
Args = $"log --date-order --no-show-signature --decorate=full --pretty=format:\"%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%B%n{_endOfBodyToken}\" " + limits;
|
||||
Args = $"log --date-order --no-show-signature --decorate=full --pretty=format:%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s " + limits;
|
||||
_findFirstMerged = needFindHead;
|
||||
}
|
||||
|
||||
|
@ -24,7 +22,6 @@ namespace SourceGit.Commands
|
|||
var nextPartIdx = 0;
|
||||
var start = 0;
|
||||
var end = rs.StdOut.IndexOf('\n', start);
|
||||
var max = rs.StdOut.Length;
|
||||
while (end > 0)
|
||||
{
|
||||
var line = rs.StdOut.Substring(start, end - start);
|
||||
|
@ -51,24 +48,17 @@ namespace SourceGit.Commands
|
|||
break;
|
||||
case 6:
|
||||
_current.CommitterTime = ulong.Parse(line);
|
||||
start = end + 1;
|
||||
end = rs.StdOut.IndexOf(_endOfBodyToken, start, StringComparison.Ordinal);
|
||||
if (end > 0)
|
||||
{
|
||||
if (end > start)
|
||||
_current.Body = rs.StdOut.Substring(start, end - start).TrimEnd();
|
||||
|
||||
start = end + _endOfBodyToken.Length + 1;
|
||||
end = start >= max ? -1 : rs.StdOut.IndexOf('\n', start);
|
||||
}
|
||||
|
||||
nextPartIdx = 0;
|
||||
continue;
|
||||
break;
|
||||
case 7:
|
||||
_current.Subject = line;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
nextPartIdx++;
|
||||
if (nextPartIdx == 8) nextPartIdx = 0;
|
||||
|
||||
start = end + 1;
|
||||
end = rs.StdOut.IndexOf('\n', start);
|
||||
}
|
||||
|
@ -157,7 +147,7 @@ namespace SourceGit.Commands
|
|||
if (l.Type != r.Type)
|
||||
return (int)l.Type - (int)r.Type;
|
||||
else
|
||||
return l.Name.CompareTo(r.Name);
|
||||
return string.Compare(l.Name, r.Name, StringComparison.Ordinal);
|
||||
});
|
||||
|
||||
if (_current.IsMerged && !_isHeadFounded)
|
||||
|
@ -187,7 +177,6 @@ namespace SourceGit.Commands
|
|||
}
|
||||
}
|
||||
|
||||
private string _endOfBodyToken = string.Empty;
|
||||
private List<Models.Commit> _commits = new List<Models.Commit>();
|
||||
private Models.Commit _current = null;
|
||||
private bool _findFirstMerged = false;
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace SourceGit.Commands
|
|||
{
|
||||
WorkingDirectory = repo;
|
||||
Context = repo;
|
||||
Args = $"show --no-show-signature --decorate=full --pretty=format:%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%B -s {sha}";
|
||||
Args = $"show --no-show-signature --decorate=full --pretty=format:%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s -s {sha}";
|
||||
}
|
||||
|
||||
public Models.Commit Result()
|
||||
|
@ -32,11 +32,7 @@ namespace SourceGit.Commands
|
|||
commit.AuthorTime = ulong.Parse(lines[4]);
|
||||
commit.Committer = Models.User.FindOrAdd(lines[5]);
|
||||
commit.CommitterTime = ulong.Parse(lines[6]);
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 7; i < lines.Length; i++)
|
||||
builder.AppendLine(lines[i]);
|
||||
commit.Body = builder.ToString().TrimEnd();
|
||||
commit.Subject = lines[7];
|
||||
|
||||
return commit;
|
||||
}
|
||||
|
@ -105,7 +101,7 @@ namespace SourceGit.Commands
|
|||
if (l.Type != r.Type)
|
||||
return (int)l.Type - (int)r.Type;
|
||||
else
|
||||
return l.Name.CompareTo(r.Name);
|
||||
return string.Compare(l.Name, r.Name, StringComparison.Ordinal);
|
||||
});
|
||||
|
||||
return isHeadOfCurrent;
|
||||
|
|
|
@ -12,31 +12,13 @@ namespace SourceGit.Models
|
|||
public ulong AuthorTime { get; set; } = 0;
|
||||
public User Committer { get; set; } = User.Invalid;
|
||||
public ulong CommitterTime { get; set; } = 0;
|
||||
public string Body { get; set; } = string.Empty;
|
||||
public string Subject { get; set; } = string.Empty;
|
||||
public List<string> Parents { get; set; } = new List<string>();
|
||||
public List<Decorator> Decorators { get; set; } = new List<Decorator>();
|
||||
public bool HasDecorators => Decorators.Count > 0;
|
||||
public bool IsMerged { get; set; } = false;
|
||||
public Thickness Margin { get; set; } = new Thickness(0);
|
||||
|
||||
public string Subject
|
||||
{
|
||||
get
|
||||
{
|
||||
var end = Body.IndexOf("\r\n\r\n", StringComparison.Ordinal);
|
||||
if (end == -1)
|
||||
{
|
||||
end = Body.IndexOf("\n\n", StringComparison.Ordinal);
|
||||
if (end > 0)
|
||||
return Body.Substring(0, end).Replace("\n", "", StringComparison.Ordinal);
|
||||
|
||||
return Body.Replace("\n", " ", StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
return Body.Substring(0, end).Replace("\r\n", " ", StringComparison.Ordinal);
|
||||
}
|
||||
}
|
||||
|
||||
public string AuthorTimeStr => _utcStart.AddSeconds(AuthorTime).ToString("yyyy/MM/dd HH:mm:ss");
|
||||
public string CommitterTimeStr => _utcStart.AddSeconds(CommitterTime).ToString("yyyy/MM/dd HH:mm:ss");
|
||||
public string AuthorTimeShortStr => _utcStart.AddSeconds(AuthorTime).ToString("yyyy/MM/dd");
|
||||
|
|
|
@ -36,6 +36,12 @@ namespace SourceGit.ViewModels
|
|||
}
|
||||
}
|
||||
|
||||
public string FullMessage
|
||||
{
|
||||
get => _fullMessage;
|
||||
private set => SetProperty(ref _fullMessage, value);
|
||||
}
|
||||
|
||||
public List<Models.Change> Changes
|
||||
{
|
||||
get => _changes;
|
||||
|
@ -376,6 +382,7 @@ namespace SourceGit.ViewModels
|
|||
private void Refresh()
|
||||
{
|
||||
_changes = null;
|
||||
FullMessage = string.Empty;
|
||||
VisibleChanges = null;
|
||||
SelectedChanges = null;
|
||||
|
||||
|
@ -389,6 +396,7 @@ namespace SourceGit.ViewModels
|
|||
|
||||
Task.Run(() =>
|
||||
{
|
||||
var fullMessage = new Commands.QueryCommitFullMessage(_repo, _commit.SHA).Result();
|
||||
var parent = _commit.Parents.Count == 0 ? "4b825dc642cb6eb9a060e54bf8d69288fbee4904" : _commit.Parents[0];
|
||||
var cmdChanges = new Commands.CompareRevisions(_repo, parent, _commit.SHA) { Cancel = _cancelToken };
|
||||
var changes = cmdChanges.Result();
|
||||
|
@ -407,6 +415,7 @@ namespace SourceGit.ViewModels
|
|||
{
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
FullMessage = fullMessage;
|
||||
Changes = changes;
|
||||
VisibleChanges = visible;
|
||||
});
|
||||
|
@ -444,6 +453,7 @@ namespace SourceGit.ViewModels
|
|||
private string _repo = string.Empty;
|
||||
private int _activePageIndex = 0;
|
||||
private Models.Commit _commit = null;
|
||||
private string _fullMessage = string.Empty;
|
||||
private List<Models.Change> _changes = null;
|
||||
private List<Models.Change> _visibleChanges = null;
|
||||
private List<Models.Change> _selectedChanges = null;
|
||||
|
|
|
@ -429,7 +429,7 @@ namespace SourceGit.ViewModels
|
|||
foreach (var c in _histories.Commits)
|
||||
{
|
||||
if (c.SHA.Contains(_searchCommitFilter, StringComparison.OrdinalIgnoreCase)
|
||||
|| c.Body.Contains(_searchCommitFilter, StringComparison.OrdinalIgnoreCase)
|
||||
|| c.Subject.Contains(_searchCommitFilter, StringComparison.OrdinalIgnoreCase)
|
||||
|| c.Author.Name.Contains(_searchCommitFilter, StringComparison.OrdinalIgnoreCase)
|
||||
|| c.Committer.Name.Contains(_searchCommitFilter, StringComparison.OrdinalIgnoreCase)
|
||||
|| c.Author.Email.Contains(_searchCommitFilter, StringComparison.OrdinalIgnoreCase)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SourceGit.ViewModels
|
||||
|
@ -21,14 +22,16 @@ namespace SourceGit.ViewModels
|
|||
public Reword(Repository repo, Models.Commit head)
|
||||
{
|
||||
_repo = repo;
|
||||
_oldMessage = new Commands.QueryCommitFullMessage(_repo.FullPath, head.SHA).Result();
|
||||
_message = _oldMessage;
|
||||
|
||||
Head = head;
|
||||
Message = head.Body;
|
||||
View = new Views.Reword() { DataContext = this };
|
||||
}
|
||||
|
||||
public override Task<bool> Sure()
|
||||
{
|
||||
if (_message == Head.Body)
|
||||
if (string.Compare(_message, _oldMessage, StringComparison.Ordinal) == 0)
|
||||
return null;
|
||||
|
||||
_repo.SetWatcherEnabled(false);
|
||||
|
@ -44,5 +47,6 @@ namespace SourceGit.ViewModels
|
|||
|
||||
private readonly Repository _repo = null;
|
||||
private string _message = string.Empty;
|
||||
private string _oldMessage = string.Empty;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,8 @@ namespace SourceGit.ViewModels
|
|||
public Squash(Repository repo, Models.Commit head, Models.Commit parent)
|
||||
{
|
||||
_repo = repo;
|
||||
_message = parent.Body;
|
||||
_message = new Commands.QueryCommitFullMessage(_repo.FullPath, parent.SHA).Result();
|
||||
|
||||
Head = head;
|
||||
Parent = parent;
|
||||
View = new Views.Squash() { DataContext = this };
|
||||
|
|
|
@ -93,16 +93,7 @@ namespace SourceGit.ViewModels
|
|||
return;
|
||||
}
|
||||
|
||||
var head = new Commands.QuerySingleCommit(_repo.FullPath, currentBranch.Head).Result();
|
||||
if (head == null)
|
||||
{
|
||||
App.RaiseException(_repo.FullPath, "No commits to amend!!!");
|
||||
_useAmend = false;
|
||||
OnPropertyChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
CommitMessage = head.Body;
|
||||
CommitMessage = new Commands.QueryCommitFullMessage(_repo.FullPath, currentBranch.Head).Result();
|
||||
}
|
||||
|
||||
OnPropertyChanged(nameof(IsCommitWithPushVisible));
|
||||
|
|
|
@ -7,14 +7,15 @@
|
|||
xmlns:v="using:SourceGit.Views"
|
||||
xmlns:c="using:SourceGit.Converters"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="SourceGit.Views.CommitBaseInfo">
|
||||
x:Class="SourceGit.Views.CommitBaseInfo"
|
||||
x:Name="ThisControl">
|
||||
<UserControl.DataTemplates>
|
||||
<DataTemplate DataType="m:Commit">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<!-- Author & Committer -->
|
||||
<UniformGrid Rows="1" Margin="0,8">
|
||||
<!-- Author -->
|
||||
<Grid Grid.Column="0" ColumnDefinitions="96,*">
|
||||
<Grid ColumnDefinitions="96,*">
|
||||
<v:Avatar Grid.Column="0" Width="64" Height="64" HorizontalAlignment="Right" User="{Binding Author}"/>
|
||||
<StackPanel Grid.Column="1" Margin="16,0,8,0" Orientation="Vertical">
|
||||
<TextBlock Classes="group_header_label" Margin="0" Text="{DynamicResource Text.CommitDetail.Info.Author}"/>
|
||||
|
@ -30,7 +31,7 @@
|
|||
</Grid>
|
||||
|
||||
<!-- Committer -->
|
||||
<Grid Grid.Column="1" ColumnDefinitions="96,*" IsVisible="{Binding IsCommitterVisible}">
|
||||
<Grid ColumnDefinitions="96,*" IsVisible="{Binding IsCommitterVisible}">
|
||||
<v:Avatar Grid.Column="0" Width="64" Height="64" HorizontalAlignment="Right" User="{Binding Committer}"/>
|
||||
<StackPanel Grid.Column="1" Margin="16,0,8,0" Orientation="Vertical">
|
||||
<TextBlock Classes="group_header_label" Margin="0" Text="{DynamicResource Text.CommitDetail.Info.Committer}"/>
|
||||
|
@ -104,7 +105,7 @@
|
|||
<!-- Messages -->
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" Classes="info_label" Text="{DynamicResource Text.CommitDetail.Info.Message}" VerticalAlignment="Top" Margin="0,4,0,0" />
|
||||
<ScrollViewer Grid.Row="3" Grid.Column="1" Margin="12,5,8,0" MaxHeight="64" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
|
||||
<SelectableTextBlock Text="{Binding Body}" FontFamily="{Binding Source={x:Static vm:Preference.Instance}, Path=MonospaceFont}" TextWrapping="Wrap"/>
|
||||
<SelectableTextBlock Text="{Binding #ThisControl.Message}" FontFamily="{Binding Source={x:Static vm:Preference.Instance}, Path=MonospaceFont}" TextWrapping="Wrap"/>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
|
|
|
@ -14,6 +14,15 @@ namespace SourceGit.Views
|
|||
get => GetValue(CanNavigateProperty);
|
||||
set => SetValue(CanNavigateProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<string> MessageProperty =
|
||||
AvaloniaProperty.Register<CommitBaseInfo, string>(nameof(Message), string.Empty);
|
||||
|
||||
public string Message
|
||||
{
|
||||
get => GetValue(MessageProperty);
|
||||
set => SetValue(MessageProperty, value);
|
||||
}
|
||||
|
||||
public CommitBaseInfo()
|
||||
{
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
<Grid RowDefinitions="Auto,1,*">
|
||||
<!-- Base Information -->
|
||||
<v:CommitBaseInfo Grid.Row="0" Content="{Binding Commit}"/>
|
||||
<v:CommitBaseInfo Grid.Row="0" Content="{Binding Commit}" Message="{Binding FullMessage}"/>
|
||||
|
||||
<!-- Line -->
|
||||
<Rectangle Grid.Row="1" Height=".65" Margin="8" Fill="{DynamicResource Brush.Border2}" VerticalAlignment="Center"/>
|
||||
|
|
Loading…
Reference in a new issue