feature: show conflict reason

Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
leo 2025-05-28 14:20:31 +08:00
parent 3437f5f4a9
commit fbc8edcc13
No known key found for this signature in database
4 changed files with 108 additions and 4 deletions

View file

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Avalonia.Threading;
namespace SourceGit.Commands
@ -128,12 +129,31 @@ namespace SourceGit.Commands
change.Set(Models.ChangeState.Deleted, Models.ChangeState.Copied);
break;
case "DD":
change.ConflictReason = Models.ConflictReason.BothDeleted;
change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
break;
case "AU":
change.ConflictReason = Models.ConflictReason.AddedByUs;
change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
break;
case "UD":
change.ConflictReason = Models.ConflictReason.DeletedByThem;
change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
break;
case "UA":
change.ConflictReason = Models.ConflictReason.AddedByThem;
change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
break;
case "DU":
change.ConflictReason = Models.ConflictReason.DeletedByUs;
change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
break;
case "AA":
change.ConflictReason = Models.ConflictReason.BothAdded;
change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
break;
case "UU":
change.ConflictReason = Models.ConflictReason.BothModified;
change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
break;
case "??":

View file

@ -22,6 +22,18 @@ namespace SourceGit.Models
Conflicted,
}
public enum ConflictReason
{
None,
BothDeleted,
AddedByUs,
DeletedByThem,
AddedByThem,
DeletedByUs,
BothAdded,
BothModified,
}
public class ChangeDataForAmend
{
public string FileMode { get; set; } = "";
@ -36,6 +48,8 @@ namespace SourceGit.Models
public string Path { get; set; } = "";
public string OriginalPath { get; set; } = "";
public ChangeDataForAmend DataForAmend { get; set; } = null;
public ConflictReason ConflictReason { get; set; } = ConflictReason.None;
public bool IsSubmodule { get; set; } = false;
public bool IsConflicted => WorkTree == ChangeState.Conflicted;
public void Set(ChangeState index, ChangeState workTree = ChangeState.None)

View file

@ -25,6 +25,18 @@ namespace SourceGit.ViewModels
public class Conflict
{
public string Marker
{
get;
private set;
}
public string Description
{
get;
private set;
}
public object Theirs
{
get;
@ -41,7 +53,13 @@ namespace SourceGit.ViewModels
{
get;
private set;
}
} = false;
public bool CanUseExternalMergeTool
{
get;
private set;
} = false;
public Conflict(Repository repo, WorkingCopy wc, Models.Change change)
{
@ -49,7 +67,51 @@ namespace SourceGit.ViewModels
_change = change;
var isSubmodule = repo.Submodules.Find(x => x.Path.Equals(change.Path, StringComparison.Ordinal)) != null;
IsResolved = !isSubmodule && new Commands.IsConflictResolved(repo.FullPath, change).Result();
switch (change.ConflictReason)
{
case Models.ConflictReason.BothDeleted:
Marker = "DD";
Description = "Both deleted";
break;
case Models.ConflictReason.AddedByUs:
Marker = "AU";
Description = "Added by us";
break;
case Models.ConflictReason.DeletedByThem:
Marker = "UD";
Description = "Deleted by them";
break;
case Models.ConflictReason.AddedByThem:
Marker = "UA";
Description = "Added by them";
break;
case Models.ConflictReason.DeletedByUs:
Marker = "DU";
Description = "Deleted by us";
break;
case Models.ConflictReason.BothAdded:
Marker = "AA";
Description = "Both added";
if (!isSubmodule)
{
CanUseExternalMergeTool = true;
IsResolved = new Commands.IsConflictResolved(repo.FullPath, change).Result();
}
break;
case Models.ConflictReason.BothModified:
Marker = "UU";
Description = "Both modified";
if (!isSubmodule)
{
CanUseExternalMergeTool = true;
IsResolved = new Commands.IsConflictResolved(repo.FullPath, change).Result();
}
break;
default:
Marker = string.Empty;
Description = string.Empty;
break;
}
var context = wc.InProgressContext;
if (context is CherryPickInProgress cherryPick)

View file

@ -15,6 +15,14 @@
<Path Width="64" Height="64" Data="{StaticResource Icons.Conflict}" Fill="{DynamicResource Brush.FG2}" HorizontalAlignment="Center"/>
<TextBlock Margin="0,16" FontSize="20" FontWeight="Bold" Text="{DynamicResource Text.WorkingCopy.Conflicts}" Foreground="{DynamicResource Brush.FG2}" HorizontalAlignment="Center"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,0,0,8">
<Border Height="16" VerticalAlignment="Center" Background="Red" CornerRadius="8">
<TextBlock Classes="primary" Text="{Binding Marker}" Foreground="White" FontWeight="Bold" Margin="8,0" FontSize="10"/>
</Border>
<TextBlock Margin="8,0,0,0" VerticalAlignment="Center" Text="{Binding Description}"/>
</StackPanel>
<Border Margin="16,0" Padding="8" CornerRadius="4" BorderThickness="1" BorderBrush="{DynamicResource Brush.Border2}">
<Border.DataTemplates>
<DataTemplate DataType="vm:ConflictSourceBranch">
@ -117,7 +125,7 @@
<TextBlock Margin="6,0,0,0" Text="{DynamicResource Text.WorkingCopy.Conflicts.UseMine}" VerticalAlignment="Center"/>
</StackPanel>
</Button>
<Button Classes="flat" Margin="8,0,0,0" Command="{Binding OpenExternalMergeTool}">
<Button Classes="flat" Margin="8,0,0,0" Command="{Binding OpenExternalMergeTool}" IsVisible="{Binding CanUseExternalMergeTool}">
<StackPanel Orientation="Horizontal">
<Path Width="12" Height="12" Data="{StaticResource Icons.OpenWith}"/>
<TextBlock Margin="6,0,0,0" Text="{DynamicResource Text.WorkingCopy.Conflicts.OpenExternalMergeTool}" VerticalAlignment="Center"/>