feature(LFS): LFS diff and preview support

This commit is contained in:
leo 2020-09-25 16:30:28 +08:00
parent f3ee044818
commit 77ba0e6cdb
7 changed files with 184 additions and 52 deletions

View file

@ -31,14 +31,6 @@ namespace SourceGit.Git {
Both,
}
/// <summary>
/// Binary change.
/// </summary>
public class BinaryChange {
public long Size = 0;
public long PreSize = 0;
}
/// <summary>
/// Block
/// </summary>
@ -63,9 +55,9 @@ namespace SourceGit.Git {
}
/// <summary>
/// Diff result.
/// Text file change.
/// </summary>
public class Result {
public class TextChange {
public bool IsValid = false;
public bool IsBinary = false;
public List<Block> Blocks = new List<Block>();
@ -119,14 +111,31 @@ namespace SourceGit.Git {
}
}
/// <summary>
/// Binary change.
/// </summary>
public class BinaryChange {
public long Size = 0;
public long PreSize = 0;
}
/// <summary>
/// Change for LFS object information.
/// </summary>
public class LFSChange {
public LFSObject Old;
public LFSObject New;
public bool IsValid => Old != null || New != null;
}
/// <summary>
/// Run diff process.
/// </summary>
/// <param name="repo"></param>
/// <param name="args"></param>
/// <returns></returns>
public static Result Run(Repository repo, string args) {
var rs = new Result();
public static TextChange GetTextChange(Repository repo, string args) {
var rs = new TextChange();
var current = new Block();
var left = 0;
var right = 0;
@ -259,5 +268,37 @@ namespace SourceGit.Git {
return change;
}
/// <summary>
/// Get LFS object changes.
/// </summary>
/// <param name="repo"></param>
/// <param name="args"></param>
/// <returns></returns>
public static LFSChange GetLFSChange(Repository repo, string args) {
var rc = new LFSChange();
repo.RunCommand($"diff --ignore-cr-at-eol {args}", line => {
if (line[0] == '-') {
if (rc.Old == null) rc.Old = new LFSObject();
line = line.Substring(1);
if (line.StartsWith("oid sha256:")) {
rc.Old.OID = line.Substring(11);
} else if (line.StartsWith("size ")) {
rc.Old.Size = int.Parse(line.Substring(5));
}
} else if (line[0] == '+') {
if (rc.New == null) rc.New = new LFSObject();
line = line.Substring(1);
if (line.StartsWith("oid sha256:")) {
rc.New.OID = line.Substring(11);
} else if (line.StartsWith("size ")) {
rc.New.Size = int.Parse(line.Substring(5));
}
}
});
return rc;
}
}
}

18
src/Git/LFS.cs Normal file
View file

@ -0,0 +1,18 @@
namespace SourceGit.Git {
/// <summary>
/// Object filtered by LFS
/// </summary>
public class LFSObject {
/// <summary>
/// Object id
/// </summary>
public string OID { get; set; }
/// <summary>
/// Object size.
/// </summary>
public long Size { get; set; }
}
}

View file

@ -999,11 +999,46 @@ namespace SourceGit.Git {
/// <returns></returns>
public long GetFileSize(string sha, string path) {
long size = 0;
RunCommand($"cat-file -s {sha}:\"{path}\"", line => {
if (!long.TryParse(line, out size)) size = 0;
});
return size;
}
/// <summary>
/// Detect if a file is managed by LFS.
/// </summary>
/// <param name="path">File path</param>
/// <returns></returns>
public bool IsLFSFiltered(string path) {
bool ok = false;
RunCommand($"check-attr -a -z \"{path}\"", line => {
ok = ok || line.Contains("filter\0lfs");
});
return ok;
}
/// <summary>
/// Get LFS object information.
/// </summary>
/// <param name="sha"></param>
/// <param name="path"></param>
/// <returns></returns>
public LFSObject GetLFSObject(string sha, string path) {
LFSObject obj = new LFSObject();
RunCommand($"show {sha}:\"{path}\"", line => {
if (line.StartsWith("oid")) {
obj.OID = line.Substring(3).Replace("sha256:", "").Trim();
} else if (line.StartsWith("size")) {
obj.Size = int.Parse(line.Substring(4).Trim());
}
});
return obj;
}
#endregion
#region METHOD_GITFLOW