From 17f94e8228134b90c21228126068c275c0bc4a59 Mon Sep 17 00:00:00 2001 From: mpagani Date: Fri, 11 Apr 2025 17:32:37 +0200 Subject: [PATCH 1/7] refactor: improve diff handling for EOL changes and enhance text diff display - Updated `Diff.cs` to streamline whitespace handling in diff arguments. - Enhanced `DiffContext.cs` to check for EOL changes when old and new hashes differ, creating a text diff if necessary. - Added support for showing end-of-line symbols in `TextDiffView.axaml.cs` options. --- src/Commands/Diff.cs | 4 +-- src/Models/DiffResult.cs | 1 + src/ViewModels/DiffContext.cs | 45 ++++++++++++++++++++++++++++++++- src/Views/TextDiffView.axaml.cs | 1 + 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/Commands/Diff.cs b/src/Commands/Diff.cs index 8ae6350f4..1c0d83629 100644 --- a/src/Commands/Diff.cs +++ b/src/Commands/Diff.cs @@ -28,9 +28,9 @@ public Diff(string repo, Models.DiffOption opt, int unified, bool ignoreWhitespa Context = repo; if (ignoreWhitespace) - Args = $"-c core.autocrlf=false diff --no-ext-diff --patch --ignore-cr-at-eol --ignore-all-space --unified={unified} {opt}"; + Args = $"-c core.autocrlf=false diff --no-ext-diff --patch --ignore-all-space --unified={unified} {opt}"; else - Args = $"-c core.autocrlf=false diff --no-ext-diff --patch --ignore-cr-at-eol --unified={unified} {opt}"; + Args = $"-c core.autocrlf=false diff --no-ext-diff --patch --unified={unified} {opt}"; } public Models.DiffResult Result() diff --git a/src/Models/DiffResult.cs b/src/Models/DiffResult.cs index 88992e10e..fbe90a0a0 100644 --- a/src/Models/DiffResult.cs +++ b/src/Models/DiffResult.cs @@ -656,6 +656,7 @@ public class ImageDiff public class NoOrEOLChange { + // The empty class is kept for backward compatibility } public class FileModeDiff diff --git a/src/ViewModels/DiffContext.cs b/src/ViewModels/DiffContext.cs index 6dd836bf3..0feb7d770 100644 --- a/src/ViewModels/DiffContext.cs +++ b/src/ViewModels/DiffContext.cs @@ -207,7 +207,50 @@ private void LoadDiffContent() } else { - rs = new Models.NoOrEOLChange(); + // Check if old and new hashes differ but no text changes found + if (!string.IsNullOrEmpty(latest.OldHash) && + !string.IsNullOrEmpty(latest.NewHash) && + latest.OldHash != latest.NewHash) + { + // If hashes differ but no text diff found, it's likely an EOL change + // Create a text diff to show the file content + var textDiff = new Models.TextDiff() + { + Repo = _repo, + Option = _option, + File = _option.Path + }; + // Query the file content to show + var fileContent = Commands.QueryFileContent.Run(_repo, "HEAD", _option.Path); + using var reader = new StreamReader(fileContent); + var line = string.Empty; + int lineNumber = 1; + + while ((line = reader.ReadLine()) != null) + { + textDiff.Lines.Add(new Models.TextDiffLine( + Models.TextDiffLineType.Normal, + line, + lineNumber, + lineNumber)); + + lineNumber++; + } + + if (textDiff.Lines.Count > 0) + { + textDiff.MaxLineNumber = lineNumber - 1; + rs = textDiff; + } + else + { + rs = new Models.NoOrEOLChange(); + } + } + else + { + rs = new Models.NoOrEOLChange(); + } } Dispatcher.UIThread.Post(() => diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index 7ce9f2880..fa065fedb 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -745,6 +745,7 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang var val = ShowHiddenSymbols; Options.ShowTabs = val; Options.ShowSpaces = val; + Options.ShowEndOfLine = val; } else if (change.Property == TabWidthProperty) { From 7d416a87516698c23a859f984e36c202c8559933 Mon Sep 17 00:00:00 2001 From: gap Date: Fri, 11 Apr 2025 20:05:38 +0200 Subject: [PATCH 2/7] localization: update translations to include EOF handling in ignore whitespace messages - Modified the ignore whitespace text in multiple language files to specify that EOF changes are also ignored. - Ensured consistency across all localization files for the patch application feature. --- src/Resources/Locales/de_DE.axaml | 4 ++-- src/Resources/Locales/en_US.axaml | 4 ++-- src/Resources/Locales/es_ES.axaml | 4 ++-- src/Resources/Locales/fr_FR.axaml | 4 ++-- src/Resources/Locales/it_IT.axaml | 4 ++-- src/Resources/Locales/ja_JP.axaml | 4 ++-- src/Resources/Locales/pt_BR.axaml | 4 ++-- src/Resources/Locales/ru_RU.axaml | 4 ++-- src/Resources/Locales/ta_IN.axaml | 4 ++-- src/Resources/Locales/zh_CN.axaml | 4 ++-- src/Resources/Locales/zh_TW.axaml | 4 ++-- 11 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index 25b54c602..494b258c6 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -23,7 +23,7 @@ Patch Patch-Datei: Wähle die anzuwendende .patch-Datei - Ignoriere Leerzeichenänderungen + Ignoriere Leerzeichenänderungen und EOF Patch anwenden Leerzeichen: Stash anwenden @@ -235,7 +235,7 @@ ALT Kopieren Dateimodus geändert - Ignoriere Leerzeichenänderungen + Ignoriere Leerzeichenänderungen und EOF LFS OBJEKT ÄNDERUNG Nächste Änderung KEINE ÄNDERUNG ODER NUR ZEILEN-ENDE ÄNDERUNGEN diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index ad71427b6..df8498cca 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -19,7 +19,7 @@ Patch Patch File: Select .patch file to apply - Ignore whitespace changes + Ignore whitespace changes and EOF Apply Patch Whitespace: Apply Stash @@ -241,7 +241,7 @@ Copy File Mode Changed First Difference - Ignore Whitespace Change + Ignore Whitespace Change and EOF Last Difference LFS OBJECT CHANGE Next Difference diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index e2af0860a..bcee784c6 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -23,7 +23,7 @@ Aplicar Parche Archivo del Parche: Seleccionar archivo .patch para aplicar - Ignorar cambios de espacios en blanco + Ignorar cambios de espacios en blanco y EOF Aplicar Parche Espacios en Blanco: Aplicar Stash @@ -240,7 +240,7 @@ Copiar Modo de Archivo Cambiado Primera Diferencia - Ignorar Cambio de Espacios en Blanco + Ignorar Cambio de Espacios en Blanco y EOF Última Diferencia CAMBIO DE OBJETO LFS Siguiente Diferencia diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index 83d590f5a..a1269d696 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -23,7 +23,7 @@ Appliquer Fichier de patch : Selectionner le fichier .patch à appliquer - Ignorer les changements d'espaces blancs + Ignorer les changements d'espaces blancs et EOF Appliquer le patch Espaces blancs : Appliquer le Stash @@ -241,7 +241,7 @@ Copier Mode de fichier changé Première différence - Ignorer les changements d'espaces + Ignorer les changements d'espaces et EOF Dernière différence CHANGEMENT D'OBJET LFS Différence suivante diff --git a/src/Resources/Locales/it_IT.axaml b/src/Resources/Locales/it_IT.axaml index 59bf3028b..a2086fa00 100644 --- a/src/Resources/Locales/it_IT.axaml +++ b/src/Resources/Locales/it_IT.axaml @@ -23,7 +23,7 @@ Applica File Patch: Seleziona file .patch da applicare - Ignora modifiche agli spazi + Ignora modifiche agli spazi e EOF Applica Patch Spazi: Applica lo stash @@ -239,7 +239,7 @@ Copia Modalità File Modificata Prima differenza - Ignora Modifiche agli Spazi + Ignora Modifiche agli Spazi e EOF Ultima differenza MODIFICA OGGETTO LFS Differenza Successiva diff --git a/src/Resources/Locales/ja_JP.axaml b/src/Resources/Locales/ja_JP.axaml index fe643b5ec..c527c4597 100644 --- a/src/Resources/Locales/ja_JP.axaml +++ b/src/Resources/Locales/ja_JP.axaml @@ -23,7 +23,7 @@ 適用 パッチファイル: 適用する .patchファイルを選択 - 空白文字の変更を無視 + 空白文字の変更とEOFを無視 パッチを適用 空白文字: スタッシュを適用 @@ -240,7 +240,7 @@ コピー ファイルモードが変更されました 先頭の差分 - 空白の変更を無視 + 空白の変更とEOFを無視 最後の差分 LFSオブジェクトの変更 次の差分 diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml index 3caac3cc7..6e93f2071 100644 --- a/src/Resources/Locales/pt_BR.axaml +++ b/src/Resources/Locales/pt_BR.axaml @@ -21,7 +21,7 @@ Patch Arquivo de Patch: Selecione o arquivo .patch para aplicar - Ignorar mudanças de espaço em branco + Ignorar mudanças de espaço em branco e EOF Aplicar Patch Espaço em Branco: Arquivar... @@ -216,7 +216,7 @@ ANTIGO Copiar Modo de Arquivo Alterado - Ignorar mudanças de espaço em branco + Ignorar mudanças de espaço em branco e EOF MUDANÇA DE OBJETO LFS Próxima Diferença SEM MUDANÇAS OU APENAS MUDANÇAS DE EOL diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index b26532ae1..c610c3cf3 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -23,7 +23,7 @@ Исправить Файл заплатки: Выберите файл .patch для применения - Игнорировать изменения пробелов + Игнорировать изменения пробелов и EOF Применить заплатку Пробел: Отложить @@ -241,7 +241,7 @@ Копировать Режим файла изменён Первое различие - Игнорировать изменение пробелов + Игнорировать изменение пробелов и EOF Последнее различие ИЗМЕНЕНИЕ ОБЪЕКТА LFS Следующее различие diff --git a/src/Resources/Locales/ta_IN.axaml b/src/Resources/Locales/ta_IN.axaml index 946a8d9c7..20a5931e1 100644 --- a/src/Resources/Locales/ta_IN.axaml +++ b/src/Resources/Locales/ta_IN.axaml @@ -23,7 +23,7 @@ ஒட்டு ஒட்டு கோப்பு: .ஒட்டு இடுவதற்கு கோப்பைத் தேர்ந்தெடு - வெள்ளைவெளி மாற்றங்களைப் புறக்கணி + வெள்ளைவெளி மாற்றங்களையும் EOF-ஐயும் புறக்கணி ஒட்டு இடு வெள்ளைவெளி: பதுக்கிவைத்ததை இடு @@ -240,7 +240,7 @@ நகல் கோப்பு முறை மாற்றப்பட்டது முதல் வேறுபாடு - வெள்ளைவெளி மாற்றத்தை புறக்கணி + வெள்ளைவெளி மாற்றத்தை மற்றும் EOF புறக்கணி கடைசி வேறுபாடு பெகோஅ பொருள் மாற்றம் அடுத்த வேறுபாடு diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 35a97b6ea..7950e857e 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -23,7 +23,7 @@ 应用补丁(apply) 补丁文件 : 选择补丁文件 - 忽略空白符号 + 忽略空白符号和EOF 应用补丁 空白符号处理 : 应用贮藏 @@ -245,7 +245,7 @@ 复制 文件权限已变化 首个差异 - 忽略空白符号变化 + 忽略空白符号变化和EOF 最后一个差异 LFS对象变更 下一个差异 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index d71281f73..adbe56ac5 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -23,7 +23,7 @@ 套用修補檔 (apply patch) 修補檔: 選擇修補檔 - 忽略空白符號 + 忽略空白符號和EOF 套用修補檔 空白字元處理: 套用擱置變更 @@ -245,7 +245,7 @@ 複製 檔案權限已變更 第一個差異 - 忽略空白符號變化 + 忽略空白符號變化和EOF 最後一個差異 LFS 物件變更 下一個差異 From 8262eb1aa52f58bf4c7476ac56bef391956d113b Mon Sep 17 00:00:00 2001 From: gap Date: Fri, 11 Apr 2025 20:30:15 +0200 Subject: [PATCH 3/7] revert: Typo in DiffResult comment --- src/Models/DiffResult.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Models/DiffResult.cs b/src/Models/DiffResult.cs index fbe90a0a0..88992e10e 100644 --- a/src/Models/DiffResult.cs +++ b/src/Models/DiffResult.cs @@ -656,7 +656,6 @@ public class ImageDiff public class NoOrEOLChange { - // The empty class is kept for backward compatibility } public class FileModeDiff From ad8ad637ae9c036e61f765b220c7b58111ad917d Mon Sep 17 00:00:00 2001 From: gap Date: Sun, 13 Apr 2025 17:41:21 +0200 Subject: [PATCH 4/7] revert: update diff arguments to ignore CR at EOL in whitespace handling (like before changes) --- src/Commands/Diff.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Commands/Diff.cs b/src/Commands/Diff.cs index 1c0d83629..a4e05ae50 100644 --- a/src/Commands/Diff.cs +++ b/src/Commands/Diff.cs @@ -28,7 +28,7 @@ public Diff(string repo, Models.DiffOption opt, int unified, bool ignoreWhitespa Context = repo; if (ignoreWhitespace) - Args = $"-c core.autocrlf=false diff --no-ext-diff --patch --ignore-all-space --unified={unified} {opt}"; + Args = $"-c core.autocrlf=false diff --no-ext-diff --patch --ignore-cr-at-eol --ignore-all-space --unified={unified} {opt}"; else Args = $"-c core.autocrlf=false diff --no-ext-diff --patch --unified={unified} {opt}"; } From ea49bf4f0fec71c9d93ce2ca44caffd77a632cd7 Mon Sep 17 00:00:00 2001 From: mpagani Date: Mon, 14 Apr 2025 08:56:49 +0200 Subject: [PATCH 5/7] revert: update translations to remove EOF references in Text.Apply.IgnoreWS and fixed typo in Text.Diff.IgnoreWhitespace (EOF => EOL) --- src/Resources/Locales/de_DE.axaml | 4 ++-- src/Resources/Locales/en_US.axaml | 4 ++-- src/Resources/Locales/es_ES.axaml | 4 ++-- src/Resources/Locales/fr_FR.axaml | 4 ++-- src/Resources/Locales/it_IT.axaml | 4 ++-- src/Resources/Locales/ja_JP.axaml | 4 ++-- src/Resources/Locales/pt_BR.axaml | 4 ++-- src/Resources/Locales/ru_RU.axaml | 4 ++-- src/Resources/Locales/ta_IN.axaml | 4 ++-- src/Resources/Locales/zh_CN.axaml | 4 ++-- src/Resources/Locales/zh_TW.axaml | 4 ++-- 11 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index 494b258c6..1ceac07c8 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -23,7 +23,7 @@ Patch Patch-Datei: Wähle die anzuwendende .patch-Datei - Ignoriere Leerzeichenänderungen und EOF + Ignoriere Leerzeichenänderungen Patch anwenden Leerzeichen: Stash anwenden @@ -235,7 +235,7 @@ ALT Kopieren Dateimodus geändert - Ignoriere Leerzeichenänderungen und EOF + Ignoriere Leerzeichenänderungen und EOL LFS OBJEKT ÄNDERUNG Nächste Änderung KEINE ÄNDERUNG ODER NUR ZEILEN-ENDE ÄNDERUNGEN diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index df8498cca..7ec386700 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -19,7 +19,7 @@ Patch Patch File: Select .patch file to apply - Ignore whitespace changes and EOF + Ignore whitespace changes Apply Patch Whitespace: Apply Stash @@ -241,7 +241,7 @@ Copy File Mode Changed First Difference - Ignore Whitespace Change and EOF + Ignore Whitespace Change and EOL Last Difference LFS OBJECT CHANGE Next Difference diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index bcee784c6..04fdde4b2 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -23,7 +23,7 @@ Aplicar Parche Archivo del Parche: Seleccionar archivo .patch para aplicar - Ignorar cambios de espacios en blanco y EOF + Ignorar cambios de espacios en blanco Aplicar Parche Espacios en Blanco: Aplicar Stash @@ -240,7 +240,7 @@ Copiar Modo de Archivo Cambiado Primera Diferencia - Ignorar Cambio de Espacios en Blanco y EOF + Ignorar Cambio de Espacios en Blanco y EOL Última Diferencia CAMBIO DE OBJETO LFS Siguiente Diferencia diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index a1269d696..f5679ab8a 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -23,7 +23,7 @@ Appliquer Fichier de patch : Selectionner le fichier .patch à appliquer - Ignorer les changements d'espaces blancs et EOF + Ignorer les changements d'espaces blancs Appliquer le patch Espaces blancs : Appliquer le Stash @@ -241,7 +241,7 @@ Copier Mode de fichier changé Première différence - Ignorer les changements d'espaces et EOF + Ignorer les changements d'espaces et EOL Dernière différence CHANGEMENT D'OBJET LFS Différence suivante diff --git a/src/Resources/Locales/it_IT.axaml b/src/Resources/Locales/it_IT.axaml index a2086fa00..5ed81da26 100644 --- a/src/Resources/Locales/it_IT.axaml +++ b/src/Resources/Locales/it_IT.axaml @@ -23,7 +23,7 @@ Applica File Patch: Seleziona file .patch da applicare - Ignora modifiche agli spazi e EOF + Ignora modifiche agli spazi Applica Patch Spazi: Applica lo stash @@ -239,7 +239,7 @@ Copia Modalità File Modificata Prima differenza - Ignora Modifiche agli Spazi e EOF + Ignora Modifiche agli Spazi e EOL Ultima differenza MODIFICA OGGETTO LFS Differenza Successiva diff --git a/src/Resources/Locales/ja_JP.axaml b/src/Resources/Locales/ja_JP.axaml index c527c4597..1b94ed6f6 100644 --- a/src/Resources/Locales/ja_JP.axaml +++ b/src/Resources/Locales/ja_JP.axaml @@ -23,7 +23,7 @@ 適用 パッチファイル: 適用する .patchファイルを選択 - 空白文字の変更とEOFを無視 + 空白文字の変更を無視 パッチを適用 空白文字: スタッシュを適用 @@ -240,7 +240,7 @@ コピー ファイルモードが変更されました 先頭の差分 - 空白の変更とEOFを無視 + 空白の変更とEOLを無視 最後の差分 LFSオブジェクトの変更 次の差分 diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml index 6e93f2071..e78c1a368 100644 --- a/src/Resources/Locales/pt_BR.axaml +++ b/src/Resources/Locales/pt_BR.axaml @@ -21,7 +21,7 @@ Patch Arquivo de Patch: Selecione o arquivo .patch para aplicar - Ignorar mudanças de espaço em branco e EOF + Ignorar mudanças de espaço em branco Aplicar Patch Espaço em Branco: Arquivar... @@ -216,7 +216,7 @@ ANTIGO Copiar Modo de Arquivo Alterado - Ignorar mudanças de espaço em branco e EOF + Ignorar mudanças de espaço em branco e EOL MUDANÇA DE OBJETO LFS Próxima Diferença SEM MUDANÇAS OU APENAS MUDANÇAS DE EOL diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index c610c3cf3..5403e1a99 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -23,7 +23,7 @@ Исправить Файл заплатки: Выберите файл .patch для применения - Игнорировать изменения пробелов и EOF + Игнорировать изменения пробелов Применить заплатку Пробел: Отложить @@ -241,7 +241,7 @@ Копировать Режим файла изменён Первое различие - Игнорировать изменение пробелов и EOF + Игнорировать изменение пробелов и EOL Последнее различие ИЗМЕНЕНИЕ ОБЪЕКТА LFS Следующее различие diff --git a/src/Resources/Locales/ta_IN.axaml b/src/Resources/Locales/ta_IN.axaml index 20a5931e1..30c2244b6 100644 --- a/src/Resources/Locales/ta_IN.axaml +++ b/src/Resources/Locales/ta_IN.axaml @@ -23,7 +23,7 @@ ஒட்டு ஒட்டு கோப்பு: .ஒட்டு இடுவதற்கு கோப்பைத் தேர்ந்தெடு - வெள்ளைவெளி மாற்றங்களையும் EOF-ஐயும் புறக்கணி + வெள்ளைவெளி மாற்றங்களைப் புறக்கணி ஒட்டு இடு வெள்ளைவெளி: பதுக்கிவைத்ததை இடு @@ -240,7 +240,7 @@ நகல் கோப்பு முறை மாற்றப்பட்டது முதல் வேறுபாடு - வெள்ளைவெளி மாற்றத்தை மற்றும் EOF புறக்கணி + வெள்ளைவெளி மாற்றத்தை மற்றும் EOL புறக்கணி கடைசி வேறுபாடு பெகோஅ பொருள் மாற்றம் அடுத்த வேறுபாடு diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 7950e857e..d8b63422f 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -23,7 +23,7 @@ 应用补丁(apply) 补丁文件 : 选择补丁文件 - 忽略空白符号和EOF + 忽略空白符号 应用补丁 空白符号处理 : 应用贮藏 @@ -245,7 +245,7 @@ 复制 文件权限已变化 首个差异 - 忽略空白符号变化和EOF + 忽略空白符号变化和EOL 最后一个差异 LFS对象变更 下一个差异 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index adbe56ac5..833e6610a 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -23,7 +23,7 @@ 套用修補檔 (apply patch) 修補檔: 選擇修補檔 - 忽略空白符號和EOF + 忽略空白符號 套用修補檔 空白字元處理: 套用擱置變更 @@ -245,7 +245,7 @@ 複製 檔案權限已變更 第一個差異 - 忽略空白符號變化和EOF + 忽略空白符號變化和EOL 最後一個差異 LFS 物件變更 下一個差異 From eeba761061b9f23b18144d280ceb56c9f142b81c Mon Sep 17 00:00:00 2001 From: mpagani Date: Mon, 14 Apr 2025 10:29:24 +0200 Subject: [PATCH 6/7] feat: add workspace-specific default clone directory functionality - Implemented logic in Clone.cs to set ParentFolder based on the active workspace's DefaultCloneDir if available, falling back to the global GitDefaultCloneDir. - Added DefaultCloneDir property to Workspace.cs to store the default clone directory for each workspace. - Updated ConfigureWorkspace.axaml to include a TextBox and Button for setting the DefaultCloneDir in the UI. - Implemented folder selection functionality in ConfigureWorkspace.axaml.cs to allow users to choose a directory for cloning. - This closes issue #1145 --- src/ViewModels/Clone.cs | 13 ++++++++++++- src/ViewModels/Workspace.cs | 7 +++++++ src/Views/ConfigureWorkspace.axaml | 13 ++++++++++--- src/Views/ConfigureWorkspace.axaml.cs | 26 ++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/ViewModels/Clone.cs b/src/ViewModels/Clone.cs index 3123d62a5..2b7c25808 100644 --- a/src/ViewModels/Clone.cs +++ b/src/ViewModels/Clone.cs @@ -64,6 +64,17 @@ public Clone(string pageId) _pageId = pageId; View = new Views.Clone() { DataContext = this }; + // Use workspace-specific DefaultCloneDir if available + var activeWorkspace = Preferences.Instance.GetActiveWorkspace(); + if (activeWorkspace != null && !string.IsNullOrEmpty(activeWorkspace.DefaultCloneDir)) + { + ParentFolder = activeWorkspace.DefaultCloneDir; + } + else + { + ParentFolder = Preferences.Instance.GitDefaultCloneDir; + } + Task.Run(async () => { try @@ -170,7 +181,7 @@ public override Task Sure() private string _remote = string.Empty; private bool _useSSH = false; private string _sshKey = string.Empty; - private string _parentFolder = Preferences.Instance.GitDefaultCloneDir; + private string _parentFolder = string.Empty; private string _local = string.Empty; private string _extraArgs = string.Empty; } diff --git a/src/ViewModels/Workspace.cs b/src/ViewModels/Workspace.cs index d527ff489..3ae935c76 100644 --- a/src/ViewModels/Workspace.cs +++ b/src/ViewModels/Workspace.cs @@ -46,6 +46,12 @@ public bool RestoreOnStartup set => SetProperty(ref _restoreOnStartup, value); } + public string DefaultCloneDir + { + get => _defaultCloneDir; + set => SetProperty(ref _defaultCloneDir, value); + } + public IBrush Brush { get => new SolidColorBrush(_color); @@ -55,5 +61,6 @@ public IBrush Brush private uint _color = 4278221015; private bool _isActive = false; private bool _restoreOnStartup = true; + private string _defaultCloneDir = string.Empty; } } diff --git a/src/Views/ConfigureWorkspace.axaml b/src/Views/ConfigureWorkspace.axaml index 79eab390d..0bef89b9d 100644 --- a/src/Views/ConfigureWorkspace.axaml +++ b/src/Views/ConfigureWorkspace.axaml @@ -98,13 +98,20 @@ - + - - + + + + + + + diff --git a/src/Views/ConfigureWorkspace.axaml.cs b/src/Views/ConfigureWorkspace.axaml.cs index 9e458f6fb..8ef5dec72 100644 --- a/src/Views/ConfigureWorkspace.axaml.cs +++ b/src/Views/ConfigureWorkspace.axaml.cs @@ -1,4 +1,7 @@ using Avalonia.Controls; +using Avalonia.Interactivity; +using Avalonia.Platform.Storage; +using System; namespace SourceGit.Views { @@ -16,5 +19,28 @@ protected override void OnClosing(WindowClosingEventArgs e) if (!Design.IsDesignMode) ViewModels.Preferences.Instance.Save(); } + + private async void SelectDefaultCloneDir(object _, RoutedEventArgs e) + { + var workspace = DataContext as ViewModels.ConfigureWorkspace; + if (workspace?.Selected == null) + return; + + var options = new FolderPickerOpenOptions() { AllowMultiple = false }; + try + { + var selected = await StorageProvider.OpenFolderPickerAsync(options); + if (selected.Count == 1) + { + workspace.Selected.DefaultCloneDir = selected[0].Path.LocalPath; + } + } + catch (Exception ex) + { + App.RaiseException(string.Empty, $"Failed to select default clone directory: {ex.Message}"); + } + + e.Handled = true; + } } } From eef5d5dc16aba6553b76426def2d4be5879c6087 Mon Sep 17 00:00:00 2001 From: mpagani Date: Mon, 14 Apr 2025 12:12:43 +0200 Subject: [PATCH 7/7] feat: implement IPC for opening repositories in new tabs - Added functionality to send repository paths to an existing instance of the application using named pipes. - Introduced a new preference option to open repositories in a new tab instead of a new window. - Updated UI to include a checkbox for the new preference. - Enhanced the handling of IPC server lifecycle based on the new preference setting. - This closes issue #1184 --- src/App.axaml.cs | 145 +++++++++++++++++++++++++++++- src/Resources/Locales/en_US.axaml | 1 + src/ViewModels/Preferences.cs | 7 ++ src/Views/Preferences.axaml | 7 +- 4 files changed, 157 insertions(+), 3 deletions(-) diff --git a/src/App.axaml.cs b/src/App.axaml.cs index 0448a247e..b1be7072c 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -2,12 +2,14 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.IO.Pipes; using System.Net.Http; using System.Reflection; using System.Text; using System.Text.Json; using System.Threading; using System.Threading.Tasks; +using System.Linq; using Avalonia; using Avalonia.Controls; @@ -46,6 +48,8 @@ public static void Main(string[] args) Environment.Exit(exitTodo); else if (TryLaunchAsRebaseMessageEditor(args, out int exitMessage)) Environment.Exit(exitMessage); + else if (TrySendArgsToExistingInstance(args)) + Environment.Exit(0); else BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); } @@ -77,6 +81,44 @@ public static AppBuilder BuildAvaloniaApp() return builder; } + private static bool TrySendArgsToExistingInstance(string[] args) + { + if (args == null || args.Length != 1 || !Directory.Exists(args[0])) + return false; + + var pref = ViewModels.Preferences.Instance; + + if (!pref.OpenReposInNewTab) + return false; + + try + { + var processes = Process.GetProcessesByName("SourceGit"); + + if (processes.Length <= 1) + return false; + + using var client = new NamedPipeClientStream(".", "SourceGitIPC", PipeDirection.Out); + + client.Connect(1000); + + if (client.IsConnected) + { + using var writer = new StreamWriter(client); + + writer.WriteLine(args[0]); + writer.Flush(); + + return true; + } + } + catch (Exception) + { + } + + return false; + } + private static void LogException(Exception ex) { if (ex == null) @@ -328,7 +370,13 @@ public override void Initialize() AvaloniaXamlLoader.Load(this); var pref = ViewModels.Preferences.Instance; - pref.PropertyChanged += (_, _) => pref.Save(); + + pref.PropertyChanged += (s, e) => { + pref.Save(); + + if (e.PropertyName.Equals(nameof(ViewModels.Preferences.OpenReposInNewTab))) + HandleOpenReposInNewTabChanged(); + }; SetLocale(pref.Locale); SetTheme(pref.Theme, pref.ThemeOverrides); @@ -488,13 +536,104 @@ private void TryLaunchAsNormal(IClassicDesktopStyleApplicationLifetime desktop) _launcher = new ViewModels.Launcher(startupRepo); desktop.MainWindow = new Views.Launcher() { DataContext = _launcher }; -#if !DISABLE_UPDATE_DETECTION var pref = ViewModels.Preferences.Instance; + + HandleOpenReposInNewTabChanged(); + +#if !DISABLE_UPDATE_DETECTION if (pref.ShouldCheck4UpdateOnStartup()) Check4Update(); #endif } + private void HandleOpenReposInNewTabChanged() + { + var pref = ViewModels.Preferences.Instance; + + if (pref.OpenReposInNewTab) + { + if (_ipcServerTask == null || _ipcServerTask.IsCompleted) + { + // Start IPC server + _ipcServerCts = new CancellationTokenSource(); + _ipcServerTask = Task.Run(() => StartIPCServer(_ipcServerCts.Token)); + } + } + else + { + // Stop IPC server if running + if (_ipcServerCts != null && !_ipcServerCts.IsCancellationRequested) + { + _ipcServerCts.Cancel(); + _ipcServerCts.Dispose(); + _ipcServerCts = null; + } + _ipcServerTask = null; + } + } + + private void StartIPCServer(CancellationToken cancellationToken) + { + try + { + while (!cancellationToken.IsCancellationRequested) + { + using var server = new NamedPipeServerStream("SourceGitIPC", PipeDirection.In); + + // Use WaitForConnectionAsync with cancellation token + try + { + Task connectionTask = server.WaitForConnectionAsync(cancellationToken); + connectionTask.Wait(cancellationToken); + } + catch (OperationCanceledException) + { + return; + } + catch (AggregateException ae) when (ae.InnerExceptions.Any(e => e is OperationCanceledException)) + { + return; + } + + // Process the connection + using var reader = new StreamReader(server); + var repoPath = reader.ReadLine(); + + if (!string.IsNullOrEmpty(repoPath) && Directory.Exists(repoPath)) + { + Dispatcher.UIThread.Post(() => + { + try + { + var test = new Commands.QueryRepositoryRootPath(repoPath).ReadToEnd(); + + if (test.IsSuccess && !string.IsNullOrEmpty(test.StdOut)) + { + var repoRootPath = test.StdOut.Trim(); + var pref = ViewModels.Preferences.Instance; + var node = pref.FindOrAddNodeByRepositoryPath(repoRootPath, null, false); + + ViewModels.Welcome.Instance.Refresh(); + + _launcher?.OpenRepositoryInTab(node, null); + + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop && desktop.MainWindow != null) + desktop.MainWindow.Activate(); + } + } + catch (Exception) + { + } + }); + } + } + } + catch (Exception) + { + // Pipe server failed, we can just exit the thread + } + } + private void Check4Update(bool manually = false) { Task.Run(async () => @@ -584,5 +723,7 @@ private string FixFontFamilyName(string input) private ResourceDictionary _activeLocale = null; private ResourceDictionary _themeOverrides = null; private ResourceDictionary _fontsOverrides = null; + private Task _ipcServerTask = null; + private CancellationTokenSource _ipcServerCts = null; } } diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 7e9319989..123b63815 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -752,4 +752,5 @@ Lock Remove Unlock + Open repositories in new tab instead of new window diff --git a/src/ViewModels/Preferences.cs b/src/ViewModels/Preferences.cs index cad6c224c..d1e78d6a1 100644 --- a/src/ViewModels/Preferences.cs +++ b/src/ViewModels/Preferences.cs @@ -90,6 +90,12 @@ public bool OnlyUseMonoFontInEditor } } + public bool OpenReposInNewTab + { + get => _openReposInNewTab; + set => SetProperty(ref _openReposInNewTab, value); + } + public bool UseSystemWindowFrame { get => _useSystemWindowFrame; @@ -632,6 +638,7 @@ private bool RemoveInvalidRepositoriesRecursive(List collection) private string _defaultFontFamily = string.Empty; private string _monospaceFontFamily = string.Empty; private bool _onlyUseMonoFontInEditor = false; + private bool _openReposInNewTab = false; private bool _useSystemWindowFrame = false; private double _defaultFontSize = 13; private double _editorFontSize = 13; diff --git a/src/Views/Preferences.axaml b/src/Views/Preferences.axaml index 702ec20f8..704757df9 100644 --- a/src/Views/Preferences.axaml +++ b/src/Views/Preferences.axaml @@ -46,7 +46,7 @@ - + + +