2021-04-29 05:05:55 -07:00
|
|
|
|
using System;
|
2021-07-28 00:02:06 -07:00
|
|
|
|
using System.Collections.Generic;
|
2021-04-29 05:05:55 -07:00
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
|
|
|
|
|
|
namespace SourceGit.Commands {
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Diff命令(用于文件文件比对)
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class Diff : Command {
|
|
|
|
|
private static readonly Regex REG_INDICATOR = new Regex(@"^@@ \-(\d+),?\d* \+(\d+),?\d* @@");
|
|
|
|
|
private Models.TextChanges changes = new Models.TextChanges();
|
2021-07-28 00:02:06 -07:00
|
|
|
|
private List<Models.TextChanges.Line> deleted = new List<Models.TextChanges.Line>();
|
|
|
|
|
private List<Models.TextChanges.Line> added = new List<Models.TextChanges.Line>();
|
2021-04-29 05:05:55 -07:00
|
|
|
|
private int oldLine = 0;
|
|
|
|
|
private int newLine = 0;
|
|
|
|
|
|
|
|
|
|
public Diff(string repo, string args) {
|
|
|
|
|
Cwd = repo;
|
2021-07-28 00:04:00 -07:00
|
|
|
|
Args = $"diff --ignore-cr-at-eol --unified=4 {args}";
|
2021-04-29 05:05:55 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Models.TextChanges Result() {
|
|
|
|
|
Exec();
|
2021-07-28 00:02:06 -07:00
|
|
|
|
ProcessChanges();
|
2021-04-29 05:05:55 -07:00
|
|
|
|
if (changes.IsBinary) changes.Lines.Clear();
|
|
|
|
|
return changes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void OnReadline(string line) {
|
|
|
|
|
if (changes.IsBinary) return;
|
|
|
|
|
|
|
|
|
|
if (changes.Lines.Count == 0) {
|
|
|
|
|
var match = REG_INDICATOR.Match(line);
|
|
|
|
|
if (!match.Success) {
|
|
|
|
|
if (line.StartsWith("Binary", StringComparison.Ordinal)) changes.IsBinary = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
oldLine = int.Parse(match.Groups[1].Value);
|
|
|
|
|
newLine = int.Parse(match.Groups[2].Value);
|
|
|
|
|
changes.Lines.Add(new Models.TextChanges.Line(Models.TextChanges.LineMode.Indicator, line, "", ""));
|
|
|
|
|
} else {
|
2021-05-27 00:35:45 -07:00
|
|
|
|
if (line.Length == 0) {
|
2021-07-28 00:02:06 -07:00
|
|
|
|
ProcessChanges();
|
2021-05-27 00:35:45 -07:00
|
|
|
|
changes.Lines.Add(new Models.TextChanges.Line(Models.TextChanges.LineMode.Normal, "", $"{oldLine}", $"{newLine}"));
|
|
|
|
|
oldLine++;
|
|
|
|
|
newLine++;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-29 05:05:55 -07:00
|
|
|
|
var ch = line[0];
|
|
|
|
|
if (ch == '-') {
|
2021-07-28 00:02:06 -07:00
|
|
|
|
deleted.Add(new Models.TextChanges.Line(Models.TextChanges.LineMode.Deleted, line.Substring(1), $"{oldLine}", ""));
|
2021-04-29 05:05:55 -07:00
|
|
|
|
oldLine++;
|
|
|
|
|
} else if (ch == '+') {
|
2021-07-28 00:02:06 -07:00
|
|
|
|
added.Add(new Models.TextChanges.Line(Models.TextChanges.LineMode.Added, line.Substring(1), "", $"{newLine}"));
|
2021-04-29 05:05:55 -07:00
|
|
|
|
newLine++;
|
|
|
|
|
} else if (ch != '\\') {
|
2021-07-28 00:02:06 -07:00
|
|
|
|
ProcessChanges();
|
2021-04-29 05:05:55 -07:00
|
|
|
|
var match = REG_INDICATOR.Match(line);
|
|
|
|
|
if (match.Success) {
|
|
|
|
|
oldLine = int.Parse(match.Groups[1].Value);
|
|
|
|
|
newLine = int.Parse(match.Groups[2].Value);
|
|
|
|
|
changes.Lines.Add(new Models.TextChanges.Line(Models.TextChanges.LineMode.Indicator, line, "", ""));
|
|
|
|
|
} else {
|
|
|
|
|
changes.Lines.Add(new Models.TextChanges.Line(Models.TextChanges.LineMode.Normal, line.Substring(1), $"{oldLine}", $"{newLine}"));
|
|
|
|
|
oldLine++;
|
|
|
|
|
newLine++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-07-28 00:02:06 -07:00
|
|
|
|
|
|
|
|
|
private void ProcessChanges() {
|
|
|
|
|
if (deleted.Count > 0) {
|
|
|
|
|
if (added.Count == deleted.Count) {
|
|
|
|
|
for (int i = added.Count - 1; i >= 0; i--) {
|
|
|
|
|
var left = deleted[i];
|
|
|
|
|
var right = added[i];
|
2021-07-28 00:26:41 -07:00
|
|
|
|
|
2021-07-28 00:02:06 -07:00
|
|
|
|
var result = DiffPlex.Differ.Instance.CreateCharacterDiffs(left.Content, right.Content, false, false);
|
2021-07-28 00:26:41 -07:00
|
|
|
|
if (result.DiffBlocks.Count > 4) break;
|
|
|
|
|
|
2021-07-28 00:02:06 -07:00
|
|
|
|
foreach (var block in result.DiffBlocks) {
|
2021-07-28 00:26:41 -07:00
|
|
|
|
if (block.DeleteCountA > 0) left.Highlights.Add(new Models.TextChanges.HighlightRange(block.DeleteStartA, block.DeleteCountA));
|
|
|
|
|
if (block.InsertCountB > 0) right.Highlights.Add(new Models.TextChanges.HighlightRange(block.InsertStartB, block.InsertCountB));
|
2021-07-28 00:02:06 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
changes.Lines.AddRange(deleted);
|
|
|
|
|
deleted.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (added.Count > 0) {
|
|
|
|
|
changes.Lines.AddRange(added);
|
|
|
|
|
added.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-04-29 05:05:55 -07:00
|
|
|
|
}
|
|
|
|
|
}
|