Skip to content

Commit 89f9eb3

Browse files
committed
feature: add pattern to .gitignore by unstaged changes' context menu
1 parent 20f5a6e commit 89f9eb3

File tree

6 files changed

+96
-11
lines changed

6 files changed

+96
-11
lines changed

src/Commands/GitIgnore.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System.IO;
2+
3+
namespace SourceGit.Commands
4+
{
5+
public static class GitIgnore
6+
{
7+
public static void Add(string repo, string pattern)
8+
{
9+
var file = Path.Combine(repo, ".gitignore");
10+
if (!File.Exists(file))
11+
File.WriteAllLines(file, [ pattern ]);
12+
else
13+
File.AppendAllLines(file, [ pattern ]);
14+
}
15+
}
16+
}

src/Resources/Icons.axaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,5 @@
9999
<StreamGeometry x:Key="Icons.Compare">M645 448l64 64 220-221L704 64l-64 64 115 115H128v90h628zM375 576l-64-64-220 224L314 960l64-64-116-115H896v-90H262z</StreamGeometry>
100100
<StreamGeometry x:Key="Icons.WordWrap">M248 221a77 77 0 00-30-21c-18-7-40-10-68-5a224 224 0 00-45 13c-5 2-10 5-15 8l-3 2v68l11-9c10-8 21-14 34-19 13-5 26-7 39-7 12 0 21 3 28 10 6 6 9 16 9 29l-62 9c-14 2-26 6-36 11a80 80 0 00-25 20c-7 8-12 17-15 27-6 21-6 44 1 65a70 70 0 0041 43c10 4 21 6 34 6a80 80 0 0063-28v22h64V298c0-16-2-31-6-44a91 91 0 00-18-33zm-41 121v15c0 8-1 15-4 22a48 48 0 01-24 29 44 44 0 01-33 2 29 29 0 01-10-6 25 25 0 01-6-9 30 30 0 01-2-12c0-5 1-9 2-14a21 21 0 015-9 28 28 0 0110-7 83 83 0 0120-5l42-6zm323-68a144 144 0 00-16-42 87 87 0 00-28-29 75 75 0 00-41-11 73 73 0 00-44 14c-6 5-12 11-17 17V64H326v398h59v-18c8 10 18 17 30 21 6 2 13 3 21 3 16 0 31-4 43-11 12-7 23-18 31-31a147 147 0 0019-46 248 248 0 006-57c0-17-2-33-5-49zm-55 49c0 15-1 28-4 39-2 11-6 20-10 27a41 41 0 01-15 15 37 37 0 01-36 1 44 44 0 01-13-12 59 59 0 01-9-18A76 76 0 01384 352v-33c0-10 1-20 4-29 2-8 6-15 10-22a43 43 0 0115-13 37 37 0 0119-5 35 35 0 0132 18c4 6 7 14 9 23 2 9 3 20 3 31zM154 634a58 58 0 0120-15c14-6 35-7 49-1 7 3 13 6 20 12l21 17V572l-6-4a124 124 0 00-58-14c-20 0-38 4-54 11-16 7-30 17-41 30-12 13-20 29-26 46-6 17-9 36-9 57 0 18 3 36 8 52 6 16 14 30 24 42 10 12 23 21 38 28 15 7 32 10 50 10 15 0 28-2 39-5 11-3 21-8 30-14l5-4v-57l-13 6a26 26 0 01-5 2c-3 1-6 2-8 3-2 1-15 6-15 6-4 2-9 3-14 4a63 63 0 01-38-4 53 53 0 01-20-14 70 70 0 01-13-24 111 111 0 01-5-34c0-13 2-26 5-36 3-10 8-19 14-26zM896 384h-256V320h288c21 1 32 12 32 32v384c0 18-12 32-32 32H504l132 133-45 45-185-185c-16-21-16-25 0-45l185-185L637 576l-128 128H896V384z</StreamGeometry>
101101
<StreamGeometry x:Key="Icons.Detached">M128 183C128 154 154 128 183 128h521c30 0 55 26 55 55v38c0 17-17 34-34 34s-34-17-34-34v-26H196v495h26c17 0 34 17 34 34s-17 34-34 34h-38c-30 0-55-26-55-55V183zM380 896h-34c-26 0-47-21-47-47v-90h68V828h64V896H380c4 0 0 0 0 0zM759 828V896h90c26 0 47-21 47-47v-90h-68V828h-68zM828 435H896V346c0-26-21-47-47-47h-90v68H828v68zM435 299v68H367V439H299V346C299 320 320 299 346 299h90zM367 649H299v-107h68v107zM546 367V299h107v68h-107zM828 546H896v107h-68v-107zM649 828V896h-107v-68h107zM730 508v188c0 17-17 34-34 34h-188c-17 0-34-17-34-34s17-34 34-34h102l-124-124c-13-13-13-34 0-47 13-13 34-13 47 0l124 124V512c0-17 17-34 34-34 21-4 38 9 38 30z</StreamGeometry>
102+
<StreamGeometry x:Key="Icons.GitIgnore">M590 74 859 342V876c0 38-31 68-68 68H233c-38 0-68-31-68-68V142c0-38 31-68 68-68h357zm-12 28H233a40 40 0 00-40 38L193 142v734a40 40 0 0038 40L233 916h558a40 40 0 0040-38L831 876V354L578 102zM855 371h-215c-46 0-83-36-84-82l0-2V74h28v213c0 30 24 54 54 55l2 0h215v28zM57 489m28 0 853 0q28 0 28 28l0 284q0 28-28 28l-853 0q-28 0-28-28l0-284q0-28 28-28ZM157 717c15 0 29-6 37-13v-51h-41v22h17v18c-2 2-6 3-10 3-21 0-30-13-30-34 0-21 12-34 28-34 9 0 15 4 20 9l14-17C184 610 172 603 156 603c-29 0-54 21-54 57 0 37 24 56 54 56zM245 711v-108h-34v108h34zm69 0v-86H341V603H262v22h28V711h24zM393 711v-108h-34v108h34zm66 6c15 0 29-6 37-13v-51h-41v22h17v18c-2 2-6 3-10 3-21 0-30-13-30-34 0-21 12-34 28-34 9 0 15 4 20 9l14-17C485 610 474 603 458 603c-29 0-54 21-54 57 0 37 24 56 54 56zm88-6v-36c0-13-2-28-3-40h1l10 24 25 52H603v-108h-23v36c0 13 2 28 3 40h-1l-10-24L548 603H523v108h23zM677 717c30 0 51-22 51-57 0-36-21-56-51-56-30 0-51 20-51 56 0 36 21 57 51 57zm3-23c-16 0-26-12-26-32 0-19 10-31 26-31 16 0 26 11 26 31S696 694 680 694zm93 17v-38h13l21 38H836l-25-43c12-5 19-15 19-31 0-26-20-34-44-34H745v108h27zm16-51H774v-34h15c16 0 25 4 25 16s-9 18-25 18zM922 711v-22h-43v-23h35v-22h-35V625h41V603H853v108h68z</StreamGeometry>
102103
</ResourceDictionary>

src/Resources/Locales/en_US.axaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,11 @@
477477
<x:String x:Key="Text.Welcome.Search" xml:space="preserve">Search Repositories ...</x:String>
478478
<x:String x:Key="Text.Welcome.Sort" xml:space="preserve">Sort</x:String>
479479
<x:String x:Key="Text.WorkingCopy" xml:space="preserve">Changes</x:String>
480+
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Add To .gitignore ...</x:String>
481+
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Ignore all *{0} files</x:String>
482+
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Ignore *{0} files in the same folder</x:String>
483+
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">Ignore files in the same folder</x:String>
484+
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ignore this file only</x:String>
480485
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Amend</x:String>
481486
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">You can stage this file now.</x:String>
482487
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">COMMIT</x:String>

src/Resources/Locales/zh_CN.axaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,11 @@
480480
<x:String x:Key="Text.Welcome.Search" xml:space="preserve">快速查找仓库...</x:String>
481481
<x:String x:Key="Text.Welcome.Sort" xml:space="preserve">排序</x:String>
482482
<x:String x:Key="Text.WorkingCopy" xml:space="preserve">本地更改</x:String>
483+
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">添加至 .gitignore 忽略列表 ...</x:String>
484+
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">忽略所有 *{0} 文件</x:String>
485+
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">忽略同目录下所有 *{0} 文件</x:String>
486+
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">忽略同目录下所有文件</x:String>
487+
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">忽略本文件</x:String>
483488
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">修补(--amend)</x:String>
484489
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">现在您已可将其加入暂存区中</x:String>
485490
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">提交</x:String>

src/Resources/Locales/zh_TW.axaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,11 @@
480480
<x:String x:Key="Text.Welcome.Search" xml:space="preserve">快速查詢倉庫...</x:String>
481481
<x:String x:Key="Text.Welcome.Sort" xml:space="preserve">排序</x:String>
482482
<x:String x:Key="Text.WorkingCopy" xml:space="preserve">本地更改</x:String>
483+
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">添加至 .gitignore 忽略清單 ...</x:String>
484+
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">忽略所有 *{0} 檔案</x:String>
485+
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">忽略同路徑下所有 *{0} 檔案</x:String>
486+
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">忽略同路徑下所有檔案</x:String>
487+
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">忽略本檔案</x:String>
483488
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">修補(--amend)</x:String>
484489
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">現在您已可將其加入暫存區中</x:String>
485490
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">提交</x:String>

src/ViewModels/WorkingCopy.cs

Lines changed: 64 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,16 @@ public ContextMenu CreateContextMenuForUnstagedChanges()
527527

528528
e.Handled = true;
529529
};
530+
531+
var assumeUnchanged = new MenuItem();
532+
assumeUnchanged.Header = App.Text("FileCM.AssumeUnchanged");
533+
assumeUnchanged.Icon = App.CreateMenuIcon("Icons.File.Ignore");
534+
assumeUnchanged.IsVisible = change.WorkTree != Models.ChangeState.Untracked;
535+
assumeUnchanged.Click += (_, e) =>
536+
{
537+
new Commands.AssumeUnchanged(_repo.FullPath).Add(change.Path);
538+
e.Handled = true;
539+
};
530540

531541
var history = new MenuItem();
532542
history.Header = App.Text("FileHistory");
@@ -538,24 +548,67 @@ public ContextMenu CreateContextMenuForUnstagedChanges()
538548
e.Handled = true;
539549
};
540550

541-
var assumeUnchanged = new MenuItem();
542-
assumeUnchanged.Header = App.Text("FileCM.AssumeUnchanged");
543-
assumeUnchanged.Icon = App.CreateMenuIcon("Icons.File.Ignore");
544-
assumeUnchanged.IsEnabled = change.WorkTree != Models.ChangeState.Untracked;
545-
assumeUnchanged.Click += (_, e) =>
546-
{
547-
new Commands.AssumeUnchanged(_repo.FullPath).Add(change.Path);
548-
e.Handled = true;
549-
};
550-
551551
menu.Items.Add(stage);
552552
menu.Items.Add(discard);
553553
menu.Items.Add(stash);
554554
menu.Items.Add(patch);
555+
menu.Items.Add(assumeUnchanged);
555556
menu.Items.Add(new MenuItem() { Header = "-" });
556557
menu.Items.Add(history);
557-
menu.Items.Add(assumeUnchanged);
558558
menu.Items.Add(new MenuItem() { Header = "-" });
559+
560+
if (change.WorkTree == Models.ChangeState.Untracked)
561+
{
562+
var isRooted = change.Path.IndexOf('/', StringComparison.Ordinal) <= 0;
563+
var addToIgnore = new MenuItem();
564+
addToIgnore.Header = App.Text("WorkingCopy.AddToGitIgnore");
565+
addToIgnore.Icon = App.CreateMenuIcon("Icons.GitIgnore");
566+
567+
var singleFile = new MenuItem();
568+
singleFile.Header = App.Text("WorkingCopy.AddToGitIgnore.SingleFile");
569+
singleFile.Click += (_, e) =>
570+
{
571+
Commands.GitIgnore.Add(_repo.FullPath, change.Path);
572+
e.Handled = true;
573+
};
574+
addToIgnore.Items.Add(singleFile);
575+
576+
var byParentFolder = new MenuItem();
577+
byParentFolder.Header = App.Text("WorkingCopy.AddToGitIgnore.InSameFolder");
578+
byParentFolder.IsVisible = !isRooted;
579+
byParentFolder.Click += (_, e) =>
580+
{
581+
Commands.GitIgnore.Add(_repo.FullPath, Path.GetDirectoryName(change.Path) + "/");
582+
e.Handled = true;
583+
};
584+
addToIgnore.Items.Add(byParentFolder);
585+
586+
var extension = Path.GetExtension(change.Path);
587+
if (!string.IsNullOrEmpty(extension))
588+
{
589+
var byExtension = new MenuItem();
590+
byExtension.Header = App.Text("WorkingCopy.AddToGitIgnore.Extension", extension);
591+
byExtension.Click += (_, e) =>
592+
{
593+
Commands.GitIgnore.Add(_repo.FullPath, "*" + extension);
594+
e.Handled = true;
595+
};
596+
addToIgnore.Items.Add(byExtension);
597+
598+
var byExtensionInSameFolder = new MenuItem();
599+
byExtensionInSameFolder.Header = App.Text("WorkingCopy.AddToGitIgnore.ExtensionInSameFolder", extension);
600+
byExtensionInSameFolder.IsVisible = !isRooted;
601+
byExtensionInSameFolder.Click += (_, e) =>
602+
{
603+
Commands.GitIgnore.Add(_repo.FullPath, Path.GetDirectoryName(change.Path) + "/*" + extension);
604+
e.Handled = true;
605+
};
606+
addToIgnore.Items.Add(byExtensionInSameFolder);
607+
}
608+
609+
menu.Items.Add(addToIgnore);
610+
menu.Items.Add(new MenuItem() { Header = "-" });
611+
}
559612
}
560613

561614
var copy = new MenuItem();

0 commit comments

Comments
 (0)