mirror of
https://github.com/sourcegit-scm/sourcegit
synced 2025-05-22 12:45:00 +00:00
Add button for running external mergetool on ALL conflicts (#1173)
* Make a few non-translated strings localizable (in Conflict view) * Add button and wiring to run mergetool on all conflicts * Corrected spelling and wording in related code and exception msg
This commit is contained in:
parent
3b18ee0b37
commit
47824dc27a
7 changed files with 48 additions and 25 deletions
|
@ -13,9 +13,12 @@ namespace SourceGit.Commands
|
||||||
cmd.Context = repo;
|
cmd.Context = repo;
|
||||||
cmd.RaiseError = true;
|
cmd.RaiseError = true;
|
||||||
|
|
||||||
|
// NOTE: If no <file> names are specified, 'git mergetool' will run the merge tool program on every file with merge conflicts.
|
||||||
|
var file_arg = string.IsNullOrEmpty(file) ? "" : $"\"{file}\"";
|
||||||
|
|
||||||
if (toolType == 0)
|
if (toolType == 0)
|
||||||
{
|
{
|
||||||
cmd.Args = $"mergetool \"{file}\"";
|
cmd.Args = $"mergetool {file_arg}";
|
||||||
return cmd.Exec();
|
return cmd.Exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +35,7 @@ namespace SourceGit.Commands
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Args = $"-c mergetool.sourcegit.cmd=\"\\\"{toolPath}\\\" {supported.Cmd}\" -c mergetool.writeToTemp=true -c mergetool.keepBackup=false -c mergetool.trustExitCode=true mergetool --tool=sourcegit \"{file}\"";
|
cmd.Args = $"-c mergetool.sourcegit.cmd=\"\\\"{toolPath}\\\" {supported.Cmd}\" -c mergetool.writeToTemp=true -c mergetool.keepBackup=false -c mergetool.trustExitCode=true mergetool --tool=sourcegit {file_arg}";
|
||||||
return cmd.Exec();
|
return cmd.Exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ namespace SourceGit.Models
|
||||||
public string OriginalPath { get; set; } = "";
|
public string OriginalPath { get; set; } = "";
|
||||||
public ChangeDataForAmend DataForAmend { get; set; } = null;
|
public ChangeDataForAmend DataForAmend { get; set; } = null;
|
||||||
|
|
||||||
public bool IsConflit
|
public bool IsConflict
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|
|
@ -726,7 +726,11 @@
|
||||||
<x:String x:Key="Text.WorkingCopy.CommitWithAutoStage" xml:space="preserve">Stage all changes and commit</x:String>
|
<x:String x:Key="Text.WorkingCopy.CommitWithAutoStage" xml:space="preserve">Stage all changes and commit</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.ConfirmCommitWithFilter">You have staged {0} file(s) but only {1} file(s) displayed ({2} files are filtered out). Do you want to continue?</x:String>
|
<x:String x:Key="Text.WorkingCopy.ConfirmCommitWithFilter">You have staged {0} file(s) but only {1} file(s) displayed ({2} files are filtered out). Do you want to continue?</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">CONFLICTS DETECTED</x:String>
|
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">CONFLICTS DETECTED</x:String>
|
||||||
|
<x:String x:Key="Text.WorkingCopy.Conflicts.OpenExternalMergeTool" xml:space="preserve">OPEN EXTERNAL MERGETOOL</x:String>
|
||||||
|
<x:String x:Key="Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts" xml:space="preserve">OPEN ALL CONFLICTS IN EXTERNAL MERGETOOL</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">FILE CONFLICTS ARE RESOLVED</x:String>
|
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">FILE CONFLICTS ARE RESOLVED</x:String>
|
||||||
|
<x:String x:Key="Text.WorkingCopy.Conflicts.UseMine" xml:space="preserve">USE MINE</x:String>
|
||||||
|
<x:String x:Key="Text.WorkingCopy.Conflicts.UseTheirs" xml:space="preserve">USE THEIRS</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">INCLUDE UNTRACKED FILES</x:String>
|
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">INCLUDE UNTRACKED FILES</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.NoCommitHistories" xml:space="preserve">NO RECENT INPUT MESSAGES</x:String>
|
<x:String x:Key="Text.WorkingCopy.NoCommitHistories" xml:space="preserve">NO RECENT INPUT MESSAGES</x:String>
|
||||||
<x:String x:Key="Text.WorkingCopy.NoCommitTemplates" xml:space="preserve">NO COMMIT TEMPLATES</x:String>
|
<x:String x:Key="Text.WorkingCopy.NoCommitTemplates" xml:space="preserve">NO COMMIT TEMPLATES</x:String>
|
||||||
|
|
|
@ -243,7 +243,7 @@ namespace SourceGit.ViewModels
|
||||||
// Just force refresh selected changes.
|
// Just force refresh selected changes.
|
||||||
Dispatcher.UIThread.Invoke(() =>
|
Dispatcher.UIThread.Invoke(() =>
|
||||||
{
|
{
|
||||||
HasUnsolvedConflicts = _cached.Find(x => x.IsConflit) != null;
|
HasUnsolvedConflicts = _cached.Find(x => x.IsConflict) != null;
|
||||||
|
|
||||||
UpdateDetail();
|
UpdateDetail();
|
||||||
UpdateInProgressState();
|
UpdateInProgressState();
|
||||||
|
@ -275,7 +275,7 @@ namespace SourceGit.ViewModels
|
||||||
if (c.WorkTree != Models.ChangeState.None)
|
if (c.WorkTree != Models.ChangeState.None)
|
||||||
{
|
{
|
||||||
unstaged.Add(c);
|
unstaged.Add(c);
|
||||||
hasConflict |= c.IsConflit;
|
hasConflict |= c.IsConflict;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,6 +314,12 @@ namespace SourceGit.ViewModels
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OpenExternalMergeToolAllConflicts()
|
||||||
|
{
|
||||||
|
// No <file> arg, mergetool runs on all files with merge conflicts!
|
||||||
|
UseExternalMergeTool(null);
|
||||||
|
}
|
||||||
|
|
||||||
public void OpenAssumeUnchanged()
|
public void OpenAssumeUnchanged()
|
||||||
{
|
{
|
||||||
App.OpenDialog(new Views.AssumeUnchangedManager()
|
App.OpenDialog(new Views.AssumeUnchangedManager()
|
||||||
|
@ -373,7 +379,7 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
foreach (var change in changes)
|
foreach (var change in changes)
|
||||||
{
|
{
|
||||||
if (!change.IsConflit)
|
if (!change.IsConflict)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (change.WorkTree == Models.ChangeState.Deleted)
|
if (change.WorkTree == Models.ChangeState.Deleted)
|
||||||
|
@ -413,7 +419,7 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
foreach (var change in changes)
|
foreach (var change in changes)
|
||||||
{
|
{
|
||||||
if (!change.IsConflit)
|
if (!change.IsConflict)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (change.Index == Models.ChangeState.Deleted)
|
if (change.Index == Models.ChangeState.Deleted)
|
||||||
|
@ -448,7 +454,8 @@ namespace SourceGit.ViewModels
|
||||||
{
|
{
|
||||||
var toolType = Preferences.Instance.ExternalMergeToolType;
|
var toolType = Preferences.Instance.ExternalMergeToolType;
|
||||||
var toolPath = Preferences.Instance.ExternalMergeToolPath;
|
var toolPath = Preferences.Instance.ExternalMergeToolPath;
|
||||||
await Task.Run(() => Commands.MergeTool.OpenForMerge(_repo.FullPath, toolType, toolPath, change.Path));
|
var file = change?.Path; // NOTE: With no <file> arg, mergetool runs on on every file with merge conflicts!
|
||||||
|
await Task.Run(() => Commands.MergeTool.OpenForMerge(_repo.FullPath, toolType, toolPath, file));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ContinueMerge()
|
public void ContinueMerge()
|
||||||
|
@ -585,7 +592,7 @@ namespace SourceGit.ViewModels
|
||||||
menu.Items.Add(openWith);
|
menu.Items.Add(openWith);
|
||||||
menu.Items.Add(new MenuItem() { Header = "-" });
|
menu.Items.Add(new MenuItem() { Header = "-" });
|
||||||
|
|
||||||
if (change.IsConflit)
|
if (change.IsConflict)
|
||||||
{
|
{
|
||||||
var useTheirs = new MenuItem();
|
var useTheirs = new MenuItem();
|
||||||
useTheirs.Icon = App.CreateMenuIcon("Icons.Incoming");
|
useTheirs.Icon = App.CreateMenuIcon("Icons.Incoming");
|
||||||
|
@ -924,20 +931,20 @@ namespace SourceGit.ViewModels
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var hasConflicts = false;
|
var hasConflicts = false;
|
||||||
var hasNoneConflicts = false;
|
var hasNonConflicts = false;
|
||||||
foreach (var change in _selectedUnstaged)
|
foreach (var change in _selectedUnstaged)
|
||||||
{
|
{
|
||||||
if (change.IsConflit)
|
if (change.IsConflict)
|
||||||
hasConflicts = true;
|
hasConflicts = true;
|
||||||
else
|
else
|
||||||
hasNoneConflicts = true;
|
hasNonConflicts = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasConflicts)
|
if (hasConflicts)
|
||||||
{
|
{
|
||||||
if (hasNoneConflicts)
|
if (hasNonConflicts)
|
||||||
{
|
{
|
||||||
App.RaiseException(_repo.FullPath, "You have selected both non-conflict changes with conflicts!");
|
App.RaiseException(_repo.FullPath, "Selection contains both conflict and non-conflict changes!");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1644,7 +1651,7 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
if (change == null)
|
if (change == null)
|
||||||
DetailContext = null;
|
DetailContext = null;
|
||||||
else if (change.IsConflit && isUnstaged)
|
else if (change.IsConflict && isUnstaged)
|
||||||
DetailContext = new Conflict(_repo, this, change);
|
DetailContext = new Conflict(_repo, this, change);
|
||||||
else
|
else
|
||||||
DetailContext = new DiffContext(_repo.FullPath, new Models.DiffOption(change, isUnstaged), _detailContext as DiffContext);
|
DetailContext = new DiffContext(_repo.FullPath, new Models.DiffOption(change, isUnstaged), _detailContext as DiffContext);
|
||||||
|
|
|
@ -93,7 +93,7 @@ namespace SourceGit.Views
|
||||||
string indicator;
|
string indicator;
|
||||||
if (IsUnstagedChange)
|
if (IsUnstagedChange)
|
||||||
{
|
{
|
||||||
if (Change.IsConflit)
|
if (Change.IsConflict)
|
||||||
{
|
{
|
||||||
background = Brushes.OrangeRed;
|
background = Brushes.OrangeRed;
|
||||||
indicator = "!";
|
indicator = "!";
|
||||||
|
@ -139,7 +139,7 @@ namespace SourceGit.Views
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isUnstaged)
|
if (isUnstaged)
|
||||||
ToolTip.SetTip(this, c.IsConflit ? "Conflict" : TIPS[(int)c.WorkTree]);
|
ToolTip.SetTip(this, c.IsConflict ? "Conflict" : TIPS[(int)c.WorkTree]);
|
||||||
else
|
else
|
||||||
ToolTip.SetTip(this, TIPS[(int)c.Index]);
|
ToolTip.SetTip(this, TIPS[(int)c.Index]);
|
||||||
|
|
||||||
|
|
|
@ -105,9 +105,9 @@
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<StackPanel Margin="0,8,0,0" Orientation="Horizontal" HorizontalAlignment="Center">
|
<StackPanel Margin="0,8,0,0" Orientation="Horizontal" HorizontalAlignment="Center">
|
||||||
<Button Classes="flat" Content="USE THEIRS" Command="{Binding UseTheirs}"/>
|
<Button Classes="flat" Margin="0,0,0,0" Content="{DynamicResource Text.WorkingCopy.Conflicts.UseTheirs}" 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="{DynamicResource Text.WorkingCopy.Conflicts.UseMine}" Command="{Binding UseMine}"/>
|
||||||
<Button Classes="flat" Margin="8,0,0,0" Content="OPEN EXTERNAL MERGETOOL" Command="{Binding OpenExternalMergeTool}"/>
|
<Button Classes="flat" Margin="8,0,0,0" Content="{DynamicResource Text.WorkingCopy.Conflicts.OpenExternalMergeTool}" Command="{Binding OpenExternalMergeTool}"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
|
|
@ -61,13 +61,22 @@
|
||||||
<Grid Grid.Row="1" RowDefinitions="28,*">
|
<Grid Grid.Row="1" RowDefinitions="28,*">
|
||||||
<!-- Unstaged Toolbar -->
|
<!-- Unstaged Toolbar -->
|
||||||
<Border Grid.Row="0" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}">
|
<Border Grid.Row="0" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}">
|
||||||
<Grid ColumnDefinitions="Auto,Auto,Auto,Auto,*,Auto,Auto,Auto,Auto,Auto">
|
<Grid ColumnDefinitions="Auto,Auto,Auto,Auto,*,Auto,Auto,Auto,Auto,Auto,Auto">
|
||||||
<Path Grid.Column="0" Margin="8,0,0,0" Width="14" Height="14" Fill="{DynamicResource Brush.FG2}" Data="{StaticResource Icons.Changes}"/>
|
<Path Grid.Column="0" Margin="8,0,0,0" Width="14" Height="14" Fill="{DynamicResource Brush.FG2}" Data="{StaticResource Icons.Changes}"/>
|
||||||
<TextBlock Grid.Column="1" Text="{DynamicResource Text.WorkingCopy.Unstaged}" Foreground="{DynamicResource Brush.FG2}" FontWeight="Bold" Margin="4,0,0,0"/>
|
<TextBlock Grid.Column="1" Text="{DynamicResource Text.WorkingCopy.Unstaged}" Foreground="{DynamicResource Brush.FG2}" FontWeight="Bold" Margin="4,0,0,0"/>
|
||||||
<TextBlock Grid.Column="2" FontWeight="Bold" Foreground="{DynamicResource Brush.FG2}" Text="{Binding Unstaged, Converter={x:Static c:ListConverters.ToCount}}"/>
|
<TextBlock Grid.Column="2" FontWeight="Bold" Foreground="{DynamicResource Brush.FG2}" Text="{Binding Unstaged, Converter={x:Static c:ListConverters.ToCount}}"/>
|
||||||
<v:LoadingIcon Grid.Column="3" Width="14" Height="14" Margin="8,0,0,0" IsVisible="{Binding IsStaging}"/>
|
<v:LoadingIcon Grid.Column="3" Width="14" Height="14" Margin="8,0,0,0" IsVisible="{Binding IsStaging}"/>
|
||||||
|
|
||||||
<Button Grid.Column="5"
|
<Button Grid.Column="5"
|
||||||
|
Classes="icon_button"
|
||||||
|
Width="26" Height="14"
|
||||||
|
Padding="0"
|
||||||
|
IsVisible="{Binding HasUnsolvedConflicts}"
|
||||||
|
ToolTip.Tip="{DynamicResource Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts}"
|
||||||
|
Command="{Binding OpenExternalMergeToolAllConflicts}">
|
||||||
|
<Path Width="14" Height="14" Data="{StaticResource Icons.Conflict}"/>
|
||||||
|
</Button>
|
||||||
|
<Button Grid.Column="6"
|
||||||
Classes="icon_button"
|
Classes="icon_button"
|
||||||
Width="26" Height="14"
|
Width="26" Height="14"
|
||||||
Padding="0"
|
Padding="0"
|
||||||
|
@ -75,12 +84,12 @@
|
||||||
Command="{Binding OpenAssumeUnchanged}">
|
Command="{Binding OpenAssumeUnchanged}">
|
||||||
<Path Width="14" Height="14" Data="{StaticResource Icons.File.Ignore}"/>
|
<Path Width="14" Height="14" Data="{StaticResource Icons.File.Ignore}"/>
|
||||||
</Button>
|
</Button>
|
||||||
<ToggleButton Grid.Column="6"
|
<ToggleButton Grid.Column="7"
|
||||||
Classes="toggle_untracked"
|
Classes="toggle_untracked"
|
||||||
Width="26" Height="14"
|
Width="26" Height="14"
|
||||||
ToolTip.Tip="{DynamicResource Text.WorkingCopy.IncludeUntracked}"
|
ToolTip.Tip="{DynamicResource Text.WorkingCopy.IncludeUntracked}"
|
||||||
IsChecked="{Binding IncludeUntracked, Mode=TwoWay}"/>
|
IsChecked="{Binding IncludeUntracked, Mode=TwoWay}"/>
|
||||||
<Button Grid.Column="7"
|
<Button Grid.Column="8"
|
||||||
Classes="icon_button"
|
Classes="icon_button"
|
||||||
Width="26" Height="14"
|
Width="26" Height="14"
|
||||||
Padding="0"
|
Padding="0"
|
||||||
|
@ -93,7 +102,7 @@
|
||||||
</ToolTip.Tip>
|
</ToolTip.Tip>
|
||||||
<Path Width="14" Height="14" Margin="0,6,0,0" Data="{StaticResource Icons.Down}"/>
|
<Path Width="14" Height="14" Margin="0,6,0,0" Data="{StaticResource Icons.Down}"/>
|
||||||
</Button>
|
</Button>
|
||||||
<Button Grid.Column="8"
|
<Button Grid.Column="9"
|
||||||
Classes="icon_button"
|
Classes="icon_button"
|
||||||
Width="26" Height="14"
|
Width="26" Height="14"
|
||||||
Padding="0"
|
Padding="0"
|
||||||
|
@ -101,7 +110,7 @@
|
||||||
Command="{Binding StageAll}">
|
Command="{Binding StageAll}">
|
||||||
<Path Width="14" Height="14" Data="{StaticResource Icons.DoubleDown}"/>
|
<Path Width="14" Height="14" Data="{StaticResource Icons.DoubleDown}"/>
|
||||||
</Button>
|
</Button>
|
||||||
<v:ChangeViewModeSwitcher Grid.Column="9"
|
<v:ChangeViewModeSwitcher Grid.Column="10"
|
||||||
Width="26" Height="14"
|
Width="26" Height="14"
|
||||||
Margin="0,1,0,0"
|
Margin="0,1,0,0"
|
||||||
ViewMode="{Binding Source={x:Static vm:Preferences.Instance}, Path=UnstagedChangeViewMode, Mode=TwoWay}"/>
|
ViewMode="{Binding Source={x:Static vm:Preferences.Instance}, Path=UnstagedChangeViewMode, Mode=TwoWay}"/>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue