From 566f521e7988961d46b7c1ed5df97b24cabba0f4 Mon Sep 17 00:00:00 2001 From: Filippo Ferrario Date: Wed, 10 May 2023 09:19:58 +0200 Subject: [PATCH 01/18] Feature: support local branch checkout --- src/Files.App/Helpers/DynamicDialogFactory.cs | 65 +++++++++++++++++++ src/Files.App/Helpers/GitHelpers.cs | 50 ++++++++++++++ src/Files.App/Strings/en-US/Resources.resw | 15 +++++ .../UserControls/StatusBarControl.xaml | 17 ++++- .../DirectoryPropertiesViewModel.cs | 43 ++++++++++-- src/Files.App/Views/Shells/BaseShellPage.cs | 23 +++++-- src/Files.Backend/Enums/GitCheckoutOptions.cs | 10 +++ 7 files changed, 209 insertions(+), 14 deletions(-) create mode 100644 src/Files.Backend/Enums/GitCheckoutOptions.cs diff --git a/src/Files.App/Helpers/DynamicDialogFactory.cs b/src/Files.App/Helpers/DynamicDialogFactory.cs index 24ec25803493..a49216edebb2 100644 --- a/src/Files.App/Helpers/DynamicDialogFactory.cs +++ b/src/Files.App/Helpers/DynamicDialogFactory.cs @@ -224,5 +224,70 @@ public static DynamicDialog GetFor_CredentialEntryDialog(string path) return dialog; } + + public static DynamicDialog GetFor_GitCheckoutConflicts() + { + DynamicDialog dialog = null!; + + var bringChangesRadio = new RadioButton() + { + Content = "BringChanges".GetLocalizedResource(), + IsChecked = true, + }; + var stashChangesRadio = new RadioButton() + { + Content = "StashChanges".GetLocalizedResource(), + }; + var discardChangesRadio = new RadioButton() + { + Content = "DiscardChanges".GetLocalizedResource(), + }; + + bringChangesRadio.Checked += (button, args) => + { + dialog.ViewModel.AdditionalData = GitCheckoutOptions.BringChanges; + }; + stashChangesRadio.Checked += (button, args) => + { + dialog.ViewModel.AdditionalData = GitCheckoutOptions.StashChanges; + }; + discardChangesRadio.Checked += (button, args) => + { + dialog.ViewModel.AdditionalData = GitCheckoutOptions.DiscardChanges; + }; + + dialog = new DynamicDialog(new DynamicDialogViewModel() + { + TitleText = "UncommitedChanges".GetLocalizedResource(), + PrimaryButtonText = "OK".GetLocalizedResource(), + CloseButtonText = "Cancel".GetLocalizedResource(), + SubtitleText = "UncommitedChangesMessage".GetLocalizedResource(), + DisplayControl = new Grid() + { + MinWidth = 250d, + Children = + { + new StackPanel() + { + Spacing = 10d, + Children = + { + bringChangesRadio, + stashChangesRadio, + discardChangesRadio + } + } + } + }, + AdditionalData = GitCheckoutOptions.BringChanges, + CloseButtonAction = (vm, e) => + { + dialog.ViewModel.AdditionalData = GitCheckoutOptions.None; + vm.HideDialog(); + } + }); + + return dialog; + } } } diff --git a/src/Files.App/Helpers/GitHelpers.cs b/src/Files.App/Helpers/GitHelpers.cs index e97886564729..d4abeccf09a5 100644 --- a/src/Files.App/Helpers/GitHelpers.cs +++ b/src/Files.App/Helpers/GitHelpers.cs @@ -3,6 +3,7 @@ using LibGit2Sharp; using Files.App.Filesystem.StorageItems; +using Windows.Devices.Display.Core; namespace Files.App.Helpers { @@ -32,5 +33,54 @@ public static class GitHelpers return null; } } + + public static string[] GetLocalBranchesNames(string? path) + { + if (string.IsNullOrWhiteSpace(path) || !Repository.IsValid(path)) + return Array.Empty(); + + using var repository = new Repository(path); + return repository.Branches + .Where(b => !b.IsRemote) + .Select(b => b.FriendlyName) + .ToArray(); + } + + public static async Task Checkout(string? repositoryPath, string? branch) + { + if (string.IsNullOrWhiteSpace(repositoryPath) || !Repository.IsValid(repositoryPath)) + return; + + using var repository = new Repository(repositoryPath); + var checkoutBranch = repository.Branches[branch]; + if (checkoutBranch is null) + return; + + var options = new CheckoutOptions(); + + if (repository.RetrieveStatus().IsDirty) + { + var dialog = DynamicDialogFactory.GetFor_GitCheckoutConflicts(); + await dialog.ShowAsync(); + + var resolveConflictOption = (GitCheckoutOptions)dialog.ViewModel.AdditionalData; + + switch (resolveConflictOption) + { + case GitCheckoutOptions.None: + return; + case GitCheckoutOptions.BringChanges: + break; + case GitCheckoutOptions.DiscardChanges: + options.CheckoutModifiers = CheckoutModifiers.Force; + break; + case GitCheckoutOptions.StashChanges: + repository.Stashes.Add(repository.Config.BuildSignature(DateTimeOffset.Now)); + break; + } + } + + LibGit2Sharp.Commands.Checkout(repository, checkoutBranch, options); + } } } diff --git a/src/Files.App/Strings/en-US/Resources.resw b/src/Files.App/Strings/en-US/Resources.resw index a576b494b6a8..11b554c42d91 100644 --- a/src/Files.App/Strings/en-US/Resources.resw +++ b/src/Files.App/Strings/en-US/Resources.resw @@ -3223,4 +3223,19 @@ Unable to display permissions. + + Stash changes + + + Discard changes + + + Bring changes + + + There are uncommited changes on the local branch + + + What do you want to do with them? + \ No newline at end of file diff --git a/src/Files.App/UserControls/StatusBarControl.xaml b/src/Files.App/UserControls/StatusBarControl.xaml index 2576610767ae..278d690c0fb9 100644 --- a/src/Files.App/UserControls/StatusBarControl.xaml +++ b/src/Files.App/UserControls/StatusBarControl.xaml @@ -53,10 +53,23 @@ VerticalAlignment="Center" Orientation="Horizontal" Spacing="8"> - + Background="Transparent" + BorderThickness="0" + Content="{x:Bind DirectoryPropertiesViewModel.GitBranchDisplayName, Mode=OneWay}"> + + + + + + diff --git a/src/Files.App/ViewModels/DirectoryPropertiesViewModel.cs b/src/Files.App/ViewModels/DirectoryPropertiesViewModel.cs index 31602dee97db..36ddae745f67 100644 --- a/src/Files.App/ViewModels/DirectoryPropertiesViewModel.cs +++ b/src/Files.App/ViewModels/DirectoryPropertiesViewModel.cs @@ -5,18 +5,49 @@ namespace Files.App.ViewModels { public class DirectoryPropertiesViewModel : ObservableObject { - private string directoryItemCount; + private int activeBranchIndex; + + private string _DirectoryItemCount; public string DirectoryItemCount { - get => directoryItemCount; - set => SetProperty(ref directoryItemCount, value); + get => _DirectoryItemCount; + set => SetProperty(ref _DirectoryItemCount, value); } - private string? gitBranchDisplayName; + private string? _GitBranchDisplayName; public string? GitBranchDisplayName { - get => gitBranchDisplayName; - set => SetProperty(ref gitBranchDisplayName, value); + get => _GitBranchDisplayName; + private set => SetProperty(ref _GitBranchDisplayName, value); + } + + private int _SelectedBranchIndex; + public int SelectedBranchIndex + { + get => _SelectedBranchIndex; + set + { + if (SetProperty(ref _SelectedBranchIndex, value) && value != -1 && value != activeBranchIndex) + CheckoutRequested?.Invoke(this, BranchesNames[value]); + } + } + + public ObservableCollection BranchesNames { get; } = new(); + + public EventHandler? CheckoutRequested; + + public void UpdateGitInfo(bool isGitRepository, string activeBranch, string[] branches) + { + GitBranchDisplayName = isGitRepository + ? string.Format("Branch".GetLocalizedResource(), activeBranch) + : null; + + BranchesNames.Clear(); + foreach (var name in branches) + BranchesNames.Add(name); + + activeBranchIndex = BranchesNames.IndexOf(activeBranch); + SelectedBranchIndex = activeBranchIndex; } } } diff --git a/src/Files.App/Views/Shells/BaseShellPage.cs b/src/Files.App/Views/Shells/BaseShellPage.cs index 472dad20bb13..7369e28625fe 100644 --- a/src/Files.App/Views/Shells/BaseShellPage.cs +++ b/src/Files.App/Views/Shells/BaseShellPage.cs @@ -75,10 +75,14 @@ public BaseLayout ContentPage { if (value != _ContentPage) { + if (_ContentPage is not null) + _ContentPage.DirectoryPropertiesViewModel.CheckoutRequested -= GitCheckout_Required; + _ContentPage = value; NotifyPropertyChanged(nameof(ContentPage)); NotifyPropertyChanged(nameof(SlimContentPage)); + _ContentPage.DirectoryPropertiesViewModel.CheckoutRequested += GitCheckout_Required; } } } @@ -219,9 +223,10 @@ protected void FilesystemViewModel_DirectoryInfoUpdated(object sender, EventArgs InstanceViewModel.GitRepositoryPath = FilesystemViewModel.GitDirectory; - ContentPage.DirectoryPropertiesViewModel.GitBranchDisplayName = InstanceViewModel.IsGitRepository - ? string.Format("Branch".GetLocalizedResource(), InstanceViewModel.GitBranchName) - : null; + ContentPage.DirectoryPropertiesViewModel.UpdateGitInfo( + InstanceViewModel.IsGitRepository, + InstanceViewModel.GitBranchName, + GitHelpers.GetLocalBranchesNames(InstanceViewModel.GitRepositoryPath)); ContentPage.DirectoryPropertiesViewModel.DirectoryItemCount = $"{FilesystemViewModel.FilesAndFolders.Count} {directoryItemCountLocalization}"; ContentPage.UpdateSelectionSize(); @@ -230,9 +235,15 @@ protected void FilesystemViewModel_DirectoryInfoUpdated(object sender, EventArgs protected void FilesystemViewModel_GitDirectoryUpdated(object sender, EventArgs e) { InstanceViewModel.UpdateCurrentBranchName(); - ContentPage.DirectoryPropertiesViewModel.GitBranchDisplayName = InstanceViewModel.IsGitRepository - ? string.Format("Branch".GetLocalizedResource(), InstanceViewModel.GitBranchName) - : null; + ContentPage.DirectoryPropertiesViewModel.UpdateGitInfo( + InstanceViewModel.IsGitRepository, + InstanceViewModel.GitBranchName, + GitHelpers.GetLocalBranchesNames(InstanceViewModel.GitRepositoryPath)); + } + + protected async void GitCheckout_Required(object? sender, string branchName) + { + await GitHelpers.Checkout(FilesystemViewModel.GitDirectory, branchName); } protected virtual void Page_Loaded(object sender, RoutedEventArgs e) diff --git a/src/Files.Backend/Enums/GitCheckoutOptions.cs b/src/Files.Backend/Enums/GitCheckoutOptions.cs new file mode 100644 index 000000000000..85c070108d17 --- /dev/null +++ b/src/Files.Backend/Enums/GitCheckoutOptions.cs @@ -0,0 +1,10 @@ +namespace Files.Backend.Enums +{ + public enum GitCheckoutOptions + { + None, + BringChanges, + StashChanges, + DiscardChanges + } +} From 942c9ef21d90778b14f628db2180641c42952a43 Mon Sep 17 00:00:00 2001 From: Filippo Ferrario Date: Wed, 10 May 2023 09:47:10 +0200 Subject: [PATCH 02/18] Support Bring Changes --- src/Files.App/Helpers/GitHelpers.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Files.App/Helpers/GitHelpers.cs b/src/Files.App/Helpers/GitHelpers.cs index d4abeccf09a5..d96174cd2df5 100644 --- a/src/Files.App/Helpers/GitHelpers.cs +++ b/src/Files.App/Helpers/GitHelpers.cs @@ -3,7 +3,6 @@ using LibGit2Sharp; using Files.App.Filesystem.StorageItems; -using Windows.Devices.Display.Core; namespace Files.App.Helpers { @@ -57,6 +56,7 @@ public static async Task Checkout(string? repositoryPath, string? branch) return; var options = new CheckoutOptions(); + var isBringingChanges = false; if (repository.RetrieveStatus().IsDirty) { @@ -69,18 +69,25 @@ public static async Task Checkout(string? repositoryPath, string? branch) { case GitCheckoutOptions.None: return; - case GitCheckoutOptions.BringChanges: - break; case GitCheckoutOptions.DiscardChanges: options.CheckoutModifiers = CheckoutModifiers.Force; break; + case GitCheckoutOptions.BringChanges: case GitCheckoutOptions.StashChanges: repository.Stashes.Add(repository.Config.BuildSignature(DateTimeOffset.Now)); + + isBringingChanges = resolveConflictOption is GitCheckoutOptions.BringChanges; break; } } LibGit2Sharp.Commands.Checkout(repository, checkoutBranch, options); + + if (isBringingChanges) + { + var lastStashIndex = repository.Stashes.Count() - 1; + repository.Stashes.Pop(lastStashIndex, new StashApplyOptions()); + } } } } From 540fc613ee176665aeeded4530b94a154e0a48aa Mon Sep 17 00:00:00 2001 From: Filippo Ferrario Date: Wed, 10 May 2023 11:34:06 +0200 Subject: [PATCH 03/18] Popup layout & Make sure the correct branch is selected --- src/Files.App/Strings/en-US/Resources.resw | 3 +++ src/Files.App/UserControls/StatusBarControl.xaml | 16 +++++++++++----- .../UserControls/StatusBarControl.xaml.cs | 11 +++++++++++ .../ViewModels/DirectoryPropertiesViewModel.cs | 8 ++++---- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/Files.App/Strings/en-US/Resources.resw b/src/Files.App/Strings/en-US/Resources.resw index 11b554c42d91..c8869328bad1 100644 --- a/src/Files.App/Strings/en-US/Resources.resw +++ b/src/Files.App/Strings/en-US/Resources.resw @@ -3238,4 +3238,7 @@ What do you want to do with them? + + Branches: + \ No newline at end of file diff --git a/src/Files.App/UserControls/StatusBarControl.xaml b/src/Files.App/UserControls/StatusBarControl.xaml index 278d690c0fb9..5393cda7db0b 100644 --- a/src/Files.App/UserControls/StatusBarControl.xaml +++ b/src/Files.App/UserControls/StatusBarControl.xaml @@ -5,6 +5,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:converters="using:Files.App.Converters" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:helpers="using:Files.App.Helpers" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" d:DesignHeight="32" d:DesignWidth="400" @@ -60,13 +61,18 @@ BorderThickness="0" Content="{x:Bind DirectoryPropertiesViewModel.GitBranchDisplayName, Mode=OneWay}"> - - + + LostFocus="StackPanel_LostFocus" + Spacing="8"> + + + diff --git a/src/Files.App/UserControls/StatusBarControl.xaml.cs b/src/Files.App/UserControls/StatusBarControl.xaml.cs index 2bbce48edc35..28b05dcfa85f 100644 --- a/src/Files.App/UserControls/StatusBarControl.xaml.cs +++ b/src/Files.App/UserControls/StatusBarControl.xaml.cs @@ -4,6 +4,7 @@ using Files.App.ViewModels; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Controls.Primitives; namespace Files.App.UserControls { @@ -42,5 +43,15 @@ public StatusBarControl() { InitializeComponent(); } + + private void Flyout_Opening(object sender, object e) + { + DirectoryPropertiesViewModel.SelectedBranchIndex = DirectoryPropertiesViewModel.ActiveBranchIndex; + } + + private void StackPanel_LostFocus(object sender, RoutedEventArgs e) + { + ((Popup)((FlyoutPresenter)((StackPanel)sender).Parent).Parent).IsOpen = false; + } } } diff --git a/src/Files.App/ViewModels/DirectoryPropertiesViewModel.cs b/src/Files.App/ViewModels/DirectoryPropertiesViewModel.cs index 36ddae745f67..636e25c1f393 100644 --- a/src/Files.App/ViewModels/DirectoryPropertiesViewModel.cs +++ b/src/Files.App/ViewModels/DirectoryPropertiesViewModel.cs @@ -5,7 +5,7 @@ namespace Files.App.ViewModels { public class DirectoryPropertiesViewModel : ObservableObject { - private int activeBranchIndex; + public int ActiveBranchIndex { get; private set; } private string _DirectoryItemCount; public string DirectoryItemCount @@ -27,7 +27,7 @@ public int SelectedBranchIndex get => _SelectedBranchIndex; set { - if (SetProperty(ref _SelectedBranchIndex, value) && value != -1 && value != activeBranchIndex) + if (SetProperty(ref _SelectedBranchIndex, value) && value != -1 && value != ActiveBranchIndex) CheckoutRequested?.Invoke(this, BranchesNames[value]); } } @@ -46,8 +46,8 @@ public void UpdateGitInfo(bool isGitRepository, string activeBranch, string[] br foreach (var name in branches) BranchesNames.Add(name); - activeBranchIndex = BranchesNames.IndexOf(activeBranch); - SelectedBranchIndex = activeBranchIndex; + ActiveBranchIndex = BranchesNames.IndexOf(activeBranch); + SelectedBranchIndex = ActiveBranchIndex; } } } From e72c24d7975291e8b88bd68a34ab6d0c575043c0 Mon Sep 17 00:00:00 2001 From: Filippo Ferrario Date: Wed, 10 May 2023 21:13:12 +0200 Subject: [PATCH 04/18] UI changes --- src/Files.App/Helpers/DynamicDialogFactory.cs | 45 +++++-------------- .../UserControls/StatusBarControl.xaml | 11 ++++- src/Files.Backend/Enums/GitCheckoutOptions.cs | 4 +- 3 files changed, 24 insertions(+), 36 deletions(-) diff --git a/src/Files.App/Helpers/DynamicDialogFactory.cs b/src/Files.App/Helpers/DynamicDialogFactory.cs index a49216edebb2..bc45e9e536ce 100644 --- a/src/Files.App/Helpers/DynamicDialogFactory.cs +++ b/src/Files.App/Helpers/DynamicDialogFactory.cs @@ -1,19 +1,11 @@ // Copyright (c) 2023 Files Community // Licensed under the MIT License. See the LICENSE. -using CommunityToolkit.WinUI; using Files.App.Dialogs; -using Files.App.Extensions; -using Files.App.Filesystem; using Files.App.ViewModels.Dialogs; -using Files.Shared.Enums; -using Files.Shared.Extensions; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Data; -using System; -using System.Collections.Generic; -using System.Linq; using Windows.System; namespace Files.App.Helpers @@ -229,31 +221,20 @@ public static DynamicDialog GetFor_GitCheckoutConflicts() { DynamicDialog dialog = null!; - var bringChangesRadio = new RadioButton() + var optionsListView = new ListView() { - Content = "BringChanges".GetLocalizedResource(), - IsChecked = true, - }; - var stashChangesRadio = new RadioButton() - { - Content = "StashChanges".GetLocalizedResource(), - }; - var discardChangesRadio = new RadioButton() - { - Content = "DiscardChanges".GetLocalizedResource(), + ItemsSource = new string[] + { + "BringChanges".GetLocalizedResource(), + "StashChanges".GetLocalizedResource(), + "DiscardChanges".GetLocalizedResource() + }, + SelectionMode = ListViewSelectionMode.Single }; - bringChangesRadio.Checked += (button, args) => - { - dialog.ViewModel.AdditionalData = GitCheckoutOptions.BringChanges; - }; - stashChangesRadio.Checked += (button, args) => - { - dialog.ViewModel.AdditionalData = GitCheckoutOptions.StashChanges; - }; - discardChangesRadio.Checked += (button, args) => + optionsListView.SelectionChanged += (listView, args) => { - dialog.ViewModel.AdditionalData = GitCheckoutOptions.DiscardChanges; + dialog.ViewModel.AdditionalData = (GitCheckoutOptions)optionsListView.SelectedIndex; }; dialog = new DynamicDialog(new DynamicDialogViewModel() @@ -272,14 +253,12 @@ public static DynamicDialog GetFor_GitCheckoutConflicts() Spacing = 10d, Children = { - bringChangesRadio, - stashChangesRadio, - discardChangesRadio + optionsListView } } } }, - AdditionalData = GitCheckoutOptions.BringChanges, + AdditionalData = GitCheckoutOptions.None, CloseButtonAction = (vm, e) => { dialog.ViewModel.AdditionalData = GitCheckoutOptions.None; diff --git a/src/Files.App/UserControls/StatusBarControl.xaml b/src/Files.App/UserControls/StatusBarControl.xaml index 5393cda7db0b..cfa2430ea88a 100644 --- a/src/Files.App/UserControls/StatusBarControl.xaml +++ b/src/Files.App/UserControls/StatusBarControl.xaml @@ -62,12 +62,21 @@ Content="{x:Bind DirectoryPropertiesViewModel.GitBranchDisplayName, Mode=OneWay}"> + + + - + Date: Wed, 10 May 2023 21:18:19 +0200 Subject: [PATCH 05/18] Preselect default option --- src/Files.App/Helpers/DynamicDialogFactory.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Files.App/Helpers/DynamicDialogFactory.cs b/src/Files.App/Helpers/DynamicDialogFactory.cs index bc45e9e536ce..1e828fc31547 100644 --- a/src/Files.App/Helpers/DynamicDialogFactory.cs +++ b/src/Files.App/Helpers/DynamicDialogFactory.cs @@ -231,6 +231,7 @@ public static DynamicDialog GetFor_GitCheckoutConflicts() }, SelectionMode = ListViewSelectionMode.Single }; + optionsListView.SelectedIndex = 0; optionsListView.SelectionChanged += (listView, args) => { @@ -258,7 +259,7 @@ public static DynamicDialog GetFor_GitCheckoutConflicts() } } }, - AdditionalData = GitCheckoutOptions.None, + AdditionalData = GitCheckoutOptions.BringChanges, CloseButtonAction = (vm, e) => { dialog.ViewModel.AdditionalData = GitCheckoutOptions.None; From 611ed5f4f5152ad0104f0146d7ebe72155891085 Mon Sep 17 00:00:00 2001 From: Yair <39923744+yaira2@users.noreply.github.com> Date: Wed, 10 May 2023 16:01:52 -0400 Subject: [PATCH 06/18] Display branch name --- src/Files.App/Helpers/DynamicDialogFactory.cs | 12 ++-- src/Files.App/Helpers/GitHelpers.cs | 2 +- src/Files.App/Strings/en-US/Resources.resw | 22 +++++--- .../UserControls/StatusBarControl.xaml | 55 +++++++++++++------ .../UserControls/StatusBarControl.xaml.cs | 5 -- 5 files changed, 60 insertions(+), 36 deletions(-) diff --git a/src/Files.App/Helpers/DynamicDialogFactory.cs b/src/Files.App/Helpers/DynamicDialogFactory.cs index 1e828fc31547..128056088a12 100644 --- a/src/Files.App/Helpers/DynamicDialogFactory.cs +++ b/src/Files.App/Helpers/DynamicDialogFactory.cs @@ -217,7 +217,7 @@ public static DynamicDialog GetFor_CredentialEntryDialog(string path) return dialog; } - public static DynamicDialog GetFor_GitCheckoutConflicts() + public static DynamicDialog GetFor_GitCheckoutConflicts(string checkoutBranchName, string headBranchName) { DynamicDialog dialog = null!; @@ -225,8 +225,8 @@ public static DynamicDialog GetFor_GitCheckoutConflicts() { ItemsSource = new string[] { - "BringChanges".GetLocalizedResource(), - "StashChanges".GetLocalizedResource(), + string.Format("BringChanges".GetLocalizedResource(), checkoutBranchName), + string.Format("StashChanges".GetLocalizedResource(), headBranchName), "DiscardChanges".GetLocalizedResource() }, SelectionMode = ListViewSelectionMode.Single @@ -240,10 +240,10 @@ public static DynamicDialog GetFor_GitCheckoutConflicts() dialog = new DynamicDialog(new DynamicDialogViewModel() { - TitleText = "UncommitedChanges".GetLocalizedResource(), - PrimaryButtonText = "OK".GetLocalizedResource(), + TitleText = "SwitchBranch".GetLocalizedResource(), + PrimaryButtonText = "Switch".GetLocalizedResource(), CloseButtonText = "Cancel".GetLocalizedResource(), - SubtitleText = "UncommitedChangesMessage".GetLocalizedResource(), + SubtitleText = "UncommittedChanges".GetLocalizedResource(), DisplayControl = new Grid() { MinWidth = 250d, diff --git a/src/Files.App/Helpers/GitHelpers.cs b/src/Files.App/Helpers/GitHelpers.cs index d96174cd2df5..763a50db250d 100644 --- a/src/Files.App/Helpers/GitHelpers.cs +++ b/src/Files.App/Helpers/GitHelpers.cs @@ -60,7 +60,7 @@ public static async Task Checkout(string? repositoryPath, string? branch) if (repository.RetrieveStatus().IsDirty) { - var dialog = DynamicDialogFactory.GetFor_GitCheckoutConflicts(); + var dialog = DynamicDialogFactory.GetFor_GitCheckoutConflicts(checkoutBranch.FriendlyName, repository.Head.FriendlyName); await dialog.ShowAsync(); var resolveConflictOption = (GitCheckoutOptions)dialog.ViewModel.AdditionalData; diff --git a/src/Files.App/Strings/en-US/Resources.resw b/src/Files.App/Strings/en-US/Resources.resw index 361ad6f4255b..7b1e785ebea2 100644 --- a/src/Files.App/Strings/en-US/Resources.resw +++ b/src/Files.App/Strings/en-US/Resources.resw @@ -3263,21 +3263,27 @@ Unable to display permissions. - Stash changes + Leave my changes on '{0}' - Discard changes + Discard my changes - Bring changes + Bring my changes to '{0}' - - There are uncommited changes on the local branch + + You have uncommitted changes on this branch. What would you like to do with them? - - What do you want to do with them? + + Switch Branch - Branches: + Branches + + + Switch + + + New branch \ No newline at end of file diff --git a/src/Files.App/UserControls/StatusBarControl.xaml b/src/Files.App/UserControls/StatusBarControl.xaml index cfa2430ea88a..866ff29e1ea3 100644 --- a/src/Files.App/UserControls/StatusBarControl.xaml +++ b/src/Files.App/UserControls/StatusBarControl.xaml @@ -62,26 +62,49 @@ Content="{x:Bind DirectoryPropertiesViewModel.GitBranchDisplayName, Mode=OneWay}"> - - - - - + + + + + + + + + + + + + diff --git a/src/Files.App/UserControls/StatusBarControl.xaml.cs b/src/Files.App/UserControls/StatusBarControl.xaml.cs index 28b05dcfa85f..da3d049641ae 100644 --- a/src/Files.App/UserControls/StatusBarControl.xaml.cs +++ b/src/Files.App/UserControls/StatusBarControl.xaml.cs @@ -48,10 +48,5 @@ private void Flyout_Opening(object sender, object e) { DirectoryPropertiesViewModel.SelectedBranchIndex = DirectoryPropertiesViewModel.ActiveBranchIndex; } - - private void StackPanel_LostFocus(object sender, RoutedEventArgs e) - { - ((Popup)((FlyoutPresenter)((StackPanel)sender).Parent).Parent).IsOpen = false; - } } } From 25504996cee687e36b96f63e53af5085fb98568f Mon Sep 17 00:00:00 2001 From: Yair <39923744+yaira2@users.noreply.github.com> Date: Wed, 10 May 2023 21:37:45 -0400 Subject: [PATCH 07/18] Update StatusBarControl.xaml.cs --- src/Files.App/UserControls/StatusBarControl.xaml.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Files.App/UserControls/StatusBarControl.xaml.cs b/src/Files.App/UserControls/StatusBarControl.xaml.cs index da3d049641ae..d38b204bcae2 100644 --- a/src/Files.App/UserControls/StatusBarControl.xaml.cs +++ b/src/Files.App/UserControls/StatusBarControl.xaml.cs @@ -4,7 +4,6 @@ using Files.App.ViewModels; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; -using Microsoft.UI.Xaml.Controls.Primitives; namespace Files.App.UserControls { From 40731fe744ce3b7eb122b1ce6552bf5c5250ee58 Mon Sep 17 00:00:00 2001 From: Filippo Ferrario Date: Thu, 11 May 2023 08:26:40 +0200 Subject: [PATCH 08/18] Remove stackpanel from dialog --- src/Files.App/Helpers/DynamicDialogFactory.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/Files.App/Helpers/DynamicDialogFactory.cs b/src/Files.App/Helpers/DynamicDialogFactory.cs index 128056088a12..0376ff5972e9 100644 --- a/src/Files.App/Helpers/DynamicDialogFactory.cs +++ b/src/Files.App/Helpers/DynamicDialogFactory.cs @@ -249,14 +249,7 @@ public static DynamicDialog GetFor_GitCheckoutConflicts(string checkoutBranchNam MinWidth = 250d, Children = { - new StackPanel() - { - Spacing = 10d, - Children = - { - optionsListView - } - } + optionsListView } }, AdditionalData = GitCheckoutOptions.BringChanges, From 6d03a75c65844259b6317fb87653fc70e7504635 Mon Sep 17 00:00:00 2001 From: Yair <39923744+yaira2@users.noreply.github.com> Date: Thu, 11 May 2023 10:15:09 -0400 Subject: [PATCH 09/18] Test --- src/Files.App/UserControls/StatusBarControl.xaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Files.App/UserControls/StatusBarControl.xaml b/src/Files.App/UserControls/StatusBarControl.xaml index 866ff29e1ea3..634b5cbc9e7b 100644 --- a/src/Files.App/UserControls/StatusBarControl.xaml +++ b/src/Files.App/UserControls/StatusBarControl.xaml @@ -58,10 +58,10 @@ x:Name="GitBranch" x:Load="{x:Bind DirectoryPropertiesViewModel.GitBranchDisplayName, Mode=OneWay, Converter={StaticResource NullToFalseConverter}}" Background="Transparent" - BorderThickness="0" + BorderThickness="0" AutomationProperties.Name="Test" Content="{x:Bind DirectoryPropertiesViewModel.GitBranchDisplayName, Mode=OneWay}"> - + Date: Thu, 11 May 2023 10:42:11 -0400 Subject: [PATCH 10/18] Update StatusBarControl.xaml --- src/Files.App/UserControls/StatusBarControl.xaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Files.App/UserControls/StatusBarControl.xaml b/src/Files.App/UserControls/StatusBarControl.xaml index 634b5cbc9e7b..866ff29e1ea3 100644 --- a/src/Files.App/UserControls/StatusBarControl.xaml +++ b/src/Files.App/UserControls/StatusBarControl.xaml @@ -58,10 +58,10 @@ x:Name="GitBranch" x:Load="{x:Bind DirectoryPropertiesViewModel.GitBranchDisplayName, Mode=OneWay, Converter={StaticResource NullToFalseConverter}}" Background="Transparent" - BorderThickness="0" AutomationProperties.Name="Test" + BorderThickness="0" Content="{x:Bind DirectoryPropertiesViewModel.GitBranchDisplayName, Mode=OneWay}"> - + Date: Thu, 11 May 2023 10:54:14 -0400 Subject: [PATCH 11/18] Update BaseShellPage.cs --- src/Files.App/Views/Shells/BaseShellPage.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Files.App/Views/Shells/BaseShellPage.cs b/src/Files.App/Views/Shells/BaseShellPage.cs index 7369e28625fe..a758bb285835 100644 --- a/src/Files.App/Views/Shells/BaseShellPage.cs +++ b/src/Files.App/Views/Shells/BaseShellPage.cs @@ -75,14 +75,14 @@ public BaseLayout ContentPage { if (value != _ContentPage) { - if (_ContentPage is not null) - _ContentPage.DirectoryPropertiesViewModel.CheckoutRequested -= GitCheckout_Required; + //if (_ContentPage is not null) + // _ContentPage.DirectoryPropertiesViewModel.CheckoutRequested -= GitCheckout_Required; _ContentPage = value; NotifyPropertyChanged(nameof(ContentPage)); NotifyPropertyChanged(nameof(SlimContentPage)); - _ContentPage.DirectoryPropertiesViewModel.CheckoutRequested += GitCheckout_Required; + //_ContentPage.DirectoryPropertiesViewModel.CheckoutRequested += GitCheckout_Required; } } } From 904aab6590e82a775f937bc4d2a6be61ced7f4a8 Mon Sep 17 00:00:00 2001 From: Filippo Ferrario Date: Thu, 11 May 2023 17:30:00 +0200 Subject: [PATCH 12/18] Re-select active branch if the user cancels the checkout --- src/Files.App/Helpers/GitHelpers.cs | 9 +++++---- src/Files.App/Views/Shells/BaseShellPage.cs | 10 ++++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/Files.App/Helpers/GitHelpers.cs b/src/Files.App/Helpers/GitHelpers.cs index 763a50db250d..c0b30f0760e8 100644 --- a/src/Files.App/Helpers/GitHelpers.cs +++ b/src/Files.App/Helpers/GitHelpers.cs @@ -45,15 +45,15 @@ public static string[] GetLocalBranchesNames(string? path) .ToArray(); } - public static async Task Checkout(string? repositoryPath, string? branch) + public static async Task Checkout(string? repositoryPath, string? branch) { if (string.IsNullOrWhiteSpace(repositoryPath) || !Repository.IsValid(repositoryPath)) - return; + return false; using var repository = new Repository(repositoryPath); var checkoutBranch = repository.Branches[branch]; if (checkoutBranch is null) - return; + return false; var options = new CheckoutOptions(); var isBringingChanges = false; @@ -68,7 +68,7 @@ public static async Task Checkout(string? repositoryPath, string? branch) switch (resolveConflictOption) { case GitCheckoutOptions.None: - return; + return false; case GitCheckoutOptions.DiscardChanges: options.CheckoutModifiers = CheckoutModifiers.Force; break; @@ -88,6 +88,7 @@ public static async Task Checkout(string? repositoryPath, string? branch) var lastStashIndex = repository.Stashes.Count() - 1; repository.Stashes.Pop(lastStashIndex, new StashApplyOptions()); } + return true; } } } diff --git a/src/Files.App/Views/Shells/BaseShellPage.cs b/src/Files.App/Views/Shells/BaseShellPage.cs index a758bb285835..a7cb81bac741 100644 --- a/src/Files.App/Views/Shells/BaseShellPage.cs +++ b/src/Files.App/Views/Shells/BaseShellPage.cs @@ -75,14 +75,15 @@ public BaseLayout ContentPage { if (value != _ContentPage) { - //if (_ContentPage is not null) - // _ContentPage.DirectoryPropertiesViewModel.CheckoutRequested -= GitCheckout_Required; + if (_ContentPage is not null) + _ContentPage.DirectoryPropertiesViewModel.CheckoutRequested -= GitCheckout_Required; _ContentPage = value; NotifyPropertyChanged(nameof(ContentPage)); NotifyPropertyChanged(nameof(SlimContentPage)); - //_ContentPage.DirectoryPropertiesViewModel.CheckoutRequested += GitCheckout_Required; + if (value is not null) + _ContentPage.DirectoryPropertiesViewModel.CheckoutRequested += GitCheckout_Required; } } } @@ -243,7 +244,8 @@ protected void FilesystemViewModel_GitDirectoryUpdated(object sender, EventArgs protected async void GitCheckout_Required(object? sender, string branchName) { - await GitHelpers.Checkout(FilesystemViewModel.GitDirectory, branchName); + if (!await GitHelpers.Checkout(FilesystemViewModel.GitDirectory, branchName)) + _ContentPage.DirectoryPropertiesViewModel.SelectedBranchIndex = _ContentPage.DirectoryPropertiesViewModel.ActiveBranchIndex; } protected virtual void Page_Loaded(object sender, RoutedEventArgs e) From 312f930300fab5c83faff4f1e7187d1e127c575a Mon Sep 17 00:00:00 2001 From: Yair <39923744+yaira2@users.noreply.github.com> Date: Thu, 11 May 2023 12:12:02 -0400 Subject: [PATCH 13/18] Close flyout on click --- src/Files.App/UserControls/StatusBarControl.xaml | 6 +++++- .../UserControls/StatusBarControl.xaml.cs | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/Files.App/UserControls/StatusBarControl.xaml b/src/Files.App/UserControls/StatusBarControl.xaml index 866ff29e1ea3..44e532fb126c 100644 --- a/src/Files.App/UserControls/StatusBarControl.xaml +++ b/src/Files.App/UserControls/StatusBarControl.xaml @@ -61,7 +61,10 @@ BorderThickness="0" Content="{x:Bind DirectoryPropertiesViewModel.GitBranchDisplayName, Mode=OneWay}"> - + Date: Thu, 11 May 2023 12:19:37 -0400 Subject: [PATCH 14/18] Fix --- src/Files.App/UserControls/StatusBarControl.xaml | 6 ++---- src/Files.App/UserControls/StatusBarControl.xaml.cs | 6 ------ 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/Files.App/UserControls/StatusBarControl.xaml b/src/Files.App/UserControls/StatusBarControl.xaml index 44e532fb126c..d717632fb6cd 100644 --- a/src/Files.App/UserControls/StatusBarControl.xaml +++ b/src/Files.App/UserControls/StatusBarControl.xaml @@ -61,10 +61,7 @@ BorderThickness="0" Content="{x:Bind DirectoryPropertiesViewModel.GitBranchDisplayName, Mode=OneWay}"> - + diff --git a/src/Files.App/UserControls/StatusBarControl.xaml.cs b/src/Files.App/UserControls/StatusBarControl.xaml.cs index 362c780f75a8..f2cf505fe2a5 100644 --- a/src/Files.App/UserControls/StatusBarControl.xaml.cs +++ b/src/Files.App/UserControls/StatusBarControl.xaml.cs @@ -50,12 +50,6 @@ private void BranchesList_SelectionChanged(object sender, SelectionChangedEventA private void BranchesFlyout_Opening(object sender, object e) { DirectoryPropertiesViewModel.SelectedBranchIndex = DirectoryPropertiesViewModel.ActiveBranchIndex; - BranchesList.SelectionChanged += BranchesList_SelectionChanged; - } - - private void BranchesFlyout_Closing(Microsoft.UI.Xaml.Controls.Primitives.FlyoutBase sender, Microsoft.UI.Xaml.Controls.Primitives.FlyoutBaseClosingEventArgs args) - { - BranchesList.SelectionChanged -= BranchesList_SelectionChanged; } } } From aaaae96bc01ccacd7ad70b7d56534decbcc04933 Mon Sep 17 00:00:00 2001 From: Yair <39923744+yaira2@users.noreply.github.com> Date: Thu, 11 May 2023 12:32:54 -0400 Subject: [PATCH 15/18] Fix --- src/Files.App/UserControls/StatusBarControl.xaml | 3 ++- src/Files.App/UserControls/StatusBarControl.xaml.cs | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Files.App/UserControls/StatusBarControl.xaml b/src/Files.App/UserControls/StatusBarControl.xaml index d717632fb6cd..e71d3a25bf54 100644 --- a/src/Files.App/UserControls/StatusBarControl.xaml +++ b/src/Files.App/UserControls/StatusBarControl.xaml @@ -102,9 +102,10 @@ Grid.Row="1" Padding="4" Background="{ThemeResource CardBackgroundFillColorDefaultBrush}" + IsItemClickEnabled="True" + ItemClick="BranchesList_ItemClick" ItemsSource="{x:Bind DirectoryPropertiesViewModel.BranchesNames, Mode=OneWay}" SelectedIndex="{x:Bind DirectoryPropertiesViewModel.SelectedBranchIndex, Mode=TwoWay}" - SelectionChanged="BranchesList_SelectionChanged" SelectionMode="Single" /> diff --git a/src/Files.App/UserControls/StatusBarControl.xaml.cs b/src/Files.App/UserControls/StatusBarControl.xaml.cs index f2cf505fe2a5..6281957952a0 100644 --- a/src/Files.App/UserControls/StatusBarControl.xaml.cs +++ b/src/Files.App/UserControls/StatusBarControl.xaml.cs @@ -42,14 +42,14 @@ public StatusBarControl() InitializeComponent(); } - private void BranchesList_SelectionChanged(object sender, SelectionChangedEventArgs e) + private void BranchesFlyout_Opening(object sender, object e) { - BranchesFlyout.Hide(); + DirectoryPropertiesViewModel.SelectedBranchIndex = DirectoryPropertiesViewModel.ActiveBranchIndex; } - private void BranchesFlyout_Opening(object sender, object e) + private void BranchesList_ItemClick(object sender, ItemClickEventArgs e) { - DirectoryPropertiesViewModel.SelectedBranchIndex = DirectoryPropertiesViewModel.ActiveBranchIndex; + BranchesFlyout.Hide(); } } } From e4e1b94c86868735f761099352e63ce28a97d45c Mon Sep 17 00:00:00 2001 From: Yair <39923744+yaira2@users.noreply.github.com> Date: Thu, 11 May 2023 12:47:22 -0400 Subject: [PATCH 16/18] Added event tracking --- src/Files.App/Helpers/GitHelpers.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Files.App/Helpers/GitHelpers.cs b/src/Files.App/Helpers/GitHelpers.cs index c0b30f0760e8..303df487ec11 100644 --- a/src/Files.App/Helpers/GitHelpers.cs +++ b/src/Files.App/Helpers/GitHelpers.cs @@ -1,8 +1,9 @@ // Copyright (c) 2023 Files Community // Licensed under the MIT License. See the LICENSE. -using LibGit2Sharp; using Files.App.Filesystem.StorageItems; +using LibGit2Sharp; +using Microsoft.AppCenter.Analytics; namespace Files.App.Helpers { @@ -58,6 +59,8 @@ public static async Task Checkout(string? repositoryPath, string? branch) var options = new CheckoutOptions(); var isBringingChanges = false; + Analytics.TrackEvent($"Triggered git checkout"); + if (repository.RetrieveStatus().IsDirty) { var dialog = DynamicDialogFactory.GetFor_GitCheckoutConflicts(checkoutBranch.FriendlyName, repository.Head.FriendlyName); @@ -80,7 +83,7 @@ public static async Task Checkout(string? repositoryPath, string? branch) break; } } - + LibGit2Sharp.Commands.Checkout(repository, checkoutBranch, options); if (isBringingChanges) From 39f0dfc77581d7aa3c72e9d1b457444d582a1c65 Mon Sep 17 00:00:00 2001 From: Filippo Ferrario Date: Thu, 11 May 2023 18:48:15 +0200 Subject: [PATCH 17/18] Order branches --- src/Files.App/Helpers/GitHelpers.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Files.App/Helpers/GitHelpers.cs b/src/Files.App/Helpers/GitHelpers.cs index 303df487ec11..f5e5d5856f90 100644 --- a/src/Files.App/Helpers/GitHelpers.cs +++ b/src/Files.App/Helpers/GitHelpers.cs @@ -42,6 +42,7 @@ public static string[] GetLocalBranchesNames(string? path) using var repository = new Repository(path); return repository.Branches .Where(b => !b.IsRemote) + .OrderByDescending(b => b.IsCurrentRepositoryHead) .Select(b => b.FriendlyName) .ToArray(); } From 7d0db5b00391f5467e17bc301679420eb72650fd Mon Sep 17 00:00:00 2001 From: Filippo Ferrario Date: Thu, 11 May 2023 19:05:26 +0200 Subject: [PATCH 18/18] Fix null variable --- src/Files.App/Helpers/GitHelpers.cs | 1 + .../ViewModels/DirectoryPropertiesViewModel.cs | 13 ++++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Files.App/Helpers/GitHelpers.cs b/src/Files.App/Helpers/GitHelpers.cs index f5e5d5856f90..0a5e0268380c 100644 --- a/src/Files.App/Helpers/GitHelpers.cs +++ b/src/Files.App/Helpers/GitHelpers.cs @@ -43,6 +43,7 @@ public static string[] GetLocalBranchesNames(string? path) return repository.Branches .Where(b => !b.IsRemote) .OrderByDescending(b => b.IsCurrentRepositoryHead) + .ThenByDescending(b => b.Tip.Committer.When) .Select(b => b.FriendlyName) .ToArray(); } diff --git a/src/Files.App/ViewModels/DirectoryPropertiesViewModel.cs b/src/Files.App/ViewModels/DirectoryPropertiesViewModel.cs index 636e25c1f393..e7eec3ed1ec8 100644 --- a/src/Files.App/ViewModels/DirectoryPropertiesViewModel.cs +++ b/src/Files.App/ViewModels/DirectoryPropertiesViewModel.cs @@ -42,12 +42,15 @@ public void UpdateGitInfo(bool isGitRepository, string activeBranch, string[] br ? string.Format("Branch".GetLocalizedResource(), activeBranch) : null; - BranchesNames.Clear(); - foreach (var name in branches) - BranchesNames.Add(name); + if (isGitRepository) + { + BranchesNames.Clear(); + foreach (var name in branches) + BranchesNames.Add(name); - ActiveBranchIndex = BranchesNames.IndexOf(activeBranch); - SelectedBranchIndex = ActiveBranchIndex; + ActiveBranchIndex = BranchesNames.IndexOf(activeBranch); + SelectedBranchIndex = ActiveBranchIndex; + } } } }