diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 0d7a3072..0f3fac65 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -52,7 +52,10 @@ Show as List Show as Tree Checkout Branch - Target : + Branch : + Local Changes : + Stash & Reapply + Discard Cherry-Pick This Commit Commit : Commit all changes diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 1b817c3b..a5c487b3 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -53,6 +53,9 @@ 树形模式 检出(checkout)分支 目标分支 : + 未提交更改 : + 贮藏(stash)并自动恢复 + 忽略 挑选(cherry-pick)此提交 提交ID : 提交变化 diff --git a/src/ViewModels/Checkout.cs b/src/ViewModels/Checkout.cs index adfc70db..3ee4b6de 100644 --- a/src/ViewModels/Checkout.cs +++ b/src/ViewModels/Checkout.cs @@ -10,6 +10,12 @@ namespace SourceGit.ViewModels private set; } + public bool AutoStash + { + get => _autoStash; + set => SetProperty(ref _autoStash, value); + } + public Checkout(Repository repo, string branch) { _repo = repo; @@ -22,14 +28,56 @@ namespace SourceGit.ViewModels _repo.SetWatcherEnabled(false); ProgressDescription = $"Checkout '{Branch}' ..."; + var hasLocalChanges = _repo.WorkingCopyChangesCount > 0; return Task.Run(() => { - var succ = new Commands.Checkout(_repo.FullPath).Branch(Branch, SetProgressDescription); + var needPopStash = false; + if (hasLocalChanges) + { + if (AutoStash) + { + SetProgressDescription("Adding untracked changes ..."); + var succ = new Commands.Add(_repo.FullPath).Exec(); + if (succ) + { + SetProgressDescription("Stash local changes ..."); + succ = new Commands.Stash(_repo.FullPath).Push("CHECKOUT_AUTO_STASH"); + } + + if (!succ) + { + CallUIThread(() => _repo.SetWatcherEnabled(true)); + return false; + } + + needPopStash = true; + } + else + { + SetProgressDescription("Discard local changes ..."); + Commands.Discard.All(_repo.FullPath); + } + } + + SetProgressDescription("Checkout branch ..."); + var rs = new Commands.Checkout(_repo.FullPath).Branch(Branch, SetProgressDescription); + + if(needPopStash) + { + SetProgressDescription("Re-apply local changes..."); + rs = new Commands.Stash(_repo.FullPath).Apply("stash@{0}"); + if (rs) + { + rs = new Commands.Stash(_repo.FullPath).Drop("stash@{0}"); + } + } + CallUIThread(() => _repo.SetWatcherEnabled(true)); - return succ; + return rs; }); } - private readonly Repository _repo; + private readonly Repository _repo = null; + private bool _autoStash = true; } } diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs index a4102543..652ba805 100644 --- a/src/ViewModels/Histories.cs +++ b/src/ViewModels/Histories.cs @@ -447,8 +447,7 @@ namespace SourceGit.ViewModels checkout.Icon = App.CreateMenuIcon("Icons.Check"); checkout.Click += (o, e) => { - if (PopupHost.CanCreatePopup()) - PopupHost.ShowAndStartPopup(new Checkout(_repo, branch.Name)); + _repo.CheckoutLocalBranch(branch.Name); e.Handled = true; }; submenu.Items.Add(checkout); @@ -524,16 +523,16 @@ namespace SourceGit.ViewModels { if (b.IsLocal && b.Upstream == branch.FullName) { - if (b.IsCurrent) - return; - if (PopupHost.CanCreatePopup()) - PopupHost.ShowAndStartPopup(new Checkout(_repo, b.Name)); + if (!b.IsCurrent) + _repo.CheckoutLocalBranch(b.Name); + return; } } if (PopupHost.CanCreatePopup()) PopupHost.ShowPopup(new CreateBranch(_repo, branch)); + e.Handled = true; }; submenu.Items.Add(checkout); diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index db35f4a9..949323cb 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -690,6 +690,17 @@ namespace SourceGit.ViewModels PopupHost.ShowPopup(new CreateBranch(this, current)); } + public void CheckoutLocalBranch(string branch) + { + if (!PopupHost.CanCreatePopup()) + return; + + if (WorkingCopyChangesCount > 0) + PopupHost.ShowPopup(new Checkout(this, branch)); + else + PopupHost.ShowAndStartPopup(new Checkout(this, branch)); + } + public void CreateNewTag() { var current = Branches.Find(x => x.IsCurrent); @@ -842,8 +853,7 @@ namespace SourceGit.ViewModels checkout.Icon = App.CreateMenuIcon("Icons.Check"); checkout.Click += (o, e) => { - if (PopupHost.CanCreatePopup()) - PopupHost.ShowAndStartPopup(new Checkout(this, branch.Name)); + CheckoutLocalBranch(branch.Name); e.Handled = true; }; menu.Items.Add(checkout); diff --git a/src/Views/Checkout.axaml b/src/Views/Checkout.axaml index 083190f8..51798fcc 100644 --- a/src/Views/Checkout.axaml +++ b/src/Views/Checkout.axaml @@ -10,10 +10,29 @@ - - - - - + + + + + + + + + + + + + + diff --git a/src/Views/Repository.axaml.cs b/src/Views/Repository.axaml.cs index 43d9ee11..717cc947 100644 --- a/src/Views/Repository.axaml.cs +++ b/src/Views/Repository.axaml.cs @@ -298,7 +298,7 @@ namespace SourceGit.Views if (branch.IsCurrent) return; - ViewModels.PopupHost.ShowAndStartPopup(new ViewModels.Checkout(repo, branch.Name)); + repo.CheckoutLocalBranch(branch.Name); e.Handled = true; } }