diff --git a/src/App.axaml.cs b/src/App.axaml.cs index 54d4354c..b23c2626 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -158,13 +158,12 @@ namespace SourceGit } } - public static async Task AskConfirmAsync(string message, Action onSure) + public static async Task AskConfirmAsync(string message) { if (Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime { MainWindow: { } owner }) { var confirm = new Views.Confirm(); confirm.Message.Text = message; - confirm.OnSure = onSure; return await confirm.ShowDialog(owner); } diff --git a/src/Models/Commit.cs b/src/Models/Commit.cs index 61438424..4fb9f7d6 100644 --- a/src/Models/Commit.cs +++ b/src/Models/Commit.cs @@ -16,6 +16,14 @@ namespace SourceGit.Models ByContent, } + public enum CommitCheckPassed + { + None = 0, + DetachedHead, + Filter, + FileCount, + } + public class Commit { // As retrieved by: git mktree onSure) + public ConfirmEmptyCommit(WorkingCopy wc, bool autoPush, int unstagedCount) { - HasLocalChanges = hasLocalChanges; - Message = App.Text(hasLocalChanges ? "ConfirmEmptyCommit.WithLocalChanges" : "ConfirmEmptyCommit.NoLocalChanges"); - _onSure = onSure; + _wc = wc; + _autoPush = autoPush; + HasLocalChanges = unstagedCount > 0; + Message = App.Text(HasLocalChanges ? "ConfirmEmptyCommit.WithLocalChanges" : "ConfirmEmptyCommit.NoLocalChanges"); } - public void StageAllThenCommit() + public async Task StageAllThenCommitAsync() { - _onSure?.Invoke(true); + await _wc.CommitAsync(true, _autoPush, Models.CommitCheckPassed.FileCount); } - public void Continue() + public async Task ContinueAsync() { - _onSure?.Invoke(false); + await _wc.CommitAsync(false, _autoPush, Models.CommitCheckPassed.FileCount); } - private Action _onSure; + private readonly WorkingCopy _wc; + private readonly bool _autoPush; } } diff --git a/src/ViewModels/CreateBranch.cs b/src/ViewModels/CreateBranch.cs index 7e266236..b79b1785 100644 --- a/src/ViewModels/CreateBranch.cs +++ b/src/ViewModels/CreateBranch.cs @@ -131,7 +131,7 @@ namespace SourceGit.ViewModels if (refs.Count == 0) { var msg = App.Text("Checkout.WarnLostCommits"); - var shouldContinue = await App.AskConfirmAsync(msg, null); + var shouldContinue = await App.AskConfirmAsync(msg); if (!shouldContinue) { _repo.SetWatcherEnabled(true); diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 945b24e5..4ff82332 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -606,19 +606,86 @@ namespace SourceGit.ViewModels CommitMessage = tmpl.Apply(_repo.CurrentBranch, _staged); } - public void Commit() + public async Task CommitAsync(bool autoStage, bool autoPush, Models.CommitCheckPassed checkPassed = Models.CommitCheckPassed.None) { - DoCommit(false, false); - } + if (string.IsNullOrWhiteSpace(_commitMessage)) + return; - public void CommitWithAutoStage() - { - DoCommit(true, false); - } + if (!_repo.CanCreatePopup()) + { + App.RaiseException(_repo.FullPath, "Repository has an unfinished job! Please wait!"); + return; + } - public void CommitWithPush() - { - DoCommit(false, true); + if (autoStage && HasUnsolvedConflicts) + { + App.RaiseException(_repo.FullPath, "Repository has unsolved conflict(s). Auto-stage and commit is disabled!"); + return; + } + + if (_repo.CurrentBranch is { IsDetachedHead: true } && checkPassed < Models.CommitCheckPassed.DetachedHead) + { + var msg = App.Text("WorkingCopy.ConfirmCommitWithDetachedHead"); + var sure = await App.AskConfirmAsync(msg); + if (sure) + await CommitAsync(autoStage, autoPush, Models.CommitCheckPassed.DetachedHead); + return; + } + + if (!string.IsNullOrEmpty(_filter) && _staged.Count > _visibleStaged.Count && checkPassed < Models.CommitCheckPassed.Filter) + { + var msg = App.Text("WorkingCopy.ConfirmCommitWithFilter", _staged.Count, _visibleStaged.Count, _staged.Count - _visibleStaged.Count); + var sure = await App.AskConfirmAsync(msg); + if (sure) + await CommitAsync(autoStage, autoPush, Models.CommitCheckPassed.Filter); + return; + } + + if (checkPassed < Models.CommitCheckPassed.FileCount && !_useAmend) + { + if ((!autoStage && _staged.Count == 0) || (autoStage && _cached.Count == 0)) + { + await App.ShowDialog(new ConfirmEmptyCommit(this, autoPush, _cached.Count)); + return; + } + } + + IsCommitting = true; + _repo.Settings.PushCommitMessage(_commitMessage); + _repo.SetWatcherEnabled(false); + + var signOff = _repo.Settings.EnableSignOffForCommit; + var log = _repo.CreateLog("Commit"); + var succ = true; + if (autoStage && _unstaged.Count > 0) + succ = await new Commands.Add(_repo.FullPath, _repo.IncludeUntracked).Use(log).ExecAsync().ConfigureAwait(false); + + if (succ) + succ = await new Commands.Commit(_repo.FullPath, _commitMessage, signOff, _useAmend, _resetAuthor).Use(log).RunAsync().ConfigureAwait(false); + + log.Complete(); + + if (succ) + { + CommitMessage = string.Empty; + UseAmend = false; + if (autoPush && _repo.Remotes.Count > 0) + { + Models.Branch pushBranch = null; + if (_repo.CurrentBranch == null) + { + var currentBranchName = await new Commands.QueryCurrentBranch(_repo.FullPath).GetResultAsync(); + pushBranch = new Models.Branch() { Name = currentBranchName }; + } + + if (_repo.CanCreatePopup()) + _repo.ShowAndStartPopup(new Push(_repo, pushBranch)); + } + } + + _repo.MarkBranchesDirtyManually(); + _repo.SetWatcherEnabled(true); + IsCommitting = false; } private List GetVisibleChanges(List changes) @@ -745,102 +812,6 @@ namespace SourceGit.ViewModels DetailContext = new DiffContext(_repo.FullPath, new Models.DiffOption(change, isUnstaged), _detailContext as DiffContext); } - private void DoCommit(bool autoStage, bool autoPush, CommitCheckPassed checkPassed = CommitCheckPassed.None) - { - if (string.IsNullOrWhiteSpace(_commitMessage)) - return; - - if (!_repo.CanCreatePopup()) - { - App.RaiseException(_repo.FullPath, "Repository has an unfinished job! Please wait!"); - return; - } - - if (autoStage && HasUnsolvedConflicts) - { - App.RaiseException(_repo.FullPath, "Repository has unsolved conflict(s). Auto-stage and commit is disabled!"); - return; - } - - if (_repo.CurrentBranch is { IsDetachedHead: true } && checkPassed < CommitCheckPassed.DetachedHead) - { - var msg = App.Text("WorkingCopy.ConfirmCommitWithDetachedHead"); - _ = App.AskConfirmAsync(msg, () => DoCommit(autoStage, autoPush, CommitCheckPassed.DetachedHead)); - return; - } - - if (!string.IsNullOrEmpty(_filter) && _staged.Count > _visibleStaged.Count && checkPassed < CommitCheckPassed.Filter) - { - var msg = App.Text("WorkingCopy.ConfirmCommitWithFilter", _staged.Count, _visibleStaged.Count, _staged.Count - _visibleStaged.Count); - _ = App.AskConfirmAsync(msg, () => DoCommit(autoStage, autoPush, CommitCheckPassed.Filter)); - return; - } - - if (checkPassed < CommitCheckPassed.FileCount && !_useAmend) - { - if ((!autoStage && _staged.Count == 0) || (autoStage && _cached.Count == 0)) - { - _ = App.ShowDialog(new ConfirmEmptyCommit(_cached.Count > 0, stageAll => DoCommit(stageAll, autoPush, CommitCheckPassed.FileCount))); - return; - } - } - - IsCommitting = true; - _repo.Settings.PushCommitMessage(_commitMessage); - _repo.SetWatcherEnabled(false); - - var signOff = _repo.Settings.EnableSignOffForCommit; - var log = _repo.CreateLog("Commit"); - Task.Run(async () => - { - var succ = true; - if (autoStage && _unstaged.Count > 0) - succ = await new Commands.Add(_repo.FullPath, _repo.IncludeUntracked).Use(log).ExecAsync().ConfigureAwait(false); - - if (succ) - succ = await new Commands.Commit(_repo.FullPath, _commitMessage, signOff, _useAmend, _resetAuthor).Use(log).RunAsync().ConfigureAwait(false); - - log.Complete(); - - Dispatcher.UIThread.Post(() => - { - if (succ) - { - CommitMessage = string.Empty; - UseAmend = false; - if (autoPush && _repo.Remotes.Count > 0) - PushAfterCommit(); - } - - _repo.MarkBranchesDirtyManually(); - _repo.SetWatcherEnabled(true); - IsCommitting = false; - }); - }); - } - - private void PushAfterCommit() - { - if (_repo.CurrentBranch == null) - { - Task.Run(async () => - { - var currentBranchName = await new Commands.QueryCurrentBranch(_repo.FullPath).GetResultAsync(); - var tmp = new Models.Branch() { Name = currentBranchName }; - - Dispatcher.UIThread.Post(() => - { - if (_repo.CanCreatePopup()) - _repo.ShowAndStartPopup(new Push(_repo, tmp)); - }); - }); - } - else if (_repo.CanCreatePopup()) - { - _repo.ShowAndStartPopup(new Push(_repo, null)); - } - } - private bool IsChanged(List old, List cur) { if (old.Count != cur.Count) @@ -857,14 +828,6 @@ namespace SourceGit.ViewModels return false; } - private enum CommitCheckPassed - { - None = 0, - DetachedHead, - Filter, - FileCount, - } - private Repository _repo = null; private bool _isLoadingData = false; private bool _isStaging = false; diff --git a/src/Views/Confirm.axaml.cs b/src/Views/Confirm.axaml.cs index f214da23..3756fa3a 100644 --- a/src/Views/Confirm.axaml.cs +++ b/src/Views/Confirm.axaml.cs @@ -1,16 +1,9 @@ -using System; using Avalonia.Interactivity; namespace SourceGit.Views { public partial class Confirm : ChromelessWindow { - public Action OnSure - { - get; - set; - } - public Confirm() { InitializeComponent(); @@ -18,7 +11,6 @@ namespace SourceGit.Views private void Sure(object _1, RoutedEventArgs _2) { - OnSure?.Invoke(); Close(true); } diff --git a/src/Views/ConfirmEmptyCommit.axaml.cs b/src/Views/ConfirmEmptyCommit.axaml.cs index 6668ee2c..101d77d4 100644 --- a/src/Views/ConfirmEmptyCommit.axaml.cs +++ b/src/Views/ConfirmEmptyCommit.axaml.cs @@ -9,15 +9,19 @@ namespace SourceGit.Views InitializeComponent(); } - private void StageAllThenCommit(object _1, RoutedEventArgs _2) + private async void StageAllThenCommit(object _1, RoutedEventArgs _2) { - (DataContext as ViewModels.ConfirmEmptyCommit)?.StageAllThenCommit(); + if (DataContext is ViewModels.ConfirmEmptyCommit vm) + await vm.StageAllThenCommitAsync(); + Close(); } - private void Continue(object _1, RoutedEventArgs _2) + private async void Continue(object _1, RoutedEventArgs _2) { - (DataContext as ViewModels.ConfirmEmptyCommit)?.Continue(); + if (DataContext is ViewModels.ConfirmEmptyCommit vm) + await vm.ContinueAsync(); + Close(); } diff --git a/src/Views/WorkingCopy.axaml b/src/Views/WorkingCopy.axaml index 99505c9f..a57cc3c2 100644 --- a/src/Views/WorkingCopy.axaml +++ b/src/Views/WorkingCopy.axaml @@ -295,7 +295,7 @@ @@ -307,7 +307,7 @@ Height="28" Margin="8,0,0,0" Padding="8,0" - Command="{Binding Commit}" + Click="OnCommit" HotKey="{OnPlatform Ctrl+Enter, macOS=⌘+Enter}" IsVisible="{Binding InProgressContext, Converter={x:Static ObjectConverters.IsNull}}" ToolTip.Placement="Top" @@ -337,7 +337,7 @@