mirror of
https://fastgit.cc/github.com/sourcegit-scm/sourcegit
synced 2026-04-21 13:20:30 +08:00
code_review: PR #1492
- Remove all synchronous method in commands - `Command.ReadToEndAsync` now is protected method - Rename `ResultAsync` to `GetResultAsync` - Call `ConfigureAwait(false)` when there's no context Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
@@ -43,16 +43,16 @@ namespace SourceGit
|
||||
public static readonly Command OpenAboutCommand = new Command(_ => ShowWindow(new Views.About(), false));
|
||||
public static readonly Command CheckForUpdateCommand = new Command(_ => (Current as App)?.Check4Update(true));
|
||||
public static readonly Command QuitCommand = new Command(_ => Quit(0));
|
||||
public static readonly Command CopyTextBlockCommand = new Command(p =>
|
||||
public static readonly Command CopyTextBlockCommand = new Command(async p =>
|
||||
{
|
||||
var textBlock = p as TextBlock;
|
||||
if (textBlock == null)
|
||||
return;
|
||||
|
||||
if (textBlock.Inlines is { Count: > 0 } inlines)
|
||||
CopyText(inlines.Text);
|
||||
await CopyTextAsync(inlines.Text);
|
||||
else if (!string.IsNullOrEmpty(textBlock.Text))
|
||||
CopyText(textBlock.Text);
|
||||
await CopyTextAsync(textBlock.Text);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,6 +146,18 @@ namespace SourceGit
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<bool> AskConfirmAsync(string message, Action onSure)
|
||||
{
|
||||
if (Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime { MainWindow: { } owner })
|
||||
{
|
||||
var confirm = new Views.Confirm();
|
||||
confirm.Message.Text = message;
|
||||
return await confirm.ShowDialog<bool>(owner);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void RaiseException(string context, string message)
|
||||
{
|
||||
if (Current is App { _launcher: not null } app)
|
||||
@@ -281,7 +293,7 @@ namespace SourceGit
|
||||
}
|
||||
}
|
||||
|
||||
public static async void CopyText(string data)
|
||||
public static async Task CopyTextAsync(string data)
|
||||
{
|
||||
if (Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime { MainWindow.Clipboard: { } clipboard })
|
||||
await clipboard.SetTextAsync(data ?? "");
|
||||
@@ -571,7 +583,7 @@ namespace SourceGit
|
||||
{
|
||||
if (!string.IsNullOrEmpty(repo) && Directory.Exists(repo))
|
||||
{
|
||||
var test = new Commands.QueryRepositoryRootPath(repo).ReadToEnd();
|
||||
var test = new Commands.QueryRepositoryRootPath(repo).GetResultAsync().Result;
|
||||
if (test.IsSuccess && !string.IsNullOrEmpty(test.StdOut))
|
||||
{
|
||||
Dispatcher.UIThread.Invoke(() =>
|
||||
|
||||
@@ -20,9 +20,9 @@ namespace SourceGit.Commands
|
||||
_result.File = file;
|
||||
}
|
||||
|
||||
public async Task<Models.BlameData> ResultAsync()
|
||||
public async Task<Models.BlameData> ReadAsync()
|
||||
{
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (!rs.IsSuccess)
|
||||
return _result;
|
||||
|
||||
|
||||
@@ -5,24 +5,6 @@ namespace SourceGit.Commands
|
||||
{
|
||||
public static class Branch
|
||||
{
|
||||
public static string ShowCurrent(string repo)
|
||||
{
|
||||
var cmd = new Command();
|
||||
cmd.WorkingDirectory = repo;
|
||||
cmd.Context = repo;
|
||||
cmd.Args = "branch --show-current";
|
||||
return cmd.ReadToEnd().StdOut.Trim();
|
||||
}
|
||||
|
||||
public static async Task<string> ShowCurrentAsync(string repo)
|
||||
{
|
||||
var cmd = new Command();
|
||||
cmd.WorkingDirectory = repo;
|
||||
cmd.Context = repo;
|
||||
cmd.Args = "branch --show-current";
|
||||
return (await cmd.ReadToEndAsync()).StdOut.Trim();
|
||||
}
|
||||
|
||||
public static async Task<bool> CreateAsync(string repo, string name, string basedOn, bool force, Models.ICommandLog log)
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
@@ -38,7 +20,7 @@ namespace SourceGit.Commands
|
||||
cmd.Context = repo;
|
||||
cmd.Args = builder.ToString();
|
||||
cmd.Log = log;
|
||||
return await cmd.ExecAsync();
|
||||
return await cmd.ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task<bool> RenameAsync(string repo, string name, string to, Models.ICommandLog log)
|
||||
@@ -48,7 +30,7 @@ namespace SourceGit.Commands
|
||||
cmd.Context = repo;
|
||||
cmd.Args = $"branch -M {name} {to}";
|
||||
cmd.Log = log;
|
||||
return await cmd.ExecAsync();
|
||||
return await cmd.ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task<bool> SetUpstreamAsync(string repo, string name, string upstream, Models.ICommandLog log)
|
||||
@@ -63,7 +45,7 @@ namespace SourceGit.Commands
|
||||
else
|
||||
cmd.Args = $"branch {name} -u {upstream}";
|
||||
|
||||
return await cmd.ExecAsync();
|
||||
return await cmd.ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task<bool> DeleteLocalAsync(string repo, string name, Models.ICommandLog log)
|
||||
@@ -73,21 +55,21 @@ namespace SourceGit.Commands
|
||||
cmd.Context = repo;
|
||||
cmd.Args = $"branch -D {name}";
|
||||
cmd.Log = log;
|
||||
return await cmd.ExecAsync();
|
||||
return await cmd.ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task<bool> DeleteRemoteAsync(string repo, string remote, string name, Models.ICommandLog log)
|
||||
{
|
||||
bool exists = await new Remote(repo).HasBranchAsync(remote, name);
|
||||
bool exists = await new Remote(repo).HasBranchAsync(remote, name).ConfigureAwait(false);
|
||||
if (exists)
|
||||
return await new Push(repo, remote, $"refs/heads/{name}", true) { Log = log }.ExecAsync();
|
||||
return await new Push(repo, remote, $"refs/heads/{name}", true) { Log = log }.ExecAsync().ConfigureAwait(false);
|
||||
|
||||
var cmd = new Command();
|
||||
cmd.WorkingDirectory = repo;
|
||||
cmd.Context = repo;
|
||||
cmd.Args = $"branch -D -r {remote}/{name}";
|
||||
cmd.Log = log;
|
||||
return await cmd.ExecAsync();
|
||||
return await cmd.ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace SourceGit.Commands
|
||||
builder.Append(branch);
|
||||
|
||||
Args = builder.ToString();
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> BranchAsync(string branch, string basedOn, bool force, bool allowOverwrite)
|
||||
@@ -36,14 +36,14 @@ namespace SourceGit.Commands
|
||||
builder.Append(basedOn);
|
||||
|
||||
Args = builder.ToString();
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> CommitAsync(string commitId, bool force)
|
||||
{
|
||||
var option = force ? "--force" : string.Empty;
|
||||
Args = $"checkout {option} --detach --progress {commitId}";
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> UseTheirsAsync(List<string> files)
|
||||
@@ -57,7 +57,7 @@ namespace SourceGit.Commands
|
||||
builder.Append("\"");
|
||||
}
|
||||
Args = builder.ToString();
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> UseMineAsync(List<string> files)
|
||||
@@ -72,13 +72,13 @@ namespace SourceGit.Commands
|
||||
}
|
||||
|
||||
Args = builder.ToString();
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> FileWithRevisionAsync(string file, string revision)
|
||||
{
|
||||
Args = $"checkout --no-overlay {revision} -- \"{file}\"";
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,11 +10,13 @@ namespace SourceGit.Commands
|
||||
{
|
||||
public partial class Command
|
||||
{
|
||||
public class ReadToEndResult
|
||||
public class Result
|
||||
{
|
||||
public bool IsSuccess { get; set; } = false;
|
||||
public string StdOut { get; set; } = "";
|
||||
public string StdErr { get; set; } = "";
|
||||
public string StdOut { get; set; } = string.Empty;
|
||||
public string StdErr { get; set; } = string.Empty;
|
||||
|
||||
public static Result Failed(string reason) => new Result() { StdErr = reason };
|
||||
}
|
||||
|
||||
public enum EditorType
|
||||
@@ -25,46 +27,16 @@ namespace SourceGit.Commands
|
||||
}
|
||||
|
||||
public string Context { get; set; } = string.Empty;
|
||||
public CancellationToken CancellationToken { get; set; } = CancellationToken.None;
|
||||
public string WorkingDirectory { get; set; } = null;
|
||||
public EditorType Editor { get; set; } = EditorType.CoreEditor; // Only used in Exec() mode
|
||||
public EditorType Editor { get; set; } = EditorType.CoreEditor;
|
||||
public string SSHKey { get; set; } = string.Empty;
|
||||
public string Args { get; set; } = string.Empty;
|
||||
|
||||
// Only used in `ExecAsync` mode.
|
||||
public CancellationToken CancellationToken { get; set; } = CancellationToken.None;
|
||||
public bool RaiseError { get; set; } = true;
|
||||
public Models.ICommandLog Log { get; set; } = null;
|
||||
|
||||
public ReadToEndResult ReadToEnd()
|
||||
{
|
||||
var start = CreateGitStartInfo();
|
||||
var proc = new Process() { StartInfo = start };
|
||||
|
||||
try
|
||||
{
|
||||
proc.Start();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new ReadToEndResult()
|
||||
{
|
||||
IsSuccess = false,
|
||||
StdOut = string.Empty,
|
||||
StdErr = e.Message,
|
||||
};
|
||||
}
|
||||
|
||||
var rs = new ReadToEndResult()
|
||||
{
|
||||
StdOut = proc.StandardOutput.ReadToEnd(),
|
||||
StdErr = proc.StandardError.ReadToEnd(),
|
||||
};
|
||||
|
||||
proc.WaitForExit();
|
||||
rs.IsSuccess = proc.ExitCode == 0;
|
||||
proc.Close();
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
public async Task<bool> ExecAsync()
|
||||
{
|
||||
Log?.AppendLine($"$ git {Args}\n");
|
||||
@@ -107,7 +79,15 @@ namespace SourceGit.Commands
|
||||
|
||||
proc.BeginOutputReadLine();
|
||||
proc.BeginErrorReadLine();
|
||||
await proc.WaitForExitAsync(CancellationToken);
|
||||
|
||||
try
|
||||
{
|
||||
await proc.WaitForExitAsync(CancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
HandleOutput(e.Message, errs);
|
||||
}
|
||||
|
||||
if (dummy != null)
|
||||
{
|
||||
@@ -136,7 +116,7 @@ namespace SourceGit.Commands
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<ReadToEndResult> ReadToEndAsync()
|
||||
protected async Task<Result> ReadToEndAsync()
|
||||
{
|
||||
var start = CreateGitStartInfo();
|
||||
var proc = new Process() { StartInfo = start };
|
||||
@@ -147,24 +127,16 @@ namespace SourceGit.Commands
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new ReadToEndResult()
|
||||
{
|
||||
IsSuccess = false,
|
||||
StdOut = string.Empty,
|
||||
StdErr = e.Message,
|
||||
};
|
||||
return Result.Failed(e.Message);
|
||||
}
|
||||
|
||||
var rs = new ReadToEndResult()
|
||||
{
|
||||
StdOut = await proc.StandardOutput.ReadToEndAsync(CancellationToken),
|
||||
StdErr = await proc.StandardError.ReadToEndAsync(CancellationToken),
|
||||
};
|
||||
var rs = new Result() { IsSuccess = true };
|
||||
rs.StdOut = await proc.StandardOutput.ReadToEndAsync().ConfigureAwait(false);
|
||||
rs.StdErr = await proc.StandardError.ReadToEndAsync().ConfigureAwait(false);
|
||||
await proc.WaitForExitAsync().ConfigureAwait(false);
|
||||
|
||||
await proc.WaitForExitAsync(CancellationToken);
|
||||
rs.IsSuccess = proc.ExitCode == 0;
|
||||
proc.Close();
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace SourceGit.Commands
|
||||
public Commit(string repo, string message, bool signOff, bool amend, bool resetAuthor)
|
||||
{
|
||||
_tmpFile = Path.GetTempFileName();
|
||||
File.WriteAllText(_tmpFile, message);
|
||||
_message = message;
|
||||
|
||||
WorkingDirectory = repo;
|
||||
Context = repo;
|
||||
@@ -21,20 +21,20 @@ namespace SourceGit.Commands
|
||||
|
||||
public async Task<bool> RunAsync()
|
||||
{
|
||||
var succ = await ExecAsync();
|
||||
|
||||
try
|
||||
{
|
||||
await File.WriteAllTextAsync(_tmpFile, _message).ConfigureAwait(false);
|
||||
var succ = await ExecAsync().ConfigureAwait(false);
|
||||
File.Delete(_tmpFile);
|
||||
return succ;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore
|
||||
return false;
|
||||
}
|
||||
|
||||
return succ;
|
||||
}
|
||||
|
||||
private readonly string _tmpFile;
|
||||
private readonly string _tmpFile = string.Empty;
|
||||
private readonly string _message = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,35 +30,22 @@ namespace SourceGit.Commands
|
||||
Args = $"diff --name-status {based} {end} -- \"{path}\"";
|
||||
}
|
||||
|
||||
public List<Models.Change> Result()
|
||||
public async Task<List<Models.Change>> ReadAsync()
|
||||
{
|
||||
var rs = ReadToEnd();
|
||||
var changes = new List<Models.Change>();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (!rs.IsSuccess)
|
||||
return _changes;
|
||||
return changes;
|
||||
|
||||
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var line in lines)
|
||||
ParseLine(line);
|
||||
ParseLine(changes, line);
|
||||
|
||||
_changes.Sort((l, r) => Models.NumericSort.Compare(l.Path, r.Path));
|
||||
return _changes;
|
||||
changes.Sort((l, r) => Models.NumericSort.Compare(l.Path, r.Path));
|
||||
return changes;
|
||||
}
|
||||
|
||||
public async Task<List<Models.Change>> ResultAsync()
|
||||
{
|
||||
var rs = await ReadToEndAsync();
|
||||
if (!rs.IsSuccess)
|
||||
return _changes;
|
||||
|
||||
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var line in lines)
|
||||
ParseLine(line);
|
||||
|
||||
_changes.Sort((l, r) => Models.NumericSort.Compare(l.Path, r.Path));
|
||||
return _changes;
|
||||
}
|
||||
|
||||
private void ParseLine(string line)
|
||||
private void ParseLine(List<Models.Change> outs, string line)
|
||||
{
|
||||
var match = REG_FORMAT().Match(line);
|
||||
if (!match.Success)
|
||||
@@ -68,7 +55,7 @@ namespace SourceGit.Commands
|
||||
{
|
||||
var renamed = new Models.Change() { Path = match.Groups[1].Value };
|
||||
renamed.Set(Models.ChangeState.Renamed);
|
||||
_changes.Add(renamed);
|
||||
outs.Add(renamed);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -81,23 +68,21 @@ namespace SourceGit.Commands
|
||||
{
|
||||
case 'M':
|
||||
change.Set(Models.ChangeState.Modified);
|
||||
_changes.Add(change);
|
||||
outs.Add(change);
|
||||
break;
|
||||
case 'A':
|
||||
change.Set(Models.ChangeState.Added);
|
||||
_changes.Add(change);
|
||||
outs.Add(change);
|
||||
break;
|
||||
case 'D':
|
||||
change.Set(Models.ChangeState.Deleted);
|
||||
_changes.Add(change);
|
||||
outs.Add(change);
|
||||
break;
|
||||
case 'C':
|
||||
change.Set(Models.ChangeState.Copied);
|
||||
_changes.Add(change);
|
||||
outs.Add(change);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly List<Models.Change> _changes = new List<Models.Change>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,45 +18,13 @@ namespace SourceGit.Commands
|
||||
Context = repository;
|
||||
_isLocal = true;
|
||||
}
|
||||
|
||||
RaiseError = false;
|
||||
}
|
||||
|
||||
public Dictionary<string, string> ListAll()
|
||||
public async Task<Dictionary<string, string>> ReadAllAsync()
|
||||
{
|
||||
Args = "config -l";
|
||||
|
||||
var output = ReadToEnd();
|
||||
var rs = new Dictionary<string, string>();
|
||||
if (output.IsSuccess)
|
||||
{
|
||||
var lines = output.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var idx = line.IndexOf('=', StringComparison.Ordinal);
|
||||
if (idx != -1)
|
||||
{
|
||||
var key = line.Substring(0, idx).Trim();
|
||||
var val = line.Substring(idx + 1).Trim();
|
||||
rs[key] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
public string Get(string key)
|
||||
{
|
||||
Args = $"config {key}";
|
||||
return ReadToEnd().StdOut.Trim();
|
||||
}
|
||||
|
||||
public async Task<Dictionary<string, string>> ListAllAsync()
|
||||
{
|
||||
Args = "config -l";
|
||||
|
||||
var output = await ReadToEndAsync();
|
||||
var output = await ReadToEndAsync().ConfigureAwait(false);
|
||||
var rs = new Dictionary<string, string>();
|
||||
if (output.IsSuccess)
|
||||
{
|
||||
@@ -79,7 +47,9 @@ namespace SourceGit.Commands
|
||||
public async Task<string> GetAsync(string key)
|
||||
{
|
||||
Args = $"config {key}";
|
||||
return (await ReadToEndAsync()).StdOut.Trim();
|
||||
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
return rs.StdOut.Trim();
|
||||
}
|
||||
|
||||
public async Task<bool> SetAsync(string key, string value, bool allowEmpty = false)
|
||||
@@ -91,7 +61,7 @@ namespace SourceGit.Commands
|
||||
else
|
||||
Args = $"config {scope} {key} \"{value}\"";
|
||||
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private bool _isLocal = false;
|
||||
|
||||
@@ -12,9 +12,9 @@ namespace SourceGit.Commands
|
||||
Args = "--no-optional-locks status -uno --ignore-submodules=all --porcelain";
|
||||
}
|
||||
|
||||
public async Task<int> ResultAsync()
|
||||
public async Task<int> GetResultAsync()
|
||||
{
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (rs.IsSuccess)
|
||||
{
|
||||
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
@@ -36,9 +36,9 @@ namespace SourceGit.Commands
|
||||
Args = $"diff --no-ext-diff --patch --unified={unified} {opt}";
|
||||
}
|
||||
|
||||
public async Task<Models.DiffResult> ResultAsync()
|
||||
public async Task<Models.DiffResult> ReadAsync()
|
||||
{
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
var start = 0;
|
||||
var end = rs.StdOut.IndexOf('\n', start);
|
||||
while (end > 0)
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace SourceGit.Commands
|
||||
/// <param name="log"></param>
|
||||
public static async Task AllAsync(string repo, bool includeIgnored, Models.ICommandLog log)
|
||||
{
|
||||
var changes = await new QueryLocalChanges(repo).ResultAsync();
|
||||
var changes = await new QueryLocalChanges(repo).GetResultAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
foreach (var c in changes)
|
||||
@@ -38,10 +38,10 @@ namespace SourceGit.Commands
|
||||
App.RaiseException(repo, $"Failed to discard changes. Reason: {e.Message}");
|
||||
}
|
||||
|
||||
await new Reset(repo, "HEAD", "--hard") { Log = log }.ExecAsync();
|
||||
await new Reset(repo, "HEAD", "--hard") { Log = log }.ExecAsync().ConfigureAwait(false);
|
||||
|
||||
if (includeIgnored)
|
||||
await new Clean(repo) { Log = log }.ExecAsync();
|
||||
await new Clean(repo) { Log = log }.ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -80,8 +80,8 @@ namespace SourceGit.Commands
|
||||
if (restores.Count > 0)
|
||||
{
|
||||
var pathSpecFile = Path.GetTempFileName();
|
||||
await File.WriteAllLinesAsync(pathSpecFile, restores);
|
||||
await new Restore(repo, pathSpecFile, false) { Log = log }.ExecAsync();
|
||||
await File.WriteAllLinesAsync(pathSpecFile, restores).ConfigureAwait(false);
|
||||
await new Restore(repo, pathSpecFile, false) { Log = log }.ExecAsync().ConfigureAwait(false);
|
||||
File.Delete(pathSpecFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
namespace SourceGit.Commands
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SourceGit.Commands
|
||||
{
|
||||
public class Fetch : Command
|
||||
{
|
||||
public Fetch(string repo, string remote, bool noTags, bool force)
|
||||
{
|
||||
_remoteKey = $"remote.{remote}.sshkey";
|
||||
|
||||
WorkingDirectory = repo;
|
||||
Context = repo;
|
||||
SSHKey = new Config(repo).Get($"remote.{remote}.sshkey");
|
||||
Args = "fetch --progress --verbose ";
|
||||
|
||||
if (noTags)
|
||||
@@ -18,14 +21,24 @@
|
||||
Args += "--force ";
|
||||
|
||||
Args += remote;
|
||||
|
||||
}
|
||||
|
||||
public Fetch(string repo, Models.Branch local, Models.Branch remote)
|
||||
{
|
||||
_remoteKey = $"remote.{remote.Remote}.sshkey";
|
||||
|
||||
WorkingDirectory = repo;
|
||||
Context = repo;
|
||||
SSHKey = new Config(repo).Get($"remote.{remote.Remote}.sshkey");
|
||||
Args = $"fetch --progress --verbose {remote.Remote} {remote.Name}:{local.Name}";
|
||||
}
|
||||
|
||||
public async Task<bool> RunAsync()
|
||||
{
|
||||
SSHKey = await new Config(WorkingDirectory).GetAsync(_remoteKey).ConfigureAwait(false);
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private readonly string _remoteKey;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,11 @@ namespace SourceGit.Commands
|
||||
Context = repo;
|
||||
Args = $"diff --diff-algorithm=minimal {opt}";
|
||||
}
|
||||
|
||||
public async Task<Result> ReadAsync()
|
||||
{
|
||||
return await ReadToEndAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
public GenerateCommitMessage(Models.OpenAIService service, string repo, List<Models.Change> changes, CancellationToken cancelToken, Action<string> onResponse)
|
||||
@@ -46,7 +51,7 @@ namespace SourceGit.Commands
|
||||
responseBuilder.Append("- ");
|
||||
summaryBuilder.Append("- ");
|
||||
|
||||
var rs = await new GetDiffContent(_repo, new Models.DiffOption(change, false)).ReadToEndAsync();
|
||||
var rs = await new GetDiffContent(_repo, new Models.DiffOption(change, false)).ReadAsync();
|
||||
if (rs.IsSuccess)
|
||||
{
|
||||
await _service.ChatAsync(
|
||||
|
||||
@@ -8,21 +8,21 @@ namespace SourceGit.Commands
|
||||
public static async Task<bool> InitAsync(string repo, string master, string develop, string feature, string release, string hotfix, string version, Models.ICommandLog log)
|
||||
{
|
||||
var config = new Config(repo);
|
||||
await config.SetAsync("gitflow.branch.master", master);
|
||||
await config.SetAsync("gitflow.branch.develop", develop);
|
||||
await config.SetAsync("gitflow.prefix.feature", feature);
|
||||
await config.SetAsync("gitflow.prefix.bugfix", "bugfix/");
|
||||
await config.SetAsync("gitflow.prefix.release", release);
|
||||
await config.SetAsync("gitflow.prefix.hotfix", hotfix);
|
||||
await config.SetAsync("gitflow.prefix.support", "support/");
|
||||
await config.SetAsync("gitflow.prefix.versiontag", version, true);
|
||||
await config.SetAsync("gitflow.branch.master", master).ConfigureAwait(false);
|
||||
await config.SetAsync("gitflow.branch.develop", develop).ConfigureAwait(false);
|
||||
await config.SetAsync("gitflow.prefix.feature", feature).ConfigureAwait(false);
|
||||
await config.SetAsync("gitflow.prefix.bugfix", "bugfix/").ConfigureAwait(false);
|
||||
await config.SetAsync("gitflow.prefix.release", release).ConfigureAwait(false);
|
||||
await config.SetAsync("gitflow.prefix.hotfix", hotfix).ConfigureAwait(false);
|
||||
await config.SetAsync("gitflow.prefix.support", "support/").ConfigureAwait(false);
|
||||
await config.SetAsync("gitflow.prefix.versiontag", version, true).ConfigureAwait(false);
|
||||
|
||||
var init = new Command();
|
||||
init.WorkingDirectory = repo;
|
||||
init.Context = repo;
|
||||
init.Args = "flow init -d";
|
||||
init.Log = log;
|
||||
return await init.ExecAsync();
|
||||
return await init.ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task<bool> StartAsync(string repo, Models.GitFlowBranchType type, string name, Models.ICommandLog log)
|
||||
@@ -48,7 +48,7 @@ namespace SourceGit.Commands
|
||||
}
|
||||
|
||||
start.Log = log;
|
||||
return await start.ExecAsync();
|
||||
return await start.ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task<bool> FinishAsync(string repo, Models.GitFlowBranchType type, string name, bool squash, bool push, bool keepBranch, Models.ICommandLog log)
|
||||
@@ -86,7 +86,7 @@ namespace SourceGit.Commands
|
||||
finish.Context = repo;
|
||||
finish.Args = builder.ToString();
|
||||
finish.Log = log;
|
||||
return await finish.ExecAsync();
|
||||
return await finish.ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,25 +11,14 @@ namespace SourceGit.Commands
|
||||
Args = "rev-parse --is-bare-repository";
|
||||
}
|
||||
|
||||
public bool Result()
|
||||
public async Task<bool> GetResultAsync()
|
||||
{
|
||||
if (!Directory.Exists(Path.Combine(WorkingDirectory, "refs")) ||
|
||||
!Directory.Exists(Path.Combine(WorkingDirectory, "objects")) ||
|
||||
!File.Exists(Path.Combine(WorkingDirectory, "HEAD")))
|
||||
return false;
|
||||
|
||||
var rs = ReadToEnd();
|
||||
return rs.IsSuccess && rs.StdOut.Trim() == "true";
|
||||
}
|
||||
|
||||
public async Task<bool> ResultAsync()
|
||||
{
|
||||
if (!Directory.Exists(Path.Combine(WorkingDirectory, "refs")) ||
|
||||
!Directory.Exists(Path.Combine(WorkingDirectory, "objects")) ||
|
||||
!File.Exists(Path.Combine(WorkingDirectory, "HEAD")))
|
||||
return false;
|
||||
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
return rs.IsSuccess && rs.StdOut.Trim() == "true";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,10 @@ namespace SourceGit.Commands
|
||||
RaiseError = false;
|
||||
}
|
||||
|
||||
public async Task<bool> ResultAsync()
|
||||
public async Task<bool> GetResultAsync()
|
||||
{
|
||||
return REG_TEST().IsMatch((await ReadToEndAsync()).StdOut);
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
return REG_TEST().IsMatch(rs.StdOut.Trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ namespace SourceGit.Commands
|
||||
Args = $"cat-file -t {hash}";
|
||||
}
|
||||
|
||||
public async Task<bool> ResultAsync()
|
||||
public async Task<bool> GetResultAsync()
|
||||
{
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
return rs.IsSuccess && rs.StdOut.Trim().Equals("commit");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,14 +13,10 @@ namespace SourceGit.Commands
|
||||
Args = $"diff -a --ignore-cr-at-eol --check {opt}";
|
||||
}
|
||||
|
||||
public bool Result()
|
||||
public async Task<bool> GetResultAsync()
|
||||
{
|
||||
return ReadToEnd().IsSuccess;
|
||||
}
|
||||
|
||||
public async Task<bool> ResultAsync()
|
||||
{
|
||||
return (await ReadToEndAsync()).IsSuccess;
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
return rs.IsSuccess;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,15 +20,9 @@ namespace SourceGit.Commands
|
||||
RaiseError = false;
|
||||
}
|
||||
|
||||
public bool Result()
|
||||
public async Task<bool> GetResultAsync()
|
||||
{
|
||||
var rs = ReadToEnd();
|
||||
return rs.IsSuccess && rs.StdOut.Contains("filter\0lfs");
|
||||
}
|
||||
|
||||
public async Task<bool> ResultAsync()
|
||||
{
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
return rs.IsSuccess && rs.StdOut.Contains("filter\0lfs");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,11 @@ namespace SourceGit.Commands
|
||||
Args = args;
|
||||
Log = log;
|
||||
}
|
||||
|
||||
public async Task<Result> ReadAsync()
|
||||
{
|
||||
return await ReadToEndAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
public LFS(string repo)
|
||||
@@ -39,40 +44,40 @@ namespace SourceGit.Commands
|
||||
|
||||
public async Task<bool> InstallAsync(Models.ICommandLog log)
|
||||
{
|
||||
return await new SubCmd(_repo, "lfs install --local", log).ExecAsync();
|
||||
return await new SubCmd(_repo, "lfs install --local", log).ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> TrackAsync(string pattern, bool isFilenameMode, Models.ICommandLog log)
|
||||
{
|
||||
var opt = isFilenameMode ? "--filename" : "";
|
||||
return await new SubCmd(_repo, $"lfs track {opt} \"{pattern}\"", log).ExecAsync();
|
||||
return await new SubCmd(_repo, $"lfs track {opt} \"{pattern}\"", log).ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task FetchAsync(string remote, Models.ICommandLog log)
|
||||
{
|
||||
await new SubCmd(_repo, $"lfs fetch {remote}", log).ExecAsync();
|
||||
await new SubCmd(_repo, $"lfs fetch {remote}", log).ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task PullAsync(string remote, Models.ICommandLog log)
|
||||
{
|
||||
await new SubCmd(_repo, $"lfs pull {remote}", log).ExecAsync();
|
||||
await new SubCmd(_repo, $"lfs pull {remote}", log).ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task PushAsync(string remote, Models.ICommandLog log)
|
||||
{
|
||||
await new SubCmd(_repo, $"lfs push {remote}", log).ExecAsync();
|
||||
await new SubCmd(_repo, $"lfs push {remote}", log).ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task PruneAsync(Models.ICommandLog log)
|
||||
{
|
||||
await new SubCmd(_repo, "lfs prune", log).ExecAsync();
|
||||
await new SubCmd(_repo, "lfs prune", log).ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<List<Models.LFSLock>> LocksAsync(string remote)
|
||||
public async Task<List<Models.LFSLock>> GetLocksAsync(string remote)
|
||||
{
|
||||
var locks = new List<Models.LFSLock>();
|
||||
var cmd = new SubCmd(_repo, $"lfs locks --remote={remote}", null);
|
||||
var rs = await cmd.ReadToEndAsync();
|
||||
var rs = await cmd.ReadAsync().ConfigureAwait(false);
|
||||
if (rs.IsSuccess)
|
||||
{
|
||||
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
@@ -96,19 +101,19 @@ namespace SourceGit.Commands
|
||||
|
||||
public async Task<bool> LockAsync(string remote, string file, Models.ICommandLog log)
|
||||
{
|
||||
return await new SubCmd(_repo, $"lfs lock --remote={remote} \"{file}\"", log).ExecAsync();
|
||||
return await new SubCmd(_repo, $"lfs lock --remote={remote} \"{file}\"", log).ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> UnlockAsync(string remote, string file, bool force, Models.ICommandLog log)
|
||||
{
|
||||
var opt = force ? "-f" : "";
|
||||
return await new SubCmd(_repo, $"lfs unlock --remote={remote} {opt} \"{file}\"", log).ExecAsync();
|
||||
return await new SubCmd(_repo, $"lfs unlock --remote={remote} {opt} \"{file}\"", log).ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> UnlockAsync(string remote, long id, bool force, Models.ICommandLog log)
|
||||
{
|
||||
var opt = force ? "-f" : "";
|
||||
return await new SubCmd(_repo, $"lfs unlock --remote={remote} {opt} --id={id}", log).ExecAsync();
|
||||
return await new SubCmd(_repo, $"lfs unlock --remote={remote} {opt} --id={id}", log).ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private readonly string _repo;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace SourceGit.Commands
|
||||
if (toolType == 0)
|
||||
{
|
||||
cmd.Args = $"mergetool {fileArg}";
|
||||
return await cmd.ExecAsync();
|
||||
return await cmd.ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (!File.Exists(toolPath))
|
||||
@@ -35,7 +35,7 @@ namespace SourceGit.Commands
|
||||
}
|
||||
|
||||
cmd.Args = $"-c mergetool.sourcegit.cmd=\"\\\"{toolPath}\\\" {supported.Cmd}\" -c mergetool.writeToTemp=true -c mergetool.keepBackup=false -c mergetool.trustExitCode=true mergetool --tool=sourcegit {fileArg}";
|
||||
return await cmd.ExecAsync();
|
||||
return await cmd.ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task<bool> OpenForDiffAsync(string repo, int toolType, string toolPath, Models.DiffOption option)
|
||||
@@ -65,7 +65,7 @@ namespace SourceGit.Commands
|
||||
}
|
||||
|
||||
cmd.Args = $"-c difftool.sourcegit.cmd=\"\\\"{toolPath}\\\" {supported.DiffCmd}\" difftool --tool=sourcegit --no-prompt {option}";
|
||||
return await cmd.ExecAsync();
|
||||
return await cmd.ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
namespace SourceGit.Commands
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SourceGit.Commands
|
||||
{
|
||||
public class Pull : Command
|
||||
{
|
||||
public Pull(string repo, string remote, string branch, bool useRebase)
|
||||
{
|
||||
_remote = remote;
|
||||
|
||||
WorkingDirectory = repo;
|
||||
Context = repo;
|
||||
SSHKey = new Config(repo).Get($"remote.{remote}.sshkey");
|
||||
Args = "pull --verbose --progress ";
|
||||
|
||||
if (useRebase)
|
||||
@@ -14,5 +17,13 @@
|
||||
|
||||
Args += $"{remote} {branch}";
|
||||
}
|
||||
|
||||
public async Task<bool> RunAsync()
|
||||
{
|
||||
SSHKey = await new Config(WorkingDirectory).GetAsync($"remote.{_remote}.sshkey").ConfigureAwait(false);
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private readonly string _remote;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
namespace SourceGit.Commands
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SourceGit.Commands
|
||||
{
|
||||
public class Push : Command
|
||||
{
|
||||
public Push(string repo, string local, string remote, string remoteBranch, bool withTags, bool checkSubmodules, bool track, bool force)
|
||||
{
|
||||
_remote = remote;
|
||||
|
||||
WorkingDirectory = repo;
|
||||
Context = repo;
|
||||
SSHKey = new Config(repo).Get($"remote.{remote}.sshkey");
|
||||
Args = "push --progress --verbose ";
|
||||
|
||||
if (withTags)
|
||||
@@ -23,9 +26,10 @@
|
||||
|
||||
public Push(string repo, string remote, string refname, bool isDelete)
|
||||
{
|
||||
_remote = remote;
|
||||
|
||||
WorkingDirectory = repo;
|
||||
Context = repo;
|
||||
SSHKey = new Config(repo).Get($"remote.{remote}.sshkey");
|
||||
Args = "push ";
|
||||
|
||||
if (isDelete)
|
||||
@@ -33,5 +37,13 @@
|
||||
|
||||
Args += $"{remote} {refname}";
|
||||
}
|
||||
|
||||
public async Task<bool> RunAsync()
|
||||
{
|
||||
SSHKey = await new Config(WorkingDirectory).GetAsync($"remote.{_remote}.sshkey").ConfigureAwait(false);
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private readonly string _remote;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,10 +17,10 @@ namespace SourceGit.Commands
|
||||
RaiseError = false;
|
||||
}
|
||||
|
||||
public async Task<List<string>> ResultAsync()
|
||||
public async Task<List<string>> GetResultAsync()
|
||||
{
|
||||
var outs = new List<string>();
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var line in lines)
|
||||
{
|
||||
|
||||
@@ -18,54 +18,10 @@ namespace SourceGit.Commands
|
||||
Args = "branch -l --all -v --format=\"%(refname)%00%(committerdate:unix)%00%(objectname)%00%(HEAD)%00%(upstream)%00%(upstream:trackshort)\"";
|
||||
}
|
||||
|
||||
public List<Models.Branch> Result(out int localBranchesCount)
|
||||
{
|
||||
localBranchesCount = 0;
|
||||
|
||||
var branches = new List<Models.Branch>();
|
||||
var rs = ReadToEnd();
|
||||
if (!rs.IsSuccess)
|
||||
return branches;
|
||||
|
||||
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
var remoteHeads = new Dictionary<string, string>();
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var b = ParseLine(line);
|
||||
if (b != null)
|
||||
{
|
||||
branches.Add(b);
|
||||
if (!b.IsLocal)
|
||||
remoteHeads.Add(b.FullName, b.Head);
|
||||
else
|
||||
localBranchesCount++;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var b in branches)
|
||||
{
|
||||
if (b.IsLocal && !string.IsNullOrEmpty(b.Upstream))
|
||||
{
|
||||
if (remoteHeads.TryGetValue(b.Upstream, out var upstreamHead))
|
||||
{
|
||||
b.IsUpstreamGone = false;
|
||||
b.TrackStatus ??= new QueryTrackStatus(WorkingDirectory, b.Head, upstreamHead).Result();
|
||||
}
|
||||
else
|
||||
{
|
||||
b.IsUpstreamGone = true;
|
||||
b.TrackStatus ??= new Models.BranchTrackStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return branches;
|
||||
}
|
||||
|
||||
public async Task<List<Models.Branch>> ResultAsync()
|
||||
public async Task<List<Models.Branch>> GetResultAsync()
|
||||
{
|
||||
var branches = new List<Models.Branch>();
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (!rs.IsSuccess)
|
||||
return branches;
|
||||
|
||||
@@ -89,7 +45,7 @@ namespace SourceGit.Commands
|
||||
if (remoteHeads.TryGetValue(b.Upstream, out var upstreamHead))
|
||||
{
|
||||
b.IsUpstreamGone = false;
|
||||
b.TrackStatus ??= await new QueryTrackStatus(WorkingDirectory, b.Head, upstreamHead).ResultAsync();
|
||||
b.TrackStatus ??= await new QueryTrackStatus(WorkingDirectory, b.Head, upstreamHead).GetResultAsync().ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -14,9 +14,9 @@ namespace SourceGit.Commands
|
||||
Args = $"rev-list -{max} --parents --branches --remotes --ancestry-path ^{commit}";
|
||||
}
|
||||
|
||||
public async Task<List<string>> ResultAsync()
|
||||
public async Task<List<string>> GetResultAsync()
|
||||
{
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
var outs = new List<string>();
|
||||
if (rs.IsSuccess)
|
||||
{
|
||||
|
||||
@@ -11,20 +11,10 @@ namespace SourceGit.Commands
|
||||
Args = $"show --no-show-signature --format=%B -s {sha}";
|
||||
}
|
||||
|
||||
public string Result()
|
||||
public async Task<string> GetResultAsync()
|
||||
{
|
||||
var rs = ReadToEnd();
|
||||
if (rs.IsSuccess)
|
||||
return rs.StdOut.TrimEnd();
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public async Task<string> ResultAsync()
|
||||
{
|
||||
var rs = await ReadToEndAsync();
|
||||
if (rs.IsSuccess)
|
||||
return rs.StdOut.TrimEnd();
|
||||
return string.Empty;
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
return rs.IsSuccess ? rs.StdOut.TrimEnd() : string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,9 +14,9 @@ namespace SourceGit.Commands
|
||||
Args = $"{(useFakeSignersFile ? fakeSignersFileArg : string.Empty)} {baseArgs} {sha}";
|
||||
}
|
||||
|
||||
public async Task<Models.CommitSignInfo> ResultAsync()
|
||||
public async Task<Models.CommitSignInfo> GetResultAsync()
|
||||
{
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (!rs.IsSuccess)
|
||||
return null;
|
||||
|
||||
|
||||
@@ -57,9 +57,9 @@ namespace SourceGit.Commands
|
||||
_findFirstMerged = false;
|
||||
}
|
||||
|
||||
public List<Models.Commit> Result()
|
||||
public async Task<List<Models.Commit>> GetResultAsync()
|
||||
{
|
||||
var rs = ReadToEnd();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (!rs.IsSuccess)
|
||||
return _commits;
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace SourceGit.Commands
|
||||
_current.Subject = rs.StdOut.Substring(start);
|
||||
|
||||
if (_findFirstMerged && !_isHeadFounded && _commits.Count > 0)
|
||||
MarkFirstMerged();
|
||||
await MarkFirstMergedAsync().ConfigureAwait(false);
|
||||
|
||||
return _commits;
|
||||
}
|
||||
@@ -124,90 +124,11 @@ namespace SourceGit.Commands
|
||||
_current.Parents.AddRange(data.Split(separator: ' ', options: StringSplitOptions.RemoveEmptyEntries));
|
||||
}
|
||||
|
||||
private void MarkFirstMerged()
|
||||
{
|
||||
Args = $"log --since=\"{_commits[^1].CommitterTimeStr}\" --format=\"%H\"";
|
||||
|
||||
var rs = ReadToEnd();
|
||||
var shas = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
if (shas.Length == 0)
|
||||
return;
|
||||
|
||||
var set = new HashSet<string>(shas);
|
||||
foreach (var c in _commits)
|
||||
{
|
||||
if (set.Contains(c.SHA))
|
||||
{
|
||||
c.IsMerged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<Models.Commit>> ResultAsync()
|
||||
{
|
||||
var rs = await ReadToEndAsync();
|
||||
if (!rs.IsSuccess)
|
||||
return _commits;
|
||||
|
||||
var nextPartIdx = 0;
|
||||
var start = 0;
|
||||
var end = rs.StdOut.IndexOf('\n', start);
|
||||
while (end > 0)
|
||||
{
|
||||
var line = rs.StdOut.Substring(start, end - start);
|
||||
switch (nextPartIdx)
|
||||
{
|
||||
case 0:
|
||||
_current = new Models.Commit() { SHA = line };
|
||||
_commits.Add(_current);
|
||||
break;
|
||||
case 1:
|
||||
ParseParent(line);
|
||||
break;
|
||||
case 2:
|
||||
_current.ParseDecorators(line);
|
||||
if (_current.IsMerged && !_isHeadFounded)
|
||||
_isHeadFounded = true;
|
||||
break;
|
||||
case 3:
|
||||
_current.Author = Models.User.FindOrAdd(line);
|
||||
break;
|
||||
case 4:
|
||||
_current.AuthorTime = ulong.Parse(line);
|
||||
break;
|
||||
case 5:
|
||||
_current.Committer = Models.User.FindOrAdd(line);
|
||||
break;
|
||||
case 6:
|
||||
_current.CommitterTime = ulong.Parse(line);
|
||||
break;
|
||||
case 7:
|
||||
_current.Subject = line;
|
||||
nextPartIdx = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
nextPartIdx++;
|
||||
|
||||
start = end + 1;
|
||||
end = rs.StdOut.IndexOf('\n', start);
|
||||
}
|
||||
|
||||
if (start < rs.StdOut.Length)
|
||||
_current.Subject = rs.StdOut.Substring(start);
|
||||
|
||||
if (_findFirstMerged && !_isHeadFounded && _commits.Count > 0)
|
||||
await MarkFirstMergedAsync();
|
||||
|
||||
return _commits;
|
||||
}
|
||||
|
||||
private async Task MarkFirstMergedAsync()
|
||||
{
|
||||
Args = $"log --since=\"{_commits[^1].CommitterTimeStr}\" --format=\"%H\"";
|
||||
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
var shas = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
if (shas.Length == 0)
|
||||
return;
|
||||
|
||||
@@ -15,9 +15,9 @@ namespace SourceGit.Commands
|
||||
Args = $"log --date-order --no-show-signature --decorate=full --format=\"%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%B%n{_boundary}\" {on}..HEAD";
|
||||
}
|
||||
|
||||
public async Task<List<Models.InteractiveCommit>> ResultAsync()
|
||||
public async Task<List<Models.InteractiveCommit>> GetResultAsync()
|
||||
{
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (!rs.IsSuccess)
|
||||
return _commits;
|
||||
|
||||
|
||||
20
src/Commands/QueryCurrentBranch.cs
Normal file
20
src/Commands/QueryCurrentBranch.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SourceGit.Commands
|
||||
{
|
||||
public class QueryCurrentBranch : Command
|
||||
{
|
||||
public QueryCurrentBranch(string repo)
|
||||
{
|
||||
WorkingDirectory = repo;
|
||||
Context = repo;
|
||||
Args = "branch --show-current";
|
||||
}
|
||||
|
||||
public async Task<string> GetResultAsync()
|
||||
{
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
return rs.StdOut.Trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,70 +7,6 @@ namespace SourceGit.Commands
|
||||
{
|
||||
public static class QueryFileContent
|
||||
{
|
||||
public static Stream 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;
|
||||
|
||||
var stream = new MemoryStream();
|
||||
try
|
||||
{
|
||||
var proc = new Process() { StartInfo = starter };
|
||||
proc.Start();
|
||||
proc.StandardOutput.BaseStream.CopyTo(stream);
|
||||
proc.WaitForExit();
|
||||
proc.Close();
|
||||
|
||||
stream.Position = 0;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
App.RaiseException(repo, $"Failed to query file content: {e}");
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
public static Stream FromLFS(string repo, string oid, long size)
|
||||
{
|
||||
var starter = new ProcessStartInfo();
|
||||
starter.WorkingDirectory = repo;
|
||||
starter.FileName = Native.OS.GitExecutable;
|
||||
starter.Arguments = "lfs smudge";
|
||||
starter.UseShellExecute = false;
|
||||
starter.CreateNoWindow = true;
|
||||
starter.WindowStyle = ProcessWindowStyle.Hidden;
|
||||
starter.RedirectStandardInput = true;
|
||||
starter.RedirectStandardOutput = true;
|
||||
|
||||
var stream = new MemoryStream();
|
||||
try
|
||||
{
|
||||
var proc = new Process() { StartInfo = starter };
|
||||
proc.Start();
|
||||
proc.StandardInput.WriteLine("version https://git-lfs.github.com/spec/v1");
|
||||
proc.StandardInput.WriteLine($"oid sha256:{oid}");
|
||||
proc.StandardInput.WriteLine($"size {size}");
|
||||
proc.StandardOutput.BaseStream.CopyTo(stream);
|
||||
proc.WaitForExit();
|
||||
proc.Close();
|
||||
|
||||
stream.Position = 0;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
App.RaiseException(repo, $"Failed to query file content: {e}");
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
public static async Task<Stream> RunAsync(string repo, string revision, string file)
|
||||
{
|
||||
var starter = new ProcessStartInfo();
|
||||
@@ -87,8 +23,8 @@ namespace SourceGit.Commands
|
||||
{
|
||||
var proc = new Process() { StartInfo = starter };
|
||||
proc.Start();
|
||||
await proc.StandardOutput.BaseStream.CopyToAsync(stream);
|
||||
await proc.WaitForExitAsync();
|
||||
await proc.StandardOutput.BaseStream.CopyToAsync(stream).ConfigureAwait(false);
|
||||
await proc.WaitForExitAsync().ConfigureAwait(false);
|
||||
proc.Close();
|
||||
|
||||
stream.Position = 0;
|
||||
@@ -118,11 +54,11 @@ namespace SourceGit.Commands
|
||||
{
|
||||
var proc = new Process() { StartInfo = starter };
|
||||
proc.Start();
|
||||
await proc.StandardInput.WriteLineAsync("version https://git-lfs.github.com/spec/v1");
|
||||
await proc.StandardInput.WriteLineAsync($"oid sha256:{oid}");
|
||||
await proc.StandardInput.WriteLineAsync($"size {size}");
|
||||
await proc.StandardOutput.BaseStream.CopyToAsync(stream);
|
||||
await proc.WaitForExitAsync();
|
||||
await proc.StandardInput.WriteLineAsync("version https://git-lfs.github.com/spec/v1").ConfigureAwait(false);
|
||||
await proc.StandardInput.WriteLineAsync($"oid sha256:{oid}").ConfigureAwait(false);
|
||||
await proc.StandardInput.WriteLineAsync($"size {size}").ConfigureAwait(false);
|
||||
await proc.StandardOutput.BaseStream.CopyToAsync(stream).ConfigureAwait(false);
|
||||
await proc.WaitForExitAsync().ConfigureAwait(false);
|
||||
proc.Close();
|
||||
|
||||
stream.Position = 0;
|
||||
|
||||
@@ -15,9 +15,9 @@ namespace SourceGit.Commands
|
||||
Args = $"ls-tree {revision} -l -- \"{file}\"";
|
||||
}
|
||||
|
||||
public async Task<long> ResultAsync()
|
||||
public async Task<long> GetResultAsync()
|
||||
{
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (rs.IsSuccess)
|
||||
{
|
||||
var match = REG_FORMAT().Match(rs.StdOut);
|
||||
|
||||
@@ -9,31 +9,19 @@ namespace SourceGit.Commands
|
||||
{
|
||||
WorkingDirectory = workDir;
|
||||
Args = "rev-parse --git-common-dir";
|
||||
RaiseError = false;
|
||||
}
|
||||
|
||||
public string Result()
|
||||
public async Task<string> GetResultAsync()
|
||||
{
|
||||
var rs = ReadToEnd().StdOut;
|
||||
if (string.IsNullOrEmpty(rs))
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (!rs.IsSuccess)
|
||||
return null;
|
||||
|
||||
rs = rs.Trim();
|
||||
if (Path.IsPathRooted(rs))
|
||||
return rs;
|
||||
return Path.GetFullPath(Path.Combine(WorkingDirectory, rs));
|
||||
}
|
||||
|
||||
public async Task<string> ResultAsync()
|
||||
{
|
||||
var rs = (await ReadToEndAsync()).StdOut;
|
||||
if (string.IsNullOrEmpty(rs))
|
||||
var stdout = rs.StdOut.Trim();
|
||||
if (string.IsNullOrEmpty(stdout))
|
||||
return null;
|
||||
|
||||
rs = rs.Trim();
|
||||
if (Path.IsPathRooted(rs))
|
||||
return rs;
|
||||
return Path.GetFullPath(Path.Combine(WorkingDirectory, rs));
|
||||
return Path.IsPathRooted(stdout) ? stdout : Path.GetFullPath(Path.Combine(WorkingDirectory, stdout));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,31 +9,19 @@ namespace SourceGit.Commands
|
||||
{
|
||||
WorkingDirectory = workDir;
|
||||
Args = "rev-parse --git-dir";
|
||||
RaiseError = false;
|
||||
}
|
||||
|
||||
public string Result()
|
||||
public async Task<string> GetResultAsync()
|
||||
{
|
||||
var rs = ReadToEnd().StdOut;
|
||||
if (string.IsNullOrEmpty(rs))
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (!rs.IsSuccess)
|
||||
return null;
|
||||
|
||||
rs = rs.Trim();
|
||||
if (Path.IsPathRooted(rs))
|
||||
return rs;
|
||||
return Path.GetFullPath(Path.Combine(WorkingDirectory, rs));
|
||||
}
|
||||
|
||||
public async Task<string> ResultAsync()
|
||||
{
|
||||
var rs = (await ReadToEndAsync()).StdOut;
|
||||
if (string.IsNullOrEmpty(rs))
|
||||
var stdout = rs.StdOut.Trim();
|
||||
if (string.IsNullOrEmpty(stdout))
|
||||
return null;
|
||||
|
||||
rs = rs.Trim();
|
||||
if (Path.IsPathRooted(rs))
|
||||
return rs;
|
||||
return Path.GetFullPath(Path.Combine(WorkingDirectory, rs));
|
||||
return Path.IsPathRooted(stdout) ? stdout : Path.GetFullPath(Path.Combine(WorkingDirectory, stdout));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,153 +18,10 @@ namespace SourceGit.Commands
|
||||
Args = $"--no-optional-locks status -u{UNTRACKED[includeUntracked ? 1 : 0]} --ignore-submodules=dirty --porcelain";
|
||||
}
|
||||
|
||||
public List<Models.Change> Result()
|
||||
public async Task<List<Models.Change>> GetResultAsync()
|
||||
{
|
||||
var outs = new List<Models.Change>();
|
||||
var rs = ReadToEnd();
|
||||
if (!rs.IsSuccess)
|
||||
{
|
||||
App.RaiseException(Context, rs.StdErr);
|
||||
return outs;
|
||||
}
|
||||
|
||||
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var match = REG_FORMAT().Match(line);
|
||||
if (!match.Success)
|
||||
continue;
|
||||
|
||||
var change = new Models.Change() { Path = match.Groups[2].Value };
|
||||
var status = match.Groups[1].Value;
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case " M":
|
||||
change.Set(Models.ChangeState.None, Models.ChangeState.Modified);
|
||||
break;
|
||||
case " T":
|
||||
change.Set(Models.ChangeState.None, Models.ChangeState.TypeChanged);
|
||||
break;
|
||||
case " A":
|
||||
change.Set(Models.ChangeState.None, Models.ChangeState.Added);
|
||||
break;
|
||||
case " D":
|
||||
change.Set(Models.ChangeState.None, Models.ChangeState.Deleted);
|
||||
break;
|
||||
case " R":
|
||||
change.Set(Models.ChangeState.None, Models.ChangeState.Renamed);
|
||||
break;
|
||||
case " C":
|
||||
change.Set(Models.ChangeState.None, Models.ChangeState.Copied);
|
||||
break;
|
||||
case "M":
|
||||
change.Set(Models.ChangeState.Modified);
|
||||
break;
|
||||
case "MM":
|
||||
change.Set(Models.ChangeState.Modified, Models.ChangeState.Modified);
|
||||
break;
|
||||
case "MT":
|
||||
change.Set(Models.ChangeState.Modified, Models.ChangeState.TypeChanged);
|
||||
break;
|
||||
case "MD":
|
||||
change.Set(Models.ChangeState.Modified, Models.ChangeState.Deleted);
|
||||
break;
|
||||
case "T":
|
||||
change.Set(Models.ChangeState.TypeChanged);
|
||||
break;
|
||||
case "TM":
|
||||
change.Set(Models.ChangeState.TypeChanged, Models.ChangeState.Modified);
|
||||
break;
|
||||
case "TT":
|
||||
change.Set(Models.ChangeState.TypeChanged, Models.ChangeState.TypeChanged);
|
||||
break;
|
||||
case "TD":
|
||||
change.Set(Models.ChangeState.TypeChanged, Models.ChangeState.Deleted);
|
||||
break;
|
||||
case "A":
|
||||
change.Set(Models.ChangeState.Added);
|
||||
break;
|
||||
case "AM":
|
||||
change.Set(Models.ChangeState.Added, Models.ChangeState.Modified);
|
||||
break;
|
||||
case "AT":
|
||||
change.Set(Models.ChangeState.Added, Models.ChangeState.TypeChanged);
|
||||
break;
|
||||
case "AD":
|
||||
change.Set(Models.ChangeState.Added, Models.ChangeState.Deleted);
|
||||
break;
|
||||
case "D":
|
||||
change.Set(Models.ChangeState.Deleted);
|
||||
break;
|
||||
case "R":
|
||||
change.Set(Models.ChangeState.Renamed);
|
||||
break;
|
||||
case "RM":
|
||||
change.Set(Models.ChangeState.Renamed, Models.ChangeState.Modified);
|
||||
break;
|
||||
case "RT":
|
||||
change.Set(Models.ChangeState.Renamed, Models.ChangeState.TypeChanged);
|
||||
break;
|
||||
case "RD":
|
||||
change.Set(Models.ChangeState.Renamed, Models.ChangeState.Deleted);
|
||||
break;
|
||||
case "C":
|
||||
change.Set(Models.ChangeState.Copied);
|
||||
break;
|
||||
case "CM":
|
||||
change.Set(Models.ChangeState.Copied, Models.ChangeState.Modified);
|
||||
break;
|
||||
case "CT":
|
||||
change.Set(Models.ChangeState.Copied, Models.ChangeState.TypeChanged);
|
||||
break;
|
||||
case "CD":
|
||||
change.Set(Models.ChangeState.Copied, Models.ChangeState.Deleted);
|
||||
break;
|
||||
case "DD":
|
||||
change.ConflictReason = Models.ConflictReason.BothDeleted;
|
||||
change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
|
||||
break;
|
||||
case "AU":
|
||||
change.ConflictReason = Models.ConflictReason.AddedByUs;
|
||||
change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
|
||||
break;
|
||||
case "UD":
|
||||
change.ConflictReason = Models.ConflictReason.DeletedByThem;
|
||||
change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
|
||||
break;
|
||||
case "UA":
|
||||
change.ConflictReason = Models.ConflictReason.AddedByThem;
|
||||
change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
|
||||
break;
|
||||
case "DU":
|
||||
change.ConflictReason = Models.ConflictReason.DeletedByUs;
|
||||
change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
|
||||
break;
|
||||
case "AA":
|
||||
change.ConflictReason = Models.ConflictReason.BothAdded;
|
||||
change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
|
||||
break;
|
||||
case "UU":
|
||||
change.ConflictReason = Models.ConflictReason.BothModified;
|
||||
change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
|
||||
break;
|
||||
case "??":
|
||||
change.Set(Models.ChangeState.None, Models.ChangeState.Untracked);
|
||||
break;
|
||||
}
|
||||
|
||||
if (change.Index != Models.ChangeState.None || change.WorkTree != Models.ChangeState.None)
|
||||
outs.Add(change);
|
||||
}
|
||||
|
||||
return outs;
|
||||
}
|
||||
|
||||
public async Task<List<Models.Change>> ResultAsync()
|
||||
{
|
||||
var outs = new List<Models.Change>();
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (!rs.IsSuccess)
|
||||
{
|
||||
App.RaiseException(Context, rs.StdErr);
|
||||
|
||||
@@ -13,54 +13,28 @@ namespace SourceGit.Commands
|
||||
Args = $"for-each-ref --format=\"%(refname)\" --contains {commit}";
|
||||
}
|
||||
|
||||
public List<Models.Decorator> Result()
|
||||
public async Task<List<Models.Decorator>> GetResultAsync()
|
||||
{
|
||||
var rs = new List<Models.Decorator>();
|
||||
var outs = new List<Models.Decorator>();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (!rs.IsSuccess)
|
||||
return outs;
|
||||
|
||||
var output = ReadToEnd();
|
||||
if (!output.IsSuccess)
|
||||
return rs;
|
||||
|
||||
var lines = output.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var line in lines)
|
||||
{
|
||||
if (line.EndsWith("/HEAD", StringComparison.Ordinal))
|
||||
continue;
|
||||
|
||||
if (line.StartsWith("refs/heads/", StringComparison.Ordinal))
|
||||
rs.Add(new() { Name = line.Substring("refs/heads/".Length), Type = Models.DecoratorType.LocalBranchHead });
|
||||
outs.Add(new() { Name = line.Substring("refs/heads/".Length), Type = Models.DecoratorType.LocalBranchHead });
|
||||
else if (line.StartsWith("refs/remotes/", StringComparison.Ordinal))
|
||||
rs.Add(new() { Name = line.Substring("refs/remotes/".Length), Type = Models.DecoratorType.RemoteBranchHead });
|
||||
outs.Add(new() { Name = line.Substring("refs/remotes/".Length), Type = Models.DecoratorType.RemoteBranchHead });
|
||||
else if (line.StartsWith("refs/tags/", StringComparison.Ordinal))
|
||||
rs.Add(new() { Name = line.Substring("refs/tags/".Length), Type = Models.DecoratorType.Tag });
|
||||
outs.Add(new() { Name = line.Substring("refs/tags/".Length), Type = Models.DecoratorType.Tag });
|
||||
}
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
public async Task<List<Models.Decorator>> ResultAsync()
|
||||
{
|
||||
var rs = new List<Models.Decorator>();
|
||||
|
||||
var output = await ReadToEndAsync();
|
||||
if (!output.IsSuccess)
|
||||
return rs;
|
||||
|
||||
var lines = output.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var line in lines)
|
||||
{
|
||||
if (line.EndsWith("/HEAD", StringComparison.Ordinal))
|
||||
continue;
|
||||
|
||||
if (line.StartsWith("refs/heads/", StringComparison.Ordinal))
|
||||
rs.Add(new() { Name = line.Substring("refs/heads/".Length), Type = Models.DecoratorType.LocalBranchHead });
|
||||
else if (line.StartsWith("refs/remotes/", StringComparison.Ordinal))
|
||||
rs.Add(new() { Name = line.Substring("refs/remotes/".Length), Type = Models.DecoratorType.RemoteBranchHead });
|
||||
else if (line.StartsWith("refs/tags/", StringComparison.Ordinal))
|
||||
rs.Add(new() { Name = line.Substring("refs/tags/".Length), Type = Models.DecoratorType.Tag });
|
||||
}
|
||||
|
||||
return rs;
|
||||
return outs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,39 +17,10 @@ namespace SourceGit.Commands
|
||||
Args = "remote -v";
|
||||
}
|
||||
|
||||
public List<Models.Remote> Result()
|
||||
public async Task<List<Models.Remote>> GetResultAsync()
|
||||
{
|
||||
var outs = new List<Models.Remote>();
|
||||
var rs = ReadToEnd();
|
||||
if (!rs.IsSuccess)
|
||||
return outs;
|
||||
|
||||
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var match = REG_REMOTE().Match(line);
|
||||
if (!match.Success)
|
||||
continue;
|
||||
|
||||
var remote = new Models.Remote()
|
||||
{
|
||||
Name = match.Groups[1].Value,
|
||||
URL = match.Groups[2].Value,
|
||||
};
|
||||
|
||||
if (outs.Find(x => x.Name == remote.Name) != null)
|
||||
continue;
|
||||
|
||||
outs.Add(remote);
|
||||
}
|
||||
|
||||
return outs;
|
||||
}
|
||||
|
||||
public async Task<List<Models.Remote>> ResultAsync()
|
||||
{
|
||||
var outs = new List<Models.Remote>();
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (!rs.IsSuccess)
|
||||
return outs;
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace SourceGit.Commands
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SourceGit.Commands
|
||||
{
|
||||
public class QueryRepositoryRootPath : Command
|
||||
{
|
||||
@@ -7,5 +9,10 @@
|
||||
WorkingDirectory = path;
|
||||
Args = "rev-parse --show-toplevel";
|
||||
}
|
||||
|
||||
public async Task<Result> GetResultAsync()
|
||||
{
|
||||
return await ReadToEndAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,18 +11,9 @@ namespace SourceGit.Commands
|
||||
Args = $"rev-parse {refname}";
|
||||
}
|
||||
|
||||
public string Result()
|
||||
public async Task<string> GetResultAsync()
|
||||
{
|
||||
var rs = ReadToEnd();
|
||||
if (rs.IsSuccess && !string.IsNullOrEmpty(rs.StdOut))
|
||||
return rs.StdOut.Trim();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<string> ResultAsync()
|
||||
{
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (rs.IsSuccess && !string.IsNullOrEmpty(rs.StdOut))
|
||||
return rs.StdOut.Trim();
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@ namespace SourceGit.Commands
|
||||
Args = $"ls-tree -r -z --name-only {revision}";
|
||||
}
|
||||
|
||||
public async Task<List<string>> ResultAsync()
|
||||
public async Task<List<string>> GetResultAsync()
|
||||
{
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (!rs.IsSuccess)
|
||||
return [];
|
||||
|
||||
|
||||
@@ -19,9 +19,10 @@ namespace SourceGit.Commands
|
||||
Args += $" -- \"{parentFolder}\"";
|
||||
}
|
||||
|
||||
public List<Models.Object> Result()
|
||||
public async Task<List<Models.Object>> GetResultAsync()
|
||||
{
|
||||
var rs = ReadToEnd();
|
||||
var outs = new List<Models.Object>();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (rs.IsSuccess)
|
||||
{
|
||||
var start = 0;
|
||||
@@ -29,41 +30,19 @@ namespace SourceGit.Commands
|
||||
while (end > 0)
|
||||
{
|
||||
var line = rs.StdOut.Substring(start, end - start);
|
||||
Parse(line);
|
||||
Parse(outs, line);
|
||||
start = end + 1;
|
||||
end = rs.StdOut.IndexOf('\0', start);
|
||||
}
|
||||
|
||||
if (start < rs.StdOut.Length)
|
||||
Parse(rs.StdOut.Substring(start));
|
||||
Parse(outs, rs.StdOut.Substring(start));
|
||||
}
|
||||
|
||||
return _objects;
|
||||
return outs;
|
||||
}
|
||||
|
||||
public async Task<List<Models.Object>> ResultAsync()
|
||||
{
|
||||
var rs = await ReadToEndAsync();
|
||||
if (rs.IsSuccess)
|
||||
{
|
||||
var start = 0;
|
||||
var end = rs.StdOut.IndexOf('\0', start);
|
||||
while (end > 0)
|
||||
{
|
||||
var line = rs.StdOut.Substring(start, end - start);
|
||||
Parse(line);
|
||||
start = end + 1;
|
||||
end = rs.StdOut.IndexOf('\0', start);
|
||||
}
|
||||
|
||||
if (start < rs.StdOut.Length)
|
||||
Parse(rs.StdOut.Substring(start));
|
||||
}
|
||||
|
||||
return _objects;
|
||||
}
|
||||
|
||||
private void Parse(string line)
|
||||
private void Parse(List<Models.Object> outs, string line)
|
||||
{
|
||||
var match = REG_FORMAT().Match(line);
|
||||
if (!match.Success)
|
||||
@@ -83,9 +62,7 @@ namespace SourceGit.Commands
|
||||
_ => obj.Type,
|
||||
};
|
||||
|
||||
_objects.Add(obj);
|
||||
outs.Add(obj);
|
||||
}
|
||||
|
||||
private List<Models.Object> _objects = new List<Models.Object>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,36 +12,9 @@ namespace SourceGit.Commands
|
||||
Args = $"show --no-show-signature --decorate=full --format=%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s -s {sha}";
|
||||
}
|
||||
|
||||
public Models.Commit Result()
|
||||
public async Task<Models.Commit> GetResultAsync()
|
||||
{
|
||||
var rs = ReadToEnd();
|
||||
if (rs.IsSuccess && !string.IsNullOrEmpty(rs.StdOut))
|
||||
{
|
||||
var commit = new Models.Commit();
|
||||
var lines = rs.StdOut.Split('\n');
|
||||
if (lines.Length < 8)
|
||||
return null;
|
||||
|
||||
commit.SHA = lines[0];
|
||||
if (!string.IsNullOrEmpty(lines[1]))
|
||||
commit.Parents.AddRange(lines[1].Split(' ', StringSplitOptions.RemoveEmptyEntries));
|
||||
if (!string.IsNullOrEmpty(lines[2]))
|
||||
commit.ParseDecorators(lines[2]);
|
||||
commit.Author = Models.User.FindOrAdd(lines[3]);
|
||||
commit.AuthorTime = ulong.Parse(lines[4]);
|
||||
commit.Committer = Models.User.FindOrAdd(lines[5]);
|
||||
commit.CommitterTime = ulong.Parse(lines[6]);
|
||||
commit.Subject = lines[7];
|
||||
|
||||
return commit;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<Models.Commit> ResultAsync()
|
||||
{
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (rs.IsSuccess && !string.IsNullOrEmpty(rs.StdOut))
|
||||
{
|
||||
var commit = new Models.Commit();
|
||||
|
||||
@@ -20,77 +20,9 @@ namespace SourceGit.Commands
|
||||
_parent = parent;
|
||||
}
|
||||
|
||||
public List<Models.Change> Result()
|
||||
public async Task<List<Models.Change>> GetResultAsync()
|
||||
{
|
||||
var rs = ReadToEnd();
|
||||
if (!rs.IsSuccess)
|
||||
return [];
|
||||
|
||||
var changes = new List<Models.Change>();
|
||||
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var match = REG_FORMAT2().Match(line);
|
||||
if (match.Success)
|
||||
{
|
||||
var change = new Models.Change()
|
||||
{
|
||||
Path = match.Groups[3].Value,
|
||||
DataForAmend = new Models.ChangeDataForAmend()
|
||||
{
|
||||
FileMode = match.Groups[1].Value,
|
||||
ObjectHash = match.Groups[2].Value,
|
||||
ParentSHA = _parent,
|
||||
},
|
||||
};
|
||||
change.Set(Models.ChangeState.Renamed);
|
||||
changes.Add(change);
|
||||
continue;
|
||||
}
|
||||
|
||||
match = REG_FORMAT1().Match(line);
|
||||
if (match.Success)
|
||||
{
|
||||
var change = new Models.Change()
|
||||
{
|
||||
Path = match.Groups[4].Value,
|
||||
DataForAmend = new Models.ChangeDataForAmend()
|
||||
{
|
||||
FileMode = match.Groups[1].Value,
|
||||
ObjectHash = match.Groups[2].Value,
|
||||
ParentSHA = _parent,
|
||||
},
|
||||
};
|
||||
|
||||
var type = match.Groups[3].Value;
|
||||
switch (type)
|
||||
{
|
||||
case "A":
|
||||
change.Set(Models.ChangeState.Added);
|
||||
break;
|
||||
case "C":
|
||||
change.Set(Models.ChangeState.Copied);
|
||||
break;
|
||||
case "D":
|
||||
change.Set(Models.ChangeState.Deleted);
|
||||
break;
|
||||
case "M":
|
||||
change.Set(Models.ChangeState.Modified);
|
||||
break;
|
||||
case "T":
|
||||
change.Set(Models.ChangeState.TypeChanged);
|
||||
break;
|
||||
}
|
||||
changes.Add(change);
|
||||
}
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
public async Task<List<Models.Change>> ResultAsync()
|
||||
{
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (!rs.IsSuccess)
|
||||
return [];
|
||||
|
||||
|
||||
@@ -15,16 +15,11 @@ namespace SourceGit.Commands
|
||||
Args = $"ls-files -s -- \"{file}\"";
|
||||
}
|
||||
|
||||
public async Task<string> ResultAsync()
|
||||
public async Task<string> GetResultAsync()
|
||||
{
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
var match = REG_FORMAT().Match(rs.StdOut.Trim());
|
||||
if (match.Success)
|
||||
{
|
||||
return match.Groups[1].Value;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
return match.Success ? match.Groups[1].Value : string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,63 +13,10 @@ namespace SourceGit.Commands
|
||||
Args = "stash list -z --no-show-signature --format=\"%H%n%P%n%ct%n%gd%n%B\"";
|
||||
}
|
||||
|
||||
public List<Models.Stash> Result()
|
||||
public async Task<List<Models.Stash>> GetResultAsync()
|
||||
{
|
||||
var outs = new List<Models.Stash>();
|
||||
var rs = ReadToEnd();
|
||||
if (!rs.IsSuccess)
|
||||
return outs;
|
||||
|
||||
var items = rs.StdOut.Split('\0', StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var item in items)
|
||||
{
|
||||
var current = new Models.Stash();
|
||||
|
||||
var nextPartIdx = 0;
|
||||
var start = 0;
|
||||
var end = item.IndexOf('\n', start);
|
||||
while (end > 0 && nextPartIdx < 4)
|
||||
{
|
||||
var line = item.Substring(start, end - start);
|
||||
|
||||
switch (nextPartIdx)
|
||||
{
|
||||
case 0:
|
||||
current.SHA = line;
|
||||
break;
|
||||
case 1:
|
||||
if (line.Length > 6)
|
||||
current.Parents.AddRange(line.Split(' ', StringSplitOptions.RemoveEmptyEntries));
|
||||
break;
|
||||
case 2:
|
||||
current.Time = ulong.Parse(line);
|
||||
break;
|
||||
case 3:
|
||||
current.Name = line;
|
||||
break;
|
||||
}
|
||||
|
||||
nextPartIdx++;
|
||||
|
||||
start = end + 1;
|
||||
if (start >= item.Length - 1)
|
||||
break;
|
||||
|
||||
end = item.IndexOf('\n', start);
|
||||
}
|
||||
|
||||
if (start < item.Length)
|
||||
current.Message = item.Substring(start);
|
||||
|
||||
outs.Add(current);
|
||||
}
|
||||
return outs;
|
||||
}
|
||||
|
||||
public async Task<List<Models.Stash>> ResultAsync()
|
||||
{
|
||||
var outs = new List<Models.Stash>();
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (!rs.IsSuccess)
|
||||
return outs;
|
||||
|
||||
|
||||
@@ -22,122 +22,10 @@ namespace SourceGit.Commands
|
||||
Args = "submodule status";
|
||||
}
|
||||
|
||||
public List<Models.Submodule> Result()
|
||||
public async Task<List<Models.Submodule>> GetResultAsync()
|
||||
{
|
||||
var submodules = new List<Models.Submodule>();
|
||||
var rs = ReadToEnd();
|
||||
|
||||
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
var map = new Dictionary<string, Models.Submodule>();
|
||||
var needCheckLocalChanges = false;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var match = REG_FORMAT_STATUS().Match(line);
|
||||
if (match.Success)
|
||||
{
|
||||
var stat = match.Groups[1].Value;
|
||||
var sha = match.Groups[2].Value;
|
||||
var path = match.Groups[3].Value;
|
||||
|
||||
var module = new Models.Submodule() { Path = path, SHA = sha };
|
||||
switch (stat[0])
|
||||
{
|
||||
case '-':
|
||||
module.Status = Models.SubmoduleStatus.NotInited;
|
||||
break;
|
||||
case '+':
|
||||
module.Status = Models.SubmoduleStatus.RevisionChanged;
|
||||
break;
|
||||
case 'U':
|
||||
module.Status = Models.SubmoduleStatus.Unmerged;
|
||||
break;
|
||||
default:
|
||||
module.Status = Models.SubmoduleStatus.Normal;
|
||||
needCheckLocalChanges = true;
|
||||
break;
|
||||
}
|
||||
|
||||
map.Add(path, module);
|
||||
submodules.Add(module);
|
||||
}
|
||||
}
|
||||
|
||||
if (submodules.Count > 0)
|
||||
{
|
||||
Args = "config --file .gitmodules --list";
|
||||
rs = ReadToEnd();
|
||||
if (rs.IsSuccess)
|
||||
{
|
||||
var modules = new Dictionary<string, ModuleInfo>();
|
||||
lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var match = REG_FORMAT_MODULE_INFO().Match(line);
|
||||
if (match.Success)
|
||||
{
|
||||
var name = match.Groups[1].Value;
|
||||
var key = match.Groups[2].Value;
|
||||
var val = match.Groups[3].Value;
|
||||
|
||||
if (!modules.TryGetValue(name, out var m))
|
||||
{
|
||||
m = new ModuleInfo();
|
||||
modules.Add(name, m);
|
||||
}
|
||||
|
||||
if (key.Equals("path", StringComparison.Ordinal))
|
||||
m.Path = val;
|
||||
else if (key.Equals("url", StringComparison.Ordinal))
|
||||
m.URL = val;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var kv in modules)
|
||||
{
|
||||
if (map.TryGetValue(kv.Value.Path, out var m))
|
||||
m.URL = kv.Value.URL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (needCheckLocalChanges)
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
foreach (var kv in map)
|
||||
{
|
||||
if (kv.Value.Status == Models.SubmoduleStatus.Normal)
|
||||
{
|
||||
builder.Append('"');
|
||||
builder.Append(kv.Key);
|
||||
builder.Append("\" ");
|
||||
}
|
||||
}
|
||||
|
||||
Args = $"--no-optional-locks status --porcelain -- {builder}";
|
||||
rs = ReadToEnd();
|
||||
if (!rs.IsSuccess)
|
||||
return submodules;
|
||||
|
||||
lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var match = REG_FORMAT_DIRTY().Match(line);
|
||||
if (match.Success)
|
||||
{
|
||||
var path = match.Groups[1].Value;
|
||||
if (map.TryGetValue(path, out var m))
|
||||
m.Status = Models.SubmoduleStatus.Modified;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return submodules;
|
||||
}
|
||||
|
||||
public async Task<List<Models.Submodule>> ResultAsync()
|
||||
{
|
||||
var submodules = new List<Models.Submodule>();
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
|
||||
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
var map = new Dictionary<string, Models.Submodule>();
|
||||
|
||||
@@ -15,42 +15,10 @@ namespace SourceGit.Commands
|
||||
Args = $"tag -l --format=\"{_boundary}%(refname)%00%(objecttype)%00%(objectname)%00%(*objectname)%00%(creatordate:unix)%00%(contents:subject)%0a%0a%(contents:body)\"";
|
||||
}
|
||||
|
||||
public List<Models.Tag> Result()
|
||||
public async Task<List<Models.Tag>> GetResultAsync()
|
||||
{
|
||||
var tags = new List<Models.Tag>();
|
||||
var rs = ReadToEnd();
|
||||
if (!rs.IsSuccess)
|
||||
return tags;
|
||||
|
||||
var records = rs.StdOut.Split(_boundary, StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var record in records)
|
||||
{
|
||||
var subs = record.Split('\0');
|
||||
if (subs.Length != 6)
|
||||
continue;
|
||||
|
||||
var name = subs[0].Substring(10);
|
||||
var message = subs[5].Trim();
|
||||
if (!string.IsNullOrEmpty(message) && message.Equals(name, StringComparison.Ordinal))
|
||||
message = null;
|
||||
|
||||
tags.Add(new Models.Tag()
|
||||
{
|
||||
Name = name,
|
||||
IsAnnotated = subs[1].Equals("tag", StringComparison.Ordinal),
|
||||
SHA = string.IsNullOrEmpty(subs[3]) ? subs[2] : subs[3],
|
||||
CreatorDate = ulong.Parse(subs[4]),
|
||||
Message = message,
|
||||
});
|
||||
}
|
||||
|
||||
return tags;
|
||||
}
|
||||
|
||||
public async Task<List<Models.Tag>> ResultAsync()
|
||||
{
|
||||
var tags = new List<Models.Tag>();
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (!rs.IsSuccess)
|
||||
return tags;
|
||||
|
||||
|
||||
@@ -12,31 +12,11 @@ namespace SourceGit.Commands
|
||||
Args = $"rev-list --left-right {local}...{upstream}";
|
||||
}
|
||||
|
||||
public Models.BranchTrackStatus Result()
|
||||
public async Task<Models.BranchTrackStatus> GetResultAsync()
|
||||
{
|
||||
var status = new Models.BranchTrackStatus();
|
||||
|
||||
var rs = ReadToEnd();
|
||||
if (!rs.IsSuccess)
|
||||
return status;
|
||||
|
||||
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var line in lines)
|
||||
{
|
||||
if (line[0] == '>')
|
||||
status.Behind.Add(line.Substring(1));
|
||||
else
|
||||
status.Ahead.Add(line.Substring(1));
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
public async Task<Models.BranchTrackStatus> ResultAsync()
|
||||
{
|
||||
var status = new Models.BranchTrackStatus();
|
||||
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (!rs.IsSuccess)
|
||||
return status;
|
||||
|
||||
|
||||
@@ -17,10 +17,10 @@ namespace SourceGit.Commands
|
||||
Args = "submodule status";
|
||||
}
|
||||
|
||||
public async Task<List<string>> ResultAsync()
|
||||
public async Task<List<string>> GetResultAsync()
|
||||
{
|
||||
var submodules = new List<string>();
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
|
||||
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var line in lines)
|
||||
|
||||
@@ -64,8 +64,8 @@ namespace SourceGit.Commands
|
||||
{
|
||||
var proc = new Process() { StartInfo = starter };
|
||||
proc.Start();
|
||||
await proc.StandardOutput.BaseStream.CopyToAsync(writer);
|
||||
await proc.WaitForExitAsync();
|
||||
await proc.StandardOutput.BaseStream.CopyToAsync(writer).ConfigureAwait(false);
|
||||
await proc.WaitForExitAsync().ConfigureAwait(false);
|
||||
var rs = proc.ExitCode == 0;
|
||||
proc.Close();
|
||||
|
||||
|
||||
@@ -13,15 +13,15 @@ namespace SourceGit.Commands
|
||||
if (!Directory.Exists(dir))
|
||||
Directory.CreateDirectory(dir);
|
||||
|
||||
var isLFSFiltered = await new IsLFSFiltered(repo, revision, file).ResultAsync();
|
||||
var isLFSFiltered = await new IsLFSFiltered(repo, revision, file).GetResultAsync().ConfigureAwait(false);
|
||||
if (isLFSFiltered)
|
||||
{
|
||||
var pointerStream = await QueryFileContent.RunAsync(repo, revision, file);
|
||||
await ExecCmdAsync(repo, "lfs smudge", saveTo, pointerStream);
|
||||
var pointerStream = await QueryFileContent.RunAsync(repo, revision, file).ConfigureAwait(false);
|
||||
await ExecCmdAsync(repo, "lfs smudge", saveTo, pointerStream).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
await ExecCmdAsync(repo, $"show {revision}:\"{file}\"", saveTo);
|
||||
await ExecCmdAsync(repo, $"show {revision}:\"{file}\"", saveTo).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace SourceGit.Commands
|
||||
builder.Append("\"");
|
||||
|
||||
Args = builder.ToString();
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> PushAsync(string message, List<Models.Change> changes, bool keepIndex)
|
||||
@@ -42,7 +42,7 @@ namespace SourceGit.Commands
|
||||
builder.Append($"\"{c.Path}\" ");
|
||||
|
||||
Args = builder.ToString();
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> PushAsync(string message, string pathspecFromFile, bool keepIndex)
|
||||
@@ -58,7 +58,7 @@ namespace SourceGit.Commands
|
||||
builder.Append("\"");
|
||||
|
||||
Args = builder.ToString();
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> PushOnlyStagedAsync(string message, bool keepIndex)
|
||||
@@ -71,32 +71,32 @@ namespace SourceGit.Commands
|
||||
builder.Append(message);
|
||||
builder.Append("\"");
|
||||
Args = builder.ToString();
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> ApplyAsync(string name, bool restoreIndex)
|
||||
{
|
||||
var opts = restoreIndex ? "--index" : string.Empty;
|
||||
Args = $"stash apply -q {opts} \"{name}\"";
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> PopAsync(string name)
|
||||
{
|
||||
Args = $"stash pop -q --index \"{name}\"";
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> DropAsync(string name)
|
||||
{
|
||||
Args = $"stash drop -q \"{name}\"";
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> ClearAsync()
|
||||
{
|
||||
Args = "stash clear";
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,10 @@ namespace SourceGit.Commands
|
||||
Args = $"log --date-order --branches --remotes -{max} --format=%ct$%aN±%aE";
|
||||
}
|
||||
|
||||
public async Task<Models.Statistics> ResultAsync()
|
||||
public async Task<Models.Statistics> ReadAsync()
|
||||
{
|
||||
var statistics = new Models.Statistics();
|
||||
var rs = await ReadToEndAsync();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
if (!rs.IsSuccess)
|
||||
return statistics;
|
||||
|
||||
|
||||
@@ -15,18 +15,20 @@ namespace SourceGit.Commands
|
||||
public async Task<bool> AddAsync(string url, string relativePath, bool recursive)
|
||||
{
|
||||
Args = $"-c protocol.file.allow=always submodule add \"{url}\" \"{relativePath}\"";
|
||||
if (!await ExecAsync())
|
||||
|
||||
var succ = await ExecAsync().ConfigureAwait(false);
|
||||
if (!succ)
|
||||
return false;
|
||||
|
||||
if (recursive)
|
||||
{
|
||||
Args = $"submodule update --init --recursive -- \"{relativePath}\"";
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
Args = $"submodule update --init -- \"{relativePath}\"";
|
||||
return true;
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,19 +51,19 @@ namespace SourceGit.Commands
|
||||
}
|
||||
|
||||
Args = builder.ToString();
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> DeinitAsync(string module, bool force)
|
||||
{
|
||||
Args = force ? $"submodule deinit -f -- \"{module}\"" : $"submodule deinit -- \"{module}\"";
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteAsync(string module)
|
||||
{
|
||||
Args = $"rm -rf \"{module}\"";
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace SourceGit.Commands
|
||||
cmd.Context = repo;
|
||||
cmd.Args = $"tag --no-sign {name} {basedOn}";
|
||||
cmd.Log = log;
|
||||
return await cmd.ExecAsync();
|
||||
return await cmd.ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task<bool> AddAsync(string repo, string name, string basedOn, string message, bool sign, Models.ICommandLog log)
|
||||
@@ -30,13 +30,13 @@ namespace SourceGit.Commands
|
||||
await File.WriteAllTextAsync(tmp, message);
|
||||
cmd.Args += $"-F \"{tmp}\"";
|
||||
|
||||
var succ = await cmd.ExecAsync();
|
||||
var succ = await cmd.ExecAsync().ConfigureAwait(false);
|
||||
File.Delete(tmp);
|
||||
return succ;
|
||||
}
|
||||
|
||||
cmd.Args += $"-m {name}";
|
||||
return await cmd.ExecAsync();
|
||||
return await cmd.ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task<bool> DeleteAsync(string repo, string name, Models.ICommandLog log)
|
||||
@@ -46,7 +46,7 @@ namespace SourceGit.Commands
|
||||
cmd.Context = repo;
|
||||
cmd.Args = $"tag --delete {name}";
|
||||
cmd.Log = log;
|
||||
return await cmd.ExecAsync();
|
||||
return await cmd.ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,43 +48,6 @@ namespace SourceGit.Commands
|
||||
}
|
||||
}
|
||||
|
||||
public bool Exec()
|
||||
{
|
||||
var starter = new ProcessStartInfo();
|
||||
starter.WorkingDirectory = _repo;
|
||||
starter.FileName = Native.OS.GitExecutable;
|
||||
starter.Arguments = "-c core.editor=true update-index --index-info";
|
||||
starter.UseShellExecute = false;
|
||||
starter.CreateNoWindow = true;
|
||||
starter.WindowStyle = ProcessWindowStyle.Hidden;
|
||||
starter.RedirectStandardInput = true;
|
||||
starter.RedirectStandardOutput = false;
|
||||
starter.RedirectStandardError = true;
|
||||
|
||||
try
|
||||
{
|
||||
var proc = new Process() { StartInfo = starter };
|
||||
proc.Start();
|
||||
proc.StandardInput.Write(_patchBuilder.ToString());
|
||||
proc.StandardInput.Close();
|
||||
|
||||
var err = proc.StandardError.ReadToEnd();
|
||||
proc.WaitForExit();
|
||||
var rs = proc.ExitCode == 0;
|
||||
proc.Close();
|
||||
|
||||
if (!rs)
|
||||
App.RaiseException(_repo, err);
|
||||
|
||||
return rs;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
App.RaiseException(_repo, "Failed to unstage changes: " + e.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> ExecAsync()
|
||||
{
|
||||
var starter = new ProcessStartInfo();
|
||||
@@ -105,8 +68,8 @@ namespace SourceGit.Commands
|
||||
await proc.StandardInput.WriteAsync(_patchBuilder.ToString());
|
||||
proc.StandardInput.Close();
|
||||
|
||||
var err = await proc.StandardError.ReadToEndAsync();
|
||||
await proc.WaitForExitAsync();
|
||||
var err = await proc.StandardError.ReadToEndAsync().ConfigureAwait(false);
|
||||
await proc.WaitForExitAsync().ConfigureAwait(false);
|
||||
var rs = proc.ExitCode == 0;
|
||||
proc.Close();
|
||||
|
||||
|
||||
@@ -13,11 +13,11 @@ namespace SourceGit.Commands
|
||||
Context = repo;
|
||||
}
|
||||
|
||||
public List<Models.Worktree> List()
|
||||
public async Task<List<Models.Worktree>> ReadAllAsync()
|
||||
{
|
||||
Args = "worktree list --porcelain";
|
||||
|
||||
var rs = ReadToEnd();
|
||||
var rs = await ReadToEndAsync().ConfigureAwait(false);
|
||||
var worktrees = new List<Models.Worktree>();
|
||||
Models.Worktree last = null;
|
||||
if (rs.IsSuccess)
|
||||
@@ -79,25 +79,25 @@ namespace SourceGit.Commands
|
||||
else if (!string.IsNullOrEmpty(name) && !createNew)
|
||||
Args += name;
|
||||
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> PruneAsync()
|
||||
{
|
||||
Args = "worktree prune -v";
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> LockAsync(string fullpath)
|
||||
{
|
||||
Args = $"worktree lock \"{fullpath}\"";
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> UnlockAsync(string fullpath)
|
||||
{
|
||||
Args = $"worktree unlock \"{fullpath}\"";
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> RemoveAsync(string fullpath, bool force)
|
||||
@@ -107,7 +107,7 @@ namespace SourceGit.Commands
|
||||
else
|
||||
Args = $"worktree remove \"{fullpath}\"";
|
||||
|
||||
return await ExecAsync();
|
||||
return await ExecAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,20 +95,29 @@ namespace SourceGit.ViewModels
|
||||
var log = _repo.CreateLog("Add Remote");
|
||||
Use(log);
|
||||
|
||||
var succ = await new Commands.Remote(_repo.FullPath).Use(log).AddAsync(_name, _url);
|
||||
var succ = await new Commands.Remote(_repo.FullPath)
|
||||
.Use(log)
|
||||
.AddAsync(_name, _url)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (succ)
|
||||
{
|
||||
await new Commands.Config(_repo.FullPath).Use(log).SetAsync($"remote.{_name}.sshkey", _useSSH ? SSHKey : null);
|
||||
await new Commands.Fetch(_repo.FullPath, _name, false, false).Use(log).ExecAsync();
|
||||
await new Commands.Config(_repo.FullPath)
|
||||
.Use(log)
|
||||
.SetAsync($"remote.{_name}.sshkey", _useSSH ? SSHKey : null)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
await new Commands.Fetch(_repo.FullPath, _name, false, false)
|
||||
.Use(log)
|
||||
.ExecAsync()
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
log.Complete();
|
||||
await CallUIThreadAsync(() =>
|
||||
{
|
||||
_repo.MarkFetched();
|
||||
_repo.MarkBranchesDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
});
|
||||
|
||||
_repo.MarkFetched();
|
||||
_repo.MarkBranchesDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return succ;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,10 +59,13 @@ namespace SourceGit.ViewModels
|
||||
relativePath = Path.GetFileName(_url);
|
||||
}
|
||||
|
||||
var succ = await new Commands.Submodule(_repo.FullPath).Use(log).AddAsync(_url, relativePath, Recursive);
|
||||
log.Complete();
|
||||
var succ = await new Commands.Submodule(_repo.FullPath)
|
||||
.Use(log)
|
||||
.AddAsync(_url, relativePath, Recursive)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
await CallUIThreadAsync(() => _repo.SetWatcherEnabled(true));
|
||||
log.Complete();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return succ;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,12 +46,8 @@ namespace SourceGit.ViewModels
|
||||
await File.AppendAllLinesAsync(file, [_pattern]);
|
||||
}
|
||||
|
||||
await CallUIThreadAsync(() =>
|
||||
{
|
||||
_repo.MarkWorkingCopyDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
});
|
||||
|
||||
_repo.MarkWorkingCopyDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -116,10 +116,13 @@ namespace SourceGit.ViewModels
|
||||
|
||||
Use(log);
|
||||
|
||||
var succ = await new Commands.Worktree(_repo.FullPath).Use(log).AddAsync(_path, branchName, _createNewBranch, tracking);
|
||||
log.Complete();
|
||||
var succ = await new Commands.Worktree(_repo.FullPath)
|
||||
.Use(log)
|
||||
.AddAsync(_path, branchName, _createNewBranch, tracking)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
await CallUIThreadAsync(() => _repo.SetWatcherEnabled(true));
|
||||
log.Complete();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return succ;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,10 +47,15 @@ namespace SourceGit.ViewModels
|
||||
ProgressDescription = "Apply patch...";
|
||||
|
||||
var log = _repo.CreateLog("Apply Patch");
|
||||
var succ = await new Commands.Apply(_repo.FullPath, _patchFile, _ignoreWhiteSpace, SelectedWhiteSpaceMode.Arg, null).Use(log).ExecAsync();
|
||||
log.Complete();
|
||||
Use(log);
|
||||
|
||||
await CallUIThreadAsync(() => _repo.SetWatcherEnabled(true));
|
||||
var succ = await new Commands.Apply(_repo.FullPath, _patchFile, _ignoreWhiteSpace, SelectedWhiteSpaceMode.Arg, null)
|
||||
.Use(log)
|
||||
.ExecAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
log.Complete();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return succ;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,14 +30,25 @@ namespace SourceGit.ViewModels
|
||||
|
||||
public override async Task<bool> Sure()
|
||||
{
|
||||
_repo.SetWatcherEnabled(false);
|
||||
ProgressDescription = $"Applying stash: {Stash.Name}";
|
||||
|
||||
var log = _repo.CreateLog("Apply Stash");
|
||||
var succ = await new Commands.Stash(_repo.FullPath).Use(log).ApplyAsync(Stash.Name, RestoreIndex);
|
||||
Use(log);
|
||||
|
||||
var succ = await new Commands.Stash(_repo.FullPath)
|
||||
.Use(log)
|
||||
.ApplyAsync(Stash.Name, RestoreIndex)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (succ && DropAfterApply)
|
||||
await new Commands.Stash(_repo.FullPath).Use(log).DropAsync(Stash.Name);
|
||||
await new Commands.Stash(_repo.FullPath)
|
||||
.Use(log)
|
||||
.DropAsync(Stash.Name)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
log.Complete();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,16 +52,16 @@ namespace SourceGit.ViewModels
|
||||
var log = _repo.CreateLog("Archive");
|
||||
Use(log);
|
||||
|
||||
var succ = await new Commands.Archive(_repo.FullPath, _revision, _saveFile).Use(log).ExecAsync();
|
||||
var succ = await new Commands.Archive(_repo.FullPath, _revision, _saveFile)
|
||||
.Use(log)
|
||||
.ExecAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
log.Complete();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
|
||||
await CallUIThreadAsync(() =>
|
||||
{
|
||||
_repo.SetWatcherEnabled(true);
|
||||
if (succ)
|
||||
App.SendNotification(_repo.FullPath, $"Save archive to : {_saveFile}");
|
||||
});
|
||||
|
||||
if (succ)
|
||||
App.SendNotification(_repo.FullPath, $"Save archive to : {_saveFile}");
|
||||
return succ;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Avalonia.Collections;
|
||||
using Avalonia.Threading;
|
||||
|
||||
@@ -16,7 +15,10 @@ namespace SourceGit.ViewModels
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var collect = await new Commands.QueryAssumeUnchangedFiles(_repo.FullPath).ResultAsync();
|
||||
var collect = await new Commands.QueryAssumeUnchangedFiles(_repo.FullPath)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
await Dispatcher.UIThread.InvokeAsync(() => Files.AddRange(collect));
|
||||
});
|
||||
}
|
||||
@@ -26,7 +28,12 @@ namespace SourceGit.ViewModels
|
||||
if (!string.IsNullOrEmpty(file))
|
||||
{
|
||||
var log = _repo.CreateLog("Remove Assume Unchanged File");
|
||||
await new Commands.AssumeUnchanged(_repo.FullPath, file, false).Use(log).ExecAsync();
|
||||
|
||||
await new Commands.AssumeUnchanged(_repo.FullPath, file, false)
|
||||
.Use(log)
|
||||
.ExecAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
log.Complete();
|
||||
Files.Remove(file);
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Avalonia.Threading;
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace SourceGit.ViewModels
|
||||
@@ -65,7 +63,10 @@ namespace SourceGit.ViewModels
|
||||
if (_commitMessages.TryGetValue(sha, out var msg))
|
||||
return msg;
|
||||
|
||||
msg = new Commands.QueryCommitFullMessage(_repo, sha).Result();
|
||||
msg = new Commands.QueryCommitFullMessage(_repo, sha)
|
||||
.GetResultAsync()
|
||||
.Result;
|
||||
|
||||
_commitMessages[sha] = msg;
|
||||
return msg;
|
||||
}
|
||||
@@ -134,7 +135,9 @@ namespace SourceGit.ViewModels
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var result = await new Commands.QuerySingleCommit(_repo, commitSHA).ResultAsync();
|
||||
var result = await new Commands.QuerySingleCommit(_repo, commitSHA)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
await Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
@@ -149,7 +152,9 @@ namespace SourceGit.ViewModels
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var result = await new Commands.Blame(_repo, FilePath, commitSHA).ResultAsync();
|
||||
var result = await new Commands.Blame(_repo, FilePath, commitSHA)
|
||||
.ReadAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
await Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
|
||||
@@ -156,9 +156,9 @@ namespace SourceGit.ViewModels
|
||||
var copyPath = new MenuItem();
|
||||
copyPath.Header = App.Text("CopyPath");
|
||||
copyPath.Icon = App.CreateMenuIcon("Icons.Copy");
|
||||
copyPath.Click += (_, ev) =>
|
||||
copyPath.Click += async (_, ev) =>
|
||||
{
|
||||
App.CopyText(change.Path);
|
||||
await App.CopyTextAsync(change.Path);
|
||||
ev.Handled = true;
|
||||
};
|
||||
menu.Items.Add(copyPath);
|
||||
@@ -166,9 +166,9 @@ namespace SourceGit.ViewModels
|
||||
var copyFullPath = new MenuItem();
|
||||
copyFullPath.Header = App.Text("CopyFullPath");
|
||||
copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy");
|
||||
copyFullPath.Click += (_, e) =>
|
||||
copyFullPath.Click += async (_, e) =>
|
||||
{
|
||||
App.CopyText(Native.OS.GetAbsPath(_repo, change.Path));
|
||||
await App.CopyTextAsync(Native.OS.GetAbsPath(_repo, change.Path));
|
||||
e.Handled = true;
|
||||
};
|
||||
menu.Items.Add(copyFullPath);
|
||||
@@ -182,8 +182,14 @@ namespace SourceGit.ViewModels
|
||||
{
|
||||
if (_baseHead == null)
|
||||
{
|
||||
var baseHead = await new Commands.QuerySingleCommit(_repo, _based.Head).ResultAsync();
|
||||
var toHead = await new Commands.QuerySingleCommit(_repo, _to.Head).ResultAsync();
|
||||
var baseHead = await new Commands.QuerySingleCommit(_repo, _based.Head)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var toHead = await new Commands.QuerySingleCommit(_repo, _to.Head)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
await Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
BaseHead = baseHead;
|
||||
@@ -191,7 +197,9 @@ namespace SourceGit.ViewModels
|
||||
});
|
||||
}
|
||||
|
||||
_changes = await new Commands.CompareRevisions(_repo, _based.Head, _to.Head).ResultAsync();
|
||||
_changes = await new Commands.CompareRevisions(_repo, _based.Head, _to.Head)
|
||||
.ReadAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var visible = _changes;
|
||||
if (!string.IsNullOrWhiteSpace(_searchFilter))
|
||||
|
||||
@@ -42,66 +42,84 @@ namespace SourceGit.ViewModels
|
||||
Use(log);
|
||||
|
||||
var updateSubmodules = IsRecurseSubmoduleVisible && RecurseSubmodules;
|
||||
bool succ;
|
||||
var succ = false;
|
||||
var needPopStash = false;
|
||||
|
||||
if (!_repo.ConfirmCheckoutBranch())
|
||||
var confirmed = await _repo.ConfirmCheckoutBranchAsync().ConfigureAwait(false);
|
||||
if (!confirmed)
|
||||
{
|
||||
await CallUIThreadAsync(() => _repo.SetWatcherEnabled(true));
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (DiscardLocalChanges)
|
||||
{
|
||||
succ = await new Commands.Checkout(_repo.FullPath).Use(log).BranchAsync(Branch, true);
|
||||
succ = await new Commands.Checkout(_repo.FullPath)
|
||||
.Use(log)
|
||||
.BranchAsync(Branch, true)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
var changes = await new Commands.CountLocalChangesWithoutUntracked(_repo.FullPath).ResultAsync();
|
||||
var changes = await new Commands.CountLocalChangesWithoutUntracked(_repo.FullPath)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (changes > 0)
|
||||
{
|
||||
succ = await new Commands.Stash(_repo.FullPath).Use(log).PushAsync("CHECKOUT_AUTO_STASH");
|
||||
succ = await new Commands.Stash(_repo.FullPath)
|
||||
.Use(log)
|
||||
.PushAsync("CHECKOUT_AUTO_STASH")
|
||||
.ConfigureAwait(false);
|
||||
if (!succ)
|
||||
{
|
||||
log.Complete();
|
||||
await CallUIThreadAsync(() => _repo.SetWatcherEnabled(true));
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
needPopStash = true;
|
||||
}
|
||||
|
||||
succ = await new Commands.Checkout(_repo.FullPath).Use(log).BranchAsync(Branch, false);
|
||||
succ = await new Commands.Checkout(_repo.FullPath)
|
||||
.Use(log)
|
||||
.BranchAsync(Branch, false)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (succ)
|
||||
{
|
||||
if (updateSubmodules)
|
||||
{
|
||||
var submodules = await new Commands.QueryUpdatableSubmodules(_repo.FullPath).ResultAsync();
|
||||
var submodules = await new Commands.QueryUpdatableSubmodules(_repo.FullPath)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (submodules.Count > 0)
|
||||
await new Commands.Submodule(_repo.FullPath).Use(log).UpdateAsync(submodules, true, true);
|
||||
await new Commands.Submodule(_repo.FullPath)
|
||||
.Use(log)
|
||||
.UpdateAsync(submodules, true, true)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (needPopStash)
|
||||
await new Commands.Stash(_repo.FullPath).Use(log).PopAsync("stash@{0}");
|
||||
await new Commands.Stash(_repo.FullPath)
|
||||
.Use(log)
|
||||
.PopAsync("stash@{0}")
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
log.Complete();
|
||||
|
||||
await CallUIThreadAsync(() =>
|
||||
{
|
||||
ProgressDescription = "Waiting for branch updated...";
|
||||
var b = _repo.Branches.Find(x => x.IsLocal && x.Name == Branch);
|
||||
if (b != null && _repo.HistoriesFilterMode == Models.FilterMode.Included)
|
||||
_repo.SetBranchFilterMode(b, Models.FilterMode.Included, true, false);
|
||||
|
||||
var b = _repo.Branches.Find(x => x.IsLocal && x.Name == Branch);
|
||||
if (b != null && _repo.HistoriesFilterMode == Models.FilterMode.Included)
|
||||
_repo.SetBranchFilterMode(b, Models.FilterMode.Included, true, false);
|
||||
_repo.MarkBranchesDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
|
||||
_repo.MarkBranchesDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
});
|
||||
|
||||
Task.Delay(400).Wait();
|
||||
ProgressDescription = "Waiting for branch updated...";
|
||||
await Task.Delay(400);
|
||||
return succ;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,62 +50,81 @@ namespace SourceGit.ViewModels
|
||||
var succ = false;
|
||||
var needPopStash = false;
|
||||
|
||||
if (!_repo.ConfirmCheckoutBranch())
|
||||
var confirmed = await _repo.ConfirmCheckoutBranchAsync().ConfigureAwait(false);
|
||||
if (!confirmed)
|
||||
{
|
||||
await CallUIThreadAsync(() => _repo.SetWatcherEnabled(true));
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (DiscardLocalChanges)
|
||||
{
|
||||
succ = await new Commands.Checkout(_repo.FullPath).Use(log).BranchAsync(LocalBranch.Name, RemoteBranch.Head, true, true);
|
||||
succ = await new Commands.Checkout(_repo.FullPath)
|
||||
.Use(log)
|
||||
.BranchAsync(LocalBranch.Name, RemoteBranch.Head, true, true)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
var changes = await new Commands.CountLocalChangesWithoutUntracked(_repo.FullPath).ResultAsync();
|
||||
var changes = await new Commands.CountLocalChangesWithoutUntracked(_repo.FullPath)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (changes > 0)
|
||||
{
|
||||
succ = await new Commands.Stash(_repo.FullPath).Use(log).PushAsync("CHECKOUT_AND_FASTFORWARD_AUTO_STASH");
|
||||
succ = await new Commands.Stash(_repo.FullPath)
|
||||
.Use(log)
|
||||
.PushAsync("CHECKOUT_AND_FASTFORWARD_AUTO_STASH")
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (!succ)
|
||||
{
|
||||
log.Complete();
|
||||
await CallUIThreadAsync(() => _repo.SetWatcherEnabled(true));
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
needPopStash = true;
|
||||
}
|
||||
|
||||
succ = await new Commands.Checkout(_repo.FullPath).Use(log).BranchAsync(LocalBranch.Name, RemoteBranch.Head, false, true);
|
||||
succ = await new Commands.Checkout(_repo.FullPath)
|
||||
.Use(log)
|
||||
.BranchAsync(LocalBranch.Name, RemoteBranch.Head, false, true)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (succ)
|
||||
{
|
||||
if (updateSubmodules)
|
||||
{
|
||||
var submodules = await new Commands.QueryUpdatableSubmodules(_repo.FullPath).ResultAsync();
|
||||
var submodules = await new Commands.QueryUpdatableSubmodules(_repo.FullPath)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (submodules.Count > 0)
|
||||
await new Commands.Submodule(_repo.FullPath).Use(log).UpdateAsync(submodules, true, true);
|
||||
await new Commands.Submodule(_repo.FullPath)
|
||||
.Use(log)
|
||||
.UpdateAsync(submodules, true, true)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (needPopStash)
|
||||
await new Commands.Stash(_repo.FullPath).Use(log).PopAsync("stash@{0}");
|
||||
await new Commands.Stash(_repo.FullPath)
|
||||
.Use(log)
|
||||
.PopAsync("stash@{0}")
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
log.Complete();
|
||||
|
||||
await CallUIThreadAsync(() =>
|
||||
{
|
||||
ProgressDescription = "Waiting for branch updated...";
|
||||
if (_repo.HistoriesFilterMode == Models.FilterMode.Included)
|
||||
_repo.SetBranchFilterMode(LocalBranch, Models.FilterMode.Included, true, false);
|
||||
|
||||
if (_repo.HistoriesFilterMode == Models.FilterMode.Included)
|
||||
_repo.SetBranchFilterMode(LocalBranch, Models.FilterMode.Included, true, false);
|
||||
_repo.MarkBranchesDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
|
||||
_repo.MarkBranchesDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
});
|
||||
|
||||
Task.Delay(400).Wait();
|
||||
ProgressDescription = "Waiting for branch updated...";
|
||||
await Task.Delay(400);
|
||||
return succ;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,50 +45,73 @@ namespace SourceGit.ViewModels
|
||||
bool succ;
|
||||
var needPop = false;
|
||||
|
||||
if (!_repo.ConfirmCheckoutBranch())
|
||||
var confirmed = await _repo.ConfirmCheckoutBranchAsync().ConfigureAwait(false);
|
||||
if (!confirmed)
|
||||
{
|
||||
await CallUIThreadAsync(() => _repo.SetWatcherEnabled(true));
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (DiscardLocalChanges)
|
||||
{
|
||||
succ = await new Commands.Checkout(_repo.FullPath).Use(log).CommitAsync(Commit.SHA, true);
|
||||
succ = await new Commands.Checkout(_repo.FullPath)
|
||||
.Use(log)
|
||||
.CommitAsync(Commit.SHA, true)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
var changes = await new Commands.CountLocalChangesWithoutUntracked(_repo.FullPath).ResultAsync();
|
||||
var changes = await new Commands.CountLocalChangesWithoutUntracked(_repo.FullPath)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (changes > 0)
|
||||
{
|
||||
succ = await new Commands.Stash(_repo.FullPath).Use(log).PushAsync("CHECKOUT_AUTO_STASH");
|
||||
succ = await new Commands.Stash(_repo.FullPath)
|
||||
.Use(log)
|
||||
.PushAsync("CHECKOUT_AUTO_STASH")
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (!succ)
|
||||
{
|
||||
log.Complete();
|
||||
await CallUIThreadAsync(() => _repo.SetWatcherEnabled(true));
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
needPop = true;
|
||||
}
|
||||
|
||||
succ = await new Commands.Checkout(_repo.FullPath).Use(log).CommitAsync(Commit.SHA, false);
|
||||
succ = await new Commands.Checkout(_repo.FullPath)
|
||||
.Use(log)
|
||||
.CommitAsync(Commit.SHA, false)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (succ)
|
||||
{
|
||||
if (updateSubmodules)
|
||||
{
|
||||
var submodules = await new Commands.QueryUpdatableSubmodules(_repo.FullPath).ResultAsync();
|
||||
var submodules = await new Commands.QueryUpdatableSubmodules(_repo.FullPath)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (submodules.Count > 0)
|
||||
await new Commands.Submodule(_repo.FullPath).Use(log).UpdateAsync(submodules, true, true);
|
||||
await new Commands.Submodule(_repo.FullPath)
|
||||
.Use(log)
|
||||
.UpdateAsync(submodules, true, true)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (needPop)
|
||||
await new Commands.Stash(_repo.FullPath).Use(log).PopAsync("stash@{0}");
|
||||
await new Commands.Stash(_repo.FullPath)
|
||||
.Use(log)
|
||||
.PopAsync("stash@{0}")
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
log.Complete();
|
||||
await CallUIThreadAsync(() => _repo.SetWatcherEnabled(true));
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return succ;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,10 @@ namespace SourceGit.ViewModels
|
||||
Targets[0].SHA,
|
||||
!AutoCommit,
|
||||
AppendSourceToMessage,
|
||||
$"-m {MainlineForMergeCommit + 1}").Use(log).ExecAsync();
|
||||
$"-m {MainlineForMergeCommit + 1}")
|
||||
.Use(log)
|
||||
.ExecAsync()
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -88,11 +91,14 @@ namespace SourceGit.ViewModels
|
||||
string.Join(' ', Targets.ConvertAll(c => c.SHA)),
|
||||
!AutoCommit,
|
||||
AppendSourceToMessage,
|
||||
string.Empty).Use(log).ExecAsync();
|
||||
string.Empty)
|
||||
.Use(log)
|
||||
.ExecAsync()
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
log.Complete();
|
||||
await CallUIThreadAsync(() => _repo.SetWatcherEnabled(true));
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,13 @@ namespace SourceGit.ViewModels
|
||||
var log = _repo.CreateLog("Cleanup (GC & prune)");
|
||||
Use(log);
|
||||
|
||||
await new Commands.GC(_repo.FullPath).Use(log).ExecAsync();
|
||||
await new Commands.GC(_repo.FullPath)
|
||||
.Use(log)
|
||||
.ExecAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
log.Complete();
|
||||
await CallUIThreadAsync(() => _repo.SetWatcherEnabled(true));
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,13 @@ namespace SourceGit.ViewModels
|
||||
var log = _repo.CreateLog("Clear Stashes");
|
||||
Use(log);
|
||||
|
||||
await new Commands.Stash(_repo.FullPath).Use(log).ClearAsync();
|
||||
await new Commands.Stash(_repo.FullPath)
|
||||
.Use(log)
|
||||
.ClearAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
log.Complete();
|
||||
await CallUIThreadAsync(() => _repo.SetWatcherEnabled(true));
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Avalonia.Threading;
|
||||
|
||||
namespace SourceGit.ViewModels
|
||||
{
|
||||
public class Clone : Popup
|
||||
@@ -68,19 +66,16 @@ namespace SourceGit.ViewModels
|
||||
if (string.IsNullOrEmpty(ParentFolder))
|
||||
_parentFolder = Preferences.Instance.GitDefaultCloneDir;
|
||||
|
||||
Task.Run(async () =>
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
var text = await App.GetClipboardTextAsync();
|
||||
if (Models.Remote.IsValidURL(text))
|
||||
await Dispatcher.UIThread.InvokeAsync(() => Remote = text);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
});
|
||||
var text = App.GetClipboardTextAsync().Result;
|
||||
if (Models.Remote.IsValidURL(text))
|
||||
Remote = text;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
public static ValidationResult ValidateRemote(string remote, ValidationContext _)
|
||||
@@ -104,8 +99,12 @@ namespace SourceGit.ViewModels
|
||||
var log = new CommandLog("Clone");
|
||||
Use(log);
|
||||
|
||||
var cmd = new Commands.Clone(_pageId, _parentFolder, _remote, _local, _useSSH ? _sshKey : "", _extraArgs).Use(log);
|
||||
if (!await cmd.ExecAsync())
|
||||
var succ = await new Commands.Clone(_pageId, _parentFolder, _remote, _local, _useSSH ? _sshKey : "", _extraArgs)
|
||||
.Use(log)
|
||||
.ExecAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (succ)
|
||||
return false;
|
||||
|
||||
var path = _parentFolder;
|
||||
@@ -132,37 +131,41 @@ namespace SourceGit.ViewModels
|
||||
|
||||
if (_useSSH && !string.IsNullOrEmpty(_sshKey))
|
||||
{
|
||||
var config = new Commands.Config(path);
|
||||
await config.SetAsync("remote.origin.sshkey", _sshKey);
|
||||
await new Commands.Config(path)
|
||||
.Use(log)
|
||||
.SetAsync("remote.origin.sshkey", _sshKey)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (InitAndUpdateSubmodules)
|
||||
{
|
||||
var submodules = await new Commands.QueryUpdatableSubmodules(path).ResultAsync();
|
||||
var submodules = await new Commands.QueryUpdatableSubmodules(path)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (submodules.Count > 0)
|
||||
await new Commands.Submodule(path).Use(log).UpdateAsync(submodules, true, true);
|
||||
await new Commands.Submodule(path)
|
||||
.Use(log)
|
||||
.UpdateAsync(submodules, true, true)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
log.Complete();
|
||||
|
||||
await CallUIThreadAsync(() =>
|
||||
var node = Preferences.Instance.FindOrAddNodeByRepositoryPath(path, null, true);
|
||||
var launcher = App.GetLauncher();
|
||||
LauncherPage page = null;
|
||||
foreach (var one in launcher.Pages)
|
||||
{
|
||||
var node = Preferences.Instance.FindOrAddNodeByRepositoryPath(path, null, true);
|
||||
var launcher = App.GetLauncher();
|
||||
LauncherPage page = null;
|
||||
foreach (var one in launcher.Pages)
|
||||
if (one.Node.Id == _pageId)
|
||||
{
|
||||
if (one.Node.Id == _pageId)
|
||||
{
|
||||
page = one;
|
||||
break;
|
||||
}
|
||||
page = one;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Welcome.Instance.Refresh();
|
||||
launcher.OpenRepositoryInTab(node, page);
|
||||
});
|
||||
|
||||
Welcome.Instance.Refresh();
|
||||
launcher.OpenRepositoryInTab(node, page);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,36 +51,41 @@ namespace SourceGit.ViewModels
|
||||
|
||||
public void AppendLine(string line = null)
|
||||
{
|
||||
var newline = line ?? string.Empty;
|
||||
|
||||
Dispatcher.UIThread.Invoke(() =>
|
||||
if (!Dispatcher.UIThread.CheckAccess())
|
||||
{
|
||||
Dispatcher.UIThread.Invoke(() => AppendLine(line));
|
||||
}
|
||||
else
|
||||
{
|
||||
var newline = line ?? string.Empty;
|
||||
_builder.AppendLine(newline);
|
||||
_onNewLineReceived?.Invoke(newline);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void Complete()
|
||||
{
|
||||
IsComplete = true;
|
||||
|
||||
Dispatcher.UIThread.Invoke(() =>
|
||||
if (!Dispatcher.UIThread.CheckAccess())
|
||||
{
|
||||
_content = _builder.ToString();
|
||||
_builder.Clear();
|
||||
_builder = null;
|
||||
Dispatcher.UIThread.Invoke(Complete);
|
||||
return;
|
||||
}
|
||||
|
||||
EndTime = DateTime.Now;
|
||||
IsComplete = true;
|
||||
EndTime = DateTime.Now;
|
||||
|
||||
OnPropertyChanged(nameof(IsComplete));
|
||||
_content = _builder.ToString();
|
||||
_builder.Clear();
|
||||
_builder = null;
|
||||
|
||||
if (_onNewLineReceived != null)
|
||||
{
|
||||
var dumpHandlers = _onNewLineReceived.GetInvocationList();
|
||||
foreach (var d in dumpHandlers)
|
||||
_onNewLineReceived -= (Action<string>)d;
|
||||
}
|
||||
});
|
||||
OnPropertyChanged(nameof(IsComplete));
|
||||
|
||||
if (_onNewLineReceived != null)
|
||||
{
|
||||
var dumpHandlers = _onNewLineReceived.GetInvocationList();
|
||||
foreach (var d in dumpHandlers)
|
||||
_onNewLineReceived -= (Action<string>)d;
|
||||
}
|
||||
}
|
||||
|
||||
private string _content = string.Empty;
|
||||
|
||||
@@ -169,9 +169,11 @@ namespace SourceGit.ViewModels
|
||||
_repo?.NavigateToCommit(commitSHA);
|
||||
}
|
||||
|
||||
public List<Models.Decorator> GetRefsContainsThisCommit()
|
||||
public async Task<List<Models.Decorator>> GetRefsContainsThisCommitAsync()
|
||||
{
|
||||
return new Commands.QueryRefsContainsCommit(_repo.FullPath, _commit.SHA).Result();
|
||||
return await new Commands.QueryRefsContainsCommit(_repo.FullPath, _commit.SHA)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public void ClearSearchChangeFilter()
|
||||
@@ -189,93 +191,34 @@ namespace SourceGit.ViewModels
|
||||
RevisionFileSearchSuggestion = null;
|
||||
}
|
||||
|
||||
public Models.Commit GetParent(string sha)
|
||||
public async Task<Models.Commit> GetCommitAsync(string sha)
|
||||
{
|
||||
return new Commands.QuerySingleCommit(_repo.FullPath, sha).Result();
|
||||
return await new Commands.QuerySingleCommit(_repo.FullPath, sha)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public List<Models.Object> GetRevisionFilesUnderFolder(string parentFolder)
|
||||
public async Task<List<Models.Object>> GetRevisionFilesUnderFolderAsync(string parentFolder)
|
||||
{
|
||||
return new Commands.QueryRevisionObjects(_repo.FullPath, _commit.SHA, parentFolder).Result();
|
||||
return await new Commands.QueryRevisionObjects(_repo.FullPath, _commit.SHA, parentFolder)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public void ViewRevisionFile(Models.Object file)
|
||||
public async Task ViewRevisionFileAsync(Models.Object file)
|
||||
{
|
||||
if (file == null)
|
||||
{
|
||||
ViewRevisionFilePath = string.Empty;
|
||||
ViewRevisionFileContent = null;
|
||||
CanOpenRevisionFileWithDefaultEditor = false;
|
||||
return;
|
||||
}
|
||||
var obj = file ?? new Models.Object() { Path = string.Empty, Type = Models.ObjectType.None };
|
||||
ViewRevisionFilePath = obj.Path;
|
||||
|
||||
ViewRevisionFilePath = file.Path;
|
||||
|
||||
switch (file.Type)
|
||||
switch (obj.Type)
|
||||
{
|
||||
case Models.ObjectType.Blob:
|
||||
CanOpenRevisionFileWithDefaultEditor = true;
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var isBinary = await new Commands.IsBinary(_repo.FullPath, _commit.SHA, file.Path).ResultAsync();
|
||||
if (isBinary)
|
||||
{
|
||||
var imgDecoder = ImageSource.GetDecoder(file.Path);
|
||||
if (imgDecoder != Models.ImageDecoder.None)
|
||||
{
|
||||
var source = ImageSource.FromRevision(_repo.FullPath, _commit.SHA, file.Path, imgDecoder);
|
||||
var image = new Models.RevisionImageFile(file.Path, source.Bitmap, source.Size);
|
||||
await Dispatcher.UIThread.InvokeAsync(() => ViewRevisionFileContent = image);
|
||||
}
|
||||
else
|
||||
{
|
||||
var size = await new Commands.QueryFileSize(_repo.FullPath, file.Path, _commit.SHA).ResultAsync();
|
||||
var binary = new Models.RevisionBinaryFile() { Size = size };
|
||||
await Dispatcher.UIThread.InvokeAsync(() => ViewRevisionFileContent = binary);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var contentStream = await Commands.QueryFileContent.RunAsync(_repo.FullPath, _commit.SHA, file.Path);
|
||||
var content = await new StreamReader(contentStream).ReadToEndAsync();
|
||||
var lfs = Models.LFSObject.Parse(content);
|
||||
if (lfs != null)
|
||||
{
|
||||
var imgDecoder = ImageSource.GetDecoder(file.Path);
|
||||
if (imgDecoder != Models.ImageDecoder.None)
|
||||
{
|
||||
var combined = new RevisionLFSImage(_repo.FullPath, file.Path, lfs, imgDecoder);
|
||||
await Dispatcher.UIThread.InvokeAsync(() => ViewRevisionFileContent = combined);
|
||||
}
|
||||
else
|
||||
{
|
||||
var rlfs = new Models.RevisionLFSObject() { Object = lfs };
|
||||
await Dispatcher.UIThread.InvokeAsync(() => ViewRevisionFileContent = rlfs);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var txt = new Models.RevisionTextFile() { FileName = file.Path, Content = content };
|
||||
await Dispatcher.UIThread.InvokeAsync(() => ViewRevisionFileContent = txt);
|
||||
}
|
||||
});
|
||||
await SetViewingBlobAsync(obj);
|
||||
break;
|
||||
case Models.ObjectType.Commit:
|
||||
CanOpenRevisionFileWithDefaultEditor = false;
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var submoduleRoot = Path.Combine(_repo.FullPath, file.Path).Replace('\\', '/').Trim('/');
|
||||
var commit = await new Commands.QuerySingleCommit(submoduleRoot, file.SHA).ResultAsync();
|
||||
var message = commit != null ? await new Commands.QueryCommitFullMessage(submoduleRoot, file.SHA).ResultAsync() : null;
|
||||
var module = new Models.RevisionSubmodule()
|
||||
{
|
||||
Commit = commit ?? new Models.Commit() { SHA = _commit.SHA },
|
||||
FullMessage = new Models.CommitFullMessage { Message = message }
|
||||
};
|
||||
|
||||
await Dispatcher.UIThread.InvokeAsync(() => ViewRevisionFileContent = module);
|
||||
});
|
||||
await SetViewingCommitAsync(obj);
|
||||
break;
|
||||
default:
|
||||
CanOpenRevisionFileWithDefaultEditor = false;
|
||||
@@ -284,17 +227,18 @@ namespace SourceGit.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public async Task OpenRevisionFileWithDefaultEditor(string file)
|
||||
public async Task OpenRevisionFileWithDefaultEditorAsync(string file)
|
||||
{
|
||||
{
|
||||
var fullPath = Native.OS.GetAbsPath(_repo.FullPath, file);
|
||||
var fileName = Path.GetFileNameWithoutExtension(fullPath) ?? "";
|
||||
var fileExt = Path.GetExtension(fullPath) ?? "";
|
||||
var tmpFile = Path.Combine(Path.GetTempPath(), $"{fileName}~{_commit.SHA.Substring(0, 10)}{fileExt}");
|
||||
var fullPath = Native.OS.GetAbsPath(_repo.FullPath, file);
|
||||
var fileName = Path.GetFileNameWithoutExtension(fullPath) ?? "";
|
||||
var fileExt = Path.GetExtension(fullPath) ?? "";
|
||||
var tmpFile = Path.Combine(Path.GetTempPath(), $"{fileName}~{_commit.SHA.Substring(0, 10)}{fileExt}");
|
||||
|
||||
await Commands.SaveRevisionFile.RunAsync(_repo.FullPath, _commit.SHA, file, tmpFile);
|
||||
Native.OS.OpenWithDefaultEditor(tmpFile);
|
||||
}
|
||||
await Commands.SaveRevisionFile
|
||||
.RunAsync(_repo.FullPath, _commit.SHA, file, tmpFile)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
Native.OS.OpenWithDefaultEditor(tmpFile);
|
||||
}
|
||||
|
||||
public ContextMenu CreateChangeContextMenuByFolder(ChangeTreeNode node, List<Models.Change> changes)
|
||||
@@ -338,7 +282,10 @@ namespace SourceGit.ViewModels
|
||||
if (storageFile != null)
|
||||
{
|
||||
var saveTo = storageFile.Path.LocalPath;
|
||||
var succ = await Commands.SaveChangesAsPatch.ProcessRevisionCompareChangesAsync(_repo.FullPath, changes, baseRevision, _commit.SHA, saveTo);
|
||||
var succ = await Commands.SaveChangesAsPatch
|
||||
.ProcessRevisionCompareChangesAsync(_repo.FullPath, changes, baseRevision, _commit.SHA, saveTo)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (succ)
|
||||
App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess"));
|
||||
}
|
||||
@@ -349,18 +296,18 @@ namespace SourceGit.ViewModels
|
||||
var copyPath = new MenuItem();
|
||||
copyPath.Header = App.Text("CopyPath");
|
||||
copyPath.Icon = App.CreateMenuIcon("Icons.Copy");
|
||||
copyPath.Click += (_, ev) =>
|
||||
copyPath.Click += async (_, ev) =>
|
||||
{
|
||||
App.CopyText(node.FullPath);
|
||||
await App.CopyTextAsync(node.FullPath);
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
var copyFullPath = new MenuItem();
|
||||
copyFullPath.Header = App.Text("CopyFullPath");
|
||||
copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy");
|
||||
copyFullPath.Click += (_, e) =>
|
||||
copyFullPath.Click += async (_, e) =>
|
||||
{
|
||||
App.CopyText(fullPath);
|
||||
await App.CopyTextAsync(fullPath);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
@@ -464,7 +411,7 @@ namespace SourceGit.ViewModels
|
||||
resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout");
|
||||
resetToThisRevision.Click += async (_, ev) =>
|
||||
{
|
||||
await ResetToThisRevision(change.Path);
|
||||
await ResetToThisRevisionAsync(change.Path);
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
@@ -474,7 +421,7 @@ namespace SourceGit.ViewModels
|
||||
resetToFirstParent.IsEnabled = _commit.Parents.Count > 0;
|
||||
resetToFirstParent.Click += async (_, ev) =>
|
||||
{
|
||||
await ResetToParentRevision(change);
|
||||
await ResetToParentRevisionAsync(change);
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
@@ -488,18 +435,18 @@ namespace SourceGit.ViewModels
|
||||
var copyPath = new MenuItem();
|
||||
copyPath.Header = App.Text("CopyPath");
|
||||
copyPath.Icon = App.CreateMenuIcon("Icons.Copy");
|
||||
copyPath.Click += (_, ev) =>
|
||||
copyPath.Click += async (_, ev) =>
|
||||
{
|
||||
App.CopyText(change.Path);
|
||||
await App.CopyTextAsync(change.Path);
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
var copyFullPath = new MenuItem();
|
||||
copyFullPath.Header = App.Text("CopyFullPath");
|
||||
copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy");
|
||||
copyFullPath.Click += (_, e) =>
|
||||
copyFullPath.Click += async (_, e) =>
|
||||
{
|
||||
App.CopyText(fullPath);
|
||||
await App.CopyTextAsync(fullPath);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
@@ -533,18 +480,18 @@ namespace SourceGit.ViewModels
|
||||
var copyPath = new MenuItem();
|
||||
copyPath.Header = App.Text("CopyPath");
|
||||
copyPath.Icon = App.CreateMenuIcon("Icons.Copy");
|
||||
copyPath.Click += (_, ev) =>
|
||||
copyPath.Click += async (_, ev) =>
|
||||
{
|
||||
App.CopyText(path);
|
||||
await App.CopyTextAsync(path);
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
var copyFullPath = new MenuItem();
|
||||
copyFullPath.Header = App.Text("CopyFullPath");
|
||||
copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy");
|
||||
copyFullPath.Click += (_, e) =>
|
||||
copyFullPath.Click += async (_, e) =>
|
||||
{
|
||||
App.CopyText(fullPath);
|
||||
await App.CopyTextAsync(fullPath);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
@@ -581,7 +528,7 @@ namespace SourceGit.ViewModels
|
||||
openWith.IsEnabled = file.Type == Models.ObjectType.Blob;
|
||||
openWith.Click += async (_, ev) =>
|
||||
{
|
||||
await OpenRevisionFileWithDefaultEditor(file.Path);
|
||||
await OpenRevisionFileWithDefaultEditorAsync(file.Path);
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
@@ -604,7 +551,10 @@ namespace SourceGit.ViewModels
|
||||
var folder = selected[0];
|
||||
var folderPath = folder is { Path: { IsAbsoluteUri: true } path } ? path.LocalPath : folder.Path.ToString();
|
||||
var saveTo = Path.Combine(folderPath, Path.GetFileName(file.Path)!);
|
||||
await Commands.SaveRevisionFile.RunAsync(_repo.FullPath, _commit.SHA, file.Path, saveTo);
|
||||
|
||||
await Commands.SaveRevisionFile
|
||||
.RunAsync(_repo.FullPath, _commit.SHA, file.Path, saveTo)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -650,7 +600,7 @@ namespace SourceGit.ViewModels
|
||||
resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout");
|
||||
resetToThisRevision.Click += async (_, ev) =>
|
||||
{
|
||||
await ResetToThisRevision(file.Path);
|
||||
await ResetToThisRevisionAsync(file.Path);
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
@@ -661,7 +611,7 @@ namespace SourceGit.ViewModels
|
||||
resetToFirstParent.IsEnabled = _commit.Parents.Count > 0;
|
||||
resetToFirstParent.Click += async (_, ev) =>
|
||||
{
|
||||
await ResetToParentRevision(change);
|
||||
await ResetToParentRevisionAsync(change);
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
@@ -675,18 +625,18 @@ namespace SourceGit.ViewModels
|
||||
var copyPath = new MenuItem();
|
||||
copyPath.Header = App.Text("CopyPath");
|
||||
copyPath.Icon = App.CreateMenuIcon("Icons.Copy");
|
||||
copyPath.Click += (_, ev) =>
|
||||
copyPath.Click += async (_, ev) =>
|
||||
{
|
||||
App.CopyText(file.Path);
|
||||
await App.CopyTextAsync(file.Path);
|
||||
ev.Handled = true;
|
||||
};
|
||||
|
||||
var copyFullPath = new MenuItem();
|
||||
copyFullPath.Header = App.Text("CopyFullPath");
|
||||
copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy");
|
||||
copyFullPath.Click += (_, e) =>
|
||||
copyFullPath.Click += async (_, e) =>
|
||||
{
|
||||
App.CopyText(fullPath);
|
||||
await App.CopyTextAsync(fullPath);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
@@ -720,18 +670,30 @@ namespace SourceGit.ViewModels
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var message = await new Commands.QueryCommitFullMessage(_repo.FullPath, _commit.SHA).ResultAsync();
|
||||
var message = await new Commands.QueryCommitFullMessage(_repo.FullPath, _commit.SHA)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
var inlines = await ParseInlinesInMessageAsync(message);
|
||||
|
||||
if (!token.IsCancellationRequested)
|
||||
await Dispatcher.UIThread.InvokeAsync(() => FullMessage = new Models.CommitFullMessage { Message = message, Inlines = inlines });
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
FullMessage = new Models.CommitFullMessage
|
||||
{
|
||||
Message = message,
|
||||
Inlines = inlines
|
||||
};
|
||||
});
|
||||
}, token);
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var signInfo = await new Commands.QueryCommitSignInfo(_repo.FullPath, _commit.SHA, !_repo.HasAllowedSignersFile).ResultAsync();
|
||||
var signInfo = await new Commands.QueryCommitSignInfo(_repo.FullPath, _commit.SHA, !_repo.HasAllowedSignersFile)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (!token.IsCancellationRequested)
|
||||
await Dispatcher.UIThread.InvokeAsync(() => SignInfo = signInfo);
|
||||
Dispatcher.UIThread.Post(() => SignInfo = signInfo);
|
||||
}, token);
|
||||
|
||||
if (Preferences.Instance.ShowChildren)
|
||||
@@ -740,7 +702,7 @@ namespace SourceGit.ViewModels
|
||||
{
|
||||
var max = Preferences.Instance.MaxHistoryCommits;
|
||||
var cmd = new Commands.QueryCommitChildren(_repo.FullPath, _commit.SHA, max) { CancellationToken = token };
|
||||
var children = await cmd.ResultAsync();
|
||||
var children = await cmd.GetResultAsync().ConfigureAwait(false);
|
||||
if (!token.IsCancellationRequested)
|
||||
Dispatcher.UIThread.Post(() => Children = children);
|
||||
}, token);
|
||||
@@ -750,7 +712,7 @@ namespace SourceGit.ViewModels
|
||||
{
|
||||
var parent = _commit.Parents.Count == 0 ? Models.Commit.EmptyTreeSHA1 : _commit.Parents[0];
|
||||
var cmd = new Commands.CompareRevisions(_repo.FullPath, parent, _commit.SHA) { CancellationToken = token };
|
||||
var changes = await cmd.ResultAsync();
|
||||
var changes = await cmd.ReadAsync().ConfigureAwait(false);
|
||||
var visible = changes;
|
||||
if (!string.IsNullOrWhiteSpace(_searchChangeFilter))
|
||||
{
|
||||
@@ -815,7 +777,7 @@ namespace SourceGit.ViewModels
|
||||
continue;
|
||||
|
||||
var sha = match.Groups[1].Value;
|
||||
var isCommitSHA = await new Commands.IsCommitSHA(_repo.FullPath, sha).ResultAsync();
|
||||
var isCommitSHA = await new Commands.IsCommitSHA(_repo.FullPath, sha).GetResultAsync().ConfigureAwait(false);
|
||||
if (isCommitSHA)
|
||||
inlines.Add(new Models.InlineElement(Models.InlineElementType.CommitSHA, start, len, sha));
|
||||
}
|
||||
@@ -867,7 +829,10 @@ namespace SourceGit.ViewModels
|
||||
lfsLock.Click += async (_, e) =>
|
||||
{
|
||||
var log = _repo.CreateLog("Lock LFS file");
|
||||
var succ = await new Commands.LFS(_repo.FullPath).LockAsync(_repo.Remotes[0].Name, path, log);
|
||||
var succ = await new Commands.LFS(_repo.FullPath)
|
||||
.LockAsync(_repo.Remotes[0].Name, path, log)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (succ)
|
||||
App.SendNotification(_repo.FullPath, $"Lock file \"{path}\" successfully!");
|
||||
|
||||
@@ -885,7 +850,10 @@ namespace SourceGit.ViewModels
|
||||
lockRemote.Click += async (_, e) =>
|
||||
{
|
||||
var log = _repo.CreateLog("Lock LFS file");
|
||||
var succ = await new Commands.LFS(_repo.FullPath).LockAsync(remoteName, path, log);
|
||||
var succ = await new Commands.LFS(_repo.FullPath)
|
||||
.LockAsync(remoteName, path, log)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (succ)
|
||||
App.SendNotification(_repo.FullPath, $"Lock file \"{path}\" successfully!");
|
||||
|
||||
@@ -905,7 +873,10 @@ namespace SourceGit.ViewModels
|
||||
lfsUnlock.Click += async (_, e) =>
|
||||
{
|
||||
var log = _repo.CreateLog("Unlock LFS file");
|
||||
var succ = await new Commands.LFS(_repo.FullPath).UnlockAsync(_repo.Remotes[0].Name, path, false, log);
|
||||
var succ = await new Commands.LFS(_repo.FullPath)
|
||||
.UnlockAsync(_repo.Remotes[0].Name, path, false, log)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (succ)
|
||||
App.SendNotification(_repo.FullPath, $"Unlock file \"{path}\" successfully!");
|
||||
|
||||
@@ -923,7 +894,10 @@ namespace SourceGit.ViewModels
|
||||
unlockRemote.Click += async (_, e) =>
|
||||
{
|
||||
var log = _repo.CreateLog("Unlock LFS file");
|
||||
var succ = await new Commands.LFS(_repo.FullPath).UnlockAsync(remoteName, path, false, log);
|
||||
var succ = await new Commands.LFS(_repo.FullPath)
|
||||
.UnlockAsync(remoteName, path, false, log)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (succ)
|
||||
App.SendNotification(_repo.FullPath, $"Unlock file \"{path}\" successfully!");
|
||||
|
||||
@@ -953,8 +927,11 @@ namespace SourceGit.ViewModels
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var files = await new Commands.QueryRevisionFileNames(_repo.FullPath, sha).ResultAsync();
|
||||
await Dispatcher.UIThread.InvokeAsync(() =>
|
||||
var files = await new Commands.QueryRevisionFileNames(_repo.FullPath, sha)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
if (sha == Commit.SHA && _requestingRevisionFiles)
|
||||
{
|
||||
@@ -995,7 +972,83 @@ namespace SourceGit.ViewModels
|
||||
RevisionFileSearchSuggestion = suggestion;
|
||||
}
|
||||
|
||||
private async Task ResetToThisRevision(string path)
|
||||
private async Task SetViewingBlobAsync(Models.Object file)
|
||||
{
|
||||
var isBinary = await new Commands.IsBinary(_repo.FullPath, _commit.SHA, file.Path)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (isBinary)
|
||||
{
|
||||
var imgDecoder = ImageSource.GetDecoder(file.Path);
|
||||
if (imgDecoder != Models.ImageDecoder.None)
|
||||
{
|
||||
var source = await ImageSource.FromRevisionAsync(_repo.FullPath, _commit.SHA, file.Path, imgDecoder).ConfigureAwait(false);
|
||||
ViewRevisionFileContent = new Models.RevisionImageFile(file.Path, source.Bitmap, source.Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
var size = await new Commands.QueryFileSize(_repo.FullPath, file.Path, _commit.SHA)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
ViewRevisionFileContent = new Models.RevisionBinaryFile() { Size = size };
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var contentStream = await Commands.QueryFileContent
|
||||
.RunAsync(_repo.FullPath, _commit.SHA, file.Path)
|
||||
.ConfigureAwait(false);
|
||||
var content = await new StreamReader(contentStream)
|
||||
.ReadToEndAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var lfs = Models.LFSObject.Parse(content);
|
||||
if (lfs != null)
|
||||
{
|
||||
var imgDecoder = ImageSource.GetDecoder(file.Path);
|
||||
if (imgDecoder != Models.ImageDecoder.None)
|
||||
ViewRevisionFileContent = new RevisionLFSImage(_repo.FullPath, file.Path, lfs, imgDecoder);
|
||||
else
|
||||
ViewRevisionFileContent = new Models.RevisionLFSObject() { Object = lfs };
|
||||
}
|
||||
else
|
||||
{
|
||||
ViewRevisionFileContent = new Models.RevisionTextFile() { FileName = file.Path, Content = content };
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SetViewingCommitAsync(Models.Object file)
|
||||
{
|
||||
var submoduleRoot = Path.Combine(_repo.FullPath, file.Path).Replace('\\', '/').Trim('/');
|
||||
var commit = await new Commands.QuerySingleCommit(submoduleRoot, file.SHA)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (commit == null)
|
||||
{
|
||||
ViewRevisionFileContent = new Models.RevisionSubmodule()
|
||||
{
|
||||
Commit = new Models.Commit() { SHA = file.SHA },
|
||||
FullMessage = new Models.CommitFullMessage()
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
var message = await new Commands.QueryCommitFullMessage(submoduleRoot, file.SHA)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
ViewRevisionFileContent = new Models.RevisionSubmodule()
|
||||
{
|
||||
Commit = commit,
|
||||
FullMessage = new Models.CommitFullMessage { Message = message }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ResetToThisRevisionAsync(string path)
|
||||
{
|
||||
var log = _repo.CreateLog($"Reset File to '{_commit.SHA}'");
|
||||
|
||||
@@ -1003,7 +1056,7 @@ namespace SourceGit.ViewModels
|
||||
log.Complete();
|
||||
}
|
||||
|
||||
private async Task ResetToParentRevision(Models.Change change)
|
||||
private async Task ResetToParentRevisionAsync(Models.Change change)
|
||||
{
|
||||
var log = _repo.CreateLog($"Reset File to '{_commit.SHA}~1'");
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace SourceGit.ViewModels
|
||||
{
|
||||
public class Confirm
|
||||
{
|
||||
public string Message
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public Confirm(string message, Action onSure, Action onCancel = null)
|
||||
{
|
||||
Message = message;
|
||||
_onSure = onSure;
|
||||
_onCancel = onCancel;
|
||||
}
|
||||
|
||||
public void Done(bool isSure)
|
||||
{
|
||||
if (isSure)
|
||||
_onSure?.Invoke();
|
||||
else
|
||||
_onCancel?.Invoke();
|
||||
}
|
||||
|
||||
private Action _onSure;
|
||||
private Action _onCancel;
|
||||
}
|
||||
}
|
||||
@@ -17,9 +17,13 @@ namespace SourceGit.ViewModels
|
||||
|
||||
public ConflictSourceBranch(Repository repo, Models.Branch branch)
|
||||
{
|
||||
var revision = new Commands.QuerySingleCommit(repo.FullPath, branch.Head).GetResultAsync().Result;
|
||||
if (revision == null)
|
||||
revision = new Models.Commit() { SHA = branch.Head };
|
||||
|
||||
Name = branch.Name;
|
||||
Head = branch.Head;
|
||||
Revision = new Commands.QuerySingleCommit(repo.FullPath, branch.Head).Result() ?? new Models.Commit() { SHA = branch.Head };
|
||||
Revision = revision;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,10 +69,10 @@ namespace SourceGit.ViewModels
|
||||
_change = change;
|
||||
|
||||
var isSubmodule = repo.Submodules.Find(x => x.Path.Equals(change.Path, StringComparison.Ordinal)) != null;
|
||||
if (!isSubmodule && (_change.ConflictReason == Models.ConflictReason.BothAdded || _change.ConflictReason == Models.ConflictReason.BothModified))
|
||||
if (!isSubmodule && (_change.ConflictReason is Models.ConflictReason.BothAdded or Models.ConflictReason.BothModified))
|
||||
{
|
||||
CanUseExternalMergeTool = true;
|
||||
IsResolved = new Commands.IsConflictResolved(repo.FullPath, change).Result();
|
||||
IsResolved = new Commands.IsConflictResolved(repo.FullPath, change).GetResultAsync().Result;
|
||||
}
|
||||
|
||||
var context = wc.InProgressContext;
|
||||
|
||||
@@ -125,10 +125,14 @@ namespace SourceGit.ViewModels
|
||||
var updateSubmodules = IsRecurseSubmoduleVisible && RecurseSubmodules;
|
||||
bool succ;
|
||||
|
||||
if (CheckoutAfterCreated && !_repo.ConfirmCheckoutBranch())
|
||||
if (CheckoutAfterCreated)
|
||||
{
|
||||
await CallUIThreadAsync(() => _repo.SetWatcherEnabled(true));
|
||||
return true;
|
||||
var confirmed = await _repo.ConfirmCheckoutBranchAsync();
|
||||
if (!confirmed)
|
||||
{
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (CheckoutAfterCreated && !_repo.IsBare)
|
||||
@@ -136,71 +140,94 @@ namespace SourceGit.ViewModels
|
||||
var needPopStash = false;
|
||||
if (DiscardLocalChanges)
|
||||
{
|
||||
succ = await new Commands.Checkout(_repo.FullPath).Use(log).BranchAsync(fixedName, _baseOnRevision, true, _allowOverwrite);
|
||||
succ = await new Commands.Checkout(_repo.FullPath)
|
||||
.Use(log)
|
||||
.BranchAsync(fixedName, _baseOnRevision, true, _allowOverwrite)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
var changes = await new Commands.CountLocalChangesWithoutUntracked(_repo.FullPath).ResultAsync();
|
||||
var changes = await new Commands.CountLocalChangesWithoutUntracked(_repo.FullPath)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (changes > 0)
|
||||
{
|
||||
succ = await new Commands.Stash(_repo.FullPath).Use(log).PushAsync("CREATE_BRANCH_AUTO_STASH");
|
||||
succ = await new Commands.Stash(_repo.FullPath)
|
||||
.Use(log)
|
||||
.PushAsync("CREATE_BRANCH_AUTO_STASH")
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (!succ)
|
||||
{
|
||||
log.Complete();
|
||||
await CallUIThreadAsync(() => _repo.SetWatcherEnabled(true));
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
needPopStash = true;
|
||||
}
|
||||
|
||||
succ = await new Commands.Checkout(_repo.FullPath).Use(log).BranchAsync(fixedName, _baseOnRevision, false, _allowOverwrite);
|
||||
succ = await new Commands.Checkout(_repo.FullPath)
|
||||
.Use(log)
|
||||
.BranchAsync(fixedName, _baseOnRevision, false, _allowOverwrite)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (succ)
|
||||
{
|
||||
if (updateSubmodules)
|
||||
{
|
||||
var submodules = await new Commands.QueryUpdatableSubmodules(_repo.FullPath).ResultAsync();
|
||||
var submodules = await new Commands.QueryUpdatableSubmodules(_repo.FullPath)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (submodules.Count > 0)
|
||||
await new Commands.Submodule(_repo.FullPath).Use(log).UpdateAsync(submodules, true, true);
|
||||
await new Commands.Submodule(_repo.FullPath)
|
||||
.Use(log)
|
||||
.UpdateAsync(submodules, true, true)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (needPopStash)
|
||||
await new Commands.Stash(_repo.FullPath).Use(log).PopAsync("stash@{0}");
|
||||
await new Commands.Stash(_repo.FullPath)
|
||||
.Use(log)
|
||||
.PopAsync("stash@{0}")
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
succ = await Commands.Branch.CreateAsync(_repo.FullPath, fixedName, _baseOnRevision, _allowOverwrite, log);
|
||||
succ = await Commands.Branch
|
||||
.CreateAsync(_repo.FullPath, fixedName, _baseOnRevision, _allowOverwrite, log)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
log.Complete();
|
||||
|
||||
await CallUIThreadAsync(() =>
|
||||
if (succ && CheckoutAfterCreated)
|
||||
{
|
||||
if (succ && CheckoutAfterCreated)
|
||||
{
|
||||
var fake = new Models.Branch() { IsLocal = true, FullName = $"refs/heads/{fixedName}" };
|
||||
if (BasedOn is Models.Branch { IsLocal: false } based)
|
||||
fake.Upstream = based.FullName;
|
||||
var fake = new Models.Branch() { IsLocal = true, FullName = $"refs/heads/{fixedName}" };
|
||||
if (BasedOn is Models.Branch { IsLocal: false } based)
|
||||
fake.Upstream = based.FullName;
|
||||
|
||||
var folderEndIdx = fake.FullName.LastIndexOf('/');
|
||||
if (folderEndIdx > 10)
|
||||
_repo.Settings.ExpandedBranchNodesInSideBar.Add(fake.FullName.Substring(0, folderEndIdx));
|
||||
var folderEndIdx = fake.FullName.LastIndexOf('/');
|
||||
if (folderEndIdx > 10)
|
||||
_repo.Settings.ExpandedBranchNodesInSideBar.Add(fake.FullName.Substring(0, folderEndIdx));
|
||||
|
||||
if (_repo.HistoriesFilterMode == Models.FilterMode.Included)
|
||||
_repo.SetBranchFilterMode(fake, Models.FilterMode.Included, true, false);
|
||||
if (_repo.HistoriesFilterMode == Models.FilterMode.Included)
|
||||
_repo.SetBranchFilterMode(fake, Models.FilterMode.Included, true, false);
|
||||
|
||||
ProgressDescription = "Waiting for branch updated...";
|
||||
}
|
||||
}
|
||||
|
||||
_repo.MarkBranchesDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
});
|
||||
_repo.MarkBranchesDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
|
||||
if (CheckoutAfterCreated)
|
||||
Task.Delay(400).Wait();
|
||||
{
|
||||
ProgressDescription = "Waiting for branch updated...";
|
||||
await Task.Delay(400);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace SourceGit.ViewModels
|
||||
}, _parent, true);
|
||||
|
||||
Welcome.Instance.Refresh();
|
||||
return null;
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
private readonly RepositoryNode _parent = null;
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace SourceGit.ViewModels
|
||||
_basedOn = branch.Head;
|
||||
|
||||
BasedOn = branch;
|
||||
SignTag = new Commands.Config(repo.FullPath).Get("tag.gpgsign").Equals("true", StringComparison.OrdinalIgnoreCase);
|
||||
SignTag = new Commands.Config(repo.FullPath).GetAsync("tag.gpgsign").Result.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).Get("tag.gpgsign").Equals("true", StringComparison.OrdinalIgnoreCase);
|
||||
SignTag = new Commands.Config(repo.FullPath).GetAsync("tag.gpgsign").Result.Equals("true", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public static ValidationResult ValidateTagName(string name, ValidationContext ctx)
|
||||
@@ -85,18 +85,21 @@ namespace SourceGit.ViewModels
|
||||
|
||||
bool succ;
|
||||
if (_annotated)
|
||||
succ = await Commands.Tag.AddAsync(_repo.FullPath, _tagName, _basedOn, Message, SignTag, log);
|
||||
succ = await Commands.Tag.AddAsync(_repo.FullPath, _tagName, _basedOn, Message, SignTag, log).ConfigureAwait(false);
|
||||
else
|
||||
succ = await Commands.Tag.AddAsync(_repo.FullPath, _tagName, _basedOn, log);
|
||||
succ = await Commands.Tag.AddAsync(_repo.FullPath, _tagName, _basedOn, log).ConfigureAwait(false);
|
||||
|
||||
if (succ && remotes != null)
|
||||
{
|
||||
foreach (var remote in remotes)
|
||||
await new Commands.Push(_repo.FullPath, remote.Name, $"refs/tags/{_tagName}", false).Use(log).ExecAsync();
|
||||
await new Commands.Push(_repo.FullPath, remote.Name, $"refs/tags/{_tagName}", false)
|
||||
.Use(log)
|
||||
.ExecAsync()
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
log.Complete();
|
||||
await CallUIThreadAsync(() => _repo.SetWatcherEnabled(true));
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return succ;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,9 +31,13 @@ namespace SourceGit.ViewModels
|
||||
var log = _repo.CreateLog("De-initialize Submodule");
|
||||
Use(log);
|
||||
|
||||
var succ = await new Commands.Submodule(_repo.FullPath).Use(log).DeinitAsync(Submodule, false);
|
||||
var succ = await new Commands.Submodule(_repo.FullPath)
|
||||
.Use(log)
|
||||
.DeinitAsync(Submodule, false)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
log.Complete();
|
||||
await CallUIThreadAsync(() => _repo.SetWatcherEnabled(true));
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return succ;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,23 +49,26 @@ namespace SourceGit.ViewModels
|
||||
|
||||
if (Target.IsLocal)
|
||||
{
|
||||
await Commands.Branch.DeleteLocalAsync(_repo.FullPath, Target.Name, log);
|
||||
await Commands.Branch
|
||||
.DeleteLocalAsync(_repo.FullPath, Target.Name, log)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (_alsoDeleteTrackingRemote && TrackingRemoteBranch != null)
|
||||
await Commands.Branch.DeleteRemoteAsync(_repo.FullPath, TrackingRemoteBranch.Remote, TrackingRemoteBranch.Name, log);
|
||||
await Commands.Branch
|
||||
.DeleteRemoteAsync(_repo.FullPath, TrackingRemoteBranch.Remote, TrackingRemoteBranch.Name, log)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
await Commands.Branch.DeleteRemoteAsync(_repo.FullPath, Target.Remote, Target.Name, log);
|
||||
await Commands.Branch
|
||||
.DeleteRemoteAsync(_repo.FullPath, Target.Remote, Target.Name, log)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
log.Complete();
|
||||
|
||||
await CallUIThreadAsync(() =>
|
||||
{
|
||||
_repo.MarkBranchesDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
});
|
||||
_repo.MarkBranchesDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,22 +28,21 @@ namespace SourceGit.ViewModels
|
||||
if (_isLocal)
|
||||
{
|
||||
foreach (var target in Targets)
|
||||
await Commands.Branch.DeleteLocalAsync(_repo.FullPath, target.Name, log);
|
||||
await Commands.Branch
|
||||
.DeleteLocalAsync(_repo.FullPath, target.Name, log)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var target in Targets)
|
||||
await Commands.Branch.DeleteRemoteAsync(_repo.FullPath, target.Remote, target.Name, log);
|
||||
await Commands.Branch
|
||||
.DeleteRemoteAsync(_repo.FullPath, target.Remote, target.Name, log)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
log.Complete();
|
||||
|
||||
await CallUIThreadAsync(() =>
|
||||
{
|
||||
_repo.MarkBranchesDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
});
|
||||
|
||||
_repo.MarkBranchesDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,14 +24,14 @@ namespace SourceGit.ViewModels
|
||||
var log = _repo.CreateLog("Delete Remote");
|
||||
Use(log);
|
||||
|
||||
var succ = await new Commands.Remote(_repo.FullPath).Use(log).DeleteAsync(Remote.Name);
|
||||
log.Complete();
|
||||
var succ = await new Commands.Remote(_repo.FullPath)
|
||||
.Use(log)
|
||||
.DeleteAsync(Remote.Name)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
await CallUIThreadAsync(() =>
|
||||
{
|
||||
_repo.MarkBranchesDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
});
|
||||
log.Complete();
|
||||
_repo.MarkBranchesDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return succ;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace SourceGit.ViewModels
|
||||
{
|
||||
Preferences.Instance.RemoveNode(Node, true);
|
||||
Welcome.Instance.Refresh();
|
||||
return null;
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,9 +24,13 @@ namespace SourceGit.ViewModels
|
||||
var log = _repo.CreateLog("Delete Submodule");
|
||||
Use(log);
|
||||
|
||||
var succ = await new Commands.Submodule(_repo.FullPath).Use(log).DeleteAsync(Submodule);
|
||||
var succ = await new Commands.Submodule(_repo.FullPath)
|
||||
.Use(log)
|
||||
.DeleteAsync(Submodule)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
log.Complete();
|
||||
await CallUIThreadAsync(() => _repo.SetWatcherEnabled(true));
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return succ;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,20 +31,22 @@ namespace SourceGit.ViewModels
|
||||
var log = _repo.CreateLog("Delete Tag");
|
||||
Use(log);
|
||||
|
||||
var succ = await Commands.Tag.DeleteAsync(_repo.FullPath, Target.Name, log);
|
||||
var succ = await Commands.Tag
|
||||
.DeleteAsync(_repo.FullPath, Target.Name, log)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (succ)
|
||||
{
|
||||
foreach (var r in remotes)
|
||||
await new Commands.Push(_repo.FullPath, r.Name, $"refs/tags/{Target.Name}", true).Use(log).ExecAsync();
|
||||
await new Commands.Push(_repo.FullPath, r.Name, $"refs/tags/{Target.Name}", true)
|
||||
.Use(log)
|
||||
.ExecAsync()
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
log.Complete();
|
||||
|
||||
await CallUIThreadAsync(() =>
|
||||
{
|
||||
_repo.MarkTagsDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
});
|
||||
_repo.MarkTagsDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return succ;
|
||||
}
|
||||
|
||||
|
||||
@@ -113,7 +113,11 @@ namespace SourceGit.ViewModels
|
||||
{
|
||||
var numLines = Preferences.Instance.UseFullTextDiff ? 999999999 : _unifiedLines;
|
||||
var ignoreWhitespace = Preferences.Instance.IgnoreWhitespaceChangesInDiff;
|
||||
var latest = await new Commands.Diff(_repo, _option, numLines, ignoreWhitespace).ResultAsync();
|
||||
|
||||
var latest = await new Commands.Diff(_repo, _option, numLines, ignoreWhitespace)
|
||||
.ReadAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var info = new Info(_option, numLines, ignoreWhitespace, latest);
|
||||
if (_info != null && info.IsSame(_info))
|
||||
return;
|
||||
@@ -141,9 +145,9 @@ namespace SourceGit.ViewModels
|
||||
|
||||
var sha = line.Content.Substring(18);
|
||||
if (line.Type == Models.TextDiffLineType.Added)
|
||||
submoduleDiff.New = QuerySubmoduleRevision(submoduleRoot, sha);
|
||||
submoduleDiff.New = await QuerySubmoduleRevisionAsync(submoduleRoot, sha).ConfigureAwait(false);
|
||||
else if (line.Type == Models.TextDiffLineType.Deleted)
|
||||
submoduleDiff.Old = QuerySubmoduleRevision(submoduleRoot, sha);
|
||||
submoduleDiff.Old = await QuerySubmoduleRevisionAsync(submoduleRoot, sha).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (isSubmodule)
|
||||
@@ -167,8 +171,8 @@ namespace SourceGit.ViewModels
|
||||
|
||||
if (_option.Revisions.Count == 2)
|
||||
{
|
||||
var oldImage = ImageSource.FromRevision(_repo, _option.Revisions[0], oldPath, imgDecoder);
|
||||
var newImage = ImageSource.FromRevision(_repo, _option.Revisions[1], _option.Path, imgDecoder);
|
||||
var oldImage = await ImageSource.FromRevisionAsync(_repo, _option.Revisions[0], oldPath, imgDecoder).ConfigureAwait(false);
|
||||
var newImage = await ImageSource.FromRevisionAsync(_repo, _option.Revisions[1], _option.Path, imgDecoder).ConfigureAwait(false);
|
||||
imgDiff.Old = oldImage.Bitmap;
|
||||
imgDiff.OldFileSize = oldImage.Size;
|
||||
imgDiff.New = newImage.Bitmap;
|
||||
@@ -178,7 +182,7 @@ namespace SourceGit.ViewModels
|
||||
{
|
||||
if (!oldPath.Equals("/dev/null", StringComparison.Ordinal))
|
||||
{
|
||||
var oldImage = ImageSource.FromRevision(_repo, "HEAD", oldPath, imgDecoder);
|
||||
var oldImage = await ImageSource.FromRevisionAsync(_repo, "HEAD", oldPath, imgDecoder).ConfigureAwait(false);
|
||||
imgDiff.Old = oldImage.Bitmap;
|
||||
imgDiff.OldFileSize = oldImage.Size;
|
||||
}
|
||||
@@ -186,7 +190,7 @@ namespace SourceGit.ViewModels
|
||||
var fullPath = Path.Combine(_repo, _option.Path);
|
||||
if (File.Exists(fullPath))
|
||||
{
|
||||
var newImage = ImageSource.FromFile(fullPath, imgDecoder);
|
||||
var newImage = await ImageSource.FromFileAsync(fullPath, imgDecoder).ConfigureAwait(false);
|
||||
imgDiff.New = newImage.Bitmap;
|
||||
imgDiff.NewFileSize = newImage.Size;
|
||||
}
|
||||
@@ -199,13 +203,13 @@ namespace SourceGit.ViewModels
|
||||
var binaryDiff = new Models.BinaryDiff();
|
||||
if (_option.Revisions.Count == 2)
|
||||
{
|
||||
binaryDiff.OldSize = await new Commands.QueryFileSize(_repo, oldPath, _option.Revisions[0]).ResultAsync();
|
||||
binaryDiff.NewSize = await new Commands.QueryFileSize(_repo, _option.Path, _option.Revisions[1]).ResultAsync();
|
||||
binaryDiff.OldSize = await new Commands.QueryFileSize(_repo, oldPath, _option.Revisions[0]).GetResultAsync().ConfigureAwait(false);
|
||||
binaryDiff.NewSize = await new Commands.QueryFileSize(_repo, _option.Path, _option.Revisions[1]).GetResultAsync().ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
var fullPath = Path.Combine(_repo, _option.Path);
|
||||
binaryDiff.OldSize = await new Commands.QueryFileSize(_repo, oldPath, "HEAD").ResultAsync();
|
||||
binaryDiff.OldSize = await new Commands.QueryFileSize(_repo, oldPath, "HEAD").GetResultAsync().ConfigureAwait(false);
|
||||
binaryDiff.NewSize = File.Exists(fullPath) ? new FileInfo(fullPath).Length : 0;
|
||||
}
|
||||
rs = binaryDiff;
|
||||
@@ -236,13 +240,13 @@ namespace SourceGit.ViewModels
|
||||
});
|
||||
}
|
||||
|
||||
private Models.RevisionSubmodule QuerySubmoduleRevision(string repo, string sha)
|
||||
private async Task<Models.RevisionSubmodule> QuerySubmoduleRevisionAsync(string repo, string sha)
|
||||
{
|
||||
var commit = new Commands.QuerySingleCommit(repo, sha).Result();
|
||||
var commit = await new Commands.QuerySingleCommit(repo, sha).GetResultAsync().ConfigureAwait(false);
|
||||
if (commit == null)
|
||||
return new Models.RevisionSubmodule() { Commit = new Models.Commit() { SHA = sha } };
|
||||
|
||||
var body = new Commands.QueryCommitFullMessage(repo, sha).Result();
|
||||
var body = await new Commands.QueryCommitFullMessage(repo, sha).GetResultAsync().ConfigureAwait(false);
|
||||
return new Models.RevisionSubmodule()
|
||||
{
|
||||
Commit = commit,
|
||||
|
||||
@@ -53,8 +53,11 @@ namespace SourceGit.ViewModels
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var commits = await new Commands.QueryCommits(_repo.FullPath, $"--date-order -n 10000 {revision ?? string.Empty} -- \"{dir}\"", false).ResultAsync();
|
||||
await Dispatcher.UIThread.InvokeAsync(() =>
|
||||
var commits = await new Commands.QueryCommits(_repo.FullPath, $"--date-order -n 10000 {revision ?? string.Empty} -- \"{dir}\"", false)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
Commits = commits;
|
||||
IsLoading = false;
|
||||
@@ -76,7 +79,7 @@ namespace SourceGit.ViewModels
|
||||
if (_cachedCommitFullMessage.TryGetValue(sha, out var msg))
|
||||
return msg;
|
||||
|
||||
msg = new Commands.QueryCommitFullMessage(_repo.FullPath, sha).Result();
|
||||
msg = new Commands.QueryCommitFullMessage(_repo.FullPath, sha).GetResultAsync().Result;
|
||||
_cachedCommitFullMessage[sha] = msg;
|
||||
return msg;
|
||||
}
|
||||
|
||||
@@ -65,18 +65,13 @@ namespace SourceGit.ViewModels
|
||||
Use(log);
|
||||
|
||||
if (Mode is DiscardAllMode all)
|
||||
await Commands.Discard.AllAsync(_repo.FullPath, all.IncludeIgnored, log);
|
||||
await Commands.Discard.AllAsync(_repo.FullPath, all.IncludeIgnored, log).ConfigureAwait(false);
|
||||
else
|
||||
await Commands.Discard.ChangesAsync(_repo.FullPath, _changes, log);
|
||||
await Commands.Discard.ChangesAsync(_repo.FullPath, _changes, log).ConfigureAwait(false);
|
||||
|
||||
log.Complete();
|
||||
|
||||
await CallUIThreadAsync(() =>
|
||||
{
|
||||
_repo.MarkWorkingCopyDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
});
|
||||
|
||||
_repo.MarkWorkingCopyDirtyManually();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,11 @@ namespace SourceGit.ViewModels
|
||||
var log = _repo.CreateLog("Drop Stash");
|
||||
Use(log);
|
||||
|
||||
await new Commands.Stash(_repo.FullPath).Use(log).DropAsync(Stash.Name);
|
||||
await new Commands.Stash(_repo.FullPath)
|
||||
.Use(log)
|
||||
.DropAsync(Stash.Name)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
log.Complete();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace SourceGit.ViewModels
|
||||
|
||||
if (_useSSH)
|
||||
{
|
||||
SSHKey = new Commands.Config(repo.FullPath).Get($"remote.{remote.Name}.sshkey");
|
||||
SSHKey = new Commands.Config(repo.FullPath).GetAsync($"remote.{remote.Name}.sshkey").Result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,25 +107,36 @@ namespace SourceGit.ViewModels
|
||||
|
||||
if (_remote.Name != _name)
|
||||
{
|
||||
var succ = await new Commands.Remote(_repo.FullPath).RenameAsync(_remote.Name, _name);
|
||||
var succ = await new Commands.Remote(_repo.FullPath)
|
||||
.RenameAsync(_remote.Name, _name)
|
||||
.ConfigureAwait(false);
|
||||
if (succ)
|
||||
_remote.Name = _name;
|
||||
}
|
||||
|
||||
if (_remote.URL != _url)
|
||||
{
|
||||
var succ = await new Commands.Remote(_repo.FullPath).SetURLAsync(_name, _url, false);
|
||||
var succ = await new Commands.Remote(_repo.FullPath)
|
||||
.SetURLAsync(_name, _url, false)
|
||||
.ConfigureAwait(false);
|
||||
if (succ)
|
||||
_remote.URL = _url;
|
||||
}
|
||||
|
||||
var pushURL = await new Commands.Remote(_repo.FullPath).GetURLAsync(_name, true);
|
||||
var pushURL = await new Commands.Remote(_repo.FullPath)
|
||||
.GetURLAsync(_name, true)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (pushURL != _url)
|
||||
await new Commands.Remote(_repo.FullPath).SetURLAsync(_name, _url, true);
|
||||
await new Commands.Remote(_repo.FullPath)
|
||||
.SetURLAsync(_name, _url, true)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
await new Commands.Config(_repo.FullPath).SetAsync($"remote.{_name}.sshkey", _useSSH ? SSHKey : null);
|
||||
await new Commands.Config(_repo.FullPath)
|
||||
.SetAsync($"remote.{_name}.sshkey", _useSSH ? SSHKey : null)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
await CallUIThreadAsync(() => _repo.SetWatcherEnabled(true));
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace SourceGit.ViewModels
|
||||
Welcome.Instance.Refresh();
|
||||
}
|
||||
|
||||
return null;
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
private RepositoryNode _node = null;
|
||||
|
||||
@@ -169,12 +169,12 @@ namespace SourceGit.ViewModels
|
||||
log.AppendLine($"$ {CustomAction.Executable} {cmdline}\n");
|
||||
|
||||
if (CustomAction.WaitForExit)
|
||||
RunAndWait(cmdline, log);
|
||||
await RunAsync(cmdline, log);
|
||||
else
|
||||
Run(cmdline);
|
||||
_ = Task.Run(() => Run(cmdline));
|
||||
|
||||
log.Complete();
|
||||
await CallUIThreadAsync(() => _repo.SetWatcherEnabled(true));
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -237,7 +237,7 @@ namespace SourceGit.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
private void RunAndWait(string args, Models.ICommandLog log)
|
||||
private async Task RunAsync(string args, Models.ICommandLog log)
|
||||
{
|
||||
var start = new ProcessStartInfo();
|
||||
start.FileName = CustomAction.Executable;
|
||||
@@ -273,7 +273,7 @@ namespace SourceGit.ViewModels
|
||||
proc.Start();
|
||||
proc.BeginOutputReadLine();
|
||||
proc.BeginErrorReadLine();
|
||||
proc.WaitForExit();
|
||||
await proc.WaitForExitAsync().ConfigureAwait(false);
|
||||
|
||||
var exitCode = proc.ExitCode;
|
||||
if (exitCode != 0)
|
||||
|
||||
@@ -66,29 +66,32 @@ namespace SourceGit.ViewModels
|
||||
if (FetchAllRemotes)
|
||||
{
|
||||
foreach (var remote in _repo.Remotes)
|
||||
await new Commands.Fetch(_repo.FullPath, remote.Name, notags, force).Use(log).ExecAsync();
|
||||
await new Commands.Fetch(_repo.FullPath, remote.Name, notags, force)
|
||||
.Use(log)
|
||||
.ExecAsync()
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
await new Commands.Fetch(_repo.FullPath, SelectedRemote.Name, notags, force).Use(log).ExecAsync();
|
||||
await new Commands.Fetch(_repo.FullPath, SelectedRemote.Name, notags, force)
|
||||
.Use(log)
|
||||
.ExecAsync()
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
log.Complete();
|
||||
|
||||
var upstream = _repo.CurrentBranch?.Upstream;
|
||||
var upstreamHead = string.Empty;
|
||||
if (!string.IsNullOrEmpty(upstream))
|
||||
upstreamHead = await new Commands.QueryRevisionByRefName(_repo.FullPath, upstream.Substring(13)).ResultAsync();
|
||||
|
||||
await CallUIThreadAsync(() =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(upstreamHead))
|
||||
_repo.NavigateToCommit(upstreamHead, true);
|
||||
|
||||
_repo.MarkFetched();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
});
|
||||
var upstreamHead = await new Commands.QueryRevisionByRefName(_repo.FullPath, upstream.Substring(13))
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
_repo.NavigateToCommit(upstreamHead, true);
|
||||
}
|
||||
|
||||
_repo.MarkFetched();
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,16 +29,19 @@ namespace SourceGit.ViewModels
|
||||
var log = _repo.CreateLog($"Fetch Into '{Local.FriendlyName}'");
|
||||
Use(log);
|
||||
|
||||
await new Commands.Fetch(_repo.FullPath, Local, Upstream).Use(log).ExecAsync();
|
||||
await new Commands.Fetch(_repo.FullPath, Local, Upstream)
|
||||
.Use(log)
|
||||
.ExecAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
log.Complete();
|
||||
|
||||
var changedLocalBranchHead = await new Commands.QueryRevisionByRefName(_repo.FullPath, Local.Name).ResultAsync();
|
||||
await CallUIThreadAsync(() =>
|
||||
{
|
||||
_repo.NavigateToCommit(changedLocalBranchHead, true);
|
||||
_repo.SetWatcherEnabled(true);
|
||||
});
|
||||
var newHead = await new Commands.QueryRevisionByRefName(_repo.FullPath, Local.Name)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
_repo.NavigateToCommit(newHead, true);
|
||||
_repo.SetWatcherEnabled(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,12 +45,14 @@ namespace SourceGit.ViewModels
|
||||
RefreshViewContent();
|
||||
}
|
||||
|
||||
public async Task<bool> ResetToSelectedRevision()
|
||||
public async Task<bool> ResetToSelectedRevisionAsync()
|
||||
{
|
||||
return await new Commands.Checkout(_repo.FullPath).FileWithRevisionAsync(_file, $"{_revision.SHA}");
|
||||
return await new Commands.Checkout(_repo.FullPath)
|
||||
.FileWithRevisionAsync(_file, $"{_revision.SHA}")
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task OpenWithDefaultEditor()
|
||||
public async Task OpenWithDefaultEditorAsync()
|
||||
{
|
||||
if (_viewContent is not FileHistoriesRevisionFile { CanOpenWithDefaultEditor: true })
|
||||
return;
|
||||
@@ -60,7 +62,10 @@ namespace SourceGit.ViewModels
|
||||
var fileExt = Path.GetExtension(fullPath) ?? "";
|
||||
var tmpFile = Path.Combine(Path.GetTempPath(), $"{fileName}~{_revision.SHA.Substring(0, 10)}{fileExt}");
|
||||
|
||||
await Commands.SaveRevisionFile.RunAsync(_repo.FullPath, _revision.SHA, _file, tmpFile);
|
||||
await Commands.SaveRevisionFile
|
||||
.RunAsync(_repo.FullPath, _revision.SHA, _file, tmpFile)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
Native.OS.OpenWithDefaultEditor(tmpFile);
|
||||
}
|
||||
|
||||
@@ -74,7 +79,7 @@ namespace SourceGit.ViewModels
|
||||
|
||||
private void SetViewContentAsRevisionFile()
|
||||
{
|
||||
var objs = new Commands.QueryRevisionObjects(_repo.FullPath, _revision.SHA, _file).Result();
|
||||
var objs = new Commands.QueryRevisionObjects(_repo.FullPath, _revision.SHA, _file).GetResultAsync().Result;
|
||||
if (objs.Count == 0)
|
||||
{
|
||||
ViewContent = new FileHistoriesRevisionFile(_file);
|
||||
@@ -87,27 +92,27 @@ namespace SourceGit.ViewModels
|
||||
case Models.ObjectType.Blob:
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var isBinary = await new Commands.IsBinary(_repo.FullPath, _revision.SHA, _file).ResultAsync();
|
||||
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 = ImageSource.FromRevision(_repo.FullPath, _revision.SHA, _file, imgDecoder);
|
||||
var source = await ImageSource.FromRevisionAsync(_repo.FullPath, _revision.SHA, _file, imgDecoder).ConfigureAwait(false);
|
||||
var image = new Models.RevisionImageFile(_file, source.Bitmap, source.Size);
|
||||
await Dispatcher.UIThread.InvokeAsync(() => ViewContent = new FileHistoriesRevisionFile(_file, image, true));
|
||||
Dispatcher.UIThread.Post(() => ViewContent = new FileHistoriesRevisionFile(_file, image, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
var size = await new Commands.QueryFileSize(_repo.FullPath, _file, _revision.SHA).ResultAsync();
|
||||
var size = await new Commands.QueryFileSize(_repo.FullPath, _file, _revision.SHA).GetResultAsync().ConfigureAwait(false);
|
||||
var binaryFile = new Models.RevisionBinaryFile() { Size = size };
|
||||
await Dispatcher.UIThread.InvokeAsync(() => ViewContent = new FileHistoriesRevisionFile(_file, binaryFile, true));
|
||||
Dispatcher.UIThread.Post(() => ViewContent = new FileHistoriesRevisionFile(_file, binaryFile, true));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var contentStream = await Commands.QueryFileContent.RunAsync(_repo.FullPath, _revision.SHA, _file);
|
||||
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)
|
||||
@@ -116,18 +121,18 @@ namespace SourceGit.ViewModels
|
||||
if (imgDecoder != Models.ImageDecoder.None)
|
||||
{
|
||||
var combined = new RevisionLFSImage(_repo.FullPath, _file, lfs, imgDecoder);
|
||||
await Dispatcher.UIThread.InvokeAsync(() => ViewContent = new FileHistoriesRevisionFile(_file, combined, true));
|
||||
Dispatcher.UIThread.Post(() => ViewContent = new FileHistoriesRevisionFile(_file, combined, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
var rlfs = new Models.RevisionLFSObject() { Object = lfs };
|
||||
await Dispatcher.UIThread.InvokeAsync(() => ViewContent = new FileHistoriesRevisionFile(_file, rlfs, true));
|
||||
Dispatcher.UIThread.Post(() => ViewContent = new FileHistoriesRevisionFile(_file, rlfs, true));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var txt = new Models.RevisionTextFile() { FileName = obj.Path, Content = content };
|
||||
await Dispatcher.UIThread.InvokeAsync(() => ViewContent = new FileHistoriesRevisionFile(_file, txt, true));
|
||||
Dispatcher.UIThread.Post(() => ViewContent = new FileHistoriesRevisionFile(_file, txt, true));
|
||||
}
|
||||
});
|
||||
break;
|
||||
@@ -135,15 +140,15 @@ namespace SourceGit.ViewModels
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var submoduleRoot = Path.Combine(_repo.FullPath, _file);
|
||||
var commit = await new Commands.QuerySingleCommit(submoduleRoot, obj.SHA).ResultAsync();
|
||||
var message = commit != null ? await new Commands.QueryCommitFullMessage(submoduleRoot, obj.SHA).ResultAsync() : null;
|
||||
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 }
|
||||
};
|
||||
|
||||
await Dispatcher.UIThread.InvokeAsync(() => ViewContent = new FileHistoriesRevisionFile(_file, module));
|
||||
Dispatcher.UIThread.Post(() => ViewContent = new FileHistoriesRevisionFile(_file, module));
|
||||
});
|
||||
break;
|
||||
default:
|
||||
@@ -202,25 +207,25 @@ namespace SourceGit.ViewModels
|
||||
|
||||
public async Task<bool> SaveAsPatch(string saveTo)
|
||||
{
|
||||
{
|
||||
await Commands.SaveChangesAsPatch.ProcessRevisionCompareChangesAsync(_repo.FullPath, _changes, _startPoint.SHA, _endPoint.SHA, saveTo);
|
||||
return true;
|
||||
}
|
||||
return await Commands.SaveChangesAsPatch
|
||||
.ProcessRevisionCompareChangesAsync(_repo.FullPath, _changes, _startPoint.SHA, _endPoint.SHA, saveTo)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private void RefreshViewContent()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
_changes = await new Commands.CompareRevisions(_repo.FullPath, _startPoint.SHA, _endPoint.SHA, _file).ResultAsync();
|
||||
_changes = await new Commands.CompareRevisions(_repo.FullPath, _startPoint.SHA, _endPoint.SHA, _file).ReadAsync().ConfigureAwait(false);
|
||||
if (_changes.Count == 0)
|
||||
{
|
||||
await Dispatcher.UIThread.InvokeAsync(() => ViewContent = null);
|
||||
return;
|
||||
Dispatcher.UIThread.Post(() => ViewContent = null);
|
||||
}
|
||||
else
|
||||
{
|
||||
var option = new Models.DiffOption(_startPoint.SHA, _endPoint.SHA, _changes[0]);
|
||||
Dispatcher.UIThread.Post(() => ViewContent = new DiffContext(_repo.FullPath, option, _viewContent));
|
||||
}
|
||||
|
||||
var option = new Models.DiffOption(_startPoint.SHA, _endPoint.SHA, _changes[0]);
|
||||
await Dispatcher.UIThread.InvokeAsync(() => ViewContent = new DiffContext(_repo.FullPath, option, _viewContent));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -274,9 +279,11 @@ namespace SourceGit.ViewModels
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var based = commit ?? string.Empty;
|
||||
var commits = await new Commands.QueryCommits(_repo.FullPath, $"--date-order -n 10000 {based} -- \"{file}\"", false).ResultAsync();
|
||||
await Dispatcher.UIThread.InvokeAsync(() =>
|
||||
var commits = await new Commands.QueryCommits(_repo.FullPath, $"--date-order -n 10000 {commit ?? string.Empty} -- \"{file}\"", false)
|
||||
.GetResultAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
IsLoading = false;
|
||||
Commits = commits;
|
||||
@@ -310,7 +317,7 @@ namespace SourceGit.ViewModels
|
||||
if (_fullCommitMessages.TryGetValue(sha, out var msg))
|
||||
return msg;
|
||||
|
||||
msg = new Commands.QueryCommitFullMessage(_repo.FullPath, sha).Result();
|
||||
msg = new Commands.QueryCommitFullMessage(_repo.FullPath, sha).GetResultAsync().Result;
|
||||
_fullCommitMessages[sha] = msg;
|
||||
return msg;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user