diff --git a/src/Files.App/Data/Enums/GitCheckoutOptions.cs b/src/Files.App/Data/Enums/GitCheckoutOptions.cs
index 646235b73cc1..9a2abdcdef55 100644
--- a/src/Files.App/Data/Enums/GitCheckoutOptions.cs
+++ b/src/Files.App/Data/Enums/GitCheckoutOptions.cs
@@ -23,6 +23,11 @@ public enum GitCheckoutOptions
///
DiscardChanges,
+ ///
+ /// Abort merge and check out to the branch.
+ ///
+ AbortMerge,
+
///
/// No operation to perform.
///
diff --git a/src/Files.App/Helpers/Dialog/DynamicDialogFactory.cs b/src/Files.App/Helpers/Dialog/DynamicDialogFactory.cs
index a6468fbafaa9..f2ff8cd29a27 100644
--- a/src/Files.App/Helpers/Dialog/DynamicDialogFactory.cs
+++ b/src/Files.App/Helpers/Dialog/DynamicDialogFactory.cs
@@ -266,6 +266,53 @@ public static DynamicDialog GetFor_GitCheckoutConflicts(string checkoutBranchNam
return dialog;
}
+ public static DynamicDialog GetFor_GitMergeConflicts(string checkoutBranchName, string headBranchName)
+ {
+ DynamicDialog dialog = null!;
+
+ var optionsListView = new ListView()
+ {
+ ItemsSource = new string[]
+ {
+ string.Format(Strings.AbortMergeAndSwitch.GetLocalizedResource(), checkoutBranchName),
+ string.Format(Strings.StayAndResolveConflicts.GetLocalizedResource(), headBranchName)
+ },
+ SelectionMode = ListViewSelectionMode.Single
+ };
+ optionsListView.SelectedIndex = 0;
+
+ optionsListView.SelectionChanged += (listView, args) =>
+ {
+ dialog.ViewModel.AdditionalData = optionsListView.SelectedIndex == 0
+ ? GitCheckoutOptions.AbortMerge
+ : GitCheckoutOptions.None;
+ };
+
+ dialog = new DynamicDialog(new DynamicDialogViewModel()
+ {
+ TitleText = Strings.SwitchBranch.GetLocalizedResource(),
+ PrimaryButtonText = Strings.OK.GetLocalizedResource(),
+ CloseButtonText = Strings.Cancel.GetLocalizedResource(),
+ SubtitleText = Strings.MergeInProgress.GetLocalizedResource(),
+ DisplayControl = new Grid()
+ {
+ MinWidth = 250d,
+ Children =
+ {
+ optionsListView
+ }
+ },
+ AdditionalData = GitCheckoutOptions.AbortMerge,
+ CloseButtonAction = (vm, e) =>
+ {
+ dialog.ViewModel.AdditionalData = GitCheckoutOptions.None;
+ vm.HideDialog();
+ }
+ });
+
+ return dialog;
+ }
+
public static DynamicDialog GetFor_GitHubConnectionError()
{
DynamicDialog dialog = new DynamicDialog(new DynamicDialogViewModel()
diff --git a/src/Files.App/Strings/en-US/Resources.resw b/src/Files.App/Strings/en-US/Resources.resw
index 22062780d1e3..ad2041f1e3b0 100644
--- a/src/Files.App/Strings/en-US/Resources.resw
+++ b/src/Files.App/Strings/en-US/Resources.resw
@@ -3132,6 +3132,15 @@
You have uncommitted changes on this branch. What would you like to do with them?
+
+ You have an ongoing merge with unresolved conflicts. You must resolve or abort the merge before switching branches.
+
+
+ Abort merge and switch to '{0}'
+
+
+ Stay on '{0}' and resolve conflicts
+
Switch branch
diff --git a/src/Files.App/Utils/Git/GitHelpers.cs b/src/Files.App/Utils/Git/GitHelpers.cs
index befa53cf1780..e49032fa77fc 100644
--- a/src/Files.App/Utils/Git/GitHelpers.cs
+++ b/src/Files.App/Utils/Git/GitHelpers.cs
@@ -194,7 +194,24 @@ public static async Task Checkout(string? repositoryPath, string? branch)
IsExecutingGitAction = true;
- if (repository.RetrieveStatus().IsDirty)
+ if (repository.Index.Conflicts.Any())
+ {
+ var dialog = DynamicDialogFactory.GetFor_GitMergeConflicts(checkoutBranch.FriendlyName, repository.Head.FriendlyName);
+ await dialog.ShowAsync();
+
+ var resolveConflictOption = (GitCheckoutOptions)dialog.ViewModel.AdditionalData;
+
+ switch (resolveConflictOption)
+ {
+ case GitCheckoutOptions.None:
+ IsExecutingGitAction = false;
+ return false;
+ case GitCheckoutOptions.AbortMerge:
+ repository.Reset(ResetMode.Hard);
+ break;
+ }
+ }
+ else if (repository.RetrieveStatus().IsDirty)
{
var dialog = DynamicDialogFactory.GetFor_GitCheckoutConflicts(checkoutBranch.FriendlyName, repository.Head.FriendlyName);
await dialog.ShowAsync();
@@ -204,6 +221,7 @@ public static async Task Checkout(string? repositoryPath, string? branch)
switch (resolveConflictOption)
{
case GitCheckoutOptions.None:
+ IsExecutingGitAction = false;
return false;
case GitCheckoutOptions.DiscardChanges:
options.CheckoutModifiers = CheckoutModifiers.Force;
@@ -212,7 +230,10 @@ public static async Task Checkout(string? repositoryPath, string? branch)
case GitCheckoutOptions.StashChanges:
var signature = repository.Config.BuildSignature(DateTimeOffset.Now);
if (signature is null)
+ {
+ IsExecutingGitAction = false;
return false;
+ }
repository.Stashes.Add(signature);