diff --git a/src/Commands/LFS.cs b/src/Commands/LFS.cs index d5fb9dcf..e621ed7d 100644 --- a/src/Commands/LFS.cs +++ b/src/Commands/LFS.cs @@ -36,9 +36,9 @@ namespace SourceGit.Commands return content.Contains("git lfs pre-push"); } - public bool Install() + public bool Install(Models.ICommandLog log) { - return new SubCmd(_repo, "lfs install --local", null).Exec(); + return new SubCmd(_repo, "lfs install --local", log).Exec(); } public bool Track(string pattern, bool isFilenameMode, Models.ICommandLog log) @@ -93,21 +93,21 @@ namespace SourceGit.Commands return locks; } - public bool Lock(string remote, string file) + public bool Lock(string remote, string file, Models.ICommandLog log) { - return new SubCmd(_repo, $"lfs lock --remote={remote} \"{file}\"", null).Exec(); + return new SubCmd(_repo, $"lfs lock --remote={remote} \"{file}\"", log).Exec(); } - public bool Unlock(string remote, string file, bool force) + public bool Unlock(string remote, string file, bool force, Models.ICommandLog log) { var opt = force ? "-f" : ""; - return new SubCmd(_repo, $"lfs unlock --remote={remote} {opt} \"{file}\"", null).Exec(); + return new SubCmd(_repo, $"lfs unlock --remote={remote} {opt} \"{file}\"", log).Exec(); } - public bool Unlock(string remote, long id, bool force) + public bool Unlock(string remote, long id, bool force, Models.ICommandLog log) { var opt = force ? "-f" : ""; - return new SubCmd(_repo, $"lfs unlock --remote={remote} {opt} --id={id}", null).Exec(); + return new SubCmd(_repo, $"lfs unlock --remote={remote} {opt} --id={id}", log).Exec(); } private readonly string _repo; diff --git a/src/ViewModels/AssumeUnchangedManager.cs b/src/ViewModels/AssumeUnchangedManager.cs index 953cb476..bbfa220a 100644 --- a/src/ViewModels/AssumeUnchangedManager.cs +++ b/src/ViewModels/AssumeUnchangedManager.cs @@ -9,14 +9,14 @@ namespace SourceGit.ViewModels { public AvaloniaList Files { get; private set; } - public AssumeUnchangedManager(string repo) + public AssumeUnchangedManager(Repository repo) { _repo = repo; Files = new AvaloniaList(); Task.Run(() => { - var collect = new Commands.QueryAssumeUnchangedFiles(_repo).Result(); + var collect = new Commands.QueryAssumeUnchangedFiles(_repo.FullPath).Result(); Dispatcher.UIThread.Invoke(() => Files.AddRange(collect)); }); } @@ -25,11 +25,13 @@ namespace SourceGit.ViewModels { if (!string.IsNullOrEmpty(file)) { - new Commands.AssumeUnchanged(_repo, file, false).Exec(); + var log = _repo.CreateLog("Remove Assue Unchanged File"); + new Commands.AssumeUnchanged(_repo.FullPath, file, false).Use(log).Exec(); + log.Complete(); Files.Remove(file); } } - private readonly string _repo; + private readonly Repository _repo; } } diff --git a/src/ViewModels/CommitDetail.cs b/src/ViewModels/CommitDetail.cs index d04e674b..81c09472 100644 --- a/src/ViewModels/CommitDetail.cs +++ b/src/ViewModels/CommitDetail.cs @@ -391,7 +391,9 @@ namespace SourceGit.ViewModels resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout"); resetToThisRevision.Click += (_, ev) => { - new Commands.Checkout(_repo.FullPath).FileWithRevision(change.Path, $"{_commit.SHA}"); + var log = _repo.CreateLog($"Reset File to '{_commit.SHA}'"); + new Commands.Checkout(_repo.FullPath).Use(log).FileWithRevision(change.Path, $"{_commit.SHA}"); + log.Complete(); ev.Handled = true; }; @@ -401,10 +403,12 @@ namespace SourceGit.ViewModels resetToFirstParent.IsEnabled = _commit.Parents.Count > 0; resetToFirstParent.Click += (_, ev) => { + var log = _repo.CreateLog($"Reset File to '{_commit.SHA}~1'"); if (change.Index == Models.ChangeState.Renamed) - new Commands.Checkout(_repo.FullPath).FileWithRevision(change.OriginalPath, $"{_commit.SHA}~1"); + new Commands.Checkout(_repo.FullPath).Use(log).FileWithRevision(change.OriginalPath, $"{_commit.SHA}~1"); - new Commands.Checkout(_repo.FullPath).FileWithRevision(change.Path, $"{_commit.SHA}~1"); + new Commands.Checkout(_repo.FullPath).Use(log).FileWithRevision(change.Path, $"{_commit.SHA}~1"); + log.Complete(); ev.Handled = true; }; @@ -530,7 +534,9 @@ namespace SourceGit.ViewModels resetToThisRevision.IsEnabled = File.Exists(fullPath); resetToThisRevision.Click += (_, ev) => { - new Commands.Checkout(_repo.FullPath).FileWithRevision(file.Path, $"{_commit.SHA}"); + var log = _repo.CreateLog($"Reset File to '{_commit.SHA}'"); + new Commands.Checkout(_repo.FullPath).Use(log).FileWithRevision(file.Path, $"{_commit.SHA}"); + log.Complete(); ev.Handled = true; }; @@ -542,7 +548,9 @@ namespace SourceGit.ViewModels resetToFirstParent.IsEnabled = _commit.Parents.Count > 0 && fileIndex != Models.ChangeState.Renamed; resetToFirstParent.Click += (_, ev) => { - new Commands.Checkout(_repo.FullPath).FileWithRevision(file.Path, $"{_commit.SHA}~1"); + var log = _repo.CreateLog($"Reset File to '{_commit.SHA}~1'"); + new Commands.Checkout(_repo.FullPath).Use(log).FileWithRevision(file.Path, $"{_commit.SHA}~1"); + log.Complete(); ev.Handled = true; }; @@ -737,10 +745,12 @@ namespace SourceGit.ViewModels { lfsLock.Click += async (_, e) => { - var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Lock(_repo.Remotes[0].Name, path)); + var log = _repo.CreateLog("Lock LFS file"); + var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Lock(_repo.Remotes[0].Name, path, log)); if (succ) App.SendNotification(_repo.FullPath, $"Lock file \"{path}\" successfully!"); + log.Complete(); e.Handled = true; }; } @@ -753,10 +763,12 @@ namespace SourceGit.ViewModels lockRemote.Header = remoteName; lockRemote.Click += async (_, e) => { - var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Lock(remoteName, path)); + var log = _repo.CreateLog("Lock LFS file"); + var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Lock(remoteName, path, log)); if (succ) App.SendNotification(_repo.FullPath, $"Lock file \"{path}\" successfully!"); + log.Complete(); e.Handled = true; }; lfsLock.Items.Add(lockRemote); @@ -772,10 +784,12 @@ namespace SourceGit.ViewModels { lfsUnlock.Click += async (_, e) => { - var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Unlock(_repo.Remotes[0].Name, path, false)); + var log = _repo.CreateLog("Unlock LFS file"); + var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Unlock(_repo.Remotes[0].Name, path, false, log)); if (succ) App.SendNotification(_repo.FullPath, $"Unlock file \"{path}\" successfully!"); + log.Complete(); e.Handled = true; }; } @@ -788,10 +802,12 @@ namespace SourceGit.ViewModels unlockRemote.Header = remoteName; unlockRemote.Click += async (_, e) => { - var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Unlock(remoteName, path, false)); + var log = _repo.CreateLog("Unlock LFS file"); + var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Unlock(remoteName, path, false, log)); if (succ) App.SendNotification(_repo.FullPath, $"Unlock file \"{path}\" successfully!"); + log.Complete(); e.Handled = true; }; lfsUnlock.Items.Add(unlockRemote); diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs index ee5e5891..ca73fa0b 100644 --- a/src/ViewModels/Histories.cs +++ b/src/ViewModels/Histories.cs @@ -297,12 +297,14 @@ namespace SourceGit.ViewModels return; var options = new FolderPickerOpenOptions() { AllowMultiple = false }; + var log = null as CommandLog; try { var picker = await storageProvider.OpenFolderPickerAsync(options); if (picker.Count == 1) { - var log = _repo.CreateLog("Save as Patch"); + log = _repo.CreateLog("Save as Patch"); + var succ = false; for (var i = 0; i < selected.Count; i++) { @@ -314,8 +316,6 @@ namespace SourceGit.ViewModels if (succ) App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess")); - - log.Complete(); } } catch (Exception exception) @@ -323,6 +323,7 @@ namespace SourceGit.ViewModels App.RaiseException(_repo.FullPath, $"Failed to save as patch: {exception.Message}"); } + log?.Complete(); e.Handled = true; }; multipleMenu.Items.Add(saveToPatchMultiple); @@ -658,13 +659,16 @@ namespace SourceGit.ViewModels return; var options = new FolderPickerOpenOptions() { AllowMultiple = false }; + var log = null as CommandLog; try { var selected = await storageProvider.OpenFolderPickerAsync(options); if (selected.Count == 1) { + log = _repo.CreateLog("Save as Patch"); + var saveTo = GetPatchFileName(selected[0].Path.LocalPath, commit); - var succ = new Commands.FormatPatch(_repo.FullPath, commit.SHA, saveTo).Exec(); + var succ = new Commands.FormatPatch(_repo.FullPath, commit.SHA, saveTo).Use(log).Exec(); if (succ) App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess")); } @@ -674,6 +678,7 @@ namespace SourceGit.ViewModels App.RaiseException(_repo.FullPath, $"Failed to save as patch: {exception.Message}"); } + log?.Complete(); e.Handled = true; }; menu.Items.Add(saveToPatch); diff --git a/src/ViewModels/InteractiveRebase.cs b/src/ViewModels/InteractiveRebase.cs index 2fd2d67c..f9ae06b5 100644 --- a/src/ViewModels/InteractiveRebase.cs +++ b/src/ViewModels/InteractiveRebase.cs @@ -174,12 +174,14 @@ namespace SourceGit.ViewModels } File.WriteAllText(saveFile, JsonSerializer.Serialize(collection, JsonCodeGen.Default.InteractiveRebaseJobCollection)); + var log = _repo.CreateLog("Interactive Rebase"); return Task.Run(() => { - var succ = new Commands.InteractiveRebase(_repo.FullPath, On.SHA).Exec(); + var succ = new Commands.InteractiveRebase(_repo.FullPath, On.SHA).Use(log).Exec(); if (succ) File.Delete(saveFile); + log.Complete(); Dispatcher.UIThread.Invoke(() => _repo.SetWatcherEnabled(true)); return succ; }); diff --git a/src/ViewModels/LFSLocks.cs b/src/ViewModels/LFSLocks.cs index e462a069..0ee149d0 100644 --- a/src/ViewModels/LFSLocks.cs +++ b/src/ViewModels/LFSLocks.cs @@ -37,17 +37,17 @@ namespace SourceGit.ViewModels private set => SetProperty(ref _visibleLocks, value); } - public LFSLocks(string repo, string remote) + public LFSLocks(Repository repo, string remote) { _repo = repo; _remote = remote; - _userName = new Commands.Config(repo).Get("user.name"); + _userName = new Commands.Config(repo.FullPath).Get("user.name"); HasValidUserName = !string.IsNullOrEmpty(_userName); Task.Run(() => { - _cachedLocks = new Commands.LFS(_repo).Locks(_remote); + _cachedLocks = new Commands.LFS(_repo.FullPath).Locks(_remote); Dispatcher.UIThread.Invoke(() => { UpdateVisibleLocks(); @@ -62,9 +62,13 @@ namespace SourceGit.ViewModels return; IsLoading = true; + + var log = _repo.CreateLog("Unlock LFS File"); Task.Run(() => { - var succ = new Commands.LFS(_repo).Unlock(_remote, lfsLock.ID, force); + var succ = new Commands.LFS(_repo.FullPath).Unlock(_remote, lfsLock.ID, force, log); + log.Complete(); + Dispatcher.UIThread.Invoke(() => { if (succ) @@ -99,7 +103,7 @@ namespace SourceGit.ViewModels VisibleLocks = visible; } - private string _repo; + private Repository _repo; private string _remote; private bool _isLoading = true; private List _cachedLocks = []; diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 36ad9cbc..edd711b3 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -1405,7 +1405,7 @@ namespace SourceGit.ViewModels { locks.Click += (_, e) => { - var dialog = new Views.LFSLocks() { DataContext = new LFSLocks(_fullpath, _remotes[0].Name) }; + var dialog = new Views.LFSLocks() { DataContext = new LFSLocks(this, _remotes[0].Name) }; App.OpenDialog(dialog); e.Handled = true; }; @@ -1419,7 +1419,7 @@ namespace SourceGit.ViewModels lockRemote.Header = remoteName; lockRemote.Click += (_, e) => { - var dialog = new Views.LFSLocks() { DataContext = new LFSLocks(_fullpath, remoteName) }; + var dialog = new Views.LFSLocks() { DataContext = new LFSLocks(this, remoteName) }; App.OpenDialog(dialog); e.Handled = true; }; @@ -1437,10 +1437,12 @@ namespace SourceGit.ViewModels install.Icon = App.CreateMenuIcon("Icons.Init"); install.Click += (_, e) => { - var succ = new Commands.LFS(_fullpath).Install(); + var log = CreateLog("Install LFS"); + var succ = new Commands.LFS(_fullpath).Install(log); if (succ) App.SendNotification(_fullpath, $"LFS enabled successfully!"); + log.Complete(); e.Handled = true; }; menu.Items.Add(install); @@ -2249,9 +2251,11 @@ namespace SourceGit.ViewModels unlock.Click += (_, ev) => { SetWatcherEnabled(false); - var succ = new Commands.Worktree(_fullpath).Unlock(worktree.FullPath); + var log = CreateLog("Unlock Worktree"); + var succ = new Commands.Worktree(_fullpath).Use(log).Unlock(worktree.FullPath); if (succ) worktree.IsLocked = false; + log.Complete(); SetWatcherEnabled(true); ev.Handled = true; }; @@ -2265,9 +2269,11 @@ namespace SourceGit.ViewModels loc.Click += (_, ev) => { SetWatcherEnabled(false); - var succ = new Commands.Worktree(_fullpath).Lock(worktree.FullPath); + var log = CreateLog("Lock Worktree"); + var succ = new Commands.Worktree(_fullpath).Use(log).Lock(worktree.FullPath); if (succ) worktree.IsLocked = true; + log.Complete(); SetWatcherEnabled(true); ev.Handled = true; }; diff --git a/src/ViewModels/StashesPage.cs b/src/ViewModels/StashesPage.cs index d77b6b3e..87e36b86 100644 --- a/src/ViewModels/StashesPage.cs +++ b/src/ViewModels/StashesPage.cs @@ -238,7 +238,9 @@ namespace SourceGit.ViewModels resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout"); resetToThisRevision.Click += (_, ev) => { - new Commands.Checkout(_repo.FullPath).FileWithRevision(change.Path, $"{_selectedStash.SHA}"); + var log = _repo.CreateLog($"Reset File to '{_selectedStash.SHA}'"); + new Commands.Checkout(_repo.FullPath).Use(log).FileWithRevision(change.Path, $"{_selectedStash.SHA}"); + log.Complete(); ev.Handled = true; }; diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 10544970..49560335 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -325,7 +325,7 @@ namespace SourceGit.ViewModels { App.OpenDialog(new Views.AssumeUnchangedManager() { - DataContext = new AssumeUnchangedManager(_repo.FullPath) + DataContext = new AssumeUnchangedManager(_repo) }); } @@ -377,6 +377,7 @@ namespace SourceGit.ViewModels var files = new List(); var needStage = new List(); + var log = _repo.CreateLog("Use Theirs"); foreach (var change in changes) { @@ -399,14 +400,15 @@ namespace SourceGit.ViewModels if (files.Count > 0) { - var succ = await Task.Run(() => new Commands.Checkout(_repo.FullPath).UseTheirs(files)); + var succ = await Task.Run(() => new Commands.Checkout(_repo.FullPath).Use(log).UseTheirs(files)); if (succ) needStage.AddRange(files); } if (needStage.Count > 0) - await Task.Run(() => new Commands.Add(_repo.FullPath, needStage).Exec()); + await Task.Run(() => new Commands.Add(_repo.FullPath, needStage).Use(log).Exec()); + log.Complete(); _repo.MarkWorkingCopyDirtyManually(); _repo.SetWatcherEnabled(true); } @@ -417,6 +419,7 @@ namespace SourceGit.ViewModels var files = new List(); var needStage = new List(); + var log = _repo.CreateLog("Use Mine"); foreach (var change in changes) { @@ -439,14 +442,15 @@ namespace SourceGit.ViewModels if (files.Count > 0) { - var succ = await Task.Run(() => new Commands.Checkout(_repo.FullPath).UseMine(files)); + var succ = await Task.Run(() => new Commands.Checkout(_repo.FullPath).Use(log).UseMine(files)); if (succ) needStage.AddRange(files); } if (needStage.Count > 0) - await Task.Run(() => new Commands.Add(_repo.FullPath, needStage).Exec()); + await Task.Run(() => new Commands.Add(_repo.FullPath, needStage).Use(log).Exec()); + log.Complete(); _repo.MarkWorkingCopyDirtyManually(); _repo.SetWatcherEnabled(true); } @@ -845,10 +849,12 @@ namespace SourceGit.ViewModels { lfsLock.Click += async (_, e) => { - var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Lock(_repo.Remotes[0].Name, change.Path)); + var log = _repo.CreateLog("Lock LFS File"); + var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Lock(_repo.Remotes[0].Name, change.Path, log)); if (succ) App.SendNotification(_repo.FullPath, $"Lock file \"{change.Path}\" successfully!"); + log.Complete(); e.Handled = true; }; } @@ -861,10 +867,12 @@ namespace SourceGit.ViewModels lockRemote.Header = remoteName; lockRemote.Click += async (_, e) => { - var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Lock(remoteName, change.Path)); + var log = _repo.CreateLog("Lock LFS File"); + var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Lock(remoteName, change.Path, log)); if (succ) App.SendNotification(_repo.FullPath, $"Lock file \"{change.Path}\" successfully!"); + log.Complete(); e.Handled = true; }; lfsLock.Items.Add(lockRemote); @@ -880,10 +888,12 @@ namespace SourceGit.ViewModels { lfsUnlock.Click += async (_, e) => { - var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Unlock(_repo.Remotes[0].Name, change.Path, false)); + var log = _repo.CreateLog("Unlock LFS File"); + var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Unlock(_repo.Remotes[0].Name, change.Path, false, log)); if (succ) App.SendNotification(_repo.FullPath, $"Unlock file \"{change.Path}\" successfully!"); + log.Complete(); e.Handled = true; }; } @@ -896,10 +906,12 @@ namespace SourceGit.ViewModels unlockRemote.Header = remoteName; unlockRemote.Click += async (_, e) => { - var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Unlock(remoteName, change.Path, false)); + var log = _repo.CreateLog("Unlock LFS File"); + var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Unlock(remoteName, change.Path, false, log)); if (succ) App.SendNotification(_repo.FullPath, $"Unlock file \"{change.Path}\" successfully!"); + log.Complete(); e.Handled = true; }; lfsUnlock.Items.Add(unlockRemote); @@ -1211,10 +1223,12 @@ namespace SourceGit.ViewModels { lfsLock.Click += async (_, e) => { - var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Lock(_repo.Remotes[0].Name, change.Path)); + var log = _repo.CreateLog("Lock LFS File"); + var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Lock(_repo.Remotes[0].Name, change.Path, log)); if (succ) App.SendNotification(_repo.FullPath, $"Lock file \"{change.Path}\" successfully!"); + log.Complete(); e.Handled = true; }; } @@ -1227,10 +1241,12 @@ namespace SourceGit.ViewModels lockRemote.Header = remoteName; lockRemote.Click += async (_, e) => { - var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Lock(remoteName, change.Path)); + var log = _repo.CreateLog("Lock LFS File"); + var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Lock(remoteName, change.Path, log)); if (succ) App.SendNotification(_repo.FullPath, $"Lock file \"{change.Path}\" successfully!"); + log.Complete(); e.Handled = true; }; lfsLock.Items.Add(lockRemote); @@ -1246,10 +1262,12 @@ namespace SourceGit.ViewModels { lfsUnlock.Click += async (_, e) => { - var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Unlock(_repo.Remotes[0].Name, change.Path, false)); + var log = _repo.CreateLog("Unlock LFS File"); + var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Unlock(_repo.Remotes[0].Name, change.Path, false, log)); if (succ) App.SendNotification(_repo.FullPath, $"Unlock file \"{change.Path}\" successfully!"); + log.Complete(); e.Handled = true; }; } @@ -1262,10 +1280,12 @@ namespace SourceGit.ViewModels unlockRemote.Header = remoteName; unlockRemote.Click += async (_, e) => { - var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Unlock(remoteName, change.Path, false)); + var log = _repo.CreateLog("Unlock LFS File"); + var succ = await Task.Run(() => new Commands.LFS(_repo.FullPath).Unlock(remoteName, change.Path, false, log)); if (succ) App.SendNotification(_repo.FullPath, $"Unlock file \"{change.Path}\" successfully!"); + log.Complete(); e.Handled = true; }; lfsUnlock.Items.Add(unlockRemote);