Skip to content

Commit ddeb2ff

Browse files
workbysaranyaira2
andauthored
Fix: Fixed crash when switching git branches during merge conflict (#17894)
Signed-off-by: Saravanan G <workbysaran@gmail.com> Co-authored-by: Yair <39923744+yaira2@users.noreply.github.com>
1 parent 4abd5f2 commit ddeb2ff

File tree

4 files changed

+83
-1
lines changed

4 files changed

+83
-1
lines changed

src/Files.App/Data/Enums/GitCheckoutOptions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ public enum GitCheckoutOptions
2323
/// </summary>
2424
DiscardChanges,
2525

26+
/// <summary>
27+
/// Abort merge and check out to the branch.
28+
/// </summary>
29+
AbortMerge,
30+
2631
/// <summary>
2732
/// No operation to perform.
2833
/// </summary>

src/Files.App/Helpers/Dialog/DynamicDialogFactory.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,53 @@ public static DynamicDialog GetFor_GitCheckoutConflicts(string checkoutBranchNam
266266
return dialog;
267267
}
268268

269+
public static DynamicDialog GetFor_GitMergeConflicts(string checkoutBranchName, string headBranchName)
270+
{
271+
DynamicDialog dialog = null!;
272+
273+
var optionsListView = new ListView()
274+
{
275+
ItemsSource = new string[]
276+
{
277+
string.Format(Strings.AbortMergeAndSwitch.GetLocalizedResource(), checkoutBranchName),
278+
string.Format(Strings.StayAndResolveConflicts.GetLocalizedResource(), headBranchName)
279+
},
280+
SelectionMode = ListViewSelectionMode.Single
281+
};
282+
optionsListView.SelectedIndex = 0;
283+
284+
optionsListView.SelectionChanged += (listView, args) =>
285+
{
286+
dialog.ViewModel.AdditionalData = optionsListView.SelectedIndex == 0
287+
? GitCheckoutOptions.AbortMerge
288+
: GitCheckoutOptions.None;
289+
};
290+
291+
dialog = new DynamicDialog(new DynamicDialogViewModel()
292+
{
293+
TitleText = Strings.SwitchBranch.GetLocalizedResource(),
294+
PrimaryButtonText = Strings.Confirm.GetLocalizedResource(),
295+
CloseButtonText = Strings.Cancel.GetLocalizedResource(),
296+
SubtitleText = Strings.MergeInProgress.GetLocalizedResource(),
297+
DisplayControl = new Grid()
298+
{
299+
MinWidth = 250d,
300+
Children =
301+
{
302+
optionsListView
303+
}
304+
},
305+
AdditionalData = GitCheckoutOptions.AbortMerge,
306+
CloseButtonAction = (vm, e) =>
307+
{
308+
dialog.ViewModel.AdditionalData = GitCheckoutOptions.None;
309+
vm.HideDialog();
310+
}
311+
});
312+
313+
return dialog;
314+
}
315+
269316
public static DynamicDialog GetFor_GitHubConnectionError()
270317
{
271318
DynamicDialog dialog = new DynamicDialog(new DynamicDialogViewModel()

src/Files.App/Strings/en-US/Resources.resw

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3132,6 +3132,15 @@
31323132
<data name="UncommittedChanges" xml:space="preserve">
31333133
<value>You have uncommitted changes on this branch. What would you like to do with them?</value>
31343134
</data>
3135+
<data name="MergeInProgress" xml:space="preserve">
3136+
<value>You have an ongoing merge with unresolved conflicts. Please resolve the conflicts or abort the merge to switch branches.</value>
3137+
</data>
3138+
<data name="AbortMergeAndSwitch" xml:space="preserve">
3139+
<value>Abort merge and switch to '{0}'</value>
3140+
</data>
3141+
<data name="StayAndResolveConflicts" xml:space="preserve">
3142+
<value>Stay on '{0}' and resolve conflicts</value>
3143+
</data>
31353144
<data name="SwitchBranch" xml:space="preserve">
31363145
<value>Switch branch</value>
31373146
</data>

src/Files.App/Utils/Git/GitHelpers.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,24 @@ public static async Task<bool> Checkout(string? repositoryPath, string? branch)
194194

195195
IsExecutingGitAction = true;
196196

197-
if (repository.RetrieveStatus().IsDirty)
197+
if (repository.Index.Conflicts.Any())
198+
{
199+
var dialog = DynamicDialogFactory.GetFor_GitMergeConflicts(checkoutBranch.FriendlyName, repository.Head.FriendlyName);
200+
await dialog.ShowAsync();
201+
202+
var resolveConflictOption = (GitCheckoutOptions)dialog.ViewModel.AdditionalData;
203+
204+
switch (resolveConflictOption)
205+
{
206+
case GitCheckoutOptions.None:
207+
IsExecutingGitAction = false;
208+
return false;
209+
case GitCheckoutOptions.AbortMerge:
210+
repository.Reset(ResetMode.Hard);
211+
break;
212+
}
213+
}
214+
else if (repository.RetrieveStatus().IsDirty)
198215
{
199216
var dialog = DynamicDialogFactory.GetFor_GitCheckoutConflicts(checkoutBranch.FriendlyName, repository.Head.FriendlyName);
200217
await dialog.ShowAsync();
@@ -204,6 +221,7 @@ public static async Task<bool> Checkout(string? repositoryPath, string? branch)
204221
switch (resolveConflictOption)
205222
{
206223
case GitCheckoutOptions.None:
224+
IsExecutingGitAction = false;
207225
return false;
208226
case GitCheckoutOptions.DiscardChanges:
209227
options.CheckoutModifiers = CheckoutModifiers.Force;
@@ -212,7 +230,10 @@ public static async Task<bool> Checkout(string? repositoryPath, string? branch)
212230
case GitCheckoutOptions.StashChanges:
213231
var signature = repository.Config.BuildSignature(DateTimeOffset.Now);
214232
if (signature is null)
233+
{
234+
IsExecutingGitAction = false;
215235
return false;
236+
}
216237

217238
repository.Stashes.Add(signature);
218239

0 commit comments

Comments
 (0)