From 6482ef227abe6d40f019756d5599095754a9d5bf Mon Sep 17 00:00:00 2001 From: GadflyFang Date: Tue, 21 Jan 2025 13:58:07 +0800 Subject: [PATCH 01/57] fix: prevent target branch HEAD from being changed when adding worktree (#919) * fix: prevent target branch HEAD from being changed when adding worktree Signed-off-by: Gadfly * fix: worktree path validator trigger error Signed-off-by: Gadfly --------- Signed-off-by: Gadfly --- src/Commands/Worktree.cs | 2 ++ src/ViewModels/AddWorktree.cs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Commands/Worktree.cs b/src/Commands/Worktree.cs index 7516b1e3..27c0e28e 100644 --- a/src/Commands/Worktree.cs +++ b/src/Commands/Worktree.cs @@ -73,6 +73,8 @@ namespace SourceGit.Commands if (!string.IsNullOrEmpty(tracking)) Args += tracking; + else if (!string.IsNullOrEmpty(name) && !createNew) + Args += name; _outputHandler = outputHandler; return Exec(); diff --git a/src/ViewModels/AddWorktree.cs b/src/ViewModels/AddWorktree.cs index cf736029..6c1c7481 100644 --- a/src/ViewModels/AddWorktree.cs +++ b/src/ViewModels/AddWorktree.cs @@ -12,7 +12,7 @@ namespace SourceGit.ViewModels public string Path { get => _path; - set => SetProperty(ref _path, value); + set => SetProperty(ref _path, value, true); } public bool CreateNewBranch From 90c04f1db2869e53fc0c5f8434e17c3907c3d5e6 Mon Sep 17 00:00:00 2001 From: aikawayataro Date: Tue, 21 Jan 2025 12:01:09 +0000 Subject: [PATCH 02/57] fix: `_` is not parsed in template variable name (#920) --- src/Models/TemplateEngine.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Models/TemplateEngine.cs b/src/Models/TemplateEngine.cs index 6b5f525d..8472750c 100644 --- a/src/Models/TemplateEngine.cs +++ b/src/Models/TemplateEngine.cs @@ -313,7 +313,7 @@ namespace SourceGit.Models private static bool IsNameChar(char c) { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'; } // (?) notice or log if variable is not found From cb4ad63ba358ca66de2dbb6391074fd8ea6f797d Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 22 Jan 2025 10:51:37 +0800 Subject: [PATCH 03/57] fix: discarding changes with selected changes should never be traited as `Discard all changes` (#904) --- src/ViewModels/WorkingCopy.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 67fd6990..0a33bff5 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -417,12 +417,7 @@ namespace SourceGit.ViewModels public void Discard(List changes) { if (_repo.CanCreatePopup()) - { - if (changes.Count == _unstaged.Count && _staged.Count == 0) - _repo.ShowPopup(new Discard(_repo)); - else - _repo.ShowPopup(new Discard(_repo, changes)); - } + _repo.ShowPopup(new Discard(_repo, changes)); } public async void UseTheirs(List changes) From 6ae66095c267798c2bc76817eeeb6c145008e72f Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 22 Jan 2025 10:55:38 +0800 Subject: [PATCH 04/57] project: upgrade `LiveChartsCore.SkiaSharpView.Avalonia` to `2.0.0-rc5.1` --- src/SourceGit.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SourceGit.csproj b/src/SourceGit.csproj index 7c098207..dfd00a98 100644 --- a/src/SourceGit.csproj +++ b/src/SourceGit.csproj @@ -49,7 +49,7 @@ - + From 75288e7a310ff041ad54184d2389665e9dedfdee Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 22 Jan 2025 11:19:48 +0800 Subject: [PATCH 05/57] =?UTF-8?q?ci:=20replacing=20`100%`=20and=20`100.00%?= =?UTF-8?q?`=20with=20`=E2=88=9A`=20for=20translation=20progress=20in=20RE?= =?UTF-8?q?ADME.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/scripts/localization-check.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/build/scripts/localization-check.js b/build/scripts/localization-check.js index 45db82be..76b5036b 100644 --- a/build/scripts/localization-check.js +++ b/build/scripts/localization-check.js @@ -25,7 +25,7 @@ async function calculateTranslationRate() { const files = (await fs.readdir(localesDir)).filter(file => file !== 'en_US.axaml' && file.endsWith('.axaml')); // Add en_US badge first - badges.push(`[![en_US](https://img.shields.io/badge/en__US-100%25-brightgreen)](TRANSLATION.md)`); + badges.push(`[![en_US](https://img.shields.io/badge/en_US-%E2%88%9A-brightgreen)](TRANSLATION.md)`); for (const file of files) { const filePath = path.join(localesDir, file); @@ -40,8 +40,12 @@ async function calculateTranslationRate() { // Add badges const locale = file.replace('.axaml', '').replace('_', '__'); - const badgeColor = translationRate === 100 ? 'brightgreen' : translationRate >= 75 ? 'yellow' : 'red'; - badges.push(`[![${locale}](https://img.shields.io/badge/${locale}-${translationRate.toFixed(2)}%25-${badgeColor})](TRANSLATION.md)`); + if (translationRate === 100) { + badges.push(`[![${locale}](https://img.shields.io/badge/${locale}-%E2%88%9A-brightgreen)](TRANSLATION.md)`); + } else { + const badgeColor = translationRate >= 75 ? 'yellow' : 'red'; + badges.push(`[![${locale}](https://img.shields.io/badge/${locale}-${translationRate.toFixed(2)}%25-${badgeColor})](TRANSLATION.md)`); + } } console.log(translationRates.join('\n\n')); From cd0b2326f5fc0d7cbe0865b6b9703a8116f5e1d7 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 22 Jan 2025 11:23:38 +0800 Subject: [PATCH 06/57] localization: update en_US --- src/Resources/Locales/en_US.axaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index d06f438d..3e66935f 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -273,7 +273,7 @@ Fast-Forward (without checkout) Fetch Fetch all remotes - Override refs check + Force to override refs check Fetch without tags Remote: Fetch Remote Changes From cce08fb086214a4f742104a0418c2e0bb82f3518 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 22 Jan 2025 03:23:54 +0000 Subject: [PATCH 07/57] doc: Update translation status and missing keys --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e922c476..4908fd5a 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ ## Translation Status -[![en_US](https://img.shields.io/badge/en__US-100%25-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-100.00%25-brightgreen)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-100.00%25-brightgreen)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-94.69%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-93.32%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-94.41%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-100.00%25-brightgreen)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-100.00%25-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-100.00%25-brightgreen)](TRANSLATION.md) +[![en_US](https://img.shields.io/badge/en_US-%E2%88%9A-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-%E2%88%9A-brightgreen)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-%E2%88%9A-brightgreen)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-94.69%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-93.32%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-94.41%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-%E2%88%9A-brightgreen)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-%E2%88%9A-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-%E2%88%9A-brightgreen)](TRANSLATION.md) > [!NOTE] > You can find the missing keys in [TRANSLATION.md](TRANSLATION.md) From e033a93dd814293247c4bf2201eab715fe29642f Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 22 Jan 2025 11:36:53 +0800 Subject: [PATCH 08/57] localization: update `Text.Fetch.Force` --- src/Resources/Locales/en_US.axaml | 2 +- src/Resources/Locales/zh_CN.axaml | 2 +- src/Resources/Locales/zh_TW.axaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 3e66935f..a07de46b 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -273,7 +273,7 @@ Fast-Forward (without checkout) Fetch Fetch all remotes - Force to override refs check + Force override local refs Fetch without tags Remote: Fetch Remote Changes diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index b5541376..3c087a91 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -276,7 +276,7 @@ 快进(fast-forward,无需checkout) 拉取(fetch) 拉取所有的远程仓库 - 覆盖REF检查 + 强制覆盖本地REFs 不拉取远程标签 远程仓库 : 拉取远程仓库内容 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index d2395e58..4697541d 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -276,7 +276,7 @@ 快進 (fast-forward,無需 checkout) 提取 (fetch) 提取所有的遠端存放庫 - 覆寫 REFs 檢查 + 強制覆寫本機 REFs 不提取遠端標籤 遠端存放庫: 提取遠端存放庫內容 From 620f411e9989f9397d9ff9944ac753cbf40e2650 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 22 Jan 2025 11:42:14 +0800 Subject: [PATCH 09/57] code_style: move `RevisionTextFileView` --- src/Views/RevisionFileContentViewer.axaml.cs | 110 +++++++++++++++++++ src/Views/RevisionFiles.axaml.cs | 110 ------------------- 2 files changed, 110 insertions(+), 110 deletions(-) diff --git a/src/Views/RevisionFileContentViewer.axaml.cs b/src/Views/RevisionFileContentViewer.axaml.cs index bca6a082..c74f2db2 100644 --- a/src/Views/RevisionFileContentViewer.axaml.cs +++ b/src/Views/RevisionFileContentViewer.axaml.cs @@ -1,7 +1,117 @@ +using System; + +using Avalonia; using Avalonia.Controls; +using Avalonia.Controls.Primitives; +using Avalonia.Interactivity; +using Avalonia.Media; + +using AvaloniaEdit; +using AvaloniaEdit.Document; +using AvaloniaEdit.Editing; +using AvaloniaEdit.TextMate; namespace SourceGit.Views { + public class RevisionTextFileView : TextEditor + { + protected override Type StyleKeyOverride => typeof(TextEditor); + + public RevisionTextFileView() : base(new TextArea(), new TextDocument()) + { + IsReadOnly = true; + ShowLineNumbers = true; + WordWrap = false; + HorizontalScrollBarVisibility = ScrollBarVisibility.Auto; + VerticalScrollBarVisibility = ScrollBarVisibility.Auto; + + TextArea.LeftMargins[0].Margin = new Thickness(8, 0); + TextArea.TextView.Margin = new Thickness(4, 0); + TextArea.TextView.Options.EnableHyperlinks = false; + TextArea.TextView.Options.EnableEmailHyperlinks = false; + } + + protected override void OnLoaded(RoutedEventArgs e) + { + base.OnLoaded(e); + + TextArea.TextView.ContextRequested += OnTextViewContextRequested; + UpdateTextMate(); + } + + protected override void OnUnloaded(RoutedEventArgs e) + { + base.OnUnloaded(e); + + TextArea.TextView.ContextRequested -= OnTextViewContextRequested; + + if (_textMate != null) + { + _textMate.Dispose(); + _textMate = null; + } + + GC.Collect(); + } + + protected override void OnDataContextChanged(EventArgs e) + { + base.OnDataContextChanged(e); + + if (DataContext is Models.RevisionTextFile source) + { + UpdateTextMate(); + Text = source.Content; + } + else + { + Text = string.Empty; + } + } + + private void OnTextViewContextRequested(object sender, ContextRequestedEventArgs e) + { + var selected = SelectedText; + if (string.IsNullOrEmpty(selected)) + return; + + var copy = new MenuItem() { Header = App.Text("Copy") }; + copy.Click += (_, ev) => + { + App.CopyText(selected); + ev.Handled = true; + }; + + if (this.FindResource("Icons.Copy") is Geometry geo) + { + copy.Icon = new Avalonia.Controls.Shapes.Path() + { + Width = 10, + Height = 10, + Stretch = Stretch.Uniform, + Data = geo, + }; + } + + var menu = new ContextMenu(); + menu.Items.Add(copy); + menu.Open(TextArea.TextView); + + e.Handled = true; + } + + private void UpdateTextMate() + { + if (_textMate == null) + _textMate = Models.TextMateHelper.CreateForEditor(this); + + if (DataContext is Models.RevisionTextFile file) + Models.TextMateHelper.SetGrammarByFileName(_textMate, file.FileName); + } + + private TextMate.Installation _textMate = null; + } + public partial class RevisionFileContentViewer : UserControl { public RevisionFileContentViewer() diff --git a/src/Views/RevisionFiles.axaml.cs b/src/Views/RevisionFiles.axaml.cs index f748fb0d..12dfe23a 100644 --- a/src/Views/RevisionFiles.axaml.cs +++ b/src/Views/RevisionFiles.axaml.cs @@ -1,118 +1,8 @@ -using System; - -using Avalonia; using Avalonia.Controls; -using Avalonia.Controls.Primitives; using Avalonia.Input; -using Avalonia.Interactivity; -using Avalonia.Media; - -using AvaloniaEdit; -using AvaloniaEdit.Document; -using AvaloniaEdit.Editing; -using AvaloniaEdit.TextMate; namespace SourceGit.Views { - public class RevisionTextFileView : TextEditor - { - protected override Type StyleKeyOverride => typeof(TextEditor); - - public RevisionTextFileView() : base(new TextArea(), new TextDocument()) - { - IsReadOnly = true; - ShowLineNumbers = true; - WordWrap = false; - HorizontalScrollBarVisibility = ScrollBarVisibility.Auto; - VerticalScrollBarVisibility = ScrollBarVisibility.Auto; - - TextArea.LeftMargins[0].Margin = new Thickness(8, 0); - TextArea.TextView.Margin = new Thickness(4, 0); - TextArea.TextView.Options.EnableHyperlinks = false; - TextArea.TextView.Options.EnableEmailHyperlinks = false; - } - - protected override void OnLoaded(RoutedEventArgs e) - { - base.OnLoaded(e); - - TextArea.TextView.ContextRequested += OnTextViewContextRequested; - UpdateTextMate(); - } - - protected override void OnUnloaded(RoutedEventArgs e) - { - base.OnUnloaded(e); - - TextArea.TextView.ContextRequested -= OnTextViewContextRequested; - - if (_textMate != null) - { - _textMate.Dispose(); - _textMate = null; - } - - GC.Collect(); - } - - protected override void OnDataContextChanged(EventArgs e) - { - base.OnDataContextChanged(e); - - if (DataContext is Models.RevisionTextFile source) - { - UpdateTextMate(); - Text = source.Content; - } - else - { - Text = string.Empty; - } - } - - private void OnTextViewContextRequested(object sender, ContextRequestedEventArgs e) - { - var selected = SelectedText; - if (string.IsNullOrEmpty(selected)) - return; - - var copy = new MenuItem() { Header = App.Text("Copy") }; - copy.Click += (_, ev) => - { - App.CopyText(selected); - ev.Handled = true; - }; - - if (this.FindResource("Icons.Copy") is Geometry geo) - { - copy.Icon = new Avalonia.Controls.Shapes.Path() - { - Width = 10, - Height = 10, - Stretch = Stretch.Uniform, - Data = geo, - }; - } - - var menu = new ContextMenu(); - menu.Items.Add(copy); - menu.Open(TextArea.TextView); - - e.Handled = true; - } - - private void UpdateTextMate() - { - if (_textMate == null) - _textMate = Models.TextMateHelper.CreateForEditor(this); - - if (DataContext is Models.RevisionTextFile file) - Models.TextMateHelper.SetGrammarByFileName(_textMate, file.FileName); - } - - private TextMate.Installation _textMate = null; - } - public partial class RevisionFiles : UserControl { public RevisionFiles() From e242119a036709469270e9be0049996202bbd9e2 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 23 Jan 2025 16:11:07 +0800 Subject: [PATCH 10/57] fix: searching by `Author & Committer` does not work when the committer is different with author --- src/Commands/QueryCommits.cs | 8 ++++++-- src/Models/Commit.cs | 3 ++- src/Resources/Locales/de_DE.axaml | 3 ++- src/Resources/Locales/en_US.axaml | 3 ++- src/Resources/Locales/es_ES.axaml | 3 ++- src/Resources/Locales/fr_FR.axaml | 3 ++- src/Resources/Locales/it_IT.axaml | 3 ++- src/Resources/Locales/pt_BR.axaml | 3 ++- src/Resources/Locales/ru_RU.axaml | 3 ++- src/Resources/Locales/zh_CN.axaml | 3 ++- src/Resources/Locales/zh_TW.axaml | 3 ++- src/ViewModels/Repository.cs | 9 ++++++--- src/Views/Repository.axaml | 3 ++- 13 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/Commands/QueryCommits.cs b/src/Commands/QueryCommits.cs index 6318f331..312c068f 100644 --- a/src/Commands/QueryCommits.cs +++ b/src/Commands/QueryCommits.cs @@ -18,9 +18,13 @@ namespace SourceGit.Commands { string search = onlyCurrentBranch ? string.Empty : "--branches --remotes "; - if (method == Models.CommitSearchMethod.ByUser) + if (method == Models.CommitSearchMethod.ByAuthor) { - search += $"-i --author=\"{filter}\" --committer=\"{filter}\""; + search += $"-i --author=\"{filter}\""; + } + else if (method == Models.CommitSearchMethod.ByCommitter) + { + search += $"-i --committer=\"{filter}\""; } else if (method == Models.CommitSearchMethod.ByFile) { diff --git a/src/Models/Commit.cs b/src/Models/Commit.cs index 9bc7f0c3..f015130a 100644 --- a/src/Models/Commit.cs +++ b/src/Models/Commit.cs @@ -8,7 +8,8 @@ namespace SourceGit.Models { public enum CommitSearchMethod { - ByUser, + ByAuthor, + ByCommitter, ByMessage, ByFile, } diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index 5143fc37..b771d080 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -583,10 +583,11 @@ REMOTES REMOTE HINZUFÜGEN Commit suchen + Autor + Committer Dateiname Commit-Nachricht SHA - Autor & Committer Aktueller Branch Zeige Tags als Baum ÜBERSPRINGEN diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index a07de46b..3cfff3d0 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -580,10 +580,11 @@ REMOTES ADD REMOTE Search Commit + Author + Committer File Message SHA - Author & Committer Current Branch Show Tags as Tree SKIP diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index 74b2f224..8e470eb6 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -584,10 +584,11 @@ REMOTOS AÑADIR REMOTO Buscar Commit + Autor + Committer Archivo Mensaje SHA - Autor & Committer Rama Actual Mostrar Etiquetas como Árbol OMITIR diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index e4bb9c26..71dab9dd 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -560,10 +560,11 @@ DEPOTS DISTANTS AJOUTER DEPOT DISTANT Rechercher un commit + Auteur + Committer Fichier Message SHA - Auteur & Committer Branche actuelle Voir les Tags en tant qu'arbre Statistiques diff --git a/src/Resources/Locales/it_IT.axaml b/src/Resources/Locales/it_IT.axaml index 72e2aa28..c986c133 100644 --- a/src/Resources/Locales/it_IT.axaml +++ b/src/Resources/Locales/it_IT.axaml @@ -552,10 +552,11 @@ REMOTI AGGIUNGI REMOTO Cerca Commit + Autore + Committente File Messaggio SHA - Autore & Committente Branch Corrente Mostra Tag come Albero Statistiche diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml index 8b17bdaf..e0fdcce0 100644 --- a/src/Resources/Locales/pt_BR.axaml +++ b/src/Resources/Locales/pt_BR.axaml @@ -579,10 +579,11 @@ REMOTOS ADICIONAR REMOTO Pesquisar Commit + Autor + Committer Arquivo Mensagem SHA - Autor & Committer Branch Atual Exibir Tags como Árvore Estatísticas diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index 75650a28..690512e8 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -585,10 +585,11 @@ ВНЕШНИЕ РЕПОЗИТОРИИ ДОБАВИТЬ ВНЕШНИЙ РЕПОЗИТОРИЙ Поиск ревизии + Автор + исполнитель Файл Сообщение SHA - Автор и исполнитель Текущая ветка Показывать метки как катлог ПРОПУСТИТЬ diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 3c087a91..d12fa07c 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -584,10 +584,11 @@ 远程列表 添加远程 查找提交 + 作者 + 提交者 文件 提交信息 提交指纹 - 作者及提交者 仅在当前分支中查找 以树型结构展示 跳过此提交 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 4697541d..6be685bb 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -583,10 +583,11 @@ 遠端列表 新增遠端 搜尋提交 + 作者 + 提交者 檔案 提交訊息 提交編號 - 作者及提交者 僅搜尋目前分支 以樹型結構展示 跳過此提交 diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 7f619f1e..4a606c9e 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -733,12 +733,15 @@ namespace SourceGit.ViewModels visible.Add(commit); break; case 1: - visible = new Commands.QueryCommits(_fullpath, _searchCommitFilter, Models.CommitSearchMethod.ByUser, _onlySearchCommitsInCurrentBranch).Result(); + visible = new Commands.QueryCommits(_fullpath, _searchCommitFilter, Models.CommitSearchMethod.ByAuthor, _onlySearchCommitsInCurrentBranch).Result(); break; case 2: - visible = new Commands.QueryCommits(_fullpath, _searchCommitFilter, Models.CommitSearchMethod.ByMessage, _onlySearchCommitsInCurrentBranch).Result(); + visible = new Commands.QueryCommits(_fullpath, _searchCommitFilter, Models.CommitSearchMethod.ByCommitter, _onlySearchCommitsInCurrentBranch).Result(); break; case 3: + visible = new Commands.QueryCommits(_fullpath, _searchCommitFilter, Models.CommitSearchMethod.ByMessage, _onlySearchCommitsInCurrentBranch).Result(); + break; + case 4: visible = new Commands.QueryCommits(_fullpath, _searchCommitFilter, Models.CommitSearchMethod.ByFile, _onlySearchCommitsInCurrentBranch).Result(); break; } @@ -2382,7 +2385,7 @@ namespace SourceGit.ViewModels private bool _isSearching = false; private bool _isSearchLoadingVisible = false; private bool _isSearchCommitSuggestionOpen = false; - private int _searchCommitFilterType = 2; + private int _searchCommitFilterType = 3; private bool _onlySearchCommitsInCurrentBranch = false; private string _searchCommitFilter = string.Empty; private List _searchedCommits = new List(); diff --git a/src/Views/Repository.axaml b/src/Views/Repository.axaml index 00f9f6ce..a3aa6f25 100644 --- a/src/Views/Repository.axaml +++ b/src/Views/Repository.axaml @@ -479,7 +479,8 @@ SelectedIndex="{Binding SearchCommitFilterType, Mode=TwoWay}"> - + + From cc111baf01dbf0ecd449c797463d1d49f306976d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 23 Jan 2025 08:11:28 +0000 Subject: [PATCH 11/57] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4908fd5a..a0d9d974 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ ## Translation Status -[![en_US](https://img.shields.io/badge/en_US-%E2%88%9A-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-%E2%88%9A-brightgreen)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-%E2%88%9A-brightgreen)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-94.69%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-93.32%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-94.41%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-%E2%88%9A-brightgreen)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-%E2%88%9A-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-%E2%88%9A-brightgreen)](TRANSLATION.md) +[![en_US](https://img.shields.io/badge/en_US-%E2%88%9A-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-%E2%88%9A-brightgreen)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-%E2%88%9A-brightgreen)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-94.69%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-93.33%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-94.42%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-%E2%88%9A-brightgreen)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-%E2%88%9A-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-%E2%88%9A-brightgreen)](TRANSLATION.md) > [!NOTE] > You can find the missing keys in [TRANSLATION.md](TRANSLATION.md) diff --git a/TRANSLATION.md b/TRANSLATION.md index aa42d82b..86325215 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -66,7 +66,7 @@ -### it_IT.axaml: 93.32% +### it_IT.axaml: 93.33%
@@ -124,7 +124,7 @@
-### pt_BR.axaml: 94.41% +### pt_BR.axaml: 94.42%
From ab080b53b12f7f2a0dd88abc0d7abd74085228ec Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 24 Jan 2025 11:40:44 +0800 Subject: [PATCH 12/57] enhance: exclude indicators or empty blocks in diff text view while copying text (#924) --- src/Views/TextDiffView.axaml.cs | 74 ++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index cca3751d..bd01a0a4 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -669,6 +669,8 @@ namespace SourceGit.Views TextArea.TextView.PointerWheelChanged += OnTextViewPointerWheelChanged; TextArea.TextView.VisualLinesChanged += OnTextViewVisualLinesChanged; + TextArea.AddHandler(KeyDownEvent, OnTextAreaKeyDown, RoutingStrategies.Tunnel); + UpdateTextMate(); OnTextViewVisualLinesChanged(null, null); } @@ -677,6 +679,8 @@ namespace SourceGit.Views { base.OnUnloaded(e); + TextArea.RemoveHandler(KeyDownEvent, OnTextAreaKeyDown); + TextArea.TextView.ContextRequested -= OnTextViewContextRequested; TextArea.TextView.PointerEntered -= OnTextViewPointerChanged; TextArea.TextView.PointerMoved -= OnTextViewPointerChanged; @@ -732,6 +736,21 @@ namespace SourceGit.Views } } + private void OnTextAreaKeyDown(object sender, KeyEventArgs e) + { + if (e.KeyModifiers.Equals(OperatingSystem.IsMacOS() ? KeyModifiers.Meta : KeyModifiers.Control)) + { + if (e.Key == Key.C) + { + CopyWithoutIndicators(); + e.Handled = true; + } + } + + if (!e.Handled) + base.OnKeyDown(e); + } + private void OnBlockNavigationPropertyChanged(object _1, PropertyChangedEventArgs _2) { TextArea?.TextView?.Redraw(); @@ -748,7 +767,7 @@ namespace SourceGit.Views copy.Icon = App.CreateMenuIcon("Icons.Copy"); copy.Click += (_, ev) => { - App.CopyText(SelectedText); + CopyWithoutIndicators(); ev.Handled = true; }; @@ -941,6 +960,59 @@ namespace SourceGit.Views } } + private void CopyWithoutIndicators() + { + var selection = TextArea.Selection; + if (selection.IsEmpty) + { + App.CopyText(string.Empty); + return; + } + + var lines = GetLines(); + var startIdx = Math.Min(selection.StartPosition.Line - 1, lines.Count - 1); + var endIdx = Math.Min(selection.EndPosition.Line - 1, lines.Count - 1); + + if (startIdx == endIdx) + { + var line = lines[startIdx]; + if (line.Type == Models.TextDiffLineType.Indicator || + line.Type == Models.TextDiffLineType.None) + { + App.CopyText(string.Empty); + return; + } + + App.CopyText(SelectedText); + return; + } + + var builder = new StringBuilder(); + for (var i = startIdx; i <= endIdx; i++) + { + var line = lines[i]; + if (line.Type == Models.TextDiffLineType.Indicator || + line.Type == Models.TextDiffLineType.None) + continue; + + if (i == startIdx && selection.StartPosition.Column > 1) + { + builder.AppendLine(line.Content.Substring(selection.StartPosition.Column - 1)); + continue; + } + + if (i == endIdx && selection.EndPosition.Column < line.Content.Length) + { + builder.AppendLine(line.Content.Substring(0, selection.EndPosition.Column)); + continue; + } + + builder.AppendLine(line.Content); + } + + App.CopyText(builder.ToString()); + } + private TextMate.Installation _textMate = null; private TextLocation _lastSelectStart = TextLocation.Empty; private TextLocation _lastSelectEnd = TextLocation.Empty; From 37c4545875cd9f7f18a43830e97d78f725850e44 Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 24 Jan 2025 12:10:56 +0800 Subject: [PATCH 13/57] feature: branch name allows spaces and auto replace spaces with dashes (#917) --- src/Converters/StringConverters.cs | 3 +++ src/Resources/Locales/en_US.axaml | 1 + src/Resources/Locales/zh_CN.axaml | 1 + src/Resources/Locales/zh_TW.axaml | 1 + src/ViewModels/CreateBranch.cs | 26 +++++++++++++++++++------- src/Views/CreateBranch.axaml | 13 ++++++++++--- 6 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/Converters/StringConverters.cs b/src/Converters/StringConverters.cs index e6f4237c..5e4608c5 100644 --- a/src/Converters/StringConverters.cs +++ b/src/Converters/StringConverters.cs @@ -78,5 +78,8 @@ namespace SourceGit.Converters return v.Substring(13); return v; }); + + public static readonly FuncValueConverter ContainsSpaces = + new FuncValueConverter(v => v != null && v.Contains(' ')); } } diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 3cfff3d0..40409b9e 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -201,6 +201,7 @@ Stash & Reapply New Branch Name: Enter branch name. + Spaces will be replaced with dashes. Create Local Branch Create Tag... New Tag At: diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index d12fa07c..cdbdcc94 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -204,6 +204,7 @@ 贮藏并自动恢复 新分支名 : 填写分支名称。 + 空格将被替换为'-'符号 创建本地分支 新建标签 ... 标签位于 : diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 6be685bb..52f4754f 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -204,6 +204,7 @@ 擱置變更並自動復原 新分支名稱: 輸入分支名稱。 + 空格將以英文破折號取代 建立本機分支 新增標籤... 標籤位於: diff --git a/src/ViewModels/CreateBranch.cs b/src/ViewModels/CreateBranch.cs index b67a453a..a9698a07 100644 --- a/src/ViewModels/CreateBranch.cs +++ b/src/ViewModels/CreateBranch.cs @@ -6,7 +6,7 @@ namespace SourceGit.ViewModels public class CreateBranch : Popup { [Required(ErrorMessage = "Branch name is required!")] - [RegularExpression(@"^[\w\-/\.#]+$", ErrorMessage = "Bad branch name format!")] + [RegularExpression(@"^[\w \-/\.#]+$", ErrorMessage = "Bad branch name format!")] [CustomValidation(typeof(CreateBranch), nameof(ValidateBranchName))] public string Name { @@ -74,9 +74,10 @@ namespace SourceGit.ViewModels if (creator == null) return new ValidationResult("Missing runtime context to create branch!"); + var fixedName = creator.FixName(name); foreach (var b in creator._repo.Branches) { - if (b.FriendlyName == name) + if (b.FriendlyName == fixedName) return new ValidationResult("A branch with same name already exists!"); } @@ -86,6 +87,8 @@ namespace SourceGit.ViewModels public override Task Sure() { _repo.SetWatcherEnabled(false); + + var fixedName = FixName(_name); return Task.Run(() => { var succ = false; @@ -114,8 +117,8 @@ namespace SourceGit.ViewModels } } - SetProgressDescription($"Create new branch '{_name}'"); - succ = new Commands.Checkout(_repo.FullPath).Branch(_name, _baseOnRevision, SetProgressDescription); + SetProgressDescription($"Create new branch '{fixedName}'"); + succ = new Commands.Checkout(_repo.FullPath).Branch(fixedName, _baseOnRevision, SetProgressDescription); if (needPopStash) { @@ -125,15 +128,15 @@ namespace SourceGit.ViewModels } else { - SetProgressDescription($"Create new branch '{_name}'"); - succ = Commands.Branch.Create(_repo.FullPath, _name, _baseOnRevision); + SetProgressDescription($"Create new branch '{fixedName}'"); + succ = Commands.Branch.Create(_repo.FullPath, fixedName, _baseOnRevision); } CallUIThread(() => { if (succ && CheckoutAfterCreated) { - var fake = new Models.Branch() { IsLocal = true, FullName = $"refs/heads/{_name}" }; + var fake = new Models.Branch() { IsLocal = true, FullName = $"refs/heads/{fixedName}" }; if (BasedOn is Models.Branch based && !based.IsLocal) fake.Upstream = based.FullName; @@ -153,6 +156,15 @@ namespace SourceGit.ViewModels }); } + private string FixName(string name) + { + if (!name.Contains(' ')) + return name; + + var parts = name.Split(' ', System.StringSplitOptions.RemoveEmptyEntries); + return string.Join("-", parts); + } + private readonly Repository _repo = null; private string _name = null; private readonly string _baseOnRevision = null; diff --git a/src/Views/CreateBranch.axaml b/src/Views/CreateBranch.axaml index 49bfda8d..dff42516 100644 --- a/src/Views/CreateBranch.axaml +++ b/src/Views/CreateBranch.axaml @@ -20,6 +20,7 @@ + + + + + - - + - From 0192e941f0740f9f8360c1eac0cd781c1c276e2d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Jan 2025 04:11:14 +0000 Subject: [PATCH 14/57] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index a0d9d974..3a6d9e50 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ ## Translation Status -[![en_US](https://img.shields.io/badge/en_US-%E2%88%9A-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-%E2%88%9A-brightgreen)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-%E2%88%9A-brightgreen)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-94.69%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-93.33%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-94.42%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-%E2%88%9A-brightgreen)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-%E2%88%9A-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-%E2%88%9A-brightgreen)](TRANSLATION.md) +[![en_US](https://img.shields.io/badge/en_US-%E2%88%9A-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-99.86%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-99.86%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-94.57%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-93.21%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-94.29%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.86%25-yellow)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-%E2%88%9A-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-%E2%88%9A-brightgreen)](TRANSLATION.md) > [!NOTE] > You can find the missing keys in [TRANSLATION.md](TRANSLATION.md) diff --git a/TRANSLATION.md b/TRANSLATION.md index 86325215..d6ca1a67 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -1,29 +1,30 @@ -### de_DE.axaml: 100.00% +### de_DE.axaml: 99.86%
Missing Keys - +- Text.CreateBranch.Name.WarnSpace
-### es_ES.axaml: 100.00% +### es_ES.axaml: 99.86%
Missing Keys - +- Text.CreateBranch.Name.WarnSpace
-### fr_FR.axaml: 94.69% +### fr_FR.axaml: 94.57%
Missing Keys +- Text.CreateBranch.Name.WarnSpace - Text.InProgress.CherryPick.Head - Text.InProgress.Merge.Operating - Text.InProgress.Rebase.StoppedAt @@ -66,7 +67,7 @@
-### it_IT.axaml: 93.33% +### it_IT.axaml: 93.21%
@@ -82,6 +83,7 @@ - Text.Configure.IssueTracker.AddSampleGitLabMergeRequest - Text.Configure.OpenAI.Preferred - Text.Configure.OpenAI.Preferred.Tip +- Text.CreateBranch.Name.WarnSpace - Text.Diff.UseBlockNavigation - Text.Fetch.Force - Text.FileCM.ResolveUsing @@ -124,7 +126,7 @@
-### pt_BR.axaml: 94.42% +### pt_BR.axaml: 94.29%
@@ -137,6 +139,7 @@ - Text.CommitDetail.Info.Children - Text.Configure.IssueTracker.AddSampleGiteeIssue - Text.Configure.IssueTracker.AddSampleGiteePullRequest +- Text.CreateBranch.Name.WarnSpace - Text.Diff.UseBlockNavigation - Text.Fetch.Force - Text.FileCM.ResolveUsing @@ -174,13 +177,13 @@
-### ru_RU.axaml: 100.00% +### ru_RU.axaml: 99.86%
Missing Keys - +- Text.CreateBranch.Name.WarnSpace
From 49ee9c8e33294930822a75911862f32ab5509bef Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 24 Jan 2025 14:45:49 +0800 Subject: [PATCH 15/57] ux: move `--signoff` toggle from repository configuration window to commit options bar Signed-off-by: leo --- src/Resources/Locales/de_DE.axaml | 1 - src/Resources/Locales/en_US.axaml | 2 +- src/Resources/Locales/es_ES.axaml | 1 - src/Resources/Locales/fr_FR.axaml | 1 - src/Resources/Locales/it_IT.axaml | 1 - src/Resources/Locales/pt_BR.axaml | 1 - src/Resources/Locales/ru_RU.axaml | 1 - src/Resources/Locales/zh_CN.axaml | 2 +- src/Resources/Locales/zh_TW.axaml | 2 +- src/ViewModels/RepositoryConfigure.cs | 6 ------ src/ViewModels/WorkingCopy.cs | 6 ++++++ src/Views/RepositoryConfigure.axaml | 10 +++------- src/Views/WorkingCopy.axaml | 24 ++++++++++++++++++++---- 13 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index b771d080..77799713 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -161,7 +161,6 @@ Minute(n) Standard Remote Aktivere --prune beim fetchen - Aktiviere --signoff für Commits TICKETSYSTEM Beispiel für Gitee Issue Regel einfügen Beispiel für Gitee Pull Request Regel einfügen diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 40409b9e..64b5e5a2 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -158,7 +158,6 @@ Minute(s) Default Remote Enable --prune on fetch - Enable --signoff for commit ISSUE TRACKER Add Sample Gitee Issue Rule Add Sample Gitee Pull Request Rule @@ -719,6 +718,7 @@ INCLUDE UNTRACKED FILES NO RECENT INPUT MESSAGES NO COMMIT TEMPLATES + SignOff STAGED UNSTAGE UNSTAGE ALL diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index 8e470eb6..441d4d63 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -161,7 +161,6 @@ Minuto(s) Remoto por Defecto Habilitar --prune para fetch - Habilitar --signoff para commit SEGUIMIENTO DE INCIDENCIAS Añadir Regla de Ejemplo para Incidencias de Gitee Añadir Regla de Ejemplo para Pull Requests de Gitee diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index 71dab9dd..4eef3815 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -162,7 +162,6 @@ minute(s) Dépôt par défaut Activer --prune pour fetch - Activer --signoff pour commit SUIVI DES PROBLÈMES Ajouter une règle d'exemple Gitee Ajouter une règle d'exemple pour Pull Request Gitee diff --git a/src/Resources/Locales/it_IT.axaml b/src/Resources/Locales/it_IT.axaml index c986c133..e63ed323 100644 --- a/src/Resources/Locales/it_IT.axaml +++ b/src/Resources/Locales/it_IT.axaml @@ -156,7 +156,6 @@ Minuto/i Remoto Predefinito Abilita --prune durante il fetch - Abilita --signoff per i commit TRACCIAMENTO ISSUE Aggiungi Regola Esempio per GitHub Aggiungi Regola Esempio per Jira diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml index e0fdcce0..7979d1b2 100644 --- a/src/Resources/Locales/pt_BR.axaml +++ b/src/Resources/Locales/pt_BR.axaml @@ -181,7 +181,6 @@ Minuto(s) Remoto padrão Habilita --prune ao buscar - Habilita --signoff para commits RASTREADOR DE PROBLEMAS Adicionar Regra de Exemplo do Github Adicionar Regra de Exemplo do Jira diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index 690512e8..1d6e9215 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -159,7 +159,6 @@ GIT Автоматическое скачивание изменений Минут(а/ы) - Разрешить '--signoff' для ревизии Внешний репозиторий по умолчанию Разрешить '--prune' при скачивании ОТСЛЕЖИВАНИЕ ПРОБЛЕМ diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index cdbdcc94..4e1320d6 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -160,7 +160,6 @@ 启用定时自动拉取远程更新 分钟 默认远程 - 提交信息追加署名 (--signoff) 拉取更新时启用修剪(--prune) ISSUE追踪 新增匹配Gitee议题规则 @@ -723,6 +722,7 @@ 显示未跟踪文件 没有提交信息记录 没有可应用的提交信息模板 + 署名 已暂存 从暂存区移除选中 从暂存区移除所有 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 52f4754f..760f958d 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -160,7 +160,6 @@ 啟用定時自動提取 (fetch) 遠端更新 分鐘 預設遠端存放庫 - 提交訊息追加署名 (--signoff) 拉取變更時進行清理 (--prune) Issue 追蹤 新增符合 Gitee 議題規則 @@ -722,6 +721,7 @@ 顯示未追蹤檔案 沒有提交訊息記錄 沒有可套用的提交訊息範本 + 署名 已暫存 取消暫存選取的檔案 取消暫存所有檔案 diff --git a/src/ViewModels/RepositoryConfigure.cs b/src/ViewModels/RepositoryConfigure.cs index 88a485bc..9cafde0a 100644 --- a/src/ViewModels/RepositoryConfigure.cs +++ b/src/ViewModels/RepositoryConfigure.cs @@ -60,12 +60,6 @@ namespace SourceGit.ViewModels set => SetProperty(ref _httpProxy, value); } - public bool EnableSignOffForCommit - { - get => _repo.Settings.EnableSignOffForCommit; - set => _repo.Settings.EnableSignOffForCommit = value; - } - public bool EnablePruneOnFetch { get => _repo.Settings.EnablePruneOnFetch; diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 0a33bff5..0a1c9a47 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -62,6 +62,12 @@ namespace SourceGit.ViewModels private set => SetProperty(ref _isCommitting, value); } + public bool EnableSignOff + { + get => _repo.Settings.EnableSignOffForCommit; + set => _repo.Settings.EnableSignOffForCommit = value; + } + public bool UseAmend { get => _useAmend; diff --git a/src/Views/RepositoryConfigure.axaml b/src/Views/RepositoryConfigure.axaml index 0aef7aa6..8ba242d5 100644 --- a/src/Views/RepositoryConfigure.axaml +++ b/src/Views/RepositoryConfigure.axaml @@ -45,7 +45,7 @@ - + - - - - + diff --git a/src/Views/WorkingCopy.axaml b/src/Views/WorkingCopy.axaml index 74792072..7f493b6a 100644 --- a/src/Views/WorkingCopy.axaml +++ b/src/Views/WorkingCopy.axaml @@ -258,7 +258,7 @@ - +
-### it_IT.axaml: 93.07% +### it_IT.axaml: 100.00%
Missing Keys -- Text.BranchCM.MergeMultiBranches -- Text.CommitCM.Merge -- Text.CommitCM.MergeMultiple -- Text.CommitDetail.Files.Search -- Text.CommitDetail.Info.Children -- Text.Configure.IssueTracker.AddSampleGiteeIssue -- Text.Configure.IssueTracker.AddSampleGiteePullRequest -- Text.Configure.IssueTracker.AddSampleGitLabMergeRequest -- Text.Configure.OpenAI.Preferred -- Text.Configure.OpenAI.Preferred.Tip -- Text.CreateBranch.Name.WarnSpace -- Text.Diff.UseBlockNavigation -- Text.Fetch.Force -- Text.FileCM.ResolveUsing -- Text.InProgress.CherryPick.Head -- Text.InProgress.Merge.Operating -- Text.InProgress.Rebase.StoppedAt -- Text.InProgress.Revert.Head -- Text.Merge.Source -- Text.MergeMultiple -- Text.MergeMultiple.CommitChanges -- Text.MergeMultiple.Strategy -- Text.MergeMultiple.Targets -- Text.Preferences.General.DateFormat -- Text.Preferences.General.ShowChildren -- Text.Preferences.Git.SSLVerify -- Text.Repository.FilterCommits -- Text.Repository.FilterCommits.Default -- Text.Repository.FilterCommits.Exclude -- Text.Repository.FilterCommits.Include -- Text.Repository.HistoriesLayout -- Text.Repository.HistoriesLayout.Horizontal -- Text.Repository.HistoriesLayout.Vertical -- Text.Repository.HistoriesOrder -- Text.Repository.HistoriesOrder.ByDate -- Text.Repository.HistoriesOrder.Topo -- Text.Repository.OnlyHighlightCurrentBranchInHistories -- Text.Repository.Skip -- Text.Repository.Tags.OrderByCreatorDate -- Text.Repository.Tags.OrderByNameAsc -- Text.Repository.Tags.OrderByNameDes -- Text.Repository.Tags.Sort -- Text.Repository.UseRelativeTimeInHistories -- Text.SetUpstream -- Text.SetUpstream.Local -- Text.SetUpstream.Unset -- Text.SetUpstream.Upstream -- Text.SHALinkCM.CopySHA -- Text.SHALinkCM.NavigateTo -- Text.WorkingCopy.CommitToEdit -- Text.WorkingCopy.SignOff +
From a4157e11e61f68f705556fc0703dbf7ac5fa2989 Mon Sep 17 00:00:00 2001 From: GadflyFang Date: Thu, 6 Feb 2025 10:00:35 +0800 Subject: [PATCH 26/57] fix: Improve in-progress rebase handling (#933) * fix: Improve in-progress rebase handling * fix: Close merge popup even if there are conflicts (#941) --- src/ViewModels/InProgressContexts.cs | 8 ++++++-- src/ViewModels/Merge.cs | 4 ++-- src/ViewModels/WorkingCopy.cs | 4 ++-- src/Views/Repository.axaml | 13 ++++++++++--- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/ViewModels/InProgressContexts.cs b/src/ViewModels/InProgressContexts.cs index 6099c2b9..2892b7cc 100644 --- a/src/ViewModels/InProgressContexts.cs +++ b/src/ViewModels/InProgressContexts.cs @@ -107,8 +107,12 @@ namespace SourceGit.ViewModels { _gitDir = repo.GitDir; - var stoppedSHA = File.ReadAllText(Path.Combine(repo.GitDir, "rebase-merge", "stopped-sha")).Trim(); - StoppedAt = new Commands.QuerySingleCommit(repo.FullPath, stoppedSHA).Result() ?? new Models.Commit() { SHA = stoppedSHA }; + var stoppedSHAPath = Path.Combine(repo.GitDir, "rebase-merge", "stopped-sha"); + if (File.Exists(stoppedSHAPath)) + { + var stoppedSHA = File.ReadAllText(stoppedSHAPath).Trim(); + StoppedAt = new Commands.QuerySingleCommit(repo.FullPath, stoppedSHA).Result() ?? new Models.Commit() { SHA = stoppedSHA }; + } var ontoSHA = File.ReadAllText(Path.Combine(repo.GitDir, "rebase-merge", "onto")).Trim(); Onto = new Commands.QuerySingleCommit(repo.FullPath, ontoSHA).Result() ?? new Models.Commit() { SHA = ontoSHA }; diff --git a/src/ViewModels/Merge.cs b/src/ViewModels/Merge.cs index d07ee9b7..174bb1e1 100644 --- a/src/ViewModels/Merge.cs +++ b/src/ViewModels/Merge.cs @@ -61,9 +61,9 @@ namespace SourceGit.ViewModels return Task.Run(() => { - var succ = new Commands.Merge(_repo.FullPath, _sourceName, SelectedMode.Arg, SetProgressDescription).Exec(); + new Commands.Merge(_repo.FullPath, _sourceName, SelectedMode.Arg, SetProgressDescription).Exec(); CallUIThread(() => _repo.SetWatcherEnabled(true)); - return succ; + return true; }); } diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 0a1c9a47..616f244a 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -218,7 +218,7 @@ namespace SourceGit.ViewModels var inProgress = null as InProgressContext; if (File.Exists(Path.Combine(_repo.GitDir, "CHERRY_PICK_HEAD"))) inProgress = new CherryPickInProgress(_repo); - else if (File.Exists(Path.Combine(_repo.GitDir, "REBASE_HEAD")) && Directory.Exists(Path.Combine(_repo.GitDir, "rebase-merge"))) + else if (Directory.Exists(Path.Combine(_repo.GitDir, "rebase-merge")) || Directory.Exists(Path.Combine(_repo.GitDir, "rebase-apply"))) inProgress = new RebaseInProgress(_repo); else if (File.Exists(Path.Combine(_repo.GitDir, "REVERT_HEAD"))) inProgress = new RevertInProgress(_repo); @@ -291,7 +291,7 @@ namespace SourceGit.ViewModels var inProgress = null as InProgressContext; if (File.Exists(Path.Combine(_repo.GitDir, "CHERRY_PICK_HEAD"))) inProgress = new CherryPickInProgress(_repo); - else if (File.Exists(Path.Combine(_repo.GitDir, "REBASE_HEAD")) && Directory.Exists(Path.Combine(_repo.GitDir, "rebase-merge"))) + else if (Directory.Exists(Path.Combine(_repo.GitDir, "rebase-merge")) || Directory.Exists(Path.Combine(_repo.GitDir, "rebase-apply"))) inProgress = new RebaseInProgress(_repo); else if (File.Exists(Path.Combine(_repo.GitDir, "REVERT_HEAD"))) inProgress = new RevertInProgress(_repo); diff --git a/src/Views/Repository.axaml b/src/Views/Repository.axaml index a3aa6f25..74f628c6 100644 --- a/src/Views/Repository.axaml +++ b/src/Views/Repository.axaml @@ -598,11 +598,18 @@ - - + + - + + + + + + + + + @@ -154,6 +201,21 @@ + + + + + + + + @@ -162,7 +224,8 @@ Margin="0,0,0,8" HorizontalAlignment="Center" Content="{DynamicResource Text.ChangeCM.CheckoutThisRevision}" - Click="OnResetToSelectedRevision"/> + Click="OnResetToSelectedRevision" + IsVisible="{Binding SelectedCommits.Count, Converter={x:Static c:IntConverters.IsOne}}"/> diff --git a/src/Views/FileHistories.axaml.cs b/src/Views/FileHistories.axaml.cs index 9d74892b..2318cb6c 100644 --- a/src/Views/FileHistories.axaml.cs +++ b/src/Views/FileHistories.axaml.cs @@ -1,6 +1,9 @@ +using System.Collections.Generic; using Avalonia.Controls; using Avalonia.Input; using Avalonia.Interactivity; +using Avalonia.Platform.Storage; +using SourceGit.Models; namespace SourceGit.Views { @@ -38,5 +41,46 @@ namespace SourceGit.Views NotifyDonePanel.IsVisible = false; e.Handled = true; } + + private void OnRowSelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (DataContext is ViewModels.FileHistories vm && sender is ListBox { SelectedItems: IList commits }) + { + var selectedCommits = new List(); + foreach (var commit in commits) + { + if (commit is Models.Commit modelCommit) + { + selectedCommits.Add(modelCommit); + } + } + vm.SelectedCommits = selectedCommits; + } + + e.Handled = true; + } + + private async void OnSaveAsPatch(object sender, RoutedEventArgs e) + { + var topLevel = TopLevel.GetTopLevel(this); + if (topLevel == null) + return; + + var vm = DataContext as ViewModels.FileHistories; + if (vm == null) + return; + + var options = new FilePickerSaveOptions(); + options.Title = App.Text("FileCM.SaveAsPatch"); + options.DefaultExtension = ".patch"; + options.FileTypeChoices = [new FilePickerFileType("Patch File") { Patterns = ["*.patch"] }]; + + var storageFile = await topLevel.StorageProvider.SaveFilePickerAsync(options); + if (storageFile != null) + await vm.SaveAsPatch(storageFile.Path.LocalPath); + NotifyDonePanel.IsVisible = true; + + e.Handled = true; + } } } From 38a8490d160b538dc0e782cc16173c9b480df9dc Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 6 Feb 2025 13:07:58 +0800 Subject: [PATCH 36/57] code_review: PR #946 Signed-off-by: leo --- src/Commands/CompareRevisions.cs | 2 +- src/Converters/IntConverters.cs | 3 - src/ViewModels/FileHistories.cs | 300 ++++++++++++++++++------------- src/Views/FileHistories.axaml | 248 +++++++++++++------------ src/Views/FileHistories.axaml.cs | 54 ++---- 5 files changed, 316 insertions(+), 291 deletions(-) diff --git a/src/Commands/CompareRevisions.cs b/src/Commands/CompareRevisions.cs index b09face9..8a6f2832 100644 --- a/src/Commands/CompareRevisions.cs +++ b/src/Commands/CompareRevisions.cs @@ -24,7 +24,7 @@ namespace SourceGit.Commands Context = repo; var based = string.IsNullOrEmpty(start) ? "-R" : start; - Args = $"diff --name-status {based} {end} -- {path}"; + Args = $"diff --name-status {based} {end} -- \"{path}\""; } public List Result() diff --git a/src/Converters/IntConverters.cs b/src/Converters/IntConverters.cs index 1634f94e..f21c5d24 100644 --- a/src/Converters/IntConverters.cs +++ b/src/Converters/IntConverters.cs @@ -22,9 +22,6 @@ namespace SourceGit.Converters public static readonly FuncValueConverter IsNotOne = new FuncValueConverter(v => v != 1); - public static readonly FuncValueConverter IsTwo = - new FuncValueConverter(v => v == 2); - public static readonly FuncValueConverter IsSubjectLengthBad = new FuncValueConverter(v => v > ViewModels.Preferences.Instance.SubjectGuideLength); diff --git a/src/ViewModels/FileHistories.cs b/src/ViewModels/FileHistories.cs index 40b3cbea..37e6c8b1 100644 --- a/src/ViewModels/FileHistories.cs +++ b/src/ViewModels/FileHistories.cs @@ -4,6 +4,7 @@ using System.IO; using System.Text.RegularExpressions; using System.Threading.Tasks; +using Avalonia.Collections; using Avalonia.Media.Imaging; using Avalonia.Threading; @@ -17,129 +18,60 @@ namespace SourceGit.ViewModels public object Content { get; set; } = content; } - public partial class FileHistories : ObservableObject + public partial class FileHistoriesSingleRevision : ObservableObject { - public bool IsLoading + public bool IsDiffMode { - get => _isLoading; - private set => SetProperty(ref _isLoading, value); - } - - public List Commits - { - get => _commits; - set => SetProperty(ref _commits, value); - } - - public List SelectedCommits - { - get => _selectedCommits; + get => _isDiffMode; set { - if (SetProperty(ref _selectedCommits, value)) + if (SetProperty(ref _isDiffMode, value)) RefreshViewContent(); } } - public bool IsViewContent - { - get => _isViewContent; - set - { - if (SetProperty(ref _isViewContent, value)) - RefreshViewContent(); - } - } - - public Models.Commit StartPoint - { - get => _startPoint; - set => SetProperty(ref _startPoint, value); - } - - public Models.Commit EndPoint - { - get => _endPoint; - set => SetProperty(ref _endPoint, value); - } - public object ViewContent { get => _viewContent; - private set => SetProperty(ref _viewContent, value); + set => SetProperty(ref _viewContent, value); } - public FileHistories(Repository repo, string file, string commit = null) + public FileHistoriesSingleRevision(Repository repo, string file, Models.Commit revision, object prev) { _repo = repo; _file = file; + _revision = revision; - Task.Run(() => + if (prev is FileHistoriesSingleRevision singleRevision) { - var based = commit ?? string.Empty; - var commits = new Commands.QueryCommits(_repo.FullPath, $"--date-order -n 10000 {based} -- \"{file}\"", false).Result(); - Dispatcher.UIThread.Invoke(() => - { - IsLoading = false; - Commits = commits; - if (commits.Count > 0) - SelectedCommits = [commits[0]]; - }); - }); - } + _isDiffMode = singleRevision._isDiffMode; + _viewContent = singleRevision._viewContent; + } + else + { + _isDiffMode = true; + _viewContent = null; + } - public void NavigateToCommit(Models.Commit commit) - { - _repo.NavigateToCommit(commit.SHA); + RefreshViewContent(); } public void ResetToSelectedRevision() { - if (_selectedCommits is not { Count: 1 }) - return; - new Commands.Checkout(_repo.FullPath).FileWithRevision(_file, $"{_selectedCommits[0].SHA}"); - } - - public void Swap() - { - if (_selectedCommits is not { Count: 2 }) - return; - - (_selectedCommits[0], _selectedCommits[1]) = (_selectedCommits[1], _selectedCommits[0]); - RefreshViewContent(); - } - - public Task SaveAsPatch(string saveTo) - { - return Task.Run(() => - { - Commands.SaveChangesAsPatch.ProcessRevisionCompareChanges(_repo.FullPath, _changes, GetSHA(_startPoint), GetSHA(_endPoint), saveTo); - return true; - }); + new Commands.Checkout(_repo.FullPath).FileWithRevision(_file, $"{_revision.SHA}"); } private void RefreshViewContent() { - if (_selectedCommits == null || _selectedCommits.Count == 0) - { - StartPoint = null; - EndPoint = null; - ViewContent = 0; - return; - } - - if (_isViewContent && _selectedCommits.Count == 1) - SetViewContentAsRevisionFile(); - else + if (_isDiffMode) SetViewContentAsDiff(); + else + SetViewContentAsRevisionFile(); } private void SetViewContentAsRevisionFile() { - StartPoint = null; - EndPoint = null; - var selectedCommit = _selectedCommits[0]; - var objs = new Commands.QueryRevisionObjects(_repo.FullPath, selectedCommit.SHA, _file).Result(); + var objs = new Commands.QueryRevisionObjects(_repo.FullPath, _revision.SHA, _file).Result(); if (objs.Count == 0) { ViewContent = new FileHistoriesRevisionFile(_file, null); @@ -152,13 +84,13 @@ namespace SourceGit.ViewModels case Models.ObjectType.Blob: Task.Run(() => { - var isBinary = new Commands.IsBinary(_repo.FullPath, selectedCommit.SHA, _file).Result(); + var isBinary = new Commands.IsBinary(_repo.FullPath, _revision.SHA, _file).Result(); if (isBinary) { var ext = Path.GetExtension(_file); if (IMG_EXTS.Contains(ext)) { - var stream = Commands.QueryFileContent.Run(_repo.FullPath, selectedCommit.SHA, _file); + var stream = Commands.QueryFileContent.Run(_repo.FullPath, _revision.SHA, _file); var fileSize = stream.Length; var bitmap = fileSize > 0 ? new Bitmap(stream) : null; var imageType = Path.GetExtension(_file).TrimStart('.').ToUpper(CultureInfo.CurrentCulture); @@ -167,7 +99,7 @@ namespace SourceGit.ViewModels } else { - var size = new Commands.QueryFileSize(_repo.FullPath, _file, selectedCommit.SHA).Result(); + var size = new Commands.QueryFileSize(_repo.FullPath, _file, _revision.SHA).Result(); var binaryFile = new Models.RevisionBinaryFile() { Size = size }; Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, binaryFile)); } @@ -175,7 +107,7 @@ namespace SourceGit.ViewModels return; } - var contentStream = Commands.QueryFileContent.Run(_repo.FullPath, selectedCommit.SHA, _file); + var contentStream = Commands.QueryFileContent.Run(_repo.FullPath, _revision.SHA, _file); var content = new StreamReader(contentStream).ReadToEnd(); var matchLFS = REG_LFS_FORMAT().Match(content); if (matchLFS.Success) @@ -218,35 +150,8 @@ namespace SourceGit.ViewModels private void SetViewContentAsDiff() { - if (_selectedCommits is { Count: 1 }) - { - StartPoint = null; - EndPoint = null; - var option = new Models.DiffOption(_selectedCommits[0], _file); - ViewContent = new DiffContext(_repo.FullPath, option, _viewContent as DiffContext); - } - else if (_selectedCommits is { Count: 2 }) - { - StartPoint = _selectedCommits[0]; - EndPoint = _selectedCommits[1]; - _changes = new Commands.CompareRevisions(_repo.FullPath, GetSHA(_selectedCommits[0]), GetSHA(_selectedCommits[1]), _file).Result(); - if (_changes.Count == 0) - { - ViewContent = null; - return; - } - var option = new Models.DiffOption(GetSHA(_selectedCommits[0]), GetSHA(_selectedCommits[1]), _changes[0]); - ViewContent = new DiffContext(_repo.FullPath, option, _viewContent as DiffContext); - } - else - { - ViewContent = _selectedCommits.Count; - } - } - - private string GetSHA(object obj) - { - return obj is Models.Commit commit ? commit.SHA : string.Empty; + var option = new Models.DiffOption(_revision, _file); + ViewContent = new DiffContext(_repo.FullPath, option, _viewContent as DiffContext); } [GeneratedRegex(@"^version https://git-lfs.github.com/spec/v\d+\r?\noid sha256:([0-9a-f]+)\r?\nsize (\d+)[\r\n]*$")] @@ -257,15 +162,152 @@ namespace SourceGit.ViewModels ".ico", ".bmp", ".jpg", ".png", ".jpeg", ".webp" }; + private Repository _repo = null; + private string _file = null; + private Models.Commit _revision = null; + private bool _isDiffMode = true; + private object _viewContent = null; + } + + public class FileHistoriesCompareRevisions : ObservableObject + { + public Models.Commit StartPoint + { + get => _startPoint; + set => SetProperty(ref _startPoint, value); + } + + public Models.Commit EndPoint + { + get => _endPoint; + set => SetProperty(ref _endPoint, value); + } + + public DiffContext ViewContent + { + get => _viewContent; + set => SetProperty(ref _viewContent, value); + } + + public FileHistoriesCompareRevisions(Repository repo, string file, Models.Commit start, Models.Commit end) + { + _repo = repo; + _file = file; + _startPoint = start; + _endPoint = end; + RefreshViewContent(); + } + + public void Swap() + { + (StartPoint, EndPoint) = (_endPoint, _startPoint); + RefreshViewContent(); + } + + public Task SaveAsPatch(string saveTo) + { + return Task.Run(() => + { + Commands.SaveChangesAsPatch.ProcessRevisionCompareChanges(_repo.FullPath, _changes, _startPoint.SHA, _endPoint.SHA, saveTo); + return true; + }); + } + + private void RefreshViewContent() + { + Task.Run(() => + { + _changes = new Commands.CompareRevisions(_repo.FullPath, _startPoint.SHA, _endPoint.SHA, _file).Result(); + if (_changes.Count == 0) + { + Dispatcher.UIThread.Invoke(() => ViewContent = null); + return; + } + + var option = new Models.DiffOption(_startPoint.SHA, _endPoint.SHA, _changes[0]); + Dispatcher.UIThread.Invoke(() => ViewContent = new DiffContext(_repo.FullPath, option, _viewContent)); + }); + } + + private Repository _repo = null; + private string _file = null; + private Models.Commit _startPoint = null; + private Models.Commit _endPoint = null; + private List _changes = []; + private DiffContext _viewContent = null; + } + + public class FileHistories : ObservableObject + { + public bool IsLoading + { + get => _isLoading; + private set => SetProperty(ref _isLoading, value); + } + + public List Commits + { + get => _commits; + set => SetProperty(ref _commits, value); + } + + public AvaloniaList SelectedCommits + { + get; + set; + } = []; + + public object ViewContent + { + get => _viewContent; + private set => SetProperty(ref _viewContent, value); + } + + public FileHistories(Repository repo, string file, string commit = null) + { + _repo = repo; + _file = file; + + Task.Run(() => + { + var based = commit ?? string.Empty; + var commits = new Commands.QueryCommits(_repo.FullPath, $"--date-order -n 10000 {based} -- \"{file}\"", false).Result(); + Dispatcher.UIThread.Invoke(() => + { + IsLoading = false; + Commits = commits; + }); + }); + + SelectedCommits.CollectionChanged += (_, _) => + { + switch (SelectedCommits.Count) + { + case 0: + ViewContent = new Models.Null(); + break; + case 1: + ViewContent = new FileHistoriesSingleRevision(_repo, _file, SelectedCommits[0], _viewContent); + break; + case 2: + ViewContent = new FileHistoriesCompareRevisions(_repo, _file, SelectedCommits[0], SelectedCommits[1]); + break; + default: + ViewContent = SelectedCommits.Count; + break; + } + }; + } + + public void NavigateToCommit(Models.Commit commit) + { + _repo.NavigateToCommit(commit.SHA); + } + private readonly Repository _repo = null; private readonly string _file = null; private bool _isLoading = true; private List _commits = null; - private List _selectedCommits = []; - private bool _isViewContent = false; private object _viewContent = null; - private Models.Commit _startPoint = null; - private Models.Commit _endPoint = null; - private List _changes = null; } } diff --git a/src/Views/FileHistories.axaml b/src/Views/FileHistories.axaml index e3bbac9c..688552e0 100644 --- a/src/Views/FileHistories.axaml +++ b/src/Views/FileHistories.axaml @@ -13,30 +13,6 @@ Icon="/App.ico" Title="{DynamicResource Text.FileHistory}" MinWidth="1280" MinHeight="720"> - - - - - - - - - - - - - - - - - - - - - - - - @@ -80,8 +56,8 @@ Margin="8,4,4,8" BorderBrush="{DynamicResource Brush.Border2}" ItemsSource="{Binding Commits}" + SelectedItems="{Binding SelectedCommits, Mode=TwoWay}" SelectionMode="Multiple" - SelectionChanged="OnRowSelectionChanged" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto"> @@ -131,102 +107,136 @@ BorderThickness="1,0,0,0" BorderBrush="{DynamicResource Brush.Border0}"/> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -