diff --git a/src/Models/DealWithLocalChanges.cs b/src/Models/DealWithLocalChanges.cs new file mode 100644 index 00000000..82609642 --- /dev/null +++ b/src/Models/DealWithLocalChanges.cs @@ -0,0 +1,9 @@ +namespace SourceGit.Models +{ + public enum DealWithLocalChanges + { + StashAndReaply, + Discard, + DoNothing, + } +} diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index d580b82b..d302b4e4 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -61,8 +61,9 @@ Commit : Branch : Local Changes : - Stash & Reapply Discard + Do Nothing + Stash & Reapply Cherry-Pick This Commit Commit : Commit all changes @@ -118,8 +119,8 @@ Check out after created Local Changes : Discard - Stash & Reapply Do Nothing + Stash & Reapply New Branch Name : Enter branch name. Create Local Branch @@ -320,9 +321,12 @@ Input path for merge tool Merger Pull - Stash & reapply local changes Branch : Into : + Local Changes : + Discard + Do Nothing + Stash & Reapply Remote : Pull (Fetch & Merge) Use rebase instead of merge diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 12ec9409..6c288f7c 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -61,8 +61,9 @@ 提交 : 目标分支 : 未提交更改 : - 贮藏(stash)并自动恢复 - 忽略 + 丢弃更改 + 不做处理 + 贮藏并自动恢复 挑选(cherry-pick)此提交 提交ID : 提交变化 @@ -117,9 +118,9 @@ 新分支基于 : 完成后切换到新分支 未提交更改 : - 放弃所有 + 丢弃更改 + 不做处理 贮藏并自动恢复 - GIT默认 新分支名 : 填写分支名称。 创建本地分支 @@ -320,9 +321,12 @@ 填写工具可执行文件所在位置 工具 拉回(pull) - 自动贮藏并恢复本地变更 拉取分支 : 本地分支 : + 未提交更改 : + 丢弃更改 + 不做处理 + 贮藏并自动恢复 远程 : 拉回(拉取并合并) 使用变基方式合并分支 diff --git a/src/ViewModels/Checkout.cs b/src/ViewModels/Checkout.cs index 82f97c96..ade6d2f8 100644 --- a/src/ViewModels/Checkout.cs +++ b/src/ViewModels/Checkout.cs @@ -10,10 +10,10 @@ namespace SourceGit.ViewModels private set; } - public bool AutoStash + public Models.DealWithLocalChanges PreAction { - get => _autoStash; - set => SetProperty(ref _autoStash, value); + get => _preAction; + set => SetProperty(ref _preAction, value); } public Checkout(Repository repo, string branch) @@ -34,7 +34,7 @@ namespace SourceGit.ViewModels var needPopStash = false; if (hasLocalChanges) { - if (AutoStash) + if (_preAction == Models.DealWithLocalChanges.StashAndReaply) { SetProgressDescription("Adding untracked changes ..."); var succ = new Commands.Add(_repo.FullPath).Exec(); @@ -52,7 +52,7 @@ namespace SourceGit.ViewModels needPopStash = true; } - else + else if (_preAction == Models.DealWithLocalChanges.Discard) { SetProgressDescription("Discard local changes ..."); Commands.Discard.All(_repo.FullPath); @@ -78,6 +78,6 @@ namespace SourceGit.ViewModels } private readonly Repository _repo = null; - private bool _autoStash = true; + private Models.DealWithLocalChanges _preAction = Models.DealWithLocalChanges.StashAndReaply; } } diff --git a/src/ViewModels/CreateBranch.cs b/src/ViewModels/CreateBranch.cs index c6bc43c9..57cc9aff 100644 --- a/src/ViewModels/CreateBranch.cs +++ b/src/ViewModels/CreateBranch.cs @@ -2,14 +2,7 @@ using System.Threading.Tasks; namespace SourceGit.ViewModels -{ - public enum BeforeCreateBranchAction - { - StashAndReaply, - Discard, - DoNothing, - } - +{ public class CreateBranch : Popup { [Required(ErrorMessage = "Branch name is required!")] @@ -27,7 +20,7 @@ namespace SourceGit.ViewModels private set; } - public BeforeCreateBranchAction PreAction + public Models.DealWithLocalChanges PreAction { get => _preAction; set => SetProperty(ref _preAction, value); @@ -97,7 +90,7 @@ namespace SourceGit.ViewModels bool needPopStash = false; if (_repo.WorkingCopyChangesCount > 0) { - if (_preAction == BeforeCreateBranchAction.StashAndReaply) + if (_preAction == Models.DealWithLocalChanges.StashAndReaply) { SetProgressDescription("Adding untracked changes..."); var succ = new Commands.Add(_repo.FullPath).Exec(); @@ -115,7 +108,7 @@ namespace SourceGit.ViewModels needPopStash = true; } - else if (_preAction == BeforeCreateBranchAction.Discard) + else if (_preAction == Models.DealWithLocalChanges.Discard) { SetProgressDescription("Discard local changes..."); Commands.Discard.All(_repo.FullPath); @@ -144,6 +137,6 @@ namespace SourceGit.ViewModels private readonly Repository _repo = null; private string _name = null; private readonly string _baseOnRevision = null; - private BeforeCreateBranchAction _preAction = BeforeCreateBranchAction.StashAndReaply; + private Models.DealWithLocalChanges _preAction = Models.DealWithLocalChanges.StashAndReaply; } } diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs index d759126c..bba8f901 100644 --- a/src/ViewModels/Histories.cs +++ b/src/ViewModels/Histories.cs @@ -513,7 +513,7 @@ namespace SourceGit.ViewModels checkout.Icon = App.CreateMenuIcon("Icons.Check"); checkout.Click += (o, e) => { - _repo.CheckoutLocalBranch(branch.Name); + _repo.CheckoutBranch(branch); e.Handled = true; }; submenu.Items.Add(checkout); @@ -585,20 +585,7 @@ namespace SourceGit.ViewModels checkout.Icon = App.CreateMenuIcon("Icons.Check"); checkout.Click += (o, e) => { - foreach (var b in _repo.Branches) - { - if (b.IsLocal && b.Upstream == branch.FullName) - { - if (!b.IsCurrent) - _repo.CheckoutLocalBranch(b.Name); - - return; - } - } - - if (PopupHost.CanCreatePopup()) - PopupHost.ShowPopup(new CreateBranch(_repo, branch)); - + _repo.CheckoutBranch(branch); e.Handled = true; }; submenu.Items.Add(checkout); diff --git a/src/ViewModels/Pull.cs b/src/ViewModels/Pull.cs index 6461e1b3..86987895 100644 --- a/src/ViewModels/Pull.cs +++ b/src/ViewModels/Pull.cs @@ -47,13 +47,13 @@ namespace SourceGit.ViewModels set => SetProperty(ref _selectedBranch, value); } - public bool UseRebase + public Models.DealWithLocalChanges PreAction { - get; - set; - } = true; + get => _preAction; + set => SetProperty(ref _preAction, value); + } - public bool AutoStash + public bool UseRebase { get; set; @@ -117,23 +117,31 @@ namespace SourceGit.ViewModels return Task.Run(() => { var needPopStash = false; - if (AutoStash && _repo.WorkingCopyChangesCount > 0) + if (_repo.WorkingCopyChangesCount > 0) { - SetProgressDescription("Adding untracked changes..."); - var succ = new Commands.Add(_repo.FullPath).Exec(); - if (succ) + if (_preAction == Models.DealWithLocalChanges.StashAndReaply) { - SetProgressDescription("Stash local changes..."); - succ = new Commands.Stash(_repo.FullPath).Push("PULL_AUTO_STASH"); - } + 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("PULL_AUTO_STASH"); + } - if (!succ) + if (!succ) + { + CallUIThread(() => _repo.SetWatcherEnabled(true)); + return false; + } + + needPopStash = true; + } + else if (_preAction == Models.DealWithLocalChanges.Discard) { - CallUIThread(() => _repo.SetWatcherEnabled(true)); - return false; + SetProgressDescription("Discard local changes ..."); + Commands.Discard.All(_repo.FullPath); } - - needPopStash = true; } SetProgressDescription($"Pull {_selectedRemote.Name}/{_selectedBranch.Name}..."); @@ -154,5 +162,6 @@ namespace SourceGit.ViewModels private Models.Remote _selectedRemote = null; private List _remoteBranches = null; private Models.Branch _selectedBranch = null; + private Models.DealWithLocalChanges _preAction = Models.DealWithLocalChanges.StashAndReaply; } } diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index df9b3f47..93f29c2a 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -711,17 +711,35 @@ namespace SourceGit.ViewModels PopupHost.ShowPopup(new CreateBranch(this, current)); } - public void CheckoutLocalBranch(string branch) + public void CheckoutBranch(Models.Branch branch) { if (!PopupHost.CanCreatePopup()) return; - if (WorkingCopyChangesCount > 0) - PopupHost.ShowPopup(new Checkout(this, branch)); + if (branch.IsLocal) + { + if (WorkingCopyChangesCount > 0) + PopupHost.ShowPopup(new Checkout(this, branch.Name)); + else + PopupHost.ShowAndStartPopup(new Checkout(this, branch.Name)); + } else - PopupHost.ShowAndStartPopup(new Checkout(this, branch)); + { + foreach (var b in Branches) + { + if (b.IsLocal && b.Upstream == branch.FullName) + { + if (!b.IsCurrent) + CheckoutBranch(b); + + return; + } + } + + PopupHost.ShowPopup(new CreateBranch(this, branch)); + } } - + public void DeleteMultipleBranches(List branches, bool isLocal) { if (PopupHost.CanCreatePopup()) @@ -880,7 +898,7 @@ namespace SourceGit.ViewModels checkout.Icon = App.CreateMenuIcon("Icons.Check"); checkout.Click += (o, e) => { - CheckoutLocalBranch(branch.Name); + CheckoutBranch(branch); e.Handled = true; }; menu.Items.Add(checkout); @@ -1182,20 +1200,7 @@ namespace SourceGit.ViewModels checkout.Icon = App.CreateMenuIcon("Icons.Check"); checkout.Click += (o, e) => { - foreach (var b in Branches) - { - if (b.IsLocal && b.Upstream == branch.FullName) - { - if (b.IsCurrent) - return; - if (PopupHost.CanCreatePopup()) - PopupHost.ShowAndStartPopup(new Checkout(this, b.Name)); - return; - } - } - - if (PopupHost.CanCreatePopup()) - PopupHost.ShowPopup(new CreateBranch(this, branch)); + CheckoutBranch(branch); e.Handled = true; }; menu.Items.Add(checkout); diff --git a/src/Views/Checkout.axaml b/src/Views/Checkout.axaml index 5974db46..501b3de0 100644 --- a/src/Views/Checkout.axaml +++ b/src/Views/Checkout.axaml @@ -2,7 +2,9 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:m="using:SourceGit.Models" xmlns:vm="using:SourceGit.ViewModels" + xmlns:ac="using:Avalonia.Controls.Converters" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="SourceGit.Views.Checkout" x:DataType="vm:Checkout"> @@ -11,7 +13,7 @@ Classes="bold" Text="{DynamicResource Text.Checkout}"/> - + - + + + + - + + Margin="8,0,0,0" + IsChecked="{Binding PreAction, Mode=TwoWay, Converter={StaticResource EnumToBoolConverter}, ConverterParameter={x:Static m:DealWithLocalChanges.Discard}}"/> + diff --git a/src/Views/CreateBranch.axaml b/src/Views/CreateBranch.axaml index 5fa0b237..b8d5a1d0 100644 --- a/src/Views/CreateBranch.axaml +++ b/src/Views/CreateBranch.axaml @@ -14,7 +14,7 @@ - + + IsChecked="{Binding PreAction, Mode=TwoWay, Converter={StaticResource EnumToBoolConverter}, ConverterParameter={x:Static m:DealWithLocalChanges.StashAndReaply}}"/> + IsChecked="{Binding PreAction, Mode=TwoWay, Converter={StaticResource EnumToBoolConverter}, ConverterParameter={x:Static m:DealWithLocalChanges.Discard}}"/> + IsChecked="{Binding PreAction, Mode=TwoWay, Converter={StaticResource EnumToBoolConverter}, ConverterParameter={x:Static m:DealWithLocalChanges.DoNothing}}"/> @@ -12,7 +13,7 @@ - + - + - + + + + + + + + + + + Content="{DynamicResource Text.Pull.UseRebase}" + IsChecked="{Binding UseRebase, Mode=TwoWay}"/> diff --git a/src/Views/Repository.axaml b/src/Views/Repository.axaml index b06cf587..09129811 100644 --- a/src/Views/Repository.axaml +++ b/src/Views/Repository.axaml @@ -22,7 +22,7 @@ - @@ -222,7 +222,7 @@ - + @@ -287,7 +287,7 @@ - + diff --git a/src/Views/Repository.axaml.cs b/src/Views/Repository.axaml.cs index ed26905a..8b66ceb9 100644 --- a/src/Views/Repository.axaml.cs +++ b/src/Views/Repository.axaml.cs @@ -63,7 +63,7 @@ namespace SourceGit.Views InitializeComponent(); } - private void OnOpenWithExternalTools(object sender, RoutedEventArgs e) + private void OpenWithExternalTools(object sender, RoutedEventArgs e) { if (sender is Button button && DataContext is ViewModels.Repository repo) { @@ -73,6 +73,58 @@ namespace SourceGit.Views } } + private void OpenGitFlowMenu(object sender, RoutedEventArgs e) + { + if (DataContext is ViewModels.Repository repo) + { + var menu = repo.CreateContextMenuForGitFlow(); + (sender as Control)?.OpenContextMenu(menu); + } + + e.Handled = true; + } + + private async void OpenStatistics(object sender, RoutedEventArgs e) + { + if (DataContext is ViewModels.Repository repo) + { + var dialog = new Statistics() { DataContext = new ViewModels.Statistics(repo.FullPath) }; + await dialog.ShowDialog(TopLevel.GetTopLevel(this) as Window); + e.Handled = true; + } + } + + private void OnSearchCommitPanelPropertyChanged(object sender, AvaloniaPropertyChangedEventArgs e) + { + var grid = sender as Grid; + if (e.Property == IsVisibleProperty && grid.IsVisible) + txtSearchCommitsBox.Focus(); + } + + private void OnSearchKeyDown(object sender, KeyEventArgs e) + { + if (e.Key == Key.Enter) + { + if (DataContext is ViewModels.Repository repo) + repo.StartSearchCommits(); + + e.Handled = true; + } + } + + private void OnSearchResultDataGridSelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (sender is DataGrid datagrid && datagrid.SelectedItem != null) + { + if (DataContext is ViewModels.Repository repo) + { + var commit = datagrid.SelectedItem as Models.Commit; + repo.NavigateToCommit(commit.SHA); + } + } + e.Handled = true; + } + private void OnLocalBranchTreeSelectionChanged(object sender, SelectionChangedEventArgs e) { if (sender is TreeView tree && tree.SelectedItem != null && DataContext is ViewModels.Repository repo) @@ -113,74 +165,6 @@ namespace SourceGit.Views } } - private void OnTagDataGridSelectionChanged(object sender, SelectionChangedEventArgs e) - { - if (sender is DataGrid datagrid && datagrid.SelectedItem != null) - { - localBranchTree.UnselectAll(); - remoteBranchTree.UnselectAll(); - - var tag = datagrid.SelectedItem as Models.Tag; - if (DataContext is ViewModels.Repository repo) - repo.NavigateToCommit(tag.SHA); - } - } - - private void OnSearchCommitPanelPropertyChanged(object sender, AvaloniaPropertyChangedEventArgs e) - { - var grid = sender as Grid; - if (e.Property == IsVisibleProperty && grid.IsVisible) - txtSearchCommitsBox.Focus(); - } - - private void OnSearchKeyDown(object sender, KeyEventArgs e) - { - if (e.Key == Key.Enter) - { - if (DataContext is ViewModels.Repository repo) - repo.StartSearchCommits(); - - e.Handled = true; - } - } - - private void OnSearchResultDataGridSelectionChanged(object sender, SelectionChangedEventArgs e) - { - if (sender is DataGrid datagrid && datagrid.SelectedItem != null) - { - if (DataContext is ViewModels.Repository repo) - { - var commit = datagrid.SelectedItem as Models.Commit; - repo.NavigateToCommit(commit.SHA); - } - } - e.Handled = true; - } - - private void OnToggleFilter(object sender, RoutedEventArgs e) - { - if (sender is ToggleButton toggle) - { - var filter = string.Empty; - if (toggle.DataContext is ViewModels.BranchTreeNode node) - { - if (node.IsBranch) - filter = (node.Backend as Models.Branch).FullName; - } - else if (toggle.DataContext is Models.Tag tag) - { - filter = tag.Name; - } - - if (!string.IsNullOrEmpty(filter) && DataContext is ViewModels.Repository repo) - { - repo.UpdateFilter(filter, toggle.IsChecked == true); - } - } - - e.Handled = true; - } - private void OnLocalBranchContextMenuRequested(object sender, ContextRequestedEventArgs e) { remoteBranchTree.UnselectAll(); @@ -193,11 +177,11 @@ namespace SourceGit.Views e.Handled = true; return; } - + var branches = new List(); foreach (var item in tree.SelectedItems) CollectBranchesFromNode(branches, item as ViewModels.BranchTreeNode); - + if (branches.Count == 1) { var item = (e.Source as Control)?.FindAncestorOfType(true); @@ -229,7 +213,7 @@ namespace SourceGit.Views { localBranchTree.UnselectAll(); tagsList.SelectedItem = null; - + var repo = DataContext as ViewModels.Repository; var tree = sender as TreeView; if (tree.SelectedItems.Count == 0) @@ -249,12 +233,12 @@ namespace SourceGit.Views var menu = repo.CreateContextMenuForRemote(node.Backend as Models.Remote); item.OpenContextMenu(menu); } - + e.Handled = true; return; } } - + var branches = new List(); foreach (var item in tree.SelectedItems) CollectBranchesFromNode(branches, item as ViewModels.BranchTreeNode); @@ -286,6 +270,39 @@ namespace SourceGit.Views e.Handled = true; } + private void OnDoubleTappedBranchNode(object sender, TappedEventArgs e) + { + if (!ViewModels.PopupHost.CanCreatePopup()) + return; + + if (sender is Grid grid && DataContext is ViewModels.Repository repo) + { + var node = grid.DataContext as ViewModels.BranchTreeNode; + if (node != null && node.IsBranch) + { + var branch = node.Backend as Models.Branch; + if (branch.IsCurrent) + return; + + repo.CheckoutBranch(branch); + e.Handled = true; + } + } + } + + private void OnTagDataGridSelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (sender is DataGrid datagrid && datagrid.SelectedItem != null) + { + localBranchTree.UnselectAll(); + remoteBranchTree.UnselectAll(); + + var tag = datagrid.SelectedItem as Models.Tag; + if (DataContext is ViewModels.Repository repo) + repo.NavigateToCommit(tag.SHA); + } + } + private void OnTagContextRequested(object sender, ContextRequestedEventArgs e) { if (sender is DataGrid datagrid && datagrid.SelectedItem != null && DataContext is ViewModels.Repository repo) @@ -298,6 +315,30 @@ namespace SourceGit.Views e.Handled = true; } + private void OnToggleFilter(object sender, RoutedEventArgs e) + { + if (sender is ToggleButton toggle) + { + var filter = string.Empty; + if (toggle.DataContext is ViewModels.BranchTreeNode node) + { + if (node.IsBranch) + filter = (node.Backend as Models.Branch).FullName; + } + else if (toggle.DataContext is Models.Tag tag) + { + filter = tag.Name; + } + + if (!string.IsNullOrEmpty(filter) && DataContext is ViewModels.Repository repo) + { + repo.UpdateFilter(filter, toggle.IsChecked == true); + } + } + + e.Handled = true; + } + private void OnSubmoduleContextRequested(object sender, ContextRequestedEventArgs e) { if (sender is DataGrid datagrid && datagrid.SelectedItem != null && DataContext is ViewModels.Repository repo) @@ -310,17 +351,6 @@ namespace SourceGit.Views e.Handled = true; } - private void OpenGitFlowMenu(object sender, RoutedEventArgs e) - { - if (DataContext is ViewModels.Repository repo) - { - var menu = repo.CreateContextMenuForGitFlow(); - (sender as Control)?.OpenContextMenu(menu); - } - - e.Handled = true; - } - private async void UpdateSubmodules(object sender, RoutedEventArgs e) { if (DataContext is ViewModels.Repository repo) @@ -334,36 +364,6 @@ namespace SourceGit.Views e.Handled = true; } - - private void OnDoubleTappedLocalBranchNode(object sender, TappedEventArgs e) - { - if (!ViewModels.PopupHost.CanCreatePopup()) - return; - - if (sender is Grid grid && DataContext is ViewModels.Repository repo) - { - var node = grid.DataContext as ViewModels.BranchTreeNode; - if (node != null && node.IsBranch) - { - var branch = node.Backend as Models.Branch; - if (branch.IsCurrent) - return; - - repo.CheckoutLocalBranch(branch.Name); - e.Handled = true; - } - } - } - - private async void OpenStatistics(object sender, RoutedEventArgs e) - { - if (DataContext is ViewModels.Repository repo) - { - var dialog = new Statistics() { DataContext = new ViewModels.Statistics(repo.FullPath) }; - await dialog.ShowDialog(TopLevel.GetTopLevel(this) as Window); - e.Handled = true; - } - } private void CollectBranchesFromNode(List outs, ViewModels.BranchTreeNode node) {