diff --git a/src/Models/DealWithLocalChanges.cs b/src/Models/DealWithLocalChanges.cs new file mode 100644 index 00000000..9775c61a --- /dev/null +++ b/src/Models/DealWithLocalChanges.cs @@ -0,0 +1,9 @@ +namespace SourceGit.Models +{ + public enum DealWithLocalChanges + { + DoNothing = 0, + StashAndReapply, + Discard, + } +} diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index c3f3f631..67bcc363 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -318,6 +318,9 @@ $1, $2, … Werte der Eingabe-Steuerelemente Ohne Anmerkung Halte ‚Strg‘ gedrückt, um direkt auszuführen Ausschneiden + Verwerfen + Nichts tun + Stashen & wieder anwenden Deinitialisiere Submodul Erzwinge Deinitialisierung, selbst wenn lokale Änderungen enthalten sind. Submodul: diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 3514fbef..2bd5d316 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -110,8 +110,6 @@ Commit: Warning: By doing a commit checkout, your Head will be detached Local Changes: - Discard - Stash & Reapply Branch: Your current HEAD contains commit(s) not connected to any branches/tags! Do you want to continue? The following submodules need to be updated:{0}Do you want to update them? @@ -301,8 +299,6 @@ Based On: Check out the created branch Local Changes: - Discard - Stash & Reapply New Branch Name: Enter branch name. Create Local Branch @@ -321,6 +317,9 @@ lightweight Hold Ctrl to start directly Cut + Discard + Do Nothing + Stash & Reapply De-initialize Submodule Force de-init even if it contains local changes. Submodule: @@ -689,8 +688,6 @@ Remote Branch: Into: Local Changes: - Discard - Stash & Reapply Remote: Pull (Fetch & Merge) Use rebase instead of merge diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index 736cc079..87b8b75b 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -324,6 +324,9 @@ ligera Mantenga Ctrl para iniciar directamente Cortar + Descartar + No Hacer Nada + Stash & Reaplicar Desinicializar Submódulo Forzar desinicialización incluso si contiene cambios locales. Submódulo: diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index 12293ff1..50829885 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -305,6 +305,9 @@ léger Maintenir Ctrl pour commencer directement Couper + Annuler + Ne rien faire + Mettre en stash et réappliquer Désinitialiser le sous-module Forcer la désinitialisation même s'il contient des modifications locales. Sous-module : diff --git a/src/Resources/Locales/id_ID.axaml b/src/Resources/Locales/id_ID.axaml index afb07fd8..1b4edd3a 100644 --- a/src/Resources/Locales/id_ID.axaml +++ b/src/Resources/Locales/id_ID.axaml @@ -290,6 +290,8 @@ lightweight Tahan Ctrl untuk memulai langsung Potong + Buang + Stash & Terapkan Ulang De-initialize Submodule Paksa de-init meski mengandung perubahan lokal. Submodule: diff --git a/src/Resources/Locales/it_IT.axaml b/src/Resources/Locales/it_IT.axaml index f7b6346b..9b36517a 100644 --- a/src/Resources/Locales/it_IT.axaml +++ b/src/Resources/Locales/it_IT.axaml @@ -317,6 +317,9 @@ ${pure_files:N} Come ${files:N}, ma senza cartelle leggero Tieni premuto Ctrl per avviare direttamente Taglia + Scarta + Non fare nulla + Stash e Ripristina Deinizializza Sottomodulo Forza deinizializzazione anche se contiene modifiche locali. Sottomodulo: diff --git a/src/Resources/Locales/ja_JP.axaml b/src/Resources/Locales/ja_JP.axaml index f2b3f277..9b301143 100644 --- a/src/Resources/Locales/ja_JP.axaml +++ b/src/Resources/Locales/ja_JP.axaml @@ -319,6 +319,8 @@ 軽量 Ctrl キーを押しながらで直接実行できます 切り取り + 破棄 + スタッシュして再適用 サブモジュールの初期化を解除 ローカルの変更の有無に関わらず、強制的に解除 サブモジュール: diff --git a/src/Resources/Locales/ko_KR.axaml b/src/Resources/Locales/ko_KR.axaml index 0768b096..3d541dca 100644 --- a/src/Resources/Locales/ko_KR.axaml +++ b/src/Resources/Locales/ko_KR.axaml @@ -289,6 +289,8 @@ 경량 태그 Ctrl을 누른 채 클릭하면 바로 시작합니다 잘라내기 + 폐기 + 스태시 & 재적용 서브모듈 초기화 해제 로컬 변경 사항이 있어도 강제로 초기화 해제합니다. 서브모듈: diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml index 97218f93..6c738cc0 100644 --- a/src/Resources/Locales/pt_BR.axaml +++ b/src/Resources/Locales/pt_BR.axaml @@ -220,6 +220,9 @@ leve Pressione Ctrl para iniciar diretamente Recortar + Descartar + Nada + Stash & Reaplicar Excluir Branch Branch: Você está prestes a excluir uma branch remota!!! diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index 629ac59d..d642c4ef 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -325,6 +325,9 @@ Простой Удерживайте Ctrl, чтобы сразу начать Вырезать + Отклонить + Ничего не делать + Отложить и примненить повторно Удалить подмодуль Принудительно удалить даже если содержит локальные изменения. Подмодуль: diff --git a/src/Resources/Locales/ta_IN.axaml b/src/Resources/Locales/ta_IN.axaml index e2dd7900..0e607ab3 100644 --- a/src/Resources/Locales/ta_IN.axaml +++ b/src/Resources/Locales/ta_IN.axaml @@ -201,6 +201,8 @@ குறைந்தஎடை நேரடியாகத் தொடங்க கட்டுப்பாட்டை அழுத்திப் பிடி வெட்டு + நிராகரி + பதுக்கிவை & மீண்டும் இடு கிளையை நீக்கு கிளை: நீங்கள் ஒரு தொலை கிளையை நீக்கப் போகிறீர்கள்!!! diff --git a/src/Resources/Locales/uk_UA.axaml b/src/Resources/Locales/uk_UA.axaml index 2ba6c0ee..af0d82d8 100644 --- a/src/Resources/Locales/uk_UA.axaml +++ b/src/Resources/Locales/uk_UA.axaml @@ -205,6 +205,8 @@ легкий Утримуйте Ctrl для запуску без діалогу Вирізати + Скасувати + Сховати та Застосувати Видалити гілку Гілка: Ви збираєтеся видалити віддалену гілку!!! diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 3f1b8c55..1f0041da 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -325,6 +325,9 @@ 轻量标签 按住Ctrl键点击将以默认参数运行 剪切 + 丢弃更改 + 不做处理 + 贮藏并自动恢复 取消初始化子模块 强制取消,即使包含本地变更 子模块 : diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index e347950e..b959405b 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -325,6 +325,9 @@ 輕量標籤 按住 Ctrl 鍵將直接以預設參數執行 剪下 + 捨棄變更 + 不做處理 + 擱置變更並自動復原 取消初始化子模組 強制取消,即使包含本機變更 子模組: diff --git a/src/ViewModels/Checkout.cs b/src/ViewModels/Checkout.cs index aca5cb1e..d2fc39b9 100644 --- a/src/ViewModels/Checkout.cs +++ b/src/ViewModels/Checkout.cs @@ -9,7 +9,7 @@ namespace SourceGit.ViewModels get => _branch.Name; } - public bool DiscardLocalChanges + public Models.DealWithLocalChanges DealWithLocalChanges { get; set; @@ -19,7 +19,7 @@ namespace SourceGit.ViewModels { _repo = repo; _branch = branch; - DiscardLocalChanges = false; + DealWithLocalChanges = Models.DealWithLocalChanges.DoNothing; } public override async Task Sure() @@ -46,7 +46,13 @@ namespace SourceGit.ViewModels var succ = false; var needPopStash = false; - if (!DiscardLocalChanges) + if (DealWithLocalChanges == Models.DealWithLocalChanges.DoNothing) + { + succ = await new Commands.Checkout(_repo.FullPath) + .Use(log) + .BranchAsync(branchName, false); + } + else if (DealWithLocalChanges == Models.DealWithLocalChanges.StashAndReapply) { var changes = await new Commands.CountLocalChanges(_repo.FullPath, false).GetResultAsync(); if (changes > 0) @@ -57,16 +63,23 @@ namespace SourceGit.ViewModels if (!succ) { log.Complete(); + _repo.MarkWorkingCopyDirtyManually(); return false; } needPopStash = true; } - } - succ = await new Commands.Checkout(_repo.FullPath) - .Use(log) - .BranchAsync(branchName, DiscardLocalChanges); + succ = await new Commands.Checkout(_repo.FullPath) + .Use(log) + .BranchAsync(branchName, false); + } + else + { + succ = await new Commands.Checkout(_repo.FullPath) + .Use(log) + .BranchAsync(branchName, true); + } if (succ) { diff --git a/src/ViewModels/CheckoutAndFastForward.cs b/src/ViewModels/CheckoutAndFastForward.cs index 120d6c4a..c80a9a8a 100644 --- a/src/ViewModels/CheckoutAndFastForward.cs +++ b/src/ViewModels/CheckoutAndFastForward.cs @@ -14,7 +14,7 @@ namespace SourceGit.ViewModels get; } - public bool DiscardLocalChanges + public Models.DealWithLocalChanges DealWithLocalChanges { get; set; @@ -25,6 +25,7 @@ namespace SourceGit.ViewModels _repo = repo; LocalBranch = localBranch; RemoteBranch = remoteBranch; + DealWithLocalChanges = Models.DealWithLocalChanges.DoNothing; } public override async Task Sure() @@ -50,7 +51,13 @@ namespace SourceGit.ViewModels var succ = false; var needPopStash = false; - if (!DiscardLocalChanges) + if (DealWithLocalChanges == Models.DealWithLocalChanges.DoNothing) + { + succ = await new Commands.Checkout(_repo.FullPath) + .Use(log) + .BranchAsync(LocalBranch.Name, RemoteBranch.Head, false, true); + } + else if (DealWithLocalChanges == Models.DealWithLocalChanges.StashAndReapply) { var changes = await new Commands.CountLocalChanges(_repo.FullPath, false).GetResultAsync(); if (changes > 0) @@ -61,16 +68,23 @@ namespace SourceGit.ViewModels if (!succ) { log.Complete(); + _repo.MarkWorkingCopyDirtyManually(); return false; } needPopStash = true; } - } - succ = await new Commands.Checkout(_repo.FullPath) - .Use(log) - .BranchAsync(LocalBranch.Name, RemoteBranch.Head, DiscardLocalChanges, true); + succ = await new Commands.Checkout(_repo.FullPath) + .Use(log) + .BranchAsync(LocalBranch.Name, RemoteBranch.Head, false, true); + } + else + { + succ = await new Commands.Checkout(_repo.FullPath) + .Use(log) + .BranchAsync(LocalBranch.Name, RemoteBranch.Head, true, true); + } if (succ) { diff --git a/src/ViewModels/CheckoutCommit.cs b/src/ViewModels/CheckoutCommit.cs index d631f5f0..c8179c23 100644 --- a/src/ViewModels/CheckoutCommit.cs +++ b/src/ViewModels/CheckoutCommit.cs @@ -9,7 +9,7 @@ namespace SourceGit.ViewModels get; } - public bool DiscardLocalChanges + public Models.DealWithLocalChanges DealWithLocalChanges { get; set; @@ -19,7 +19,7 @@ namespace SourceGit.ViewModels { _repo = repo; Commit = commit; - DiscardLocalChanges = false; + DealWithLocalChanges = Models.DealWithLocalChanges.DoNothing; } public override async Task Sure() @@ -45,7 +45,13 @@ namespace SourceGit.ViewModels var succ = false; var needPop = false; - if (!DiscardLocalChanges) + if (DealWithLocalChanges == Models.DealWithLocalChanges.DoNothing) + { + succ = await new Commands.Checkout(_repo.FullPath) + .Use(log) + .CommitAsync(Commit.SHA, false); + } + else if (DealWithLocalChanges == Models.DealWithLocalChanges.StashAndReapply) { var changes = await new Commands.CountLocalChanges(_repo.FullPath, false).GetResultAsync(); if (changes > 0) @@ -56,16 +62,23 @@ namespace SourceGit.ViewModels if (!succ) { log.Complete(); + _repo.MarkWorkingCopyDirtyManually(); return false; } needPop = true; } - } - succ = await new Commands.Checkout(_repo.FullPath) - .Use(log) - .CommitAsync(Commit.SHA, DiscardLocalChanges); + succ = await new Commands.Checkout(_repo.FullPath) + .Use(log) + .CommitAsync(Commit.SHA, false); + } + else + { + succ = await new Commands.Checkout(_repo.FullPath) + .Use(log) + .CommitAsync(Commit.SHA, true); + } if (succ) { diff --git a/src/ViewModels/CreateBranch.cs b/src/ViewModels/CreateBranch.cs index 832f5626..8060f20f 100644 --- a/src/ViewModels/CreateBranch.cs +++ b/src/ViewModels/CreateBranch.cs @@ -20,7 +20,12 @@ namespace SourceGit.ViewModels get; } - public bool DiscardLocalChanges + public bool HasLocalChanges + { + get => _repo.LocalChangesCount > 0; + } + + public Models.DealWithLocalChanges DealWithLocalChanges { get; set; @@ -35,6 +40,7 @@ namespace SourceGit.ViewModels { _repo.UIStates.CheckoutBranchOnCreateBranch = value; OnPropertyChanged(); + UpdateOverrideTip(); } } } @@ -44,6 +50,12 @@ namespace SourceGit.ViewModels get => _repo.IsBare; } + public string OverrideTip + { + get => _overrideTip; + private set => SetProperty(ref _overrideTip, value); + } + public bool AllowOverwrite { get => _allowOverwrite; @@ -65,7 +77,8 @@ namespace SourceGit.ViewModels Name = branch.Name; BasedOn = branch; - DiscardLocalChanges = false; + DealWithLocalChanges = Models.DealWithLocalChanges.DoNothing; + UpdateOverrideTip(); } public CreateBranch(Repository repo, Models.Commit commit) @@ -76,7 +89,8 @@ namespace SourceGit.ViewModels _head = commit.SHA; BasedOn = commit; - DiscardLocalChanges = false; + DealWithLocalChanges = Models.DealWithLocalChanges.DoNothing; + UpdateOverrideTip(); } public CreateBranch(Repository repo, Models.Tag tag) @@ -87,7 +101,8 @@ namespace SourceGit.ViewModels _head = tag.SHA; BasedOn = tag; - DiscardLocalChanges = false; + DealWithLocalChanges = Models.DealWithLocalChanges.DoNothing; + UpdateOverrideTip(); } public static ValidationResult ValidateBranchName(string name, ValidationContext ctx) @@ -144,7 +159,13 @@ namespace SourceGit.ViewModels if (CheckoutAfterCreated && !_repo.IsBare) { var needPopStash = false; - if (!DiscardLocalChanges) + if (DealWithLocalChanges == Models.DealWithLocalChanges.DoNothing) + { + succ = await new Commands.Checkout(_repo.FullPath) + .Use(log) + .BranchAsync(_name, _baseOnRevision, false, _allowOverwrite); + } + else if (DealWithLocalChanges == Models.DealWithLocalChanges.StashAndReapply) { var changes = await new Commands.CountLocalChanges(_repo.FullPath, false).GetResultAsync(); if (changes > 0) @@ -155,16 +176,23 @@ namespace SourceGit.ViewModels if (!succ) { log.Complete(); + _repo.MarkWorkingCopyDirtyManually(); return false; } needPopStash = true; } - } - succ = await new Commands.Checkout(_repo.FullPath) - .Use(log) - .BranchAsync(_name, _baseOnRevision, DiscardLocalChanges, _allowOverwrite); + succ = await new Commands.Checkout(_repo.FullPath) + .Use(log) + .BranchAsync(_name, _baseOnRevision, false, _allowOverwrite); + } + else + { + succ = await new Commands.Checkout(_repo.FullPath) + .Use(log) + .BranchAsync(_name, _baseOnRevision, true, _allowOverwrite); + } if (succ) { @@ -205,11 +233,17 @@ namespace SourceGit.ViewModels return true; } + private void UpdateOverrideTip() + { + OverrideTip = CheckoutAfterCreated ? "-B in `git checkout`" : "-f in `git branch`"; + } + private readonly Repository _repo = null; private readonly string _baseOnRevision = null; private readonly ulong _committerDate = 0; private readonly string _head = string.Empty; private string _name = null; + private string _overrideTip = "-B"; private bool _allowOverwrite = false; } } diff --git a/src/ViewModels/Pull.cs b/src/ViewModels/Pull.cs index 09388bc0..4e4fe832 100644 --- a/src/ViewModels/Pull.cs +++ b/src/ViewModels/Pull.cs @@ -38,11 +38,11 @@ namespace SourceGit.ViewModels set => SetProperty(ref _selectedBranch, value, true); } - public bool DiscardLocalChanges + public Models.DealWithLocalChanges DealWithLocalChanges { get; set; - } = false; + } = Models.DealWithLocalChanges.DoNothing; public bool UseRebase { @@ -111,21 +111,26 @@ namespace SourceGit.ViewModels var needPopStash = false; if (changes > 0) { - if (DiscardLocalChanges) + if (DealWithLocalChanges == Models.DealWithLocalChanges.DoNothing) { - await Commands.Discard.AllAsync(_repo.FullPath, false, false, log); + // Do nothing, just let the pull command fail and show the error to user } - else + else if (DealWithLocalChanges == Models.DealWithLocalChanges.StashAndReapply) { var succ = await new Commands.Stash(_repo.FullPath).Use(log).PushAsync("PULL_AUTO_STASH", false); if (!succ) { log.Complete(); + _repo.MarkWorkingCopyDirtyManually(); return false; } needPopStash = true; } + else + { + await Commands.Discard.AllAsync(_repo.FullPath, false, false, log); + } } bool rs = await new Commands.Pull( diff --git a/src/Views/Checkout.axaml b/src/Views/Checkout.axaml index 26fafe81..7d3d12b1 100644 --- a/src/Views/Checkout.axaml +++ b/src/Views/Checkout.axaml @@ -3,6 +3,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vm="using:SourceGit.ViewModels" + xmlns:v="using:SourceGit.Views" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="SourceGit.Views.Checkout" x:DataType="vm:Checkout"> @@ -33,18 +34,15 @@ - - - - - + + + + diff --git a/src/Views/CheckoutAndFastForward.axaml b/src/Views/CheckoutAndFastForward.axaml index 13c12d33..1a4381df 100644 --- a/src/Views/CheckoutAndFastForward.axaml +++ b/src/Views/CheckoutAndFastForward.axaml @@ -3,6 +3,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vm="using:SourceGit.ViewModels" + xmlns:v="using:SourceGit.Views" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="SourceGit.Views.CheckoutAndFastForward" x:DataType="vm:CheckoutAndFastForward"> @@ -55,18 +56,15 @@ - - - - - + + + + diff --git a/src/Views/CheckoutCommit.axaml b/src/Views/CheckoutCommit.axaml index 3315a861..3b60aa31 100644 --- a/src/Views/CheckoutCommit.axaml +++ b/src/Views/CheckoutCommit.axaml @@ -3,7 +3,8 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vm="using:SourceGit.ViewModels" - xmlns:c="clr-namespace:SourceGit.Converters" + xmlns:v="using:SourceGit.Views" + xmlns:c="using:SourceGit.Converters" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="SourceGit.Views.CheckoutCommit" x:DataType="vm:CheckoutCommit"> @@ -35,18 +36,15 @@ - - - - - + + + + - - - - - - + + + + + + + + + + + + + + + + + ToolTip.Tip="{Binding OverrideTip, Mode=OneWay}"/> + + + + + + diff --git a/src/Views/DealWithLocalChangesMethod.axaml.cs b/src/Views/DealWithLocalChangesMethod.axaml.cs new file mode 100644 index 00000000..bd12c1de --- /dev/null +++ b/src/Views/DealWithLocalChangesMethod.axaml.cs @@ -0,0 +1,56 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Interactivity; + +namespace SourceGit.Views +{ + public partial class DealWithLocalChangesMethod : UserControl + { + public static readonly StyledProperty MethodProperty = + AvaloniaProperty.Register(nameof(Method), Models.DealWithLocalChanges.DoNothing); + + public Models.DealWithLocalChanges Method + { + get => GetValue(MethodProperty); + set => SetValue(MethodProperty, value); + } + + public DealWithLocalChangesMethod() + { + InitializeComponent(); + UpdateRadioButtons(); + } + + private void OnRadioButtonClicked(object sender, RoutedEventArgs e) + { + if (sender is RadioButton { Tag: Models.DealWithLocalChanges way }) + { + Method = way; + UpdateRadioButtons(); + e.Handled = true; + } + } + + private void UpdateRadioButtons() + { + switch (Method) + { + case Models.DealWithLocalChanges.DoNothing: + RadioDoNothing.IsChecked = true; + RadioStashAndReapply.IsChecked = false; + RadioDiscard.IsChecked = false; + break; + case Models.DealWithLocalChanges.StashAndReapply: + RadioDoNothing.IsChecked = false; + RadioStashAndReapply.IsChecked = true; + RadioDiscard.IsChecked = false; + break; + default: + RadioDoNothing.IsChecked = false; + RadioStashAndReapply.IsChecked = false; + RadioDiscard.IsChecked = true; + break; + } + } + } +} diff --git a/src/Views/Pull.axaml b/src/Views/Pull.axaml index b09f280f..19246f86 100644 --- a/src/Views/Pull.axaml +++ b/src/Views/Pull.axaml @@ -4,6 +4,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:m="using:SourceGit.Models" xmlns:vm="using:SourceGit.ViewModels" + xmlns:v="using:SourceGit.Views" mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450" x:Class="SourceGit.Views.Pull" x:DataType="vm:Pull"> @@ -78,18 +79,15 @@ - - - - - + + + +