2024-02-05 23:08:37 -08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Text;
|
2021-04-29 05:05:55 -07:00
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
namespace SourceGit.Commands
|
|
|
|
|
{
|
|
|
|
|
public partial class Blame : Command
|
|
|
|
|
{
|
2024-03-16 02:09:27 -07:00
|
|
|
|
[GeneratedRegex(@"^\^?([0-9a-f]+)\s+.*\((.*)\s+(\d+)\s+[\-\+]?\d+\s+\d+\) (.*)")]
|
|
|
|
|
private static partial Regex REG_FORMAT();
|
2023-10-09 20:25:57 -07:00
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public Blame(string repo, string file, string revision)
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
WorkingDirectory = repo;
|
|
|
|
|
Context = repo;
|
2021-04-29 05:05:55 -07:00
|
|
|
|
Args = $"blame -t {revision} -- \"{file}\"";
|
2024-02-05 23:08:37 -08:00
|
|
|
|
RaiseError = false;
|
|
|
|
|
|
|
|
|
|
_result.File = file;
|
2021-04-29 05:05:55 -07:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
public Models.BlameData Result()
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
var succ = Exec();
|
2024-03-17 18:37:06 -07:00
|
|
|
|
if (!succ)
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
return new Models.BlameData();
|
|
|
|
|
}
|
2023-08-23 22:39:49 -07:00
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
if (_needUnifyCommitSHA)
|
|
|
|
|
{
|
|
|
|
|
foreach (var line in _result.LineInfos)
|
|
|
|
|
{
|
|
|
|
|
if (line.CommitSHA.Length > _minSHALen)
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
line.CommitSHA = line.CommitSHA.Substring(0, _minSHALen);
|
2023-08-23 22:39:49 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-05 23:08:37 -08:00
|
|
|
|
_result.Content = _content.ToString();
|
|
|
|
|
return _result;
|
2021-04-29 05:05:55 -07:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
protected override void OnReadline(string line)
|
|
|
|
|
{
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (_result.IsBinary)
|
|
|
|
|
return;
|
|
|
|
|
if (string.IsNullOrEmpty(line))
|
|
|
|
|
return;
|
2021-04-29 05:05:55 -07:00
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
if (line.IndexOf('\0', StringComparison.Ordinal) >= 0)
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
_result.IsBinary = true;
|
|
|
|
|
_result.LineInfos.Clear();
|
2021-04-29 05:05:55 -07:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-16 02:09:27 -07:00
|
|
|
|
var match = REG_FORMAT().Match(line);
|
2024-03-31 01:54:29 -07:00
|
|
|
|
if (!match.Success)
|
|
|
|
|
return;
|
2021-04-29 05:05:55 -07:00
|
|
|
|
|
2024-02-05 23:08:37 -08:00
|
|
|
|
_content.AppendLine(match.Groups[4].Value);
|
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
var commit = match.Groups[1].Value;
|
2024-02-29 23:09:17 -08:00
|
|
|
|
var author = match.Groups[2].Value;
|
|
|
|
|
var timestamp = int.Parse(match.Groups[3].Value);
|
2024-07-01 21:30:12 -07:00
|
|
|
|
var when = DateTime.UnixEpoch.AddSeconds(timestamp).ToLocalTime().ToString("yyyy/MM/dd");
|
2021-04-29 05:05:55 -07:00
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
var info = new Models.BlameLineInfo()
|
|
|
|
|
{
|
2024-02-29 23:09:17 -08:00
|
|
|
|
IsFirstInGroup = commit != _lastSHA,
|
|
|
|
|
CommitSHA = commit,
|
|
|
|
|
Author = author,
|
|
|
|
|
Time = when,
|
|
|
|
|
};
|
2024-02-05 23:08:37 -08:00
|
|
|
|
|
2024-02-29 23:09:17 -08:00
|
|
|
|
_result.LineInfos.Add(info);
|
|
|
|
|
_lastSHA = commit;
|
2023-08-23 22:39:49 -07:00
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
if (line[0] == '^')
|
|
|
|
|
{
|
2024-02-05 23:08:37 -08:00
|
|
|
|
_needUnifyCommitSHA = true;
|
|
|
|
|
_minSHALen = Math.Min(_minSHALen, commit.Length);
|
2024-02-29 23:09:17 -08:00
|
|
|
|
}
|
2021-04-29 05:05:55 -07:00
|
|
|
|
}
|
2024-02-05 23:08:37 -08:00
|
|
|
|
|
2024-03-17 18:37:06 -07:00
|
|
|
|
private readonly Models.BlameData _result = new Models.BlameData();
|
|
|
|
|
private readonly StringBuilder _content = new StringBuilder();
|
2024-02-05 23:08:37 -08:00
|
|
|
|
private string _lastSHA = string.Empty;
|
|
|
|
|
private bool _needUnifyCommitSHA = false;
|
|
|
|
|
private int _minSHALen = 64;
|
2021-04-29 05:05:55 -07:00
|
|
|
|
}
|
2024-03-31 01:54:29 -07:00
|
|
|
|
}
|