From 927a1cab24bcd8c803bf5e952aff49e5a07af0d6 Mon Sep 17 00:00:00 2001 From: Alexander Bogomolets Date: Sun, 28 Apr 2024 16:43:53 +0300 Subject: [PATCH 1/2] Add checkout local changes handling This commit adds the local changes handling behavior for branch checkout. One of three can be selected: stash and reapply after checkout, discard changes or leave them as is (previous behaviour) --- src/Resources/Locales/en_US.axaml | 4 ++ src/Resources/Locales/zh_CN.axaml | 4 ++ src/ViewModels/Checkout.cs | 73 ++++++++++++++++++++++++++++++- src/ViewModels/Histories.cs | 6 ++- src/ViewModels/Repository.cs | 5 ++- src/Views/Checkout.axaml | 12 +++++ src/Views/Repository.axaml.cs | 2 +- 7 files changed, 101 insertions(+), 5 deletions(-) diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 0d7a3072..dfe51cd4 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -53,6 +53,10 @@ Show as Tree Checkout Branch Target : + Local Changes : + Stash & Reapply + Discard + Leave 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..217dbf7f 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -53,6 +53,10 @@ 树形模式 检出(checkout)分支 目标分支 : + 未提交更改 : + 贮藏(stash)并自动恢复 + 忽略 + 保持原样 挑选(cherry-pick)此提交 提交ID : 提交变化 diff --git a/src/ViewModels/Checkout.cs b/src/ViewModels/Checkout.cs index adfc70db..327253cf 100644 --- a/src/ViewModels/Checkout.cs +++ b/src/ViewModels/Checkout.cs @@ -9,27 +9,98 @@ namespace SourceGit.ViewModels get; private set; } + + public bool HasLocalChanges + { + get => _repo.WorkingCopyChangesCount > 0; + } + + public bool LeaveLocalChanges + { + get => _leaveLocalChanges; + set => SetProperty(ref _leaveLocalChanges, value); + } + + public bool DiscardLocalChanges + { + get => _discardLocalChanges; + set => SetProperty(ref _discardLocalChanges, value); + } + + public bool StashLocalChanges + { + get => _stashLocalChanges; + set => SetProperty(ref _stashLocalChanges, value); + } public Checkout(Repository repo, string branch) { _repo = repo; Branch = branch; View = new Views.Checkout() { DataContext = this }; + + StashLocalChanges = true; } public override Task Sure() { _repo.SetWatcherEnabled(false); ProgressDescription = $"Checkout '{Branch}' ..."; + var hasLocalChanges = HasLocalChanges; return Task.Run(() => { - var succ = new Commands.Checkout(_repo.FullPath).Branch(Branch, SetProgressDescription); + var succ = false; + if (hasLocalChanges) + { + if (DiscardLocalChanges) + { + SetProgressDescription("Discard local changes..."); + Commands.Discard.All(_repo.FullPath); + } + + if (StashLocalChanges) + { + SetProgressDescription("Stash local changes..."); + succ = new Commands.Add(_repo.FullPath).Exec(); + succ = new Commands.Stash(_repo.FullPath).Push("CHECKOUT_AUTO_STASH"); + } + } + + SetProgressDescription("Checkout branch ..."); + succ = new Commands.Checkout(_repo.FullPath).Branch(Branch, SetProgressDescription); + + if(hasLocalChanges && StashLocalChanges) + { + SetProgressDescription("Re-apply local changes..."); + succ = new Commands.Stash(_repo.FullPath).Apply("stash@{0}"); + if (succ) + { + succ = new Commands.Stash(_repo.FullPath).Drop("stash@{0}"); + } + } + CallUIThread(() => _repo.SetWatcherEnabled(true)); return succ; }); } + + public static void ShowPopup(Repository repo, string branch) + { + var checkout = new Checkout(repo, branch); + if (repo.WorkingCopyChangesCount > 0) + { + PopupHost.ShowPopup(checkout); + } + else + { + PopupHost.ShowAndStartPopup(checkout); + } + } private readonly Repository _repo; + private bool _leaveLocalChanges; + private bool _discardLocalChanges; + private bool _stashLocalChanges; } } diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs index a4102543..4fc1e1b9 100644 --- a/src/ViewModels/Histories.cs +++ b/src/ViewModels/Histories.cs @@ -448,7 +448,9 @@ namespace SourceGit.ViewModels checkout.Click += (o, e) => { if (PopupHost.CanCreatePopup()) - PopupHost.ShowAndStartPopup(new Checkout(_repo, branch.Name)); + { + Checkout.ShowPopup(_repo, branch.Name); + } e.Handled = true; }; submenu.Items.Add(checkout); @@ -527,7 +529,7 @@ namespace SourceGit.ViewModels if (b.IsCurrent) return; if (PopupHost.CanCreatePopup()) - PopupHost.ShowAndStartPopup(new Checkout(_repo, b.Name)); + Checkout.ShowPopup(_repo, b.Name); return; } } diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index db35f4a9..fe99b0ec 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -843,7 +843,10 @@ namespace SourceGit.ViewModels checkout.Click += (o, e) => { if (PopupHost.CanCreatePopup()) - PopupHost.ShowAndStartPopup(new Checkout(this, branch.Name)); + { + Checkout.ShowPopup(this, branch.Name); + } + e.Handled = true; }; menu.Items.Add(checkout); diff --git a/src/Views/Checkout.axaml b/src/Views/Checkout.axaml index 083190f8..50bb3b8c 100644 --- a/src/Views/Checkout.axaml +++ b/src/Views/Checkout.axaml @@ -15,5 +15,17 @@ + + + + + + diff --git a/src/Views/Repository.axaml.cs b/src/Views/Repository.axaml.cs index 43d9ee11..0d010cc0 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)); + ViewModels.Checkout.ShowPopup(repo, branch.Name); e.Handled = true; } } From 776605cb68145cc323b8ccc04dc3e446eceeb43f Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 29 Apr 2024 17:22:22 +0800 Subject: [PATCH 2/2] code_review: PR #98 * remove the `Leave` option (it may lead to an undefined behaviour), so user can only choose `Stash & reapply` or `Discard`. * re-design the UI * remove unused resources --- src/Resources/Locales/en_US.axaml | 3 +- src/Resources/Locales/zh_CN.axaml | 1 - src/ViewModels/Checkout.cs | 87 ++++++++++++------------------- src/ViewModels/Histories.cs | 13 ++--- src/ViewModels/Repository.cs | 17 ++++-- src/Views/Checkout.axaml | 41 +++++++++------ src/Views/Repository.axaml.cs | 2 +- 7 files changed, 75 insertions(+), 89 deletions(-) diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index dfe51cd4..0f3fac65 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -52,11 +52,10 @@ Show as List Show as Tree Checkout Branch - Target : + Branch : Local Changes : Stash & Reapply Discard - Leave 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 217dbf7f..a5c487b3 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -56,7 +56,6 @@ 未提交更改 : 贮藏(stash)并自动恢复 忽略 - 保持原样 挑选(cherry-pick)此提交 提交ID : 提交变化 diff --git a/src/ViewModels/Checkout.cs b/src/ViewModels/Checkout.cs index 327253cf..3ee4b6de 100644 --- a/src/ViewModels/Checkout.cs +++ b/src/ViewModels/Checkout.cs @@ -9,28 +9,11 @@ namespace SourceGit.ViewModels get; private set; } - - public bool HasLocalChanges - { - get => _repo.WorkingCopyChangesCount > 0; - } - public bool LeaveLocalChanges + public bool AutoStash { - get => _leaveLocalChanges; - set => SetProperty(ref _leaveLocalChanges, value); - } - - public bool DiscardLocalChanges - { - get => _discardLocalChanges; - set => SetProperty(ref _discardLocalChanges, value); - } - - public bool StashLocalChanges - { - get => _stashLocalChanges; - set => SetProperty(ref _stashLocalChanges, value); + get => _autoStash; + set => SetProperty(ref _autoStash, value); } public Checkout(Repository repo, string branch) @@ -38,69 +21,63 @@ namespace SourceGit.ViewModels _repo = repo; Branch = branch; View = new Views.Checkout() { DataContext = this }; - - StashLocalChanges = true; } public override Task Sure() { _repo.SetWatcherEnabled(false); ProgressDescription = $"Checkout '{Branch}' ..."; - var hasLocalChanges = HasLocalChanges; + var hasLocalChanges = _repo.WorkingCopyChangesCount > 0; return Task.Run(() => { - var succ = false; + var needPopStash = false; if (hasLocalChanges) { - if (DiscardLocalChanges) + if (AutoStash) { - SetProgressDescription("Discard local changes..."); - Commands.Discard.All(_repo.FullPath); - } + 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 (StashLocalChanges) + if (!succ) + { + CallUIThread(() => _repo.SetWatcherEnabled(true)); + return false; + } + + needPopStash = true; + } + else { - SetProgressDescription("Stash local changes..."); - succ = new Commands.Add(_repo.FullPath).Exec(); - succ = new Commands.Stash(_repo.FullPath).Push("CHECKOUT_AUTO_STASH"); + SetProgressDescription("Discard local changes ..."); + Commands.Discard.All(_repo.FullPath); } } SetProgressDescription("Checkout branch ..."); - succ = new Commands.Checkout(_repo.FullPath).Branch(Branch, SetProgressDescription); + var rs = new Commands.Checkout(_repo.FullPath).Branch(Branch, SetProgressDescription); - if(hasLocalChanges && StashLocalChanges) + if(needPopStash) { SetProgressDescription("Re-apply local changes..."); - succ = new Commands.Stash(_repo.FullPath).Apply("stash@{0}"); - if (succ) + rs = new Commands.Stash(_repo.FullPath).Apply("stash@{0}"); + if (rs) { - succ = new Commands.Stash(_repo.FullPath).Drop("stash@{0}"); + rs = new Commands.Stash(_repo.FullPath).Drop("stash@{0}"); } } CallUIThread(() => _repo.SetWatcherEnabled(true)); - return succ; + return rs; }); } - - public static void ShowPopup(Repository repo, string branch) - { - var checkout = new Checkout(repo, branch); - if (repo.WorkingCopyChangesCount > 0) - { - PopupHost.ShowPopup(checkout); - } - else - { - PopupHost.ShowAndStartPopup(checkout); - } - } - private readonly Repository _repo; - private bool _leaveLocalChanges; - private bool _discardLocalChanges; - private bool _stashLocalChanges; + private readonly Repository _repo = null; + private bool _autoStash = true; } } diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs index 4fc1e1b9..652ba805 100644 --- a/src/ViewModels/Histories.cs +++ b/src/ViewModels/Histories.cs @@ -447,10 +447,7 @@ namespace SourceGit.ViewModels checkout.Icon = App.CreateMenuIcon("Icons.Check"); checkout.Click += (o, e) => { - if (PopupHost.CanCreatePopup()) - { - Checkout.ShowPopup(_repo, branch.Name); - } + _repo.CheckoutLocalBranch(branch.Name); e.Handled = true; }; submenu.Items.Add(checkout); @@ -526,16 +523,16 @@ namespace SourceGit.ViewModels { if (b.IsLocal && b.Upstream == branch.FullName) { - if (b.IsCurrent) - return; - if (PopupHost.CanCreatePopup()) - Checkout.ShowPopup(_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 fe99b0ec..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,11 +853,7 @@ namespace SourceGit.ViewModels checkout.Icon = App.CreateMenuIcon("Icons.Check"); checkout.Click += (o, e) => { - if (PopupHost.CanCreatePopup()) - { - Checkout.ShowPopup(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 50bb3b8c..51798fcc 100644 --- a/src/Views/Checkout.axaml +++ b/src/Views/Checkout.axaml @@ -10,22 +10,29 @@ - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/src/Views/Repository.axaml.cs b/src/Views/Repository.axaml.cs index 0d010cc0..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.Checkout.ShowPopup(repo, branch.Name); + repo.CheckoutLocalBranch(branch.Name); e.Handled = true; } }