refactor: rewrite Commands.QueryFileContent and use it instead of GetImageFileAsBitmap

This commit is contained in:
leo 2024-04-08 09:57:41 +08:00
parent 9a4f928ece
commit 8dd1ce9185
4 changed files with 44 additions and 64 deletions

View file

@ -1,40 +0,0 @@
using System;
using System.Diagnostics;
using System.IO;
using Avalonia.Media.Imaging;
namespace SourceGit.Commands
{
public static class GetImageFileAsBitmap
{
public static Bitmap Run(string repo, string revision, string file)
{
var starter = new ProcessStartInfo();
starter.WorkingDirectory = repo;
starter.FileName = Native.OS.GitExecutable;
starter.Arguments = $"show {revision}:\"{file}\"";
starter.UseShellExecute = false;
starter.CreateNoWindow = true;
starter.WindowStyle = ProcessWindowStyle.Hidden;
starter.RedirectStandardOutput = true;
try
{
var stream = new MemoryStream();
var proc = new Process() { StartInfo = starter };
proc.Start();
proc.StandardOutput.BaseStream.CopyTo(stream);
proc.WaitForExit();
proc.Close();
stream.Position = 0;
return new Bitmap(stream);
}
catch
{
return null;
}
}
}
}

View file

@ -1,28 +1,39 @@
using System.Text; using System;
using System.Diagnostics;
using System.IO;
namespace SourceGit.Commands namespace SourceGit.Commands
{ {
public class QueryFileContent : Command public static class QueryFileContent
{ {
public QueryFileContent(string repo, string revision, string file) public static Stream Run(string repo, string revision, string file)
{ {
WorkingDirectory = repo; var starter = new ProcessStartInfo();
Context = repo; starter.WorkingDirectory = repo;
Args = $"show {revision}:\"{file}\""; starter.FileName = Native.OS.GitExecutable;
} starter.Arguments = $"show {revision}:\"{file}\"";
starter.UseShellExecute = false;
starter.CreateNoWindow = true;
starter.WindowStyle = ProcessWindowStyle.Hidden;
starter.RedirectStandardOutput = true;
public string Result() try
{ {
Exec(); var stream = new MemoryStream();
return _builder.ToString(); var proc = new Process() { StartInfo = starter };
} proc.Start();
proc.StandardOutput.BaseStream.CopyTo(stream);
proc.WaitForExit();
proc.Close();
protected override void OnReadline(string line) stream.Position = 0;
{ return stream;
_builder.Append(line); }
_builder.Append('\n'); catch (Exception e)
{
App.RaiseException(repo, $"Failed to query file content: {e}");
return null;
}
} }
private readonly StringBuilder _builder = new StringBuilder();
} }
} }

View file

@ -4,6 +4,7 @@ using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Media.Imaging;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using Avalonia.Threading; using Avalonia.Threading;
@ -255,7 +256,7 @@ namespace SourceGit.ViewModels
menu.Items.Add(blame); menu.Items.Add(blame);
menu.Items.Add(explore); menu.Items.Add(explore);
menu.Items.Add(new MenuItem { Header = "-" }); menu.Items.Add(new MenuItem { Header = "-" });
} }
var copyPath = new MenuItem(); var copyPath = new MenuItem();
copyPath.Header = App.Text("CopyPath"); copyPath.Header = App.Text("CopyPath");
@ -473,7 +474,8 @@ namespace SourceGit.ViewModels
var ext = Path.GetExtension(file.Path); var ext = Path.GetExtension(file.Path);
if (IMG_EXTS.Contains(ext)) if (IMG_EXTS.Contains(ext))
{ {
var bitmap = Commands.GetImageFileAsBitmap.Run(_repo, _commit.SHA, file.Path); var stream = Commands.QueryFileContent.Run(_repo, _commit.SHA, file.Path);
var bitmap = stream != null ? new Bitmap(stream) : null as Bitmap;
Dispatcher.UIThread.Invoke(() => Dispatcher.UIThread.Invoke(() =>
{ {
ViewRevisionFileContent = new Models.RevisionImageFile() { Image = bitmap }; ViewRevisionFileContent = new Models.RevisionImageFile() { Image = bitmap };
@ -491,7 +493,8 @@ namespace SourceGit.ViewModels
return; return;
} }
var content = new Commands.QueryFileContent(_repo, _commit.SHA, file.Path).Result(); var contentStream = Commands.QueryFileContent.Run(_repo, _commit.SHA, file.Path);
var content = new StreamReader(contentStream).ReadToEnd();
if (content.StartsWith("version https://git-lfs.github.com/spec/", StringComparison.Ordinal)) if (content.StartsWith("version https://git-lfs.github.com/spec/", StringComparison.Ordinal))
{ {
var obj = new Models.RevisionLFSObject() { Object = new Models.LFSObject() }; var obj = new Models.RevisionLFSObject() { Object = new Models.LFSObject() };

View file

@ -101,13 +101,13 @@ namespace SourceGit.ViewModels
var imgDiff = new Models.ImageDiff(); var imgDiff = new Models.ImageDiff();
if (option.Revisions.Count == 2) if (option.Revisions.Count == 2)
{ {
imgDiff.Old = Commands.GetImageFileAsBitmap.Run(repo, option.Revisions[0], oldPath); imgDiff.Old = BitmapFromRevisionFile(repo, option.Revisions[0], oldPath);
imgDiff.New = Commands.GetImageFileAsBitmap.Run(repo, option.Revisions[1], oldPath); imgDiff.New = BitmapFromRevisionFile(repo, option.Revisions[1], oldPath);
} }
else else
{ {
var fullPath = Path.Combine(repo, _option.Path); var fullPath = Path.Combine(repo, _option.Path);
imgDiff.Old = Commands.GetImageFileAsBitmap.Run(repo, "HEAD", oldPath); imgDiff.Old = BitmapFromRevisionFile(repo, "HEAD", oldPath);
imgDiff.New = File.Exists(fullPath) ? new Bitmap(fullPath) : null; imgDiff.New = File.Exists(fullPath) ? new Bitmap(fullPath) : null;
} }
rs = imgDiff; rs = imgDiff;
@ -163,6 +163,12 @@ namespace SourceGit.ViewModels
Task.Run(() => Commands.MergeTool.OpenForDiff(_repo, exec, args, _option)); Task.Run(() => Commands.MergeTool.OpenForDiff(_repo, exec, args, _option));
} }
private Bitmap BitmapFromRevisionFile(string repo, string revision, string file)
{
var stream = Commands.QueryFileContent.Run(repo, revision, file);
return stream != null ? new Bitmap(stream) : null;
}
private static readonly HashSet<string> IMG_EXTS = new HashSet<string>() private static readonly HashSet<string> IMG_EXTS = new HashSet<string>()
{ {
".ico", ".bmp", ".jpg", ".png", ".jpeg" ".ico", ".bmp", ".jpg", ".png", ".jpeg"