diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index fddd9986..3b0d34d4 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -89,6 +89,7 @@ Stash & Reapply Update all submodules Branch: + Your current HEAD contains commit(s) not connected to any branches/tags! Do you want to continue? Checkout & Fast-Forward Fast-Forward to: Cherry Pick diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 1debd516..aa864da8 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -93,6 +93,7 @@ 贮藏并自动恢复 同时更新所有子模块 目标分支 : + 您当前游离的HEAD包含未被任何分支及标签引用的提交!是否继续? 检出分支并快进 上游分支 : 挑选提交 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index aed59a18..c57890d5 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -93,6 +93,7 @@ 擱置變更並自動復原 同時更新所有子模組 目標分支: + 您目前的分離的 HEAD 包含與任何分支/標籤無關的提交!您要繼續嗎? 簽出分支並快轉 上游分支 : 揀選提交 diff --git a/src/ViewModels/Checkout.cs b/src/ViewModels/Checkout.cs index 630a97a5..ddcbb295 100644 --- a/src/ViewModels/Checkout.cs +++ b/src/ViewModels/Checkout.cs @@ -47,6 +47,12 @@ namespace SourceGit.ViewModels var succ = false; var needPopStash = false; + if (!_repo.ConfirmCheckoutBranch()) + { + CallUIThread(() => _repo.SetWatcherEnabled(true)); + return true; + } + if (DiscardLocalChanges) { succ = new Commands.Checkout(_repo.FullPath).Use(log).Branch(Branch, true); diff --git a/src/ViewModels/CheckoutAndFastForward.cs b/src/ViewModels/CheckoutAndFastForward.cs index 97ab86d7..9ae931fe 100644 --- a/src/ViewModels/CheckoutAndFastForward.cs +++ b/src/ViewModels/CheckoutAndFastForward.cs @@ -52,6 +52,12 @@ namespace SourceGit.ViewModels var succ = false; var needPopStash = false; + if (!_repo.ConfirmCheckoutBranch()) + { + CallUIThread(() => _repo.SetWatcherEnabled(true)); + return true; + } + if (DiscardLocalChanges) { succ = new Commands.Checkout(_repo.FullPath).Use(log).Branch(LocalBranch.Name, RemoteBranch.Head, true, true); diff --git a/src/ViewModels/CheckoutCommit.cs b/src/ViewModels/CheckoutCommit.cs index c41fd2ce..3acc457c 100644 --- a/src/ViewModels/CheckoutCommit.cs +++ b/src/ViewModels/CheckoutCommit.cs @@ -47,6 +47,12 @@ namespace SourceGit.ViewModels var succ = false; var needPop = false; + if (!_repo.ConfirmCheckoutBranch()) + { + CallUIThread(() => _repo.SetWatcherEnabled(true)); + return true; + } + if (DiscardLocalChanges) { succ = new Commands.Checkout(_repo.FullPath).Use(log).Commit(Commit.SHA, true); diff --git a/src/ViewModels/Confirm.cs b/src/ViewModels/Confirm.cs new file mode 100644 index 00000000..ecbda72c --- /dev/null +++ b/src/ViewModels/Confirm.cs @@ -0,0 +1,31 @@ +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; + } +} diff --git a/src/ViewModels/ConfirmCommit.cs b/src/ViewModels/ConfirmCommit.cs deleted file mode 100644 index cea56948..00000000 --- a/src/ViewModels/ConfirmCommit.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; - -namespace SourceGit.ViewModels -{ - public class ConfirmCommit - { - public string Message - { - get; - private set; - } - - public ConfirmCommit(string message, Action onSure) - { - Message = message; - _onSure = onSure; - } - - public void Continue() - { - _onSure?.Invoke(); - } - - private Action _onSure; - } -} diff --git a/src/ViewModels/CreateBranch.cs b/src/ViewModels/CreateBranch.cs index e518e977..3c245589 100644 --- a/src/ViewModels/CreateBranch.cs +++ b/src/ViewModels/CreateBranch.cs @@ -130,6 +130,13 @@ namespace SourceGit.ViewModels return Task.Run(() => { bool succ = false; + + if (CheckoutAfterCreated && !_repo.ConfirmCheckoutBranch()) + { + CallUIThread(() => _repo.SetWatcherEnabled(true)); + return true; + } + if (CheckoutAfterCreated && !_repo.IsBare) { var needPopStash = false; diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index cc6314ce..9b43bd99 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -1330,6 +1330,41 @@ namespace SourceGit.ViewModels ShowPopup(new CreateBranch(this, _currentBranch)); } + public bool ConfirmCheckoutBranch() + { + if (Dispatcher.UIThread.CheckAccess()) + return true; + + if (_currentBranch is not { IsDetachedHead: true }) + return true; + + var refs = new Commands.QueryRefsContainsCommit(_fullpath, _currentBranch.Head).Result(); + if (refs.Count == 0) + { + var confirmCheckout = false; + var resetEvent = new AutoResetEvent(false); + + Dispatcher.UIThread.Invoke(() => + { + var msg = App.Text("Checkout.WarnLostCommits"); + App.ShowWindow(new Confirm(msg, () => + { + confirmCheckout = true; + resetEvent.Set(); + }, () => + { + confirmCheckout = false; + resetEvent.Set(); + }), true); + }); + + resetEvent.WaitOne(); + return confirmCheckout; + } + + return true; + } + public void CheckoutBranch(Models.Branch branch) { if (branch.IsLocal) diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index e03e8e49..7232f372 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -1795,14 +1795,14 @@ namespace SourceGit.ViewModels if (_repo.CurrentBranch is { IsDetachedHead: true } && checkPassed < CommitCheckPassed.DetachedHead) { var msg = App.Text("WorkingCopy.ConfirmCommitWithDetachedHead"); - App.ShowWindow(new ConfirmCommit(msg, () => DoCommit(autoStage, autoPush, CommitCheckPassed.DetachedHead)), true); + App.ShowWindow(new Confirm(msg, () => DoCommit(autoStage, autoPush, CommitCheckPassed.DetachedHead)), true); 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.ShowWindow(new ConfirmCommit(msg, () => DoCommit(autoStage, autoPush, CommitCheckPassed.Filter)), true); + App.ShowWindow(new Confirm(msg, () => DoCommit(autoStage, autoPush, CommitCheckPassed.Filter)), true); return; } diff --git a/src/Views/ConfirmCommit.axaml b/src/Views/Confirm.axaml similarity index 96% rename from src/Views/ConfirmCommit.axaml rename to src/Views/Confirm.axaml index a835f0b6..93361533 100644 --- a/src/Views/ConfirmCommit.axaml +++ b/src/Views/Confirm.axaml @@ -5,8 +5,8 @@ xmlns:v="using:SourceGit.Views" xmlns:vm="using:SourceGit.ViewModels" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" - x:Class="SourceGit.Views.ConfirmCommit" - x:DataType="vm:ConfirmCommit" + x:Class="SourceGit.Views.Confirm" + x:DataType="vm:Confirm" x:Name="ThisControl" Icon="/App.ico" Title="{DynamicResource Text.Warn}" diff --git a/src/Views/Confirm.axaml.cs b/src/Views/Confirm.axaml.cs new file mode 100644 index 00000000..13e488ee --- /dev/null +++ b/src/Views/Confirm.axaml.cs @@ -0,0 +1,32 @@ +using System; +using Avalonia.Interactivity; + +namespace SourceGit.Views +{ + public partial class Confirm : ChromelessWindow + { + public Confirm() + { + InitializeComponent(); + } + + protected override void OnClosed(EventArgs e) + { + (DataContext as ViewModels.Confirm)?.Done(_isOkPressed); + base.OnClosed(e); + } + + private void Sure(object _1, RoutedEventArgs _2) + { + _isOkPressed = true; + Close(); + } + + private void CloseWindow(object _1, RoutedEventArgs _2) + { + Close(); + } + + private bool _isOkPressed = false; + } +} diff --git a/src/Views/ConfirmCommit.axaml.cs b/src/Views/ConfirmCommit.axaml.cs deleted file mode 100644 index 1cf770cb..00000000 --- a/src/Views/ConfirmCommit.axaml.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Avalonia.Interactivity; - -namespace SourceGit.Views -{ - public partial class ConfirmCommit : ChromelessWindow - { - public ConfirmCommit() - { - InitializeComponent(); - } - - private void Sure(object _1, RoutedEventArgs _2) - { - (DataContext as ViewModels.ConfirmCommit)?.Continue(); - Close(); - } - - private void CloseWindow(object _1, RoutedEventArgs _2) - { - Close(); - } - } -}