mirror of
https://fastgit.cc/github.com/sourcegit-scm/sourcegit
synced 2026-04-24 19:02:39 +08:00
115 lines
4.0 KiB
C#
115 lines
4.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
|
|
namespace SourceGit.Commands
|
|
{
|
|
public class QuerySingleCommit : Command
|
|
{
|
|
public QuerySingleCommit(string repo, string sha)
|
|
{
|
|
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}";
|
|
}
|
|
|
|
public Models.Commit Result()
|
|
{
|
|
var rs = ReadToEnd();
|
|
if (rs.IsSuccess && !string.IsNullOrEmpty(rs.StdOut))
|
|
{
|
|
var commit = new Models.Commit();
|
|
var lines = rs.StdOut.Split('\n');
|
|
if (lines.Length < 8)
|
|
return null;
|
|
|
|
commit.SHA = lines[0];
|
|
if (!string.IsNullOrEmpty(lines[1]))
|
|
commit.Parents.AddRange(lines[1].Split(' ', StringSplitOptions.RemoveEmptyEntries));
|
|
if (!string.IsNullOrEmpty(lines[2]))
|
|
commit.IsMerged = ParseDecorators(commit.Decorators, lines[2]);
|
|
commit.Author = Models.User.FindOrAdd(lines[3]);
|
|
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();
|
|
|
|
return commit;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private bool ParseDecorators(List<Models.Decorator> decorators, string data)
|
|
{
|
|
bool isHeadOfCurrent = false;
|
|
|
|
var subs = data.Split(',', StringSplitOptions.RemoveEmptyEntries);
|
|
foreach (var sub in subs)
|
|
{
|
|
var d = sub.Trim();
|
|
if (d.StartsWith("tag: refs/tags/", StringComparison.Ordinal))
|
|
{
|
|
decorators.Add(new Models.Decorator()
|
|
{
|
|
Type = Models.DecoratorType.Tag,
|
|
Name = d.Substring(15),
|
|
});
|
|
}
|
|
else if (d.EndsWith("/HEAD", StringComparison.Ordinal))
|
|
{
|
|
continue;
|
|
}
|
|
else if (d.StartsWith("HEAD -> refs/heads/", StringComparison.Ordinal))
|
|
{
|
|
isHeadOfCurrent = true;
|
|
decorators.Add(new Models.Decorator()
|
|
{
|
|
Type = Models.DecoratorType.CurrentBranchHead,
|
|
Name = d.Substring(19),
|
|
});
|
|
}
|
|
else if (d.Equals("HEAD"))
|
|
{
|
|
isHeadOfCurrent = true;
|
|
decorators.Add(new Models.Decorator()
|
|
{
|
|
Type = Models.DecoratorType.CurrentCommitHead,
|
|
Name = d,
|
|
});
|
|
}
|
|
else if (d.StartsWith("refs/heads/", StringComparison.Ordinal))
|
|
{
|
|
decorators.Add(new Models.Decorator()
|
|
{
|
|
Type = Models.DecoratorType.LocalBranchHead,
|
|
Name = d.Substring(11),
|
|
});
|
|
}
|
|
else if (d.StartsWith("refs/remotes/", StringComparison.Ordinal))
|
|
{
|
|
decorators.Add(new Models.Decorator()
|
|
{
|
|
Type = Models.DecoratorType.RemoteBranchHead,
|
|
Name = d.Substring(13),
|
|
});
|
|
}
|
|
}
|
|
|
|
decorators.Sort((l, r) =>
|
|
{
|
|
if (l.Type != r.Type)
|
|
return (int)l.Type - (int)r.Type;
|
|
else
|
|
return l.Name.CompareTo(r.Name);
|
|
});
|
|
|
|
return isHeadOfCurrent;
|
|
}
|
|
}
|
|
}
|