[wip] Display file content

This commit is contained in:
Vladimir Eremeev 2025-01-13 09:38:02 +03:00
parent 67f4330dd4
commit e8fcd6f659
3 changed files with 260 additions and 1 deletions

View file

@ -41,10 +41,21 @@
private set;
}
public Models.Change Change
{
get => _change;
}
public Repository Repository
{
get => _repo;
}
public Conflict(Repository repo, WorkingCopy wc, Models.Change change)
{
_wc = wc;
_change = change;
_repo = repo;
IsResolved = new Commands.IsConflictResolved(repo.FullPath, change).ReadToEnd().IsSuccess;
@ -98,5 +109,6 @@
private WorkingCopy _wc = null;
private Models.Change _change = null;
private Repository _repo = null;
}
}

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using Avalonia;
@ -2016,4 +2017,111 @@ namespace SourceGit.Views
repo.SetWatcherEnabled(true);
}
}
public class ConflictTextDiffPresenter: SingleSideTextDiffPresenter
{
public enum Side : int
{
Ours = 0, WorkingCopy = 1, Theirs = 2
}
public Side DisplaySide {
get; set;
}
protected override void OnLoaded(RoutedEventArgs e)
{
base.OnLoaded(e);
}
protected override void OnUnloaded(RoutedEventArgs e)
{
base.OnUnloaded(e);
}
protected override void OnDataContextChanged(EventArgs e)
{
base.OnDataContextChanged(e);
if (DataContext is ViewModels.Conflict diff)
{
string conflict_start_marker = "<<<<<<< HEAD";
string conflict_separator_marker = "=======";
string conflict_end_marker = ">>>>>>> ";
var cmd = new Commands.QueryRefsContainsCommit(diff.Repository.FullPath, (diff.Theirs as Models.Commit)?.SHA);
var their_branches = cmd.Result().ToArray();
string filePath = Path.Combine(diff.Repository.FullPath, diff.Change.Path);
var lines =File.ReadAllLines(filePath).ToList<string>();
bool shouldFilter = DisplaySide != Side.WorkingCopy;
while(shouldFilter) {
int idx_start = lines.IndexOf(conflict_start_marker);
if (idx_start == -1) {
shouldFilter = false;
break;
}
int idx_sep = lines.IndexOf(conflict_separator_marker, idx_start);
if (idx_sep == -1) {
shouldFilter = false;
break;
}
int idx_end = idx_sep + 1;
while(idx_end < lines.Count - 1) {
bool found = false;
for (int i = 0; i < their_branches.Length; i++) {
string ce_marker = conflict_end_marker + their_branches[i].Name;
if(lines[idx_end].StartsWith(ce_marker)) {
found = true;
break;
}
}
if (found) {
break;
}
idx_end++;
}
if (idx_end == lines.Count - 1) {
shouldFilter = false;
break;
}
switch (DisplaySide) {
case Side.Ours:
lines.RemoveRange(idx_sep, idx_end - idx_sep + 1);
lines.RemoveAt(idx_start);
break;
case Side.WorkingCopy:
break;
case Side.Theirs:
lines.RemoveAt(idx_end);
lines.RemoveRange(idx_start, idx_sep - idx_start + 1);
break;
}
}
var builder = new StringBuilder();
foreach (var line in lines)
{
if (line.Length > 10000)
{
builder.Append(line.Substring(0, 1000));
builder.Append($"...({line.Length - 1000} characters trimmed)");
builder.AppendLine();
}
else
{
builder.AppendLine(line);
}
}
Text = builder.ToString();
}
else
{
Text = string.Empty;
}
}
}
}

View file

@ -203,7 +203,146 @@
<ContentControl Content="{Binding DetailContext}">
<ContentControl.DataTemplates>
<DataTemplate DataType="vm:Conflict">
<v:Conflict/>
<Border Background="{DynamicResource Brush.Window}" BorderThickness="1" BorderBrush="{DynamicResource Brush.Border2}">
<Grid VerticalAlignment="Center">
<StackPanel Orientation="Vertical" IsVisible="{Binding !IsResolved}">
<StackPanel.DataTemplates>
<DataTemplate DataType="m:Branch">
<StackPanel Orientation="Horizontal">
<Path Width="12" Height="12" Data="{StaticResource Icons.Branch}"/>
<TextBlock Margin="4,0,0,0" Text="{Binding FriendlyName}"/>
<TextBlock Margin="4,0,0,0" Text="{Binding Head, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange"/>
</StackPanel>
</DataTemplate>
<DataTemplate DataType="m:Commit">
<StackPanel Orientation="Horizontal">
<Path Width="12" Height="12" Data="{StaticResource Icons.Commit}"/>
<v:CommitRefsPresenter Margin="8,0,0,0"
TagBackground="{DynamicResource Brush.DecoratorTag}"
Foreground="{DynamicResource Brush.FG1}"
FontFamily="{DynamicResource Fonts.Primary}"
FontSize="11"
VerticalAlignment="Center"
UseGraphColor="False"/>
<TextBlock Margin="4,0,0,0" Text="{Binding SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange"/>
<TextBlock Margin="4,0,0,0" Text="{Binding Subject}"/>
</StackPanel>
</DataTemplate>
<DataTemplate DataType="m:Tag">
<StackPanel Orientation="Horizontal">
<Path Width="12" Height="12" Data="{StaticResource Icons.Tag}"/>
<TextBlock Margin="4,0,0,0" Text="{Binding Name}"/>
<TextBlock Margin="4,0,0,0" Text="{Binding SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange"/>
</StackPanel>
</DataTemplate>
</StackPanel.DataTemplates>
<StackPanel Orientation="Horizontal">
<Path Width="32" Height="32" Margin="10,10,10,10"
Data="{StaticResource Icons.Conflict}" Fill="{DynamicResource Brush.FG2}" HorizontalAlignment="Center"/>
<TextBlock Margin="10,10,10,10" FontSize="20" FontWeight="Bold"
Text="{DynamicResource Text.WorkingCopy.Conflicts}"
Foreground="{DynamicResource Brush.FG2}" HorizontalAlignment="Center"/>
</StackPanel>
<Border Margin="16,0" Padding="8" CornerRadius="4" BorderThickness="1" BorderBrush="{DynamicResource Brush.Border2}">
<Border.IsVisible>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Path="Theirs" Converter="{x:Static ObjectConverters.IsNotNull}"/>
<Binding Path="Mine" Converter="{x:Static ObjectConverters.IsNotNull}"/>
</MultiBinding>
</Border.IsVisible>
<Grid Margin="8,0,0,0" RowDefinitions="32,32,*" ColumnDefinitions="*,1,*,1,*,1,12">
<TextBlock Grid.Row="0" Grid.Column="0" Classes="info_label" HorizontalAlignment="Left" Text="MINE"/>
<ContentControl Grid.Row="1" Grid.Column="0" Margin="16,0,0,0" HorizontalAlignment="Left" Content="{Binding Mine}"/>
<TextBlock Grid.Row="0" Grid.RowSpan="2" Grid.Column="2" Classes="info_label" HorizontalAlignment="Center" Text="{DynamicResource Text.WorkingCopy}"/>
<TextBlock Grid.Row="0" Grid.Column="4" Classes="info_label" HorizontalAlignment="Right" Text="THEIRS"/>
<ContentControl Grid.Row="1" Grid.Column="4" Margin="16,0,0,0" HorizontalAlignment="Right" Content="{Binding Theirs}"/>
<v:ConflictTextDiffPresenter Grid.Row="2" Grid.Column="0"
x:Name="OurSidePresenter"
DisplaySide="0"
Foreground="{DynamicResource Brush.FG1}"
LineBrush="{DynamicResource Brush.Border2}"
EmptyContentBackground="{DynamicResource Brush.Diff.EmptyBG}"
AddedContentBackground="{DynamicResource Brush.Diff.AddedBG}"
DeletedContentBackground="{DynamicResource Brush.Diff.DeletedBG}"
AddedHighlightBrush="{DynamicResource Brush.Diff.AddedHighlight}"
DeletedHighlightBrush="{DynamicResource Brush.Diff.DeletedHighlight}"
IndicatorForeground="{DynamicResource Brush.FG2}"
FontFamily="{DynamicResource Fonts.Monospace}"
FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorFontSize}"
UseSyntaxHighlighting="{Binding Source={x:Static vm:Preferences.Instance}, Path=UseSyntaxHighlighting}"
WordWrap="False"
ShowHiddenSymbols="{Binding Source={x:Static vm:Preferences.Instance}, Path=ShowHiddenSymbolsInDiffView}"
EnableChunkSelection="True"/>
<Rectangle Grid.Row="2" Grid.Column="1" Fill="{DynamicResource Brush.Border2}" Width="1" HorizontalAlignment="Center" VerticalAlignment="Stretch"/>
<v:ConflictTextDiffPresenter Grid.Row="2" Grid.Column="2"
x:Name="WorkingCopyPresenter"
DisplaySide="1"
Foreground="{DynamicResource Brush.FG1}"
LineBrush="{DynamicResource Brush.Border2}"
EmptyContentBackground="{DynamicResource Brush.Diff.EmptyBG}"
AddedContentBackground="{DynamicResource Brush.Diff.AddedBG}"
DeletedContentBackground="{DynamicResource Brush.Diff.DeletedBG}"
AddedHighlightBrush="{DynamicResource Brush.Diff.AddedHighlight}"
DeletedHighlightBrush="{DynamicResource Brush.Diff.DeletedHighlight}"
IndicatorForeground="{DynamicResource Brush.FG2}"
FontFamily="{DynamicResource Fonts.Monospace}"
FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorFontSize}"
UseSyntaxHighlighting="{Binding Source={x:Static vm:Preferences.Instance}, Path=UseSyntaxHighlighting}"
WordWrap="False"
ShowHiddenSymbols="{Binding Source={x:Static vm:Preferences.Instance}, Path=ShowHiddenSymbolsInDiffView}"/>
<Rectangle Grid.Row="2" Grid.Column="3" Fill="{DynamicResource Brush.Border2}" Width="1" HorizontalAlignment="Center" VerticalAlignment="Stretch"/>
<v:ConflictTextDiffPresenter Grid.Row="2" Grid.Column="4"
x:Name="TherrSidePresenter"
DisplaySide="2"
Foreground="{DynamicResource Brush.FG1}"
LineBrush="{DynamicResource Brush.Border2}"
EmptyContentBackground="{DynamicResource Brush.Diff.EmptyBG}"
AddedContentBackground="{DynamicResource Brush.Diff.AddedBG}"
DeletedContentBackground="{DynamicResource Brush.Diff.DeletedBG}"
AddedHighlightBrush="{DynamicResource Brush.Diff.AddedHighlight}"
DeletedHighlightBrush="{DynamicResource Brush.Diff.DeletedHighlight}"
IndicatorForeground="{DynamicResource Brush.FG2}"
FontFamily="{DynamicResource Fonts.Monospace}"
FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorFontSize}"
UseSyntaxHighlighting="{Binding Source={x:Static vm:Preferences.Instance}, Path=UseSyntaxHighlighting}"
WordWrap="False"
ShowHiddenSymbols="{Binding Source={x:Static vm:Preferences.Instance}, Path=ShowHiddenSymbolsInDiffView}"/>
<Rectangle Grid.Row="2" Grid.Column="5" Fill="{DynamicResource Brush.Border2}" Width="1" HorizontalAlignment="Center" VerticalAlignment="Stretch"/>
<v:TextDiffViewMinimap Grid.Column="6"
DisplayRange="{Binding #OurSidePresenter.DisplayRange}"
AddedLineBrush="{DynamicResource Brush.Diff.AddedBG}"
DeletedLineBrush="{DynamicResource Brush.Diff.DeletedBG}"/>
</Grid>
</Border>
<StackPanel Margin="0,8,0,0" Orientation="Horizontal" HorizontalAlignment="Center">
<Button Classes="flat" Content="USE THEIRS" Command="{Binding UseTheirs}"/>
<Button Classes="flat" Margin="8,0,0,0" Content="USE MINE" Command="{Binding UseMine}"/>
<Button Classes="flat" Margin="8,0,0,0" Content="OPEN EXTERNAL MERGETOOL" Command="{Binding OpenExternalMergeTool}"/>
</StackPanel>
</StackPanel>
<StackPanel Orientation="Vertical" IsVisible="{Binding IsResolved}">
<Path Width="64" Height="64" Data="{StaticResource Icons.Check}" Fill="Green"/>
<TextBlock Margin="0,16,0,8" FontSize="20" FontWeight="Bold" Text="{DynamicResource Text.WorkingCopy.Conflicts.Resolved}" Foreground="{DynamicResource Brush.FG2}" HorizontalAlignment="Center"/>
<TextBlock Text="{DynamicResource Text.WorkingCopy.CanStageTip}" Foreground="{DynamicResource Brush.FG2}" HorizontalAlignment="Center"/>
</StackPanel>
</Grid>
</Border>
</DataTemplate>
<DataTemplate DataType="vm:DiffContext">