enhance: make commit's subject the same with pretty print parameter %s in git log command

This commit is contained in:
leo 2024-06-07 12:31:10 +08:00
parent b4e01a8b93
commit 78c7168a46
No known key found for this signature in database
GPG key ID: B528468E49CD0E58
6 changed files with 98 additions and 83 deletions

View file

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
namespace SourceGit.Commands namespace SourceGit.Commands
{ {
@ -18,7 +17,61 @@ namespace SourceGit.Commands
public List<Models.Commit> Result() public List<Models.Commit> Result()
{ {
Exec(); var rs = ReadToEnd();
if (!rs.IsSuccess)
return _commits;
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);
switch (nextPartIdx)
{
case 0:
_current = new Models.Commit() { SHA = line };
_commits.Add(_current);
break;
case 1:
ParseParent(line);
break;
case 2:
ParseDecorators(line);
break;
case 3:
_current.Author = Models.User.FindOrAdd(line);
break;
case 4:
_current.AuthorTime = ulong.Parse(line);
break;
case 5:
_current.Committer = Models.User.FindOrAdd(line);
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;
default:
break;
}
nextPartIdx++;
start = end + 1;
end = rs.StdOut.IndexOf('\n', start);
}
if (_findFirstMerged && !_isHeadFounded && _commits.Count > 0) if (_findFirstMerged && !_isHeadFounded && _commits.Count > 0)
MarkFirstMerged(); MarkFirstMerged();
@ -26,56 +79,6 @@ namespace SourceGit.Commands
return _commits; return _commits;
} }
protected override void OnReadline(string line)
{
switch (_nextPartIdx)
{
case 0:
_current = new Models.Commit() { SHA = line };
_isSubjectSet = false;
_commits.Add(_current);
break;
case 1:
ParseParent(line);
break;
case 2:
ParseDecorators(line);
break;
case 3:
_current.Author = Models.User.FindOrAdd(line);
break;
case 4:
_current.AuthorTime = ulong.Parse(line);
break;
case 5:
_current.Committer = Models.User.FindOrAdd(line);
break;
case 6:
_current.CommitterTime = ulong.Parse(line);
break;
default:
if (line.Equals(_endOfBodyToken, StringComparison.Ordinal))
{
_nextPartIdx = 0;
_current.Body = _bodyReader.ToString().TrimEnd();
_bodyReader.Clear();
}
else
{
if (!_isSubjectSet)
{
_isSubjectSet = true;
_current.SubjectLen = line.Length;
}
_bodyReader.AppendLine(line);
}
return;
}
_nextPartIdx++;
}
private void ParseParent(string data) private void ParseParent(string data)
{ {
if (data.Length < 8) if (data.Length < 8)
@ -106,7 +109,7 @@ namespace SourceGit.Commands
_current.Decorators.Add(new Models.Decorator() _current.Decorators.Add(new Models.Decorator()
{ {
Type = Models.DecoratorType.Tag, Type = Models.DecoratorType.Tag,
Name = d.Substring(15).Trim(), Name = d.Substring(15),
}); });
} }
else if (d.EndsWith("/HEAD", StringComparison.Ordinal)) else if (d.EndsWith("/HEAD", StringComparison.Ordinal))
@ -119,7 +122,7 @@ namespace SourceGit.Commands
_current.Decorators.Add(new Models.Decorator() _current.Decorators.Add(new Models.Decorator()
{ {
Type = Models.DecoratorType.CurrentBranchHead, Type = Models.DecoratorType.CurrentBranchHead,
Name = d.Substring(19).Trim(), Name = d.Substring(19),
}); });
} }
else if (d.Equals("HEAD")) else if (d.Equals("HEAD"))
@ -128,7 +131,7 @@ namespace SourceGit.Commands
_current.Decorators.Add(new Models.Decorator() _current.Decorators.Add(new Models.Decorator()
{ {
Type = Models.DecoratorType.CurrentCommitHead, Type = Models.DecoratorType.CurrentCommitHead,
Name = d.Trim(), Name = d,
}); });
} }
else if (d.StartsWith("refs/heads/", StringComparison.Ordinal)) else if (d.StartsWith("refs/heads/", StringComparison.Ordinal))
@ -136,7 +139,7 @@ namespace SourceGit.Commands
_current.Decorators.Add(new Models.Decorator() _current.Decorators.Add(new Models.Decorator()
{ {
Type = Models.DecoratorType.LocalBranchHead, Type = Models.DecoratorType.LocalBranchHead,
Name = d.Substring(11).Trim(), Name = d.Substring(11),
}); });
} }
else if (d.StartsWith("refs/remotes/", StringComparison.Ordinal)) else if (d.StartsWith("refs/remotes/", StringComparison.Ordinal))
@ -144,7 +147,7 @@ namespace SourceGit.Commands
_current.Decorators.Add(new Models.Decorator() _current.Decorators.Add(new Models.Decorator()
{ {
Type = Models.DecoratorType.RemoteBranchHead, Type = Models.DecoratorType.RemoteBranchHead,
Name = d.Substring(13).Trim(), Name = d.Substring(13),
}); });
} }
} }
@ -152,13 +155,9 @@ namespace SourceGit.Commands
_current.Decorators.Sort((l, r) => _current.Decorators.Sort((l, r) =>
{ {
if (l.Type != r.Type) if (l.Type != r.Type)
{
return (int)l.Type - (int)r.Type; return (int)l.Type - (int)r.Type;
}
else else
{
return l.Name.CompareTo(r.Name); return l.Name.CompareTo(r.Name);
}
}); });
if (_current.IsMerged && !_isHeadFounded) if (_current.IsMerged && !_isHeadFounded)
@ -191,10 +190,7 @@ namespace SourceGit.Commands
private string _endOfBodyToken = string.Empty; private string _endOfBodyToken = string.Empty;
private List<Models.Commit> _commits = new List<Models.Commit>(); private List<Models.Commit> _commits = new List<Models.Commit>();
private Models.Commit _current = null; private Models.Commit _current = null;
private bool _findFirstMerged = false;
private bool _isHeadFounded = false; private bool _isHeadFounded = false;
private bool _findFirstMerged = true;
private int _nextPartIdx = 0;
private bool _isSubjectSet = false;
private StringBuilder _bodyReader = new StringBuilder();
} }
} }

View file

@ -32,7 +32,6 @@ namespace SourceGit.Commands
commit.AuthorTime = ulong.Parse(lines[4]); commit.AuthorTime = ulong.Parse(lines[4]);
commit.Committer = Models.User.FindOrAdd(lines[5]); commit.Committer = Models.User.FindOrAdd(lines[5]);
commit.CommitterTime = ulong.Parse(lines[6]); commit.CommitterTime = ulong.Parse(lines[6]);
commit.SubjectLen = lines[7].Length;
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
for (int i = 7; i < lines.Length; i++) for (int i = 7; i < lines.Length; i++)
@ -58,7 +57,7 @@ namespace SourceGit.Commands
decorators.Add(new Models.Decorator() decorators.Add(new Models.Decorator()
{ {
Type = Models.DecoratorType.Tag, Type = Models.DecoratorType.Tag,
Name = d.Substring(15).Trim(), Name = d.Substring(15),
}); });
} }
else if (d.EndsWith("/HEAD", StringComparison.Ordinal)) else if (d.EndsWith("/HEAD", StringComparison.Ordinal))
@ -71,7 +70,7 @@ namespace SourceGit.Commands
decorators.Add(new Models.Decorator() decorators.Add(new Models.Decorator()
{ {
Type = Models.DecoratorType.CurrentBranchHead, Type = Models.DecoratorType.CurrentBranchHead,
Name = d.Substring(19).Trim(), Name = d.Substring(19),
}); });
} }
else if (d.Equals("HEAD")) else if (d.Equals("HEAD"))
@ -80,7 +79,7 @@ namespace SourceGit.Commands
decorators.Add(new Models.Decorator() decorators.Add(new Models.Decorator()
{ {
Type = Models.DecoratorType.CurrentCommitHead, Type = Models.DecoratorType.CurrentCommitHead,
Name = d.Trim(), Name = d,
}); });
} }
else if (d.StartsWith("refs/heads/", StringComparison.Ordinal)) else if (d.StartsWith("refs/heads/", StringComparison.Ordinal))
@ -88,7 +87,7 @@ namespace SourceGit.Commands
decorators.Add(new Models.Decorator() decorators.Add(new Models.Decorator()
{ {
Type = Models.DecoratorType.LocalBranchHead, Type = Models.DecoratorType.LocalBranchHead,
Name = d.Substring(11).Trim(), Name = d.Substring(11),
}); });
} }
else if (d.StartsWith("refs/remotes/", StringComparison.Ordinal)) else if (d.StartsWith("refs/remotes/", StringComparison.Ordinal))
@ -96,7 +95,7 @@ namespace SourceGit.Commands
decorators.Add(new Models.Decorator() decorators.Add(new Models.Decorator()
{ {
Type = Models.DecoratorType.RemoteBranchHead, Type = Models.DecoratorType.RemoteBranchHead,
Name = d.Substring(13).Trim(), Name = d.Substring(13),
}); });
} }
} }
@ -104,13 +103,9 @@ namespace SourceGit.Commands
decorators.Sort((l, r) => decorators.Sort((l, r) =>
{ {
if (l.Type != r.Type) if (l.Type != r.Type)
{
return (int)l.Type - (int)r.Type; return (int)l.Type - (int)r.Type;
}
else else
{
return l.Name.CompareTo(r.Name); return l.Name.CompareTo(r.Name);
}
}); });
return isHeadOfCurrent; return isHeadOfCurrent;

View file

@ -12,7 +12,6 @@ namespace SourceGit.Models
public ulong AuthorTime { get; set; } = 0; public ulong AuthorTime { get; set; } = 0;
public User Committer { get; set; } = User.Invalid; public User Committer { get; set; } = User.Invalid;
public ulong CommitterTime { get; set; } = 0; public ulong CommitterTime { get; set; } = 0;
public int SubjectLen { get; set; } = 0;
public string Body { get; set; } = string.Empty; public string Body { get; set; } = string.Empty;
public List<string> Parents { get; set; } = new List<string>(); public List<string> Parents { get; set; } = new List<string>();
public List<Decorator> Decorators { get; set; } = new List<Decorator>(); public List<Decorator> Decorators { get; set; } = new List<Decorator>();
@ -20,7 +19,24 @@ namespace SourceGit.Models
public bool IsMerged { get; set; } = false; public bool IsMerged { get; set; } = false;
public Thickness Margin { get; set; } = new Thickness(0); public Thickness Margin { get; set; } = new Thickness(0);
public string Subject => string.IsNullOrWhiteSpace(Body) ? string.Empty : Body.Substring(0, SubjectLen); 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 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 CommitterTimeStr => _utcStart.AddSeconds(CommitterTime).ToString("yyyy/MM/dd HH:mm:ss");
public string AuthorTimeShortStr => _utcStart.AddSeconds(AuthorTime).ToString("yyyy/MM/dd"); public string AuthorTimeShortStr => _utcStart.AddSeconds(AuthorTime).ToString("yyyy/MM/dd");

View file

@ -62,7 +62,7 @@ namespace SourceGit.ViewModels
Task.Run(() => Task.Run(() =>
{ {
var commits = new Commands.QueryCommits(_repo, $"-n 10000 -- \"{file}\"").Result(); var commits = new Commands.QueryCommits(_repo, $"-n 10000 -- \"{file}\"", false).Result();
Dispatcher.UIThread.Invoke(() => Dispatcher.UIThread.Invoke(() =>
{ {
IsLoading = false; IsLoading = false;

View file

@ -84,17 +84,25 @@ namespace SourceGit.ViewModels
{ {
if (SetProperty(ref _useAmend, value) && value) if (SetProperty(ref _useAmend, value) && value)
{ {
var commits = new Commands.QueryCommits(_repo.FullPath, "-n 1", false).Result(); var currentBranch = _repo.Branches.Find(x => x.IsCurrent);
if (commits.Count == 0) if (currentBranch == null)
{ {
App.RaiseException(_repo.FullPath, "No commits to amend!!!"); App.RaiseException(_repo.FullPath, "No commits to amend!!!");
_useAmend = false; _useAmend = false;
OnPropertyChanged(); OnPropertyChanged();
return;
} }
else
var head = new Commands.QuerySingleCommit(_repo.FullPath, currentBranch.Head).Result();
if (head == null)
{ {
CommitMessage = commits[0].Body; App.RaiseException(_repo.FullPath, "No commits to amend!!!");
_useAmend = false;
OnPropertyChanged();
return;
} }
CommitMessage = head.Body;
} }
OnPropertyChanged(nameof(IsCommitWithPushVisible)); OnPropertyChanged(nameof(IsCommitWithPushVisible));

View file

@ -68,7 +68,7 @@
</ItemsControl> </ItemsControl>
<TextBlock Classes="monospace" <TextBlock Classes="monospace"
Text="{Binding Subject}" Text="{Binding Subject}"
Opacity="{Binding IsMerged, Converter={x:Static c:BoolConverters.HalfIfFalse}}" Opacity="{Binding IsMerged, Converter={x:Static c:BoolConverters.HalfIfFalse}}"
FontWeight="{Binding IsCurrentHead, Converter={x:Static c:BoolConverters.BoldIfTrue}}"/> FontWeight="{Binding IsCurrentHead, Converter={x:Static c:BoolConverters.BoldIfTrue}}"/>
</StackPanel> </StackPanel>