fix: main thread deadlock cause by calling .Result directly (#1720)

Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
leo
2025-08-12 16:03:58 +08:00
parent 20ca646307
commit bd81ccd94f
29 changed files with 475 additions and 338 deletions

View File

@@ -63,10 +63,7 @@ namespace SourceGit.ViewModels
if (_commitMessages.TryGetValue(sha, out var msg))
return msg;
msg = new Commands.QueryCommitFullMessage(_repo, sha)
.GetResultAsync()
.Result;
msg = new Commands.QueryCommitFullMessage(_repo, sha).GetResult();
_commitMessages[sha] = msg;
return msg;
}

View File

@@ -20,7 +20,7 @@ namespace SourceGit.ViewModels
{
Name = branch.Name;
Head = branch.Head;
Revision = new Commands.QuerySingleCommit(repo.FullPath, branch.Head).GetResultAsync().Result ?? new Models.Commit() { SHA = branch.Head };
Revision = new Commands.QuerySingleCommit(repo.FullPath, branch.Head).GetResult() ?? new Models.Commit() { SHA = branch.Head };
}
}
@@ -69,7 +69,7 @@ namespace SourceGit.ViewModels
if (!isSubmodule && (_change.ConflictReason is Models.ConflictReason.BothAdded or Models.ConflictReason.BothModified))
{
CanUseExternalMergeTool = true;
IsResolved = new Commands.IsConflictResolved(repo.FullPath, change).GetResultAsync().Result;
IsResolved = new Commands.IsConflictResolved(repo.FullPath, change).GetResult();
}
switch (wc.InProgressContext)

View File

@@ -51,7 +51,7 @@ namespace SourceGit.ViewModels
_basedOn = branch.Head;
BasedOn = branch;
SignTag = new Commands.Config(repo.FullPath).GetAsync("tag.gpgsign").Result.Equals("true", StringComparison.OrdinalIgnoreCase);
SignTag = new Commands.Config(repo.FullPath).Get("tag.gpgsign").Equals("true", StringComparison.OrdinalIgnoreCase);
}
public CreateTag(Repository repo, Models.Commit commit)
@@ -60,7 +60,7 @@ namespace SourceGit.ViewModels
_basedOn = commit.SHA;
BasedOn = commit;
SignTag = new Commands.Config(repo.FullPath).GetAsync("tag.gpgsign").Result.Equals("true", StringComparison.OrdinalIgnoreCase);
SignTag = new Commands.Config(repo.FullPath).Get("tag.gpgsign").Equals("true", StringComparison.OrdinalIgnoreCase);
}
public static ValidationResult ValidateTagName(string name, ValidationContext ctx)

View File

@@ -87,7 +87,7 @@ namespace SourceGit.ViewModels
if (_cachedCommitFullMessage.TryGetValue(sha, out var msg))
return msg;
msg = new Commands.QueryCommitFullMessage(_repo.FullPath, sha).GetResultAsync().Result;
msg = new Commands.QueryCommitFullMessage(_repo.FullPath, sha).GetResult();
_cachedCommitFullMessage[sha] = msg;
return msg;
}

View File

@@ -74,89 +74,83 @@ namespace SourceGit.ViewModels
private void RefreshViewContent()
{
if (_isDiffMode)
SetViewContentAsDiff();
else
SetViewContentAsRevisionFile();
}
private void SetViewContentAsRevisionFile()
{
var objs = new Commands.QueryRevisionObjects(_repo.FullPath, _revision.SHA, _file).GetResultAsync().Result;
if (objs.Count == 0)
{
ViewContent = new FileHistoriesRevisionFile(_file);
SetViewContentAsDiff();
return;
}
var obj = objs[0];
switch (obj.Type)
Task.Run(async () =>
{
case Models.ObjectType.Blob:
Task.Run(async () =>
var objs = await new Commands.QueryRevisionObjects(_repo.FullPath, _revision.SHA, _file)
.GetResultAsync()
.ConfigureAwait(false);
if (objs.Count == 0)
{
Dispatcher.UIThread.Post(() => ViewContent = new FileHistoriesRevisionFile(_file));
return;
}
var revisionContent = await GetRevisionFileContentAsync(objs[0]).ConfigureAwait(false);
Dispatcher.UIThread.Post(() => ViewContent = revisionContent);
});
}
private async Task<object> GetRevisionFileContentAsync(Models.Object obj)
{
if (obj.Type == Models.ObjectType.Blob)
{
var isBinary = await new Commands.IsBinary(_repo.FullPath, _revision.SHA, _file).GetResultAsync().ConfigureAwait(false);
if (isBinary)
{
var imgDecoder = ImageSource.GetDecoder(_file);
if (imgDecoder != Models.ImageDecoder.None)
{
var isBinary = await new Commands.IsBinary(_repo.FullPath, _revision.SHA, _file).GetResultAsync().ConfigureAwait(false);
if (isBinary)
{
var imgDecoder = ImageSource.GetDecoder(_file);
if (imgDecoder != Models.ImageDecoder.None)
{
var source = await ImageSource.FromRevisionAsync(_repo.FullPath, _revision.SHA, _file, imgDecoder).ConfigureAwait(false);
var image = new Models.RevisionImageFile(_file, source.Bitmap, source.Size);
Dispatcher.UIThread.Post(() => ViewContent = new FileHistoriesRevisionFile(_file, image, true));
}
else
{
var size = await new Commands.QueryFileSize(_repo.FullPath, _file, _revision.SHA).GetResultAsync().ConfigureAwait(false);
var binaryFile = new Models.RevisionBinaryFile() { Size = size };
Dispatcher.UIThread.Post(() => ViewContent = new FileHistoriesRevisionFile(_file, binaryFile, true));
}
var source = await ImageSource.FromRevisionAsync(_repo.FullPath, _revision.SHA, _file, imgDecoder).ConfigureAwait(false);
var image = new Models.RevisionImageFile(_file, source.Bitmap, source.Size);
return new FileHistoriesRevisionFile(_file, image, true);
}
return;
}
var size = await new Commands.QueryFileSize(_repo.FullPath, _file, _revision.SHA).GetResultAsync().ConfigureAwait(false);
var binaryFile = new Models.RevisionBinaryFile() { Size = size };
return new FileHistoriesRevisionFile(_file, binaryFile, true);
}
var contentStream = await Commands.QueryFileContent.RunAsync(_repo.FullPath, _revision.SHA, _file).ConfigureAwait(false);
var content = await new StreamReader(contentStream).ReadToEndAsync();
var lfs = Models.LFSObject.Parse(content);
if (lfs != null)
{
var imgDecoder = ImageSource.GetDecoder(_file);
if (imgDecoder != Models.ImageDecoder.None)
{
var combined = new RevisionLFSImage(_repo.FullPath, _file, lfs, imgDecoder);
Dispatcher.UIThread.Post(() => ViewContent = new FileHistoriesRevisionFile(_file, combined, true));
}
else
{
var rlfs = new Models.RevisionLFSObject() { Object = lfs };
Dispatcher.UIThread.Post(() => ViewContent = new FileHistoriesRevisionFile(_file, rlfs, true));
}
}
else
{
var txt = new Models.RevisionTextFile() { FileName = obj.Path, Content = content };
Dispatcher.UIThread.Post(() => ViewContent = new FileHistoriesRevisionFile(_file, txt, true));
}
});
break;
case Models.ObjectType.Commit:
Task.Run(async () =>
var contentStream = await Commands.QueryFileContent.RunAsync(_repo.FullPath, _revision.SHA, _file).ConfigureAwait(false);
var content = await new StreamReader(contentStream).ReadToEndAsync();
var lfs = Models.LFSObject.Parse(content);
if (lfs != null)
{
var imgDecoder = ImageSource.GetDecoder(_file);
if (imgDecoder != Models.ImageDecoder.None)
{
var submoduleRoot = Path.Combine(_repo.FullPath, _file);
var commit = await new Commands.QuerySingleCommit(submoduleRoot, obj.SHA).GetResultAsync().ConfigureAwait(false);
var message = commit != null ? await new Commands.QueryCommitFullMessage(submoduleRoot, obj.SHA).GetResultAsync().ConfigureAwait(false) : null;
var module = new Models.RevisionSubmodule()
{
Commit = commit ?? new Models.Commit() { SHA = obj.SHA },
FullMessage = new Models.CommitFullMessage { Message = message }
};
var combined = new RevisionLFSImage(_repo.FullPath, _file, lfs, imgDecoder);
return new FileHistoriesRevisionFile(_file, combined, true);
}
Dispatcher.UIThread.Post(() => ViewContent = new FileHistoriesRevisionFile(_file, module));
});
break;
default:
ViewContent = new FileHistoriesRevisionFile(_file);
break;
var rlfs = new Models.RevisionLFSObject() { Object = lfs };
return new FileHistoriesRevisionFile(_file, rlfs, true);
}
var txt = new Models.RevisionTextFile() { FileName = obj.Path, Content = content };
return new FileHistoriesRevisionFile(_file, txt, true);
}
if (obj.Type == Models.ObjectType.Commit)
{
var submoduleRoot = Path.Combine(_repo.FullPath, _file);
var commit = await new Commands.QuerySingleCommit(submoduleRoot, obj.SHA).GetResultAsync().ConfigureAwait(false);
var message = commit != null ? await new Commands.QueryCommitFullMessage(submoduleRoot, obj.SHA).GetResultAsync().ConfigureAwait(false) : null;
var module = new Models.RevisionSubmodule()
{
Commit = commit ?? new Models.Commit() { SHA = obj.SHA },
FullMessage = new Models.CommitFullMessage { Message = message }
};
return new FileHistoriesRevisionFile(_file, module);
}
return new FileHistoriesRevisionFile(_file);
}
private void SetViewContentAsDiff()
@@ -326,7 +320,7 @@ namespace SourceGit.ViewModels
if (_fullCommitMessages.TryGetValue(sha, out var msg))
return msg;
msg = new Commands.QueryCommitFullMessage(_repo.FullPath, sha).GetResultAsync().Result;
msg = new Commands.QueryCommitFullMessage(_repo.FullPath, sha).GetResult();
_fullCommitMessages[sha] = msg;
return msg;
}

View File

@@ -11,9 +11,9 @@ namespace SourceGit.ViewModels
_cmd = cmd;
}
public Task<bool> AbortAsync()
public async Task<bool> AbortAsync()
{
return new Commands.Command()
return await new Commands.Command()
{
WorkingDirectory = _repo,
Context = _repo,
@@ -21,9 +21,9 @@ namespace SourceGit.ViewModels
}.ExecAsync();
}
public virtual Task<bool> SkipAsync()
public virtual async Task<bool> SkipAsync()
{
return new Commands.Command()
return await new Commands.Command()
{
WorkingDirectory = _repo,
Context = _repo,
@@ -31,9 +31,9 @@ namespace SourceGit.ViewModels
}.ExecAsync();
}
public virtual Task<bool> ContinueAsync()
public virtual async Task<bool> ContinueAsync()
{
return new Commands.Command()
return await new Commands.Command()
{
WorkingDirectory = _repo,
Context = _repo,
@@ -61,7 +61,7 @@ namespace SourceGit.ViewModels
public CherryPickInProgress(Repository repo) : base(repo.FullPath, "cherry-pick")
{
var headSHA = File.ReadAllText(Path.Combine(repo.GitDir, "CHERRY_PICK_HEAD")).Trim();
Head = new Commands.QuerySingleCommit(repo.FullPath, headSHA).GetResultAsync().Result ?? new Models.Commit() { SHA = headSHA };
Head = new Commands.QuerySingleCommit(repo.FullPath, headSHA).GetResult() ?? new Models.Commit() { SHA = headSHA };
HeadName = Head.GetFriendlyName();
}
}
@@ -99,19 +99,19 @@ namespace SourceGit.ViewModels
var stoppedSHAPath = Path.Combine(repo.GitDir, "rebase-merge", "stopped-sha");
var stoppedSHA = File.Exists(stoppedSHAPath)
? File.ReadAllText(stoppedSHAPath).Trim()
: new Commands.QueryRevisionByRefName(repo.FullPath, HeadName).GetResultAsync().Result;
: new Commands.QueryRevisionByRefName(repo.FullPath, HeadName).GetResult();
if (!string.IsNullOrEmpty(stoppedSHA))
StoppedAt = new Commands.QuerySingleCommit(repo.FullPath, stoppedSHA).GetResultAsync().Result ?? new Models.Commit() { SHA = stoppedSHA };
StoppedAt = new Commands.QuerySingleCommit(repo.FullPath, stoppedSHA).GetResult() ?? new Models.Commit() { SHA = stoppedSHA };
var ontoSHA = File.ReadAllText(Path.Combine(repo.GitDir, "rebase-merge", "onto")).Trim();
Onto = new Commands.QuerySingleCommit(repo.FullPath, ontoSHA).GetResultAsync().Result ?? new Models.Commit() { SHA = ontoSHA };
Onto = new Commands.QuerySingleCommit(repo.FullPath, ontoSHA).GetResult() ?? new Models.Commit() { SHA = ontoSHA };
BaseName = Onto.GetFriendlyName();
}
public override Task<bool> ContinueAsync()
public override async Task<bool> ContinueAsync()
{
return new Commands.Command()
return await new Commands.Command()
{
WorkingDirectory = _repo,
Context = _repo,
@@ -131,7 +131,7 @@ namespace SourceGit.ViewModels
public RevertInProgress(Repository repo) : base(repo.FullPath, "revert")
{
var headSHA = File.ReadAllText(Path.Combine(repo.GitDir, "REVERT_HEAD")).Trim();
Head = new Commands.QuerySingleCommit(repo.FullPath, headSHA).GetResultAsync().Result ?? new Models.Commit() { SHA = headSHA };
Head = new Commands.QuerySingleCommit(repo.FullPath, headSHA).GetResult() ?? new Models.Commit() { SHA = headSHA };
}
}
@@ -154,16 +154,16 @@ namespace SourceGit.ViewModels
public MergeInProgress(Repository repo) : base(repo.FullPath, "merge")
{
Current = new Commands.QueryCurrentBranch(repo.FullPath).GetResultAsync().Result;
Current = new Commands.QueryCurrentBranch(repo.FullPath).GetResult();
var sourceSHA = File.ReadAllText(Path.Combine(repo.GitDir, "MERGE_HEAD")).Trim();
Source = new Commands.QuerySingleCommit(repo.FullPath, sourceSHA).GetResultAsync().Result ?? new Models.Commit() { SHA = sourceSHA };
Source = new Commands.QuerySingleCommit(repo.FullPath, sourceSHA).GetResult() ?? new Models.Commit() { SHA = sourceSHA };
SourceName = Source.GetFriendlyName();
}
public override Task<bool> SkipAsync()
public override async Task<bool> SkipAsync()
{
return Task.FromResult(true);
return await Task.FromResult(true);
}
}
}

View File

@@ -94,7 +94,7 @@ namespace SourceGit.ViewModels
foreach (var w in pref.Workspaces)
w.IsActive = false;
var test = new Commands.QueryRepositoryRootPath(startupRepo).GetResultAsync().Result;
var test = new Commands.QueryRepositoryRootPath(startupRepo).GetResult();
if (!test.IsSuccess || string.IsNullOrEmpty(test.StdOut))
{
Pages[0].Notifications.Add(new Models.Notification
@@ -344,7 +344,7 @@ namespace SourceGit.ViewModels
return;
}
var isBare = new Commands.IsBareRepository(node.Id).GetResultAsync().Result;
var isBare = new Commands.IsBareRepository(node.Id).GetResult();
var gitDir = isBare ? node.Id : GetRepositoryGitDir(node.Id);
if (string.IsNullOrEmpty(gitDir))
{
@@ -446,7 +446,7 @@ namespace SourceGit.ViewModels
return null;
}
return new Commands.QueryGitDir(repo).GetResultAsync().Result;
return new Commands.QueryGitDir(repo).GetResult();
}
private void CloseRepositoryInTab(LauncherPage page, bool removeFromWorkspace = true)

View File

@@ -79,7 +79,7 @@ namespace SourceGit.ViewModels
private Models.MergeMode AutoSelectMergeMode()
{
var config = new Commands.Config(_repo.FullPath).GetAsync($"branch.{Into}.mergeoptions").Result;
var config = new Commands.Config(_repo.FullPath).Get($"branch.{Into}.mergeoptions");
var mode = config switch
{
"--ff-only" => Models.MergeMode.FastForward,

View File

@@ -96,7 +96,7 @@ namespace SourceGit.ViewModels
if (value != _settings.EnableTopoOrderInHistories)
{
_settings.EnableTopoOrderInHistories = value;
Task.Run(RefreshCommits);
RefreshCommits();
}
}
}
@@ -109,7 +109,7 @@ namespace SourceGit.ViewModels
if (value != _settings.HistoryShowFlags)
{
_settings.HistoryShowFlags = value;
Task.Run(RefreshCommits);
RefreshCommits();
}
}
}
@@ -266,7 +266,7 @@ namespace SourceGit.ViewModels
{
_settings.IncludeUntrackedInLocalChanges = value;
OnPropertyChanged();
Task.Run(RefreshWorkingCopyChanges);
RefreshWorkingCopyChanges();
}
}
}
@@ -536,7 +536,7 @@ namespace SourceGit.ViewModels
var gitDirForWatcher = _gitDir;
if (_gitDir.Replace('\\', '/').IndexOf("/worktrees/", StringComparison.Ordinal) > 0)
{
var commonDir = new Commands.QueryGitCommonDir(_fullpath).GetResultAsync().Result;
var commonDir = new Commands.QueryGitCommonDir(_fullpath).GetResult();
if (!string.IsNullOrEmpty(commonDir))
gitDirForWatcher = commonDir;
}
@@ -762,13 +762,13 @@ namespace SourceGit.ViewModels
public void RefreshAll()
{
Task.Run(RefreshCommits);
Task.Run(RefreshBranches);
Task.Run(RefreshTags);
Task.Run(RefreshSubmodules);
Task.Run(RefreshWorktrees);
Task.Run(RefreshWorkingCopyChanges);
Task.Run(RefreshStashes);
RefreshCommits();
RefreshBranches();
RefreshTags();
RefreshSubmodules();
RefreshWorktrees();
RefreshWorkingCopyChanges();
RefreshStashes();
Task.Run(async () =>
{
@@ -959,10 +959,10 @@ namespace SourceGit.ViewModels
{
if (_watcher == null)
{
Task.Run(RefreshBranches);
Task.Run(RefreshCommits);
Task.Run(RefreshWorkingCopyChanges);
Task.Run(RefreshWorktrees);
RefreshBranches();
RefreshCommits();
RefreshWorkingCopyChanges();
RefreshWorktrees();
}
else
{
@@ -974,8 +974,8 @@ namespace SourceGit.ViewModels
{
if (_watcher == null)
{
Task.Run(RefreshTags);
Task.Run(RefreshCommits);
RefreshTags();
RefreshCommits();
}
else
{
@@ -986,7 +986,7 @@ namespace SourceGit.ViewModels
public void MarkWorkingCopyDirtyManually()
{
if (_watcher == null)
Task.Run(RefreshWorkingCopyChanges);
RefreshWorkingCopyChanges();
else
_watcher.MarkWorkingCopyDirtyManually();
}
@@ -1028,7 +1028,7 @@ namespace SourceGit.ViewModels
ResetBranchTreeFilterMode(LocalBranchTrees);
ResetBranchTreeFilterMode(RemoteBranchTrees);
ResetTagFilterMode();
Task.Run(RefreshCommits);
RefreshCommits();
}
public void RemoveHistoriesFilter(Models.Filter filter)
@@ -1186,74 +1186,83 @@ namespace SourceGit.ViewModels
public void RefreshBranches()
{
var branches = new Commands.QueryBranches(_fullpath).GetResultAsync().Result;
var remotes = new Commands.QueryRemotes(_fullpath).GetResultAsync().Result;
var builder = BuildBranchTree(branches, remotes);
Dispatcher.UIThread.Invoke(() =>
Task.Run(async () =>
{
lock (_lockRemotes)
Remotes = remotes;
var branches = await new Commands.QueryBranches(_fullpath).GetResultAsync().ConfigureAwait(false);
var remotes = await new Commands.QueryRemotes(_fullpath).GetResultAsync().ConfigureAwait(false);
var builder = BuildBranchTree(branches, remotes);
Branches = branches;
CurrentBranch = branches.Find(x => x.IsCurrent);
LocalBranchTrees = builder.Locals;
RemoteBranchTrees = builder.Remotes;
var localBranchesCount = 0;
foreach (var b in branches)
Dispatcher.UIThread.Invoke(() =>
{
if (b.IsLocal && !b.IsDetachedHead)
localBranchesCount++;
}
LocalBranchesCount = localBranchesCount;
lock (_lockRemotes)
Remotes = remotes;
if (_workingCopy != null)
_workingCopy.HasRemotes = remotes.Count > 0;
Branches = branches;
CurrentBranch = branches.Find(x => x.IsCurrent);
LocalBranchTrees = builder.Locals;
RemoteBranchTrees = builder.Remotes;
var hasPendingPullOrPush = CurrentBranch?.TrackStatus.IsVisible ?? false;
GetOwnerPage()?.ChangeDirtyState(Models.DirtyState.HasPendingPullOrPush, !hasPendingPullOrPush);
var localBranchesCount = 0;
foreach (var b in branches)
{
if (b.IsLocal && !b.IsDetachedHead)
localBranchesCount++;
}
LocalBranchesCount = localBranchesCount;
if (_workingCopy != null)
_workingCopy.HasRemotes = remotes.Count > 0;
var hasPendingPullOrPush = CurrentBranch?.TrackStatus.IsVisible ?? false;
GetOwnerPage()?.ChangeDirtyState(Models.DirtyState.HasPendingPullOrPush, !hasPendingPullOrPush);
});
});
}
public void RefreshWorktrees()
{
var worktrees = new Commands.Worktree(_fullpath).ReadAllAsync().Result;
if (worktrees.Count > 0)
Task.Run(async () =>
{
var cleaned = new List<Models.Worktree>();
var normalizedGitDir = _gitDir.Replace('\\', '/');
foreach (var worktree in worktrees)
var worktrees = await new Commands.Worktree(_fullpath).ReadAllAsync().ConfigureAwait(false);
if (worktrees.Count > 0)
{
if (worktree.FullPath.Equals(_fullpath, StringComparison.Ordinal) ||
worktree.FullPath.Equals(normalizedGitDir, StringComparison.Ordinal))
continue;
var cleaned = new List<Models.Worktree>();
var normalizedGitDir = _gitDir.Replace('\\', '/');
cleaned.Add(worktree);
foreach (var worktree in worktrees)
{
if (worktree.FullPath.Equals(_fullpath, StringComparison.Ordinal) ||
worktree.FullPath.Equals(normalizedGitDir, StringComparison.Ordinal))
continue;
cleaned.Add(worktree);
}
Dispatcher.UIThread.Invoke(() =>
{
Worktrees = cleaned;
});
}
Dispatcher.UIThread.Invoke(() =>
else
{
Worktrees = cleaned;
});
}
else
{
Dispatcher.UIThread.Invoke(() =>
{
Worktrees = worktrees;
});
}
Dispatcher.UIThread.Invoke(() =>
{
Worktrees = worktrees;
});
}
});
}
public void RefreshTags()
{
var tags = new Commands.QueryTags(_fullpath).GetResultAsync().Result;
Dispatcher.UIThread.Invoke(() =>
Task.Run(async () =>
{
Tags = tags;
VisibleTags = BuildVisibleTags();
var tags = await new Commands.QueryTags(_fullpath).GetResultAsync().ConfigureAwait(false);
Dispatcher.UIThread.Invoke(() =>
{
Tags = tags;
VisibleTags = BuildVisibleTags();
});
});
}
@@ -1261,47 +1270,50 @@ namespace SourceGit.ViewModels
{
Dispatcher.UIThread.Invoke(() => _histories.IsLoading = true);
var builder = new StringBuilder();
builder.Append($"-{Preferences.Instance.MaxHistoryCommits} ");
if (_settings.EnableTopoOrderInHistories)
builder.Append("--topo-order ");
else
builder.Append("--date-order ");
if (_settings.HistoryShowFlags.HasFlag(Models.HistoryShowFlags.Reflog))
builder.Append("--reflog ");
if (_settings.HistoryShowFlags.HasFlag(Models.HistoryShowFlags.FirstParentOnly))
builder.Append("--first-parent ");
if (_settings.HistoryShowFlags.HasFlag(Models.HistoryShowFlags.SimplifyByDecoration))
builder.Append("--simplify-by-decoration ");
var filters = _settings.BuildHistoriesFilter();
if (string.IsNullOrEmpty(filters))
builder.Append("--branches --remotes --tags HEAD");
else
builder.Append(filters);
var commits = new Commands.QueryCommits(_fullpath, builder.ToString()).GetResultAsync().Result;
var graph = Models.CommitGraph.Parse(commits, _settings.HistoryShowFlags.HasFlag(Models.HistoryShowFlags.FirstParentOnly));
Dispatcher.UIThread.Invoke(() =>
Task.Run(async () =>
{
if (_histories != null)
var builder = new StringBuilder();
builder.Append($"-{Preferences.Instance.MaxHistoryCommits} ");
if (_settings.EnableTopoOrderInHistories)
builder.Append("--topo-order ");
else
builder.Append("--date-order ");
if (_settings.HistoryShowFlags.HasFlag(Models.HistoryShowFlags.Reflog))
builder.Append("--reflog ");
if (_settings.HistoryShowFlags.HasFlag(Models.HistoryShowFlags.FirstParentOnly))
builder.Append("--first-parent ");
if (_settings.HistoryShowFlags.HasFlag(Models.HistoryShowFlags.SimplifyByDecoration))
builder.Append("--simplify-by-decoration ");
var filters = _settings.BuildHistoriesFilter();
if (string.IsNullOrEmpty(filters))
builder.Append("--branches --remotes --tags HEAD");
else
builder.Append(filters);
var commits = await new Commands.QueryCommits(_fullpath, builder.ToString()).GetResultAsync().ConfigureAwait(false);
var graph = Models.CommitGraph.Parse(commits, _settings.HistoryShowFlags.HasFlag(Models.HistoryShowFlags.FirstParentOnly));
Dispatcher.UIThread.Invoke(() =>
{
_histories.IsLoading = false;
_histories.Commits = commits;
_histories.Graph = graph;
if (_histories != null)
{
_histories.IsLoading = false;
_histories.Commits = commits;
_histories.Graph = graph;
BisectState = _histories.UpdateBisectInfo();
BisectState = _histories.UpdateBisectInfo();
if (!string.IsNullOrEmpty(_navigateToCommitDelayed))
NavigateToCommit(_navigateToCommitDelayed);
}
if (!string.IsNullOrEmpty(_navigateToCommitDelayed))
NavigateToCommit(_navigateToCommitDelayed);
}
_navigateToCommitDelayed = string.Empty;
_navigateToCommitDelayed = string.Empty;
});
});
}
@@ -1321,41 +1333,44 @@ namespace SourceGit.ViewModels
return;
}
var submodules = new Commands.QuerySubmodules(_fullpath).GetResultAsync().Result;
_watcher?.SetSubmodules(submodules);
Dispatcher.UIThread.Invoke(() =>
Task.Run(async () =>
{
bool hasChanged = _submodules.Count != submodules.Count;
if (!hasChanged)
{
var old = new Dictionary<string, Models.Submodule>();
foreach (var module in _submodules)
old.Add(module.Path, module);
var submodules = await new Commands.QuerySubmodules(_fullpath).GetResultAsync().ConfigureAwait(false);
_watcher?.SetSubmodules(submodules);
foreach (var module in submodules)
Dispatcher.UIThread.Invoke(() =>
{
bool hasChanged = _submodules.Count != submodules.Count;
if (!hasChanged)
{
if (!old.TryGetValue(module.Path, out var exist))
var old = new Dictionary<string, Models.Submodule>();
foreach (var module in _submodules)
old.Add(module.Path, module);
foreach (var module in submodules)
{
hasChanged = true;
break;
if (!old.TryGetValue(module.Path, out var exist))
{
hasChanged = true;
break;
}
hasChanged = !exist.SHA.Equals(module.SHA, StringComparison.Ordinal) ||
!exist.Branch.Equals(module.Branch, StringComparison.Ordinal) ||
!exist.URL.Equals(module.URL, StringComparison.Ordinal) ||
exist.Status != module.Status;
if (hasChanged)
break;
}
hasChanged = !exist.SHA.Equals(module.SHA, StringComparison.Ordinal) ||
!exist.Branch.Equals(module.Branch, StringComparison.Ordinal) ||
!exist.URL.Equals(module.URL, StringComparison.Ordinal) ||
exist.Status != module.Status;
if (hasChanged)
break;
}
}
if (hasChanged)
{
Submodules = submodules;
VisibleSubmodules = BuildVisibleSubmodules();
}
if (hasChanged)
{
Submodules = submodules;
VisibleSubmodules = BuildVisibleSubmodules();
}
});
});
}
@@ -1364,18 +1379,24 @@ namespace SourceGit.ViewModels
if (IsBare)
return;
var changes = new Commands.QueryLocalChanges(_fullpath, _settings.IncludeUntrackedInLocalChanges).GetResultAsync().Result;
if (_workingCopy == null)
return;
changes.Sort((l, r) => Models.NumericSort.Compare(l.Path, r.Path));
_workingCopy.SetData(changes);
Dispatcher.UIThread.Invoke(() =>
Task.Run(async () =>
{
LocalChangesCount = changes.Count;
OnPropertyChanged(nameof(InProgressContext));
GetOwnerPage()?.ChangeDirtyState(Models.DirtyState.HasLocalChanges, changes.Count == 0);
var changes = await new Commands.QueryLocalChanges(_fullpath, _settings.IncludeUntrackedInLocalChanges)
.GetResultAsync()
.ConfigureAwait(false);
if (_workingCopy == null)
return;
changes.Sort((l, r) => Models.NumericSort.Compare(l.Path, r.Path));
_workingCopy.SetData(changes);
Dispatcher.UIThread.Invoke(() =>
{
LocalChangesCount = changes.Count;
OnPropertyChanged(nameof(InProgressContext));
GetOwnerPage()?.ChangeDirtyState(Models.DirtyState.HasLocalChanges, changes.Count == 0);
});
});
}
@@ -1384,13 +1405,16 @@ namespace SourceGit.ViewModels
if (IsBare)
return;
var stashes = new Commands.QueryStashes(_fullpath).GetResultAsync().Result;
Dispatcher.UIThread.Invoke(() =>
Task.Run(async () =>
{
if (_stashesPage != null)
_stashesPage.Stashes = stashes;
var stashes = await new Commands.QueryStashes(_fullpath).GetResultAsync().ConfigureAwait(false);
Dispatcher.UIThread.Invoke(() =>
{
if (_stashesPage != null)
_stashesPage.Stashes = stashes;
StashesCount = stashes.Count;
StashesCount = stashes.Count;
});
});
}
@@ -1806,8 +1830,7 @@ namespace SourceGit.ViewModels
UpdateBranchTreeFilterMode(LocalBranchTrees, filters);
UpdateBranchTreeFilterMode(RemoteBranchTrees, filters);
UpdateTagFilterMode(filters);
Task.Run(RefreshCommits);
RefreshCommits();
}
private void UpdateBranchTreeFilterMode(List<BranchTreeNode> nodes, Dictionary<string, Models.FilterMode> filters)

View File

@@ -161,7 +161,7 @@ namespace SourceGit.ViewModels
if (!AvailableOpenAIServices.Contains(PreferredOpenAIService))
PreferredOpenAIService = "---";
_cached = new Commands.Config(repo.FullPath).ReadAllAsync().Result;
_cached = new Commands.Config(repo.FullPath).ReadAll();
if (_cached.TryGetValue("user.name", out var name))
UserName = name;
if (_cached.TryGetValue("user.email", out var email))

View File

@@ -81,8 +81,7 @@ namespace SourceGit.ViewModels
_startPoint = (object)startPoint ?? new Models.Null();
_endPoint = (object)endPoint ?? new Models.Null();
CanSaveAsPatch = startPoint != null && endPoint != null;
Task.Run(Refresh);
Refresh();
}
public void Dispose()
@@ -125,7 +124,7 @@ namespace SourceGit.ViewModels
VisibleChanges = [];
SelectedChanges = [];
IsLoading = true;
Task.Run(Refresh);
Refresh();
}
public void SaveAsPatch(string saveTo)
@@ -167,28 +166,33 @@ namespace SourceGit.ViewModels
private void Refresh()
{
_changes = new Commands.CompareRevisions(_repo, GetSHA(_startPoint), GetSHA(_endPoint)).ReadAsync().Result;
var visible = _changes;
if (!string.IsNullOrWhiteSpace(_searchFilter))
Task.Run(async () =>
{
visible = [];
foreach (var c in _changes)
_changes = await new Commands.CompareRevisions(_repo, GetSHA(_startPoint), GetSHA(_endPoint))
.ReadAsync()
.ConfigureAwait(false);
var visible = _changes;
if (!string.IsNullOrWhiteSpace(_searchFilter))
{
if (c.Path.Contains(_searchFilter, StringComparison.OrdinalIgnoreCase))
visible.Add(c);
visible = [];
foreach (var c in _changes)
{
if (c.Path.Contains(_searchFilter, StringComparison.OrdinalIgnoreCase))
visible.Add(c);
}
}
}
Dispatcher.UIThread.Post(() =>
{
VisibleChanges = visible;
IsLoading = false;
Dispatcher.UIThread.Post(() =>
{
VisibleChanges = visible;
IsLoading = false;
if (VisibleChanges.Count > 0)
SelectedChanges = [VisibleChanges[0]];
else
SelectedChanges = [];
if (VisibleChanges.Count > 0)
SelectedChanges = [VisibleChanges[0]];
else
SelectedChanges = [];
});
});
}

View File

@@ -88,9 +88,7 @@ namespace SourceGit.ViewModels
return;
}
CommitMessage = new Commands.QueryCommitFullMessage(_repo.FullPath, currentBranch.Head)
.GetResultAsync()
.Result;
CommitMessage = new Commands.QueryCommitFullMessage(_repo.FullPath, currentBranch.Head).GetResult();
}
else
{
@@ -670,13 +668,8 @@ namespace SourceGit.ViewModels
{
if (_useAmend)
{
var head = new Commands.QuerySingleCommit(_repo.FullPath, "HEAD")
.GetResultAsync()
.Result;
return new Commands.QueryStagedChangesWithAmend(_repo.FullPath, head.Parents.Count == 0 ? Models.Commit.EmptyTreeSHA1 : $"{head.SHA}^")
.GetResultAsync()
.Result;
var head = new Commands.QuerySingleCommit(_repo.FullPath, "HEAD").GetResult();
return new Commands.QueryStagedChangesWithAmend(_repo.FullPath, head.Parents.Count == 0 ? Models.Commit.EmptyTreeSHA1 : $"{head.SHA}^").GetResult();
}
var rs = new List<Models.Change>();
@@ -722,7 +715,7 @@ namespace SourceGit.ViewModels
if (File.Exists(rebaseMsgFile))
CommitMessage = File.ReadAllText(rebaseMsgFile);
else if (rebasing.StoppedAt != null)
CommitMessage = new Commands.QueryCommitFullMessage(_repo.FullPath, rebasing.StoppedAt.SHA).GetResultAsync().Result;
CommitMessage = new Commands.QueryCommitFullMessage(_repo.FullPath, rebasing.StoppedAt.SHA).GetResult();
}
}
else if (File.Exists(Path.Combine(_repo.GitDir, "REVERT_HEAD")))
@@ -809,26 +802,14 @@ namespace SourceGit.ViewModels
log.Complete();
Dispatcher.UIThread.Post(async () =>
Dispatcher.UIThread.Post(() =>
{
if (succ)
{
CommitMessage = string.Empty;
UseAmend = false;
if (autoPush && _repo.Remotes.Count > 0)
{
if (_repo.CurrentBranch == null)
{
var currentBranchName = await new Commands.QueryCurrentBranch(_repo.FullPath).GetResultAsync();
var tmp = new Models.Branch() { Name = currentBranchName };
_repo.ShowAndStartPopup(new Push(_repo, tmp));
}
else
{
_repo.ShowAndStartPopup(new Push(_repo, null));
}
}
PushAfterCommit();
}
_repo.MarkBranchesDirtyManually();
@@ -838,6 +819,28 @@ namespace SourceGit.ViewModels
});
}
private void PushAfterCommit()
{
if (_repo.CurrentBranch == null)
{
Task.Run(async () =>
{
var currentBranchName = await new Commands.QueryCurrentBranch(_repo.FullPath).GetResultAsync();
var tmp = new Models.Branch() { Name = currentBranchName };
Dispatcher.UIThread.Post(() =>
{
if (_repo.CanCreatePopup())
_repo.ShowAndStartPopup(new Push(_repo, tmp));
});
});
}
else if (_repo.CanCreatePopup())
{
_repo.ShowAndStartPopup(new Push(_repo, null));
}
}
private bool IsChanged(List<Models.Change> old, List<Models.Change> cur)
{
if (old.Count != cur.Count)