mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-10-31 13:03:20 -07:00
feature<AssumeUnchanged>: supports update-index --[no]-assume-unchanged
This commit is contained in:
parent
79b5136a46
commit
f13b1ee9fe
9 changed files with 272 additions and 3 deletions
60
src/Commands/AssumeUnchanged.cs
Normal file
60
src/Commands/AssumeUnchanged.cs
Normal file
|
@ -0,0 +1,60 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace SourceGit.Commands {
|
||||
/// <summary>
|
||||
/// 查看、添加或移除忽略变更文件
|
||||
/// </summary>
|
||||
public class AssumeUnchanged {
|
||||
private string repo;
|
||||
|
||||
class ViewCommand : Command {
|
||||
private static readonly Regex REG = new Regex(@"^(\w)\s+(.+)$");
|
||||
private List<string> outs = new List<string>();
|
||||
|
||||
public ViewCommand(string repo) {
|
||||
Cwd = repo;
|
||||
Args = "ls-files -v";
|
||||
}
|
||||
|
||||
public List<string> Result() {
|
||||
Exec();
|
||||
return outs;
|
||||
}
|
||||
|
||||
public override void OnReadline(string line) {
|
||||
var match = REG.Match(line);
|
||||
if (!match.Success) return;
|
||||
|
||||
if (match.Groups[1].Value == "h") {
|
||||
outs.Add(match.Groups[2].Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ModCommand : Command {
|
||||
public ModCommand(string repo, string file, bool bAdd) {
|
||||
var mode = bAdd ? "--assume-unchanged" : "--no-assume-unchanged";
|
||||
|
||||
Cwd = repo;
|
||||
Args = $"update-index {mode} -- \"{file}\"";
|
||||
}
|
||||
}
|
||||
|
||||
public AssumeUnchanged(string repo) {
|
||||
this.repo = repo;
|
||||
}
|
||||
|
||||
public List<string> View() {
|
||||
return new ViewCommand(repo).Result();
|
||||
}
|
||||
|
||||
public void Add(string file) {
|
||||
new ModCommand(repo, file, true).Exec();
|
||||
}
|
||||
|
||||
public void Remove(string file) {
|
||||
new ModCommand(repo, file, false).Exec();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -70,4 +70,6 @@
|
|||
|
||||
<StreamGeometry x:Key="Icon.VSCode">M719 85 388 417l-209-165L87 299v427l92 47 210-164L720 939 939 850V171zM186 610V412l104 104zm526 55L514 512l198-153z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icon.Sort">M426.7 554.7v-85.3h341.3v85.3h-341.3m0 256v-85.3h170.7v85.3h-170.7m0-512V213.3h512v85.3H426.7M256 725.3h106.7L213.3 874.7 64 725.3H170.7V298.7H64L213.3 149.3 362.7 298.7H256v426.7z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icon.Ignores">M854 170c-189-189-495-189-684 0s-189 495 0 684 495 189 684 0 187-495 0-684zM213 706c-89-137-74-325 48-444 122-122 307-137 444-48L213 706zm106 105 493-493c89 137 74 325-48 444-120 122-307 137-444 48z</StreamGeometry>
|
||||
<StreamGeometry x:Key="Icon.Empty">M469 235V107h85v128h-85zm-162-94 85 85-60 60-85-85 60-60zm469 60-85 85-60-60 85-85 60 60zm-549 183A85 85 0 01302 341H722a85 85 0 0174 42l131 225A85 85 0 01939 652V832a85 85 0 01-85 85H171a85 85 0 01-85-85v-180a85 85 0 0112-43l131-225zM722 427H302l-100 171h255l10 29a59 59 0 002 5c2 4 5 9 9 14 8 9 18 17 34 17 16 0 26-7 34-17a72 72 0 0011-18l0-0 10-29h255l-100-171zM853 683H624a155 155 0 01-12 17C593 722 560 747 512 747c-48 0-81-25-99-47a155 155 0 01-12-17H171v149h683v-149z</StreamGeometry>
|
||||
</ResourceDictionary>
|
|
@ -217,6 +217,7 @@
|
|||
<sys:String x:Key="Text.FileCM.DiscardMulti">Discard {0} files...</sys:String>
|
||||
<sys:String x:Key="Text.FileCM.StashMulti">Stash {0} files...</sys:String>
|
||||
<sys:String x:Key="Text.FileCM.SaveAsPatch">Save As Patch...</sys:String>
|
||||
<sys:String x:Key="Text.FileCM.AssumeUnchanged">Assume unchaged</sys:String>
|
||||
|
||||
<sys:String x:Key="Text.DeleteBranch">Confirm To Delete Branch</sys:String>
|
||||
<sys:String x:Key="Text.DeleteBranch.Branch">Branch :</sys:String>
|
||||
|
@ -394,6 +395,7 @@
|
|||
|
||||
<sys:String x:Key="Text.WorkingCopy">Changes</sys:String>
|
||||
<sys:String x:Key="Text.WorkingCopy.Unstaged">UNSTAGED</sys:String>
|
||||
<sys:String x:Key="Text.WorkingCopy.Unstaged.ViewAssumeUnchaged">VIEW ASSUME UNCHANGED</sys:String>
|
||||
<sys:String x:Key="Text.WorkingCopy.Unstaged.Stage">STAGE</sys:String>
|
||||
<sys:String x:Key="Text.WorkingCopy.Unstaged.StageAll">STAGE ALL</sys:String>
|
||||
<sys:String x:Key="Text.WorkingCopy.Staged">STAGED</sys:String>
|
||||
|
@ -477,6 +479,10 @@
|
|||
<sys:String x:Key="Text.Statistics.CommitterName">COMMITTER</sys:String>
|
||||
<sys:String x:Key="Text.Statistics.CommitAmount">COMMITS</sys:String>
|
||||
|
||||
<sys:String x:Key="Text.AssumeUnchanged">FILES ASSUME UNCHANGED</sys:String>
|
||||
<sys:String x:Key="Text.AssumeUnchanged.Remove">REMOVE</sys:String>
|
||||
<sys:String x:Key="Text.AssumeUnchanged.Empty">NO FILES ASSUMED AS UNCHANGED</sys:String>
|
||||
|
||||
<sys:String x:Key="Text.Weekday.0">SUN</sys:String>
|
||||
<sys:String x:Key="Text.Weekday.1">MON</sys:String>
|
||||
<sys:String x:Key="Text.Weekday.2">TUE</sys:String>
|
||||
|
|
|
@ -216,6 +216,7 @@
|
|||
<sys:String x:Key="Text.FileCM.DiscardMulti">放弃 {0} 个文件的更改...</sys:String>
|
||||
<sys:String x:Key="Text.FileCM.StashMulti">贮藏选中的 {0} 个文件...</sys:String>
|
||||
<sys:String x:Key="Text.FileCM.SaveAsPatch">另存为补丁...</sys:String>
|
||||
<sys:String x:Key="Text.FileCM.AssumeUnchanged">不跟踪此文件的更改</sys:String>
|
||||
|
||||
<sys:String x:Key="Text.DeleteBranch">确定要删除此分支吗?</sys:String>
|
||||
<sys:String x:Key="Text.DeleteBranch.Branch">分支名 :</sys:String>
|
||||
|
@ -393,6 +394,7 @@
|
|||
|
||||
<sys:String x:Key="Text.WorkingCopy">本地更改</sys:String>
|
||||
<sys:String x:Key="Text.WorkingCopy.Unstaged">未暂存</sys:String>
|
||||
<sys:String x:Key="Text.WorkingCopy.Unstaged.ViewAssumeUnchaged">查看忽略变更文件</sys:String>
|
||||
<sys:String x:Key="Text.WorkingCopy.Unstaged.Stage">暂存选中</sys:String>
|
||||
<sys:String x:Key="Text.WorkingCopy.Unstaged.StageAll">暂存所有</sys:String>
|
||||
<sys:String x:Key="Text.WorkingCopy.Staged">已暂存</sys:String>
|
||||
|
@ -476,6 +478,10 @@
|
|||
<sys:String x:Key="Text.Statistics.CommitterName">提交者</sys:String>
|
||||
<sys:String x:Key="Text.Statistics.CommitAmount">提交次数</sys:String>
|
||||
|
||||
<sys:String x:Key="Text.AssumeUnchanged">不跟踪更改的文件</sys:String>
|
||||
<sys:String x:Key="Text.AssumeUnchanged.Remove">移除</sys:String>
|
||||
<sys:String x:Key="Text.AssumeUnchanged.Empty">没有不跟踪更改的文件</sys:String>
|
||||
|
||||
<sys:String x:Key="Text.Weekday.0">星期日</sys:String>
|
||||
<sys:String x:Key="Text.Weekday.1">星期一</sys:String>
|
||||
<sys:String x:Key="Text.Weekday.2">星期二</sys:String>
|
||||
|
|
100
src/Views/AssumeUnchanged.xaml
Normal file
100
src/Views/AssumeUnchanged.xaml
Normal file
|
@ -0,0 +1,100 @@
|
|||
<controls:Window
|
||||
x:Class="SourceGit.Views.AssumeUnchanged"
|
||||
x:Name="me"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:controls="clr-namespace:SourceGit.Views.Controls"
|
||||
mc:Ignorable="d"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Title="{DynamicResource Text.AssumeUnchanged}"
|
||||
Width="600" MinHeight="200" SizeToContent="Height"
|
||||
ResizeMode="NoResize">
|
||||
<Window.Resources>
|
||||
<Style x:Key="Style.DataGridRow.Change" TargetType="{x:Type DataGridRow}" BasedOn="{StaticResource Style.DataGridRow}">
|
||||
<EventSetter Event="RequestBringIntoView" Handler="OnRequestBringIntoView"/>
|
||||
</Style>
|
||||
</Window.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="28"/>
|
||||
<RowDefinition Height="1"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Title bar -->
|
||||
<Grid Grid.Row="0" Background="{DynamicResource Brush.TitleBar}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Icon -->
|
||||
<Path Grid.Column="0" Margin="6,0" Width="16" Height="16" Data="{StaticResource Icon.Ignores}"/>
|
||||
|
||||
<!-- Title -->
|
||||
<TextBlock Grid.Column="1" Text="{DynamicResource Text.AssumeUnchanged}"/>
|
||||
|
||||
<!-- Close -->
|
||||
<controls:IconButton
|
||||
Grid.Column="3"
|
||||
Click="OnQuit"
|
||||
Width="28"
|
||||
IconSize="10"
|
||||
Icon="{StaticResource Icon.Close}"
|
||||
HoverBackground="Red"
|
||||
WindowChrome.IsHitTestVisibleInChrome="True"/>
|
||||
</Grid>
|
||||
|
||||
<Rectangle
|
||||
Grid.Row="1"
|
||||
Height="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
Fill="{DynamicResource Brush.Border0}"/>
|
||||
|
||||
<DataGrid
|
||||
Grid.Row="2"
|
||||
x:Name="list"
|
||||
Margin="8,4"
|
||||
RowHeight="24"
|
||||
SelectionMode="Extended"
|
||||
SelectionUnit="FullRow"
|
||||
Background="{DynamicResource Brush.Contents}"
|
||||
ItemsSource="{Binding ElementName=me, Path=Files}"
|
||||
RowStyle="{StaticResource Style.DataGridRow.Change}"
|
||||
Visibility="Collapsed">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn IsReadOnly="True" Width="*">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Margin="8,0" Text="{Binding .}" FontSize="14"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
||||
<DataGridTemplateColumn Width="32">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<controls:IconButton
|
||||
Grid.Column="6"
|
||||
Click="Remove"
|
||||
Width="12" Height="12"
|
||||
Margin="4,0"
|
||||
Icon="{StaticResource Icon.Close}"
|
||||
ToolTip="{DynamicResource Text.AssumeUnchanged.Remove}"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
<StackPanel Grid.Row="2" x:Name="mask" Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Collapsed">
|
||||
<Path Width="48" Height="48" Margin="0,32,0,8" Data="{StaticResource Icon.Empty}" Fill="{DynamicResource Brush.FG2}"/>
|
||||
<TextBlock Margin="0,0,0,32" Text="{DynamicResource Text.AssumeUnchanged.Empty}" Foreground="{DynamicResource Brush.FG2}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</controls:Window>
|
64
src/Views/AssumeUnchanged.xaml.cs
Normal file
64
src/Views/AssumeUnchanged.xaml.cs
Normal file
|
@ -0,0 +1,64 @@
|
|||
using System.Collections.ObjectModel;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace SourceGit.Views {
|
||||
/// <summary>
|
||||
/// 管理不跟踪变更的文件
|
||||
/// </summary>
|
||||
public partial class AssumeUnchanged : Controls.Window {
|
||||
private string repo = null;
|
||||
|
||||
public ObservableCollection<string> Files { get; set; }
|
||||
|
||||
public AssumeUnchanged(string repo) {
|
||||
this.repo = repo;
|
||||
this.Files = new ObservableCollection<string>();
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
Task.Run(() => {
|
||||
var unchanged = new Commands.AssumeUnchanged(repo).View();
|
||||
Dispatcher.Invoke(() => {
|
||||
if (unchanged.Count > 0) {
|
||||
foreach (var file in unchanged) Files.Add(file);
|
||||
|
||||
mask.Visibility = Visibility.Collapsed;
|
||||
list.Visibility = Visibility.Visible;
|
||||
list.ItemsSource = Files;
|
||||
} else {
|
||||
list.Visibility = Visibility.Collapsed;
|
||||
mask.Visibility = Visibility.Visible;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void OnQuit(object sender, RoutedEventArgs e) {
|
||||
Close();
|
||||
}
|
||||
|
||||
private void OnRequestBringIntoView(object sender, RequestBringIntoViewEventArgs e) {
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void Remove(object sender, RoutedEventArgs e) {
|
||||
var btn = sender as Button;
|
||||
if (btn == null) return;
|
||||
|
||||
var file = btn.DataContext as string;
|
||||
if (file == null) return;
|
||||
|
||||
new Commands.AssumeUnchanged(repo).Remove(file);
|
||||
Files.Remove(file);
|
||||
|
||||
if (Files.Count == 0) {
|
||||
list.Visibility = Visibility.Collapsed;
|
||||
mask.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -41,6 +41,7 @@
|
|||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<controls:ChangeDisplaySwitcher
|
||||
|
@ -61,8 +62,15 @@
|
|||
x:Name="iconStaging"
|
||||
IsAnimating="{Binding ElementName=unstagedContainer, Path=IsStaging}"
|
||||
Visibility="{Binding ElementName=unstagedContainer, Path=IsStaging, Converter={StaticResource BoolToCollapsed}}"/>
|
||||
<ToggleButton
|
||||
<controls:IconButton
|
||||
Grid.Column="4"
|
||||
Click="ViewAssumeUnchanged"
|
||||
Width="14" Height="14"
|
||||
Margin="4,0"
|
||||
Icon="{StaticResource Icon.Ignores}"
|
||||
ToolTip="{DynamicResource Text.WorkingCopy.Unstaged.ViewAssumeUnchaged}"/>
|
||||
<ToggleButton
|
||||
Grid.Column="5"
|
||||
Width="14" Height="14"
|
||||
Margin="4,0"
|
||||
Style="{StaticResource Style.ToggleButton.Eye}"
|
||||
|
@ -70,14 +78,14 @@
|
|||
IsChecked="{Binding Source={x:Static models:Preference.Instance}, Path=Git.IncludeUntrackedInWC, Mode=TwoWay}"
|
||||
Checked="ToggleIncludeUntracked" Unchecked="ToggleIncludeUntracked"/>
|
||||
<controls:IconButton
|
||||
Grid.Column="5"
|
||||
Grid.Column="6"
|
||||
Click="StageSelected"
|
||||
Width="14" Height="14"
|
||||
Margin="4,0"
|
||||
Icon="{StaticResource Icon.Down}"
|
||||
ToolTip="{DynamicResource Text.WorkingCopy.Unstaged.Stage}"/>
|
||||
<controls:IconButton
|
||||
Grid.Column="6"
|
||||
Grid.Column="7"
|
||||
Click="StageAll"
|
||||
Width="14" Height="14"
|
||||
Margin="4,0"
|
||||
|
|
|
@ -98,6 +98,12 @@ namespace SourceGit.Views.Widgets {
|
|||
}
|
||||
|
||||
#region STAGE_UNSTAGE
|
||||
private void ViewAssumeUnchanged(object sender, RoutedEventArgs e) {
|
||||
var dialog = new AssumeUnchanged(repo.Path);
|
||||
dialog.Owner = App.Current.MainWindow;
|
||||
dialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void StageSelected(object sender, RoutedEventArgs e) {
|
||||
unstagedContainer.StageSelected();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Microsoft.Win32;
|
||||
using SourceGit.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
|
@ -484,6 +485,14 @@ namespace SourceGit.Views.Widgets {
|
|||
menu.Items.Add(patch);
|
||||
menu.Items.Add(new Separator());
|
||||
if (node.Change != null) {
|
||||
var assumeUnchanged = new MenuItem();
|
||||
assumeUnchanged.Header = App.Text("FileCM.AssumeUnchanged");
|
||||
assumeUnchanged.Click += (o, e) => {
|
||||
new Commands.AssumeUnchanged(repo).Add(node.Path);
|
||||
e.Handled = true;
|
||||
};
|
||||
menu.Items.Add(assumeUnchanged);
|
||||
|
||||
var history = new MenuItem();
|
||||
history.Header = App.Text("FileHistory");
|
||||
history.Click += (o, e) => {
|
||||
|
@ -622,6 +631,13 @@ namespace SourceGit.Views.Widgets {
|
|||
e.Handled = true;
|
||||
};
|
||||
|
||||
var assumeUnchanged = new MenuItem();
|
||||
assumeUnchanged.Header = App.Text("FileCM.AssumeUnchanged");
|
||||
assumeUnchanged.Click += (o, e) => {
|
||||
new Commands.AssumeUnchanged(repo).Add(change.Path);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
menu.Items.Add(explore);
|
||||
menu.Items.Add(new Separator());
|
||||
menu.Items.Add(stage);
|
||||
|
@ -629,6 +645,7 @@ namespace SourceGit.Views.Widgets {
|
|||
menu.Items.Add(stash);
|
||||
menu.Items.Add(patch);
|
||||
menu.Items.Add(new Separator());
|
||||
menu.Items.Add(assumeUnchanged);
|
||||
menu.Items.Add(history);
|
||||
menu.Items.Add(new Separator());
|
||||
menu.Items.Add(copyPath);
|
||||
|
|
Loading…
Reference in a new issue