Skip to content

Commit 2df1830

Browse files
committed
enhance: try load lfs image from local cache first before loading it by git lfs smudge command
Signed-off-by: leo <[email protected]>
1 parent 7642651 commit 2df1830

File tree

8 files changed

+74
-30
lines changed

8 files changed

+74
-30
lines changed

src/Commands/QueryGitCommonDir.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System.IO;
2+
using System.Threading.Tasks;
3+
4+
namespace SourceGit.Commands
5+
{
6+
public class QueryGitCommonDir : Command
7+
{
8+
public QueryGitCommonDir(string workDir)
9+
{
10+
WorkingDirectory = workDir;
11+
Args = "rev-parse --git-common-dir";
12+
RaiseError = false;
13+
}
14+
15+
public async Task<string> GetResultAsync()
16+
{
17+
var rs = await ReadToEndAsync().ConfigureAwait(false);
18+
if (!rs.IsSuccess || string.IsNullOrEmpty(rs.StdOut))
19+
return string.Empty;
20+
21+
var dir = rs.StdOut.Trim();
22+
if (Path.IsPathRooted(dir))
23+
return dir;
24+
return Path.GetFullPath(Path.Combine(WorkingDirectory, dir));
25+
}
26+
}
27+
}

src/ViewModels/FileHistories.cs

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public object ViewContent
3636
set => SetProperty(ref _viewContent, value);
3737
}
3838

39-
public FileHistoriesSingleRevision(Repository repo, string file, Models.Commit revision, bool prevIsDiffMode)
39+
public FileHistoriesSingleRevision(string repo, string file, Models.Commit revision, bool prevIsDiffMode)
4040
{
4141
_repo = repo;
4242
_file = file;
@@ -49,7 +49,7 @@ public FileHistoriesSingleRevision(Repository repo, string file, Models.Commit r
4949

5050
public async Task<bool> ResetToSelectedRevisionAsync()
5151
{
52-
return await new Commands.Checkout(_repo.FullPath)
52+
return await new Commands.Checkout(_repo)
5353
.FileWithRevisionAsync(_file, $"{_revision.SHA}")
5454
.ConfigureAwait(false);
5555
}
@@ -59,13 +59,13 @@ public async Task OpenWithDefaultEditorAsync()
5959
if (_viewContent is not FileHistoriesRevisionFile { CanOpenWithDefaultEditor: true })
6060
return;
6161

62-
var fullPath = Native.OS.GetAbsPath(_repo.FullPath, _file);
62+
var fullPath = Native.OS.GetAbsPath(_repo, _file);
6363
var fileName = Path.GetFileNameWithoutExtension(fullPath) ?? "";
6464
var fileExt = Path.GetExtension(fullPath) ?? "";
6565
var tmpFile = Path.Combine(Path.GetTempPath(), $"{fileName}~{_revision.SHA.AsSpan(0, 10)}{fileExt}");
6666

6767
await Commands.SaveRevisionFile
68-
.RunAsync(_repo.FullPath, _revision.SHA, _file, tmpFile)
68+
.RunAsync(_repo, _revision.SHA, _file, tmpFile)
6969
.ConfigureAwait(false);
7070

7171
Native.OS.OpenWithDefaultEditor(tmpFile);
@@ -81,7 +81,7 @@ private void RefreshViewContent()
8181

8282
Task.Run(async () =>
8383
{
84-
var objs = await new Commands.QueryRevisionObjects(_repo.FullPath, _revision.SHA, _file)
84+
var objs = await new Commands.QueryRevisionObjects(_repo, _revision.SHA, _file)
8585
.GetResultAsync()
8686
.ConfigureAwait(false);
8787

@@ -100,31 +100,31 @@ private async Task<object> GetRevisionFileContentAsync(Models.Object obj)
100100
{
101101
if (obj.Type == Models.ObjectType.Blob)
102102
{
103-
var isBinary = await new Commands.IsBinary(_repo.FullPath, _revision.SHA, _file).GetResultAsync().ConfigureAwait(false);
103+
var isBinary = await new Commands.IsBinary(_repo, _revision.SHA, _file).GetResultAsync().ConfigureAwait(false);
104104
if (isBinary)
105105
{
106106
var imgDecoder = ImageSource.GetDecoder(_file);
107107
if (imgDecoder != Models.ImageDecoder.None)
108108
{
109-
var source = await ImageSource.FromRevisionAsync(_repo.FullPath, _revision.SHA, _file, imgDecoder).ConfigureAwait(false);
109+
var source = await ImageSource.FromRevisionAsync(_repo, _revision.SHA, _file, imgDecoder).ConfigureAwait(false);
110110
var image = new Models.RevisionImageFile(_file, source.Bitmap, source.Size);
111111
return new FileHistoriesRevisionFile(_file, image, true);
112112
}
113113

114-
var size = await new Commands.QueryFileSize(_repo.FullPath, _file, _revision.SHA).GetResultAsync().ConfigureAwait(false);
114+
var size = await new Commands.QueryFileSize(_repo, _file, _revision.SHA).GetResultAsync().ConfigureAwait(false);
115115
var binaryFile = new Models.RevisionBinaryFile() { Size = size };
116116
return new FileHistoriesRevisionFile(_file, binaryFile, true);
117117
}
118118

119-
var contentStream = await Commands.QueryFileContent.RunAsync(_repo.FullPath, _revision.SHA, _file).ConfigureAwait(false);
119+
var contentStream = await Commands.QueryFileContent.RunAsync(_repo, _revision.SHA, _file).ConfigureAwait(false);
120120
var content = await new StreamReader(contentStream).ReadToEndAsync();
121121
var lfs = Models.LFSObject.Parse(content);
122122
if (lfs != null)
123123
{
124124
var imgDecoder = ImageSource.GetDecoder(_file);
125125
if (imgDecoder != Models.ImageDecoder.None)
126126
{
127-
var combined = new RevisionLFSImage(_repo.FullPath, _file, lfs, imgDecoder);
127+
var combined = new RevisionLFSImage(_repo, _file, lfs, imgDecoder);
128128
return new FileHistoriesRevisionFile(_file, combined, true);
129129
}
130130

@@ -138,7 +138,7 @@ private async Task<object> GetRevisionFileContentAsync(Models.Object obj)
138138

139139
if (obj.Type == Models.ObjectType.Commit)
140140
{
141-
var submoduleRoot = Path.Combine(_repo.FullPath, _file);
141+
var submoduleRoot = Path.Combine(_repo, _file);
142142
var commit = await new Commands.QuerySingleCommit(submoduleRoot, obj.SHA).GetResultAsync().ConfigureAwait(false);
143143
var message = commit != null ? await new Commands.QueryCommitFullMessage(submoduleRoot, obj.SHA).GetResultAsync().ConfigureAwait(false) : null;
144144
var module = new Models.RevisionSubmodule()
@@ -156,10 +156,10 @@ private async Task<object> GetRevisionFileContentAsync(Models.Object obj)
156156
private void SetViewContentAsDiff()
157157
{
158158
var option = new Models.DiffOption(_revision, _file);
159-
ViewContent = new DiffContext(_repo.FullPath, option, _viewContent as DiffContext);
159+
ViewContent = new DiffContext(_repo, option, _viewContent as DiffContext);
160160
}
161161

162-
private Repository _repo = null;
162+
private string _repo = null;
163163
private string _file = null;
164164
private Models.Commit _revision = null;
165165
private bool _isDiffMode = false;
@@ -186,7 +186,7 @@ public DiffContext ViewContent
186186
set => SetProperty(ref _viewContent, value);
187187
}
188188

189-
public FileHistoriesCompareRevisions(Repository repo, string file, Models.Commit start, Models.Commit end)
189+
public FileHistoriesCompareRevisions(string repo, string file, Models.Commit start, Models.Commit end)
190190
{
191191
_repo = repo;
192192
_file = file;
@@ -204,28 +204,28 @@ public void Swap()
204204
public async Task<bool> SaveAsPatch(string saveTo)
205205
{
206206
return await Commands.SaveChangesAsPatch
207-
.ProcessRevisionCompareChangesAsync(_repo.FullPath, _changes, _startPoint.SHA, _endPoint.SHA, saveTo)
207+
.ProcessRevisionCompareChangesAsync(_repo, _changes, _startPoint.SHA, _endPoint.SHA, saveTo)
208208
.ConfigureAwait(false);
209209
}
210210

211211
private void RefreshViewContent()
212212
{
213213
Task.Run(async () =>
214214
{
215-
_changes = await new Commands.CompareRevisions(_repo.FullPath, _startPoint.SHA, _endPoint.SHA, _file).ReadAsync().ConfigureAwait(false);
215+
_changes = await new Commands.CompareRevisions(_repo, _startPoint.SHA, _endPoint.SHA, _file).ReadAsync().ConfigureAwait(false);
216216
if (_changes.Count == 0)
217217
{
218218
Dispatcher.UIThread.Post(() => ViewContent = null);
219219
}
220220
else
221221
{
222222
var option = new Models.DiffOption(_startPoint.SHA, _endPoint.SHA, _changes[0]);
223-
Dispatcher.UIThread.Post(() => ViewContent = new DiffContext(_repo.FullPath, option, _viewContent));
223+
Dispatcher.UIThread.Post(() => ViewContent = new DiffContext(_repo, option, _viewContent));
224224
}
225225
});
226226
}
227227

228-
private Repository _repo = null;
228+
private string _repo = null;
229229
private string _file = null;
230230
private Models.Commit _startPoint = null;
231231
private Models.Commit _endPoint = null;
@@ -264,7 +264,7 @@ public object ViewContent
264264
private set => SetProperty(ref _viewContent, value);
265265
}
266266

267-
public FileHistories(Repository repo, string file, string commit = null)
267+
public FileHistories(string repo, string file, string commit = null)
268268
{
269269
if (!string.IsNullOrEmpty(commit))
270270
Title = $"{file} @ {commit}";
@@ -282,7 +282,7 @@ public FileHistories(Repository repo, string file, string commit = null)
282282
.Append(" -- ")
283283
.Append(file.Quoted());
284284

285-
var commits = await new Commands.QueryCommits(_repo.FullPath, argsBuilder.ToString(), false)
285+
var commits = await new Commands.QueryCommits(_repo, argsBuilder.ToString(), false)
286286
.GetResultAsync()
287287
.ConfigureAwait(false);
288288

@@ -311,7 +311,18 @@ public FileHistories(Repository repo, string file, string commit = null)
311311

312312
public void NavigateToCommit(Models.Commit commit)
313313
{
314-
_repo.NavigateToCommit(commit.SHA);
314+
var launcher = App.GetLauncher();
315+
if (launcher != null)
316+
{
317+
foreach (var page in launcher.Pages)
318+
{
319+
if (page.Data is Repository repo && repo.FullPath.Equals(_repo, StringComparison.Ordinal))
320+
{
321+
repo.NavigateToCommit(commit.SHA);
322+
break;
323+
}
324+
}
325+
}
315326
}
316327

317328
public string GetCommitFullMessage(Models.Commit commit)
@@ -320,12 +331,12 @@ public string GetCommitFullMessage(Models.Commit commit)
320331
if (_fullCommitMessages.TryGetValue(sha, out var msg))
321332
return msg;
322333

323-
msg = new Commands.QueryCommitFullMessage(_repo.FullPath, sha).GetResult();
334+
msg = new Commands.QueryCommitFullMessage(_repo, sha).GetResult();
324335
_fullCommitMessages[sha] = msg;
325336
return msg;
326337
}
327338

328-
private readonly Repository _repo = null;
339+
private readonly string _repo = null;
329340
private bool _isLoading = true;
330341
private bool _prevIsDiffMode = true;
331342
private List<Models.Commit> _commits = null;

src/ViewModels/ImageSource.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.IO;
44
using System.Runtime.InteropServices;
55
using System.Threading.Tasks;
6+
67
using Avalonia;
78
using Avalonia.Media.Imaging;
89
using Avalonia.Platform;
@@ -52,7 +53,12 @@ public static async Task<ImageSource> FromLFSObjectAsync(string repo, Models.LFS
5253
if (string.IsNullOrEmpty(lfs.Oid) || lfs.Size == 0)
5354
return new ImageSource(null, 0);
5455

55-
var stream = await Commands.QueryFileContent.FromLFSAsync(repo, lfs.Oid, lfs.Size).ConfigureAwait(false);
56+
var commonDir = await new Commands.QueryGitCommonDir(repo).GetResultAsync().ConfigureAwait(false);
57+
var localFile = Path.Combine(commonDir, "lfs", "objects", lfs.Oid.Substring(0, 2), lfs.Oid.Substring(2, 2), lfs.Oid);
58+
if (File.Exists(localFile))
59+
return await FromFileAsync(localFile, decoder).ConfigureAwait(false);
60+
61+
await using var stream = await Commands.QueryFileContent.FromLFSAsync(repo, lfs.Oid, lfs.Size).ConfigureAwait(false);
5662
return await Task.Run(() => LoadFromStream(stream, decoder)).ConfigureAwait(false);
5763
}
5864

src/ViewModels/RevisionLFSImage.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public RevisionLFSImage(string repo, string file, Models.LFSObject lfs, Models.I
2525
{
2626
var source = await ImageSource.FromLFSObjectAsync(repo, lfs, decoder).ConfigureAwait(false);
2727
var img = new Models.RevisionImageFile(file, source.Bitmap, source.Size);
28-
Dispatcher.UIThread.Invoke(() => Image = img);
28+
Dispatcher.UIThread.Post(() => Image = img);
2929
});
3030
}
3131

src/Views/CommitDetail.axaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ public ContextMenu CreateChangeContextMenu(Models.Change change)
137137
history.Icon = App.CreateMenuIcon("Icons.Histories");
138138
history.Click += (_, ev) =>
139139
{
140-
App.ShowWindow(new ViewModels.FileHistories(repo, change.Path, commit.SHA));
140+
App.ShowWindow(new ViewModels.FileHistories(repo.FullPath, change.Path, commit.SHA));
141141
ev.Handled = true;
142142
};
143143

src/Views/RevisionFileTreeView.axaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,7 @@ public ContextMenu CreateRevisionFileContextMenu(ViewModels.Repository repo, Vie
535535
history.Icon = App.CreateMenuIcon("Icons.Histories");
536536
history.Click += (_, ev) =>
537537
{
538-
App.ShowWindow(new ViewModels.FileHistories(repo, file.Path, commit.SHA));
538+
App.ShowWindow(new ViewModels.FileHistories(repo.FullPath, file.Path, commit.SHA));
539539
ev.Handled = true;
540540
};
541541

src/Views/SubmodulesView.axaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ private void OnItemContextRequested(object sender, ContextRequestedEventArgs e)
248248
histories.Icon = App.CreateMenuIcon("Icons.Histories");
249249
histories.Click += (_, ev) =>
250250
{
251-
App.ShowWindow(new ViewModels.FileHistories(repo, submodule.Path));
251+
App.ShowWindow(new ViewModels.FileHistories(repo.FullPath, submodule.Path));
252252
ev.Handled = true;
253253
};
254254

src/Views/WorkingCopy.axaml.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,7 @@ private ContextMenu CreateContextMenuForUnstagedChanges(ViewModels.WorkingCopy v
620620
history.Icon = App.CreateMenuIcon("Icons.Histories");
621621
history.Click += (_, e) =>
622622
{
623-
App.ShowWindow(new ViewModels.FileHistories(repo, change.Path));
623+
App.ShowWindow(new ViewModels.FileHistories(repo.FullPath, change.Path));
624624
e.Handled = true;
625625
};
626626

@@ -1086,7 +1086,7 @@ public ContextMenu CreateContextMenuForStagedChanges(ViewModels.WorkingCopy vm,
10861086
history.Icon = App.CreateMenuIcon("Icons.Histories");
10871087
history.Click += (_, e) =>
10881088
{
1089-
App.ShowWindow(new ViewModels.FileHistories(repo, change.Path));
1089+
App.ShowWindow(new ViewModels.FileHistories(repo.FullPath, change.Path));
10901090
e.Handled = true;
10911091
};
10921092

0 commit comments

Comments
 (0)