From dd85760b7abf6b963ebab44c638ae312f25c0d09 Mon Sep 17 00:00:00 2001 From: Nils van Rijsinge Date: Mon, 16 Dec 2024 02:50:59 +0100 Subject: [PATCH 001/865] localization: add missing de_DE keys (#817) * localization: add missing de_DE keys BranchCM.MergeMultiBranches, CommitCM.MergeMultiple, MergeMultiple #793 CommitCM.Merge 2053ce033d1e24e9e6b74cecfcc0761fad899f6f CommitDetail.Files.Search 894f3e9b033f15df5f87f251299afa6ce9428227 Diff.UseBlockNavigation #703 FileCM.ResolveUsing 3b5d87391d11b27aff061cb57a32862046ee791f Hotkeys.Global.Clone bea2a39feb18cf4ef427f319f0436bd3f80546f5 InProgress.CherryPick.Head e1df5c52f10042523ba1d40483703bcbeeedf053 InProgress.Merge.Operating ef40e4b7387fb82d16984c5e4cc6a77559bd01e6 InProgress.Rebase.StoppedAt, Repository.Skip #790 InProgress.Revert.Head 93d9a044608c84fc8335f25269b1d5572c41b0e1 Merge.Source 2504a523987f0279afacef0b80b2ea00547d2145 WorkingCopy.CommitToEdit c1368212dfe08f3c0586cbefcace26c329c31d90 * localization: consistently use clone with 'k' for most other keys a more "germanized" version with a k is used rather than a c --- src/Resources/Locales/de_DE.axaml | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index 2045a229..ff8a1d97 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -61,6 +61,7 @@ Fetche ${0}$ in ${1}$ hinein... Git Flow - Abschließen ${0}$ Merge ${0}$ in ${1}$ hinein... + Merge ausgewählte {0} Branches in aktuellen hinein Pull ${0}$ Pull ${0}$ in ${1}$ hinein... Push ${0}$ @@ -113,6 +114,8 @@ SHA kopieren Benutzerdefinierte Aktion Interactives Rebase von ${0}$ auf diesen Commit + Merge in ${0}$ hinein + Merge ... Rebase von ${0}$ auf diesen Commit Reset ${0}$ auf diesen Commit Commit rückgängig machen @@ -124,6 +127,7 @@ Änderungen durchsuchen... DATEIEN LFS DATEI + Dateien durchsuchen... Submodule INFORMATION AUTOR @@ -249,6 +253,7 @@ Seiten wechseln Syntax Hervorhebung Zeilenumbruch + Aktiviere Block-Navigation Öffne in Merge Tool Alle Zeilen anzeigen Weniger Zeilen anzeigen @@ -280,6 +285,7 @@ Verwerfe {0} Dateien... Verwerfe Änderungen in ausgewählten Zeilen Öffne externes Merge Tool + Löse mit ${0}$ Als Patch speichern... Stagen {0} Dateien stagen @@ -358,6 +364,7 @@ Tastaturkürzel Referenz GLOBAL Aktuelles Popup schließen + Klone neues Repository Aktuellen Tab schließen Zum vorherigen Tab wechseln Zum nächsten Tab wechseln @@ -390,9 +397,13 @@ Initialisiere Repository Pfad: Cherry-Pick wird durchgeführt. + Verarbeite commit Merge request wird durchgeführt. + Verarbeite Rebase wird durchgeführt. + Angehalten bei Revert wird durchgeführt. + Reverte commit Interaktiver Rebase Ziel Branch: Auf: @@ -403,6 +414,11 @@ Branch mergen Ziel-Branch: Merge Option: + Quelle: + Merge (mehrere) + Alle Änderungen committen + Strategie: + Ziele: Bewege Repository Knoten Wähle Vorgänger-Knoten für: Name: @@ -459,7 +475,7 @@ Längenvorgabe für Commit-Nachrichten GIT Aktiviere Auto-CRLF - Clone Standardordner + Klon Standardordner Benutzer Email Globale Git Benutzer Email Installationspfad @@ -568,6 +584,7 @@ Autor & Committer Aktueller Branch Zeige Tags als Baum + ÜBERSPRINGEN Statistiken SUBMODULE SUBMODUL HINZUFÜGEN @@ -666,7 +683,7 @@ Öffne alle Repositories Öffne Repository Öffne Terminal - Clone Standardordner erneut nach Repositories durchsuchen + Klon Standardordner erneut nach Repositories durchsuchen Suche Repositories... Sortieren Änderungen @@ -681,6 +698,7 @@ COMMIT & PUSH Template/Historie Klick-Ereignis auslösen + Commit (Bearbeitung) Alle Änderungen stagen und committen Leerer Commit erkannt! Fortfahren (--allow-empty)? KONFLIKTE ERKANNT From e4cfca0ffdb85980b3221d30febea5997a48c384 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 16 Dec 2024 01:51:11 +0000 Subject: [PATCH 002/865] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 21 ++------------------- 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 6916edbc..9f1d302a 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-97.50%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.78%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-95.00%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-95.56%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-96.81%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-97.92%25-yellow)](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-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-97.78%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-95.00%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-95.56%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-96.81%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-97.92%25-yellow)](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) ## How to Use diff --git a/TRANSLATION.md b/TRANSLATION.md index 6e743f14..59ed0ff7 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -1,27 +1,10 @@ -### de_DE.axaml: 97.50% +### de_DE.axaml: 100.00%
Missing Keys -- Text.BranchCM.MergeMultiBranches -- Text.CommitCM.Merge -- Text.CommitCM.MergeMultiple -- Text.CommitDetail.Files.Search -- Text.Diff.UseBlockNavigation -- Text.FileCM.ResolveUsing -- Text.Hotkeys.Global.Clone -- 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.Repository.Skip -- Text.WorkingCopy.CommitToEdit +
From 5425fa64fe46c5c025c09bcc9f7aa6662ce29661 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 16 Dec 2024 13:29:46 +0800 Subject: [PATCH 003/865] refactor: use another way to open tooltip of SHA after getting commit info (#810) --- src/Views/CommitBaseInfo.axaml.cs | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/Views/CommitBaseInfo.axaml.cs b/src/Views/CommitBaseInfo.axaml.cs index 0b4c1f2d..79f65a4d 100644 --- a/src/Views/CommitBaseInfo.axaml.cs +++ b/src/Views/CommitBaseInfo.axaml.cs @@ -5,6 +5,7 @@ using Avalonia.Collections; using Avalonia.Controls; using Avalonia.Input; using Avalonia.Interactivity; +using Avalonia.Threading; namespace SourceGit.Views { @@ -124,7 +125,7 @@ namespace SourceGit.Views e.Handled = true; } - private async void OnSHAPointerEntered(object sender, PointerEventArgs e) + private void OnSHAPointerEntered(object sender, PointerEventArgs e) { if (DataContext is ViewModels.CommitDetail detail && sender is Control { DataContext: string sha } ctl) { @@ -132,14 +133,22 @@ namespace SourceGit.Views if (tooltip is Models.Commit commit && commit.SHA == sha) return; - var c = await Task.Run(() => detail.GetParent(sha)); - if (c != null && ctl.IsVisible && ctl.DataContext is string newSHA && newSHA == sha) + Task.Run(() => { - ToolTip.SetTip(ctl, c); + var c = detail.GetParent(sha); + if (c == null) return; - if (ctl.IsPointerOver) - ToolTip.SetIsOpen(ctl, true); - } + Dispatcher.UIThread.Invoke(() => + { + if (ctl.IsEffectivelyVisible && ctl.DataContext is string newSHA && newSHA == sha) + { + ToolTip.SetTip(ctl, c); + + if (ctl.IsPointerOver) + ToolTip.SetIsOpen(ctl, true); + } + }); + }); } e.Handled = true; From f418b72c64391b178ccb6a1ce46df1eaaae51f41 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 16 Dec 2024 15:47:33 +0800 Subject: [PATCH 004/865] feature: use `[$workspace] $repo_name ($repo_path)` as main window's title (#818) --- src/ViewModels/Launcher.cs | 48 +++++++++++++++++++++++++++++++++++--- src/Views/Launcher.axaml | 2 +- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/ViewModels/Launcher.cs b/src/ViewModels/Launcher.cs index 8e4f7775..02844312 100644 --- a/src/ViewModels/Launcher.cs +++ b/src/ViewModels/Launcher.cs @@ -11,6 +11,12 @@ namespace SourceGit.ViewModels { public class Launcher : ObservableObject { + public string Title + { + get => _title; + private set => SetProperty(ref _title, value); + } + public AvaloniaList Pages { get; @@ -31,9 +37,10 @@ namespace SourceGit.ViewModels if (SetProperty(ref _activePage, value)) { PopupHost.Active = value; + UpdateTitle(); if (!_ignoreIndexChange && value is { Data: Repository repo }) - ActiveWorkspace.ActiveIdx = ActiveWorkspace.Repositories.IndexOf(repo.FullPath); + _activeWorkspace.ActiveIdx = _activeWorkspace.Repositories.IndexOf(repo.FullPath); } } } @@ -105,6 +112,9 @@ namespace SourceGit.ViewModels } _ignoreIndexChange = false; + + if (string.IsNullOrEmpty(_title)) + UpdateTitle(); } public void Quit(double width, double height) @@ -185,6 +195,7 @@ namespace SourceGit.ViewModels last.Node = new RepositoryNode() { Id = Guid.NewGuid().ToString() }; last.Data = Welcome.Instance; last.Popup = null; + UpdateTitle(); GC.Collect(); } @@ -193,7 +204,6 @@ namespace SourceGit.ViewModels App.Quit(0); } - _ignoreIndexChange = false; return; } @@ -308,7 +318,10 @@ namespace SourceGit.ViewModels page.Data = repo; } - ActivePage = page; + if (page != _activePage) + ActivePage = page; + else + UpdateTitle(); ActiveWorkspace.Repositories.Clear(); foreach (var p in Pages) @@ -530,8 +543,37 @@ namespace SourceGit.ViewModels page.Data = null; } + private void UpdateTitle() + { + if (_activeWorkspace == null) + return; + + var workspace = _activeWorkspace.Name; + if (_activePage is { Data: Repository repo }) + { + var node = _activePage.Node; + var name = node.Name; + var path = node.Id; + + if (!OperatingSystem.IsWindows()) + { + var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); + var prefixLen = home.EndsWith('/') ? home.Length - 1 : home.Length; + if (path.StartsWith(home, StringComparison.Ordinal)) + path = "~" + path.Substring(prefixLen); + } + + Title = $"[{workspace}] {name} ({path})"; + } + else + { + Title = $"[{workspace}] Repositories"; + } + } + private Workspace _activeWorkspace = null; private LauncherPage _activePage = null; private bool _ignoreIndexChange = false; + private string _title = string.Empty; } } diff --git a/src/Views/Launcher.axaml b/src/Views/Launcher.axaml index ad5a7f34..d37cf928 100644 --- a/src/Views/Launcher.axaml +++ b/src/Views/Launcher.axaml @@ -10,7 +10,7 @@ x:DataType="vm:Launcher" x:Name="ThisControl" Icon="/App.ico" - Title="SourceGit" + Title="{Binding Title}" MinWidth="1024" MinHeight="600" WindowStartupLocation="CenterScreen"> From 707a227aca594b46475ad149a080a38a208352cf Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 17 Dec 2024 09:36:06 +0800 Subject: [PATCH 005/865] ux: make Welcome page responsive (#821) --- src/Views/Welcome.axaml | 265 ++++++++++++++++++++-------------------- 1 file changed, 132 insertions(+), 133 deletions(-) diff --git a/src/Views/Welcome.axaml b/src/Views/Welcome.axaml index 6f12c119..cdc892f4 100644 --- a/src/Views/Welcome.axaml +++ b/src/Views/Welcome.axaml @@ -9,149 +9,148 @@ x:Class="SourceGit.Views.Welcome" x:DataType="vm:Welcome"> - - - - - - - - - - - - + + + + + + + + - - - - + + + - - - - - - - + + + + - - - - - + + + + - - - - - - - - - + + - - - - - - + + + + + - + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + - - - - - + + + + + From c768b1750e715091504fe9d866013f6a6d44ac22 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 17 Dec 2024 10:26:35 +0800 Subject: [PATCH 006/865] feature: use `-p:DisableUpdateDetection=true` to disable built-in update detection feature (#819) --- src/App.Commands.cs | 12 ++++++++++++ src/App.axaml | 2 +- src/App.axaml.cs | 2 ++ src/SourceGit.csproj | 4 ++++ src/Views/Launcher.axaml | 4 ++-- src/Views/Preference.axaml | 4 +++- 6 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/App.Commands.cs b/src/App.Commands.cs index 8a485029..18016a1c 100644 --- a/src/App.Commands.cs +++ b/src/App.Commands.cs @@ -25,6 +25,18 @@ namespace SourceGit private Action _action = null; } + public static bool IsCheckForUpdateCommandVisible + { + get + { + #if DISABLE_UPDATE_DETECTION + return false; + #else + return true; + #endif + } + } + public static readonly Command OpenPreferenceCommand = new Command(_ => OpenDialog(new Views.Preference())); public static readonly Command OpenHotkeysCommand = new Command(_ => OpenDialog(new Views.Hotkeys())); public static readonly Command OpenAppDataDirCommand = new Command(_ => Native.OS.OpenInFileManager(Native.OS.DataDir)); diff --git a/src/App.axaml b/src/App.axaml index 0f40031d..55aacb89 100644 --- a/src/App.axaml +++ b/src/App.axaml @@ -33,7 +33,7 @@ - + diff --git a/src/App.axaml.cs b/src/App.axaml.cs index 0615724a..3d1547c9 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -548,9 +548,11 @@ namespace SourceGit _launcher = new ViewModels.Launcher(startupRepo); desktop.MainWindow = new Views.Launcher() { DataContext = _launcher }; + #if !DISABLE_UPDATE_DETECTION var pref = ViewModels.Preference.Instance; if (pref.ShouldCheck4UpdateOnStartup()) Check4Update(); + #endif } private ViewModels.Launcher _launcher = null; diff --git a/src/SourceGit.csproj b/src/SourceGit.csproj index 32f68d03..89893a39 100644 --- a/src/SourceGit.csproj +++ b/src/SourceGit.csproj @@ -26,6 +26,10 @@ link + + $(DefineConstants);DISABLE_UPDATE_DETECTION + + diff --git a/src/Views/Launcher.axaml b/src/Views/Launcher.axaml index d37cf928..a0691c4c 100644 --- a/src/Views/Launcher.axaml +++ b/src/Views/Launcher.axaml @@ -51,12 +51,12 @@ - + - + diff --git a/src/Views/Preference.axaml b/src/Views/Preference.axaml index 0ed598c2..6adbaca4 100644 --- a/src/Views/Preference.axaml +++ b/src/Views/Preference.axaml @@ -2,6 +2,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:s="using:SourceGit" xmlns:m="using:SourceGit.Models" xmlns:c="using:SourceGit.Converters" xmlns:vm="using:SourceGit.ViewModels" @@ -45,7 +46,7 @@ - + From 1c345df37db53e416d98887d860c919ef8c8311e Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 17 Dec 2024 11:24:59 +0800 Subject: [PATCH 007/865] ux: add some tooltips to checkboxes --- src/Resources/Locales/en_US.axaml | 2 +- src/Resources/Locales/zh_CN.axaml | 2 +- src/Resources/Locales/zh_TW.axaml | 2 +- src/Views/Apply.axaml | 3 ++- src/Views/Fetch.axaml | 9 ++++++--- src/Views/Pull.axaml | 6 ++++-- src/Views/Push.axaml | 12 ++++++++---- src/Views/StashChanges.axaml | 9 ++++++--- 8 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 65b4dd96..73e82074 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 - Enable '--force' option + Override refs check Fetch without tags Remote: Fetch Remote Changes diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index f711cdee..e53af9a8 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -276,7 +276,7 @@ 快进(fast-forward,无需checkout) 拉取(fetch) 拉取所有的远程仓库 - 启用 --force 选项 + 覆盖REF检查 不拉取远程标签 远程仓库 : 拉取远程仓库内容 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 90444967..e96f68ad 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -276,7 +276,7 @@ 快進 (fast-forward,無需 checkout) 提取 (fetch) 提取所有的遠端存放庫 - 啟用 [--force] 選項 + 覆寫 REFs 檢查 不提取遠端標籤 遠端存放庫: 提取遠端存放庫內容 diff --git a/src/Views/Apply.axaml b/src/Views/Apply.axaml index c3cb420c..a5100cd6 100644 --- a/src/Views/Apply.axaml +++ b/src/Views/Apply.axaml @@ -54,7 +54,8 @@ + IsChecked="{Binding IgnoreWhiteSpace, Mode=TwoWay}" + ToolTip.Tip="--ignore-whitespace"/> diff --git a/src/Views/Fetch.axaml b/src/Views/Fetch.axaml index f9380ab0..67669380 100644 --- a/src/Views/Fetch.axaml +++ b/src/Views/Fetch.axaml @@ -34,15 +34,18 @@ + IsChecked="{Binding Force, Mode=TwoWay}" + ToolTip.Tip="--force"/> + IsChecked="{Binding FetchAllRemotes, Mode=TwoWay}" + ToolTip.Tip="--all"/> + IsChecked="{Binding NoTags, Mode=TwoWay}" + ToolTip.Tip="--no-tags"/> diff --git a/src/Views/Pull.axaml b/src/Views/Pull.axaml index f6aa245f..50615bc6 100644 --- a/src/Views/Pull.axaml +++ b/src/Views/Pull.axaml @@ -99,11 +99,13 @@ + IsChecked="{Binding NoTags, Mode=TwoWay}" + ToolTip.Tip="--no-tags"/> + IsChecked="{Binding UseRebase, Mode=TwoWay}" + ToolTip.Tip="--rebase"/> diff --git a/src/Views/Push.axaml b/src/Views/Push.axaml index 87921c88..6bc02cff 100644 --- a/src/Views/Push.axaml +++ b/src/Views/Push.axaml @@ -83,21 +83,25 @@ Height="32" Content="{DynamicResource Text.Push.Tracking}" IsChecked="{Binding Tracking, Mode=TwoWay}" - IsVisible="{Binding IsSetTrackOptionVisible}"/> + IsVisible="{Binding IsSetTrackOptionVisible}" + ToolTip.Tip="-u"/> + IsVisible="{Binding IsCheckSubmodulesVisible}" + ToolTip.Tip="--recurse-submodules=check"/> + IsChecked="{Binding PushAllTags, Mode=TwoWay}" + ToolTip.Tip="--tags"/> + IsChecked="{Binding ForcePush, Mode=TwoWay}" + ToolTip.Tip="--force-with-lease"/> diff --git a/src/Views/StashChanges.axaml b/src/Views/StashChanges.axaml index b3e6254a..772b09e6 100644 --- a/src/Views/StashChanges.axaml +++ b/src/Views/StashChanges.axaml @@ -27,18 +27,21 @@ Height="32" Content="{DynamicResource Text.Stash.IncludeUntracked}" IsChecked="{Binding IncludeUntracked, Mode=TwoWay}" - IsVisible="{Binding !HasSelectedFiles}"/> + IsVisible="{Binding !HasSelectedFiles}" + ToolTip.Tip="--include-untracked"/> + IsVisible="{Binding !HasSelectedFiles}" + ToolTip.Tip="--staged"/> + IsChecked="{Binding KeepIndex, Mode=TwoWay}" + ToolTip.Tip="--keep-index"/> Date: Tue, 17 Dec 2024 12:08:25 +0800 Subject: [PATCH 008/865] ux: new notification theme --- src/Views/LauncherPage.axaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Views/LauncherPage.axaml b/src/Views/LauncherPage.axaml index d09c2c0d..d40fd243 100644 --- a/src/Views/LauncherPage.axaml +++ b/src/Views/LauncherPage.axaml @@ -125,7 +125,7 @@ - + From 23326d179a875047db004cb76bd575db44a4c1bc Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 17 Dec 2024 14:39:18 +0800 Subject: [PATCH 009/865] refactor: commit hash detection in message --- src/Views/CommitMessagePresenter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Views/CommitMessagePresenter.cs b/src/Views/CommitMessagePresenter.cs index a767b395..0ae3d6cf 100644 --- a/src/Views/CommitMessagePresenter.cs +++ b/src/Views/CommitMessagePresenter.cs @@ -15,7 +15,7 @@ namespace SourceGit.Views { public partial class CommitMessagePresenter : SelectableTextBlock { - [GeneratedRegex(@"\b([0-9a-fA-F]{8,40})\b")] + [GeneratedRegex(@"\b([0-9a-fA-F]{10,40})\b")] private static partial Regex REG_SHA_FORMAT(); public static readonly StyledProperty MessageProperty = From 39dff8a93f8fc8df0adabf562a1cf9a7874d2d85 Mon Sep 17 00:00:00 2001 From: Martin Garstenauer Date: Wed, 18 Dec 2024 02:25:56 +0100 Subject: [PATCH 010/865] ux: change text selection brush to improve readability (#825) --- src/Resources/Styles.axaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Resources/Styles.axaml b/src/Resources/Styles.axaml index 2cc09e39..28eabbab 100644 --- a/src/Resources/Styles.axaml +++ b/src/Resources/Styles.axaml @@ -4,6 +4,7 @@ xmlns:vm="using:SourceGit.ViewModels" xmlns:c="using:SourceGit.Converters" xmlns:ae="using:AvaloniaEdit" + xmlns:aee="using:AvaloniaEdit.Editing" xmlns:aes="using:AvaloniaEdit.Search"> @@ -580,6 +581,19 @@ + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Views/LauncherTabsSelector.axaml.cs b/src/Views/LauncherTabsSelector.axaml.cs new file mode 100644 index 00000000..01c5fa0d --- /dev/null +++ b/src/Views/LauncherTabsSelector.axaml.cs @@ -0,0 +1,120 @@ +using System; + +using Avalonia; +using Avalonia.Collections; +using Avalonia.Controls; +using Avalonia.Interactivity; + +namespace SourceGit.Views +{ + public class LauncherTabSelectedEventArgs : RoutedEventArgs + { + public ViewModels.LauncherPage Page { get; } + + public LauncherTabSelectedEventArgs(ViewModels.LauncherPage page) + { + RoutedEvent = LauncherTabsSelector.PageSelectedEvent; + Page = page; + } + } + + public partial class LauncherTabsSelector : UserControl + { + public static readonly StyledProperty> PagesProperty = + AvaloniaProperty.Register>(nameof(Pages)); + + public AvaloniaList Pages + { + get => GetValue(PagesProperty); + set => SetValue(PagesProperty, value); + } + + public static readonly StyledProperty SearchFilterProperty = + AvaloniaProperty.Register(nameof(SearchFilter)); + + public string SearchFilter + { + get => GetValue(SearchFilterProperty); + set => SetValue(SearchFilterProperty, value); + } + + public static readonly RoutedEvent PageSelectedEvent = + RoutedEvent.Register(nameof(PageSelected), RoutingStrategies.Tunnel | RoutingStrategies.Bubble); + + public event EventHandler PageSelected + { + add { AddHandler(PageSelectedEvent, value); } + remove { RemoveHandler(PageSelectedEvent, value); } + } + + public AvaloniaList VisiblePages + { + get; + private set; + } + + public LauncherTabsSelector() + { + VisiblePages = new AvaloniaList(); + InitializeComponent(); + } + + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); + + if (change.Property == PagesProperty || change.Property == SearchFilterProperty) + UpdateVisiblePages(); + } + + private void OnClearSearchFilter(object sender, RoutedEventArgs e) + { + SearchFilter = string.Empty; + } + + private void OnPageSelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (sender is ListBox { SelectedItem : ViewModels.LauncherPage page }) + { + _isProcessingSelection = true; + RaiseEvent(new LauncherTabSelectedEventArgs(page)); + _isProcessingSelection = false; + } + + e.Handled = true; + } + + private void UpdateVisiblePages() + { + if (_isProcessingSelection) + return; + + VisiblePages.Clear(); + + if (Pages == null) + return; + + var filter = SearchFilter?.Trim() ?? ""; + if (string.IsNullOrEmpty(filter)) + { + foreach (var p in Pages) + VisiblePages.Add(p); + + return; + } + + foreach (var page in Pages) + { + if (!page.Node.IsRepository) + continue; + + if (page.Node.Name.Contains(filter, StringComparison.OrdinalIgnoreCase) || + page.Node.Id.Contains(filter, StringComparison.OrdinalIgnoreCase)) + VisiblePages.Add(page); + } + } + + private bool _isProcessingSelection = false; + } +} + From aebfffee003413b679ed7523c04c834764fe0a82 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 10 Feb 2025 20:51:36 +0800 Subject: [PATCH 209/865] fix: GUI stops refreshing after manually refresh while merge tool is open (#949) Signed-off-by: leo --- src/ViewModels/WorkingCopy.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index ecb3c0d6..7ac13dc2 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -431,10 +431,7 @@ namespace SourceGit.ViewModels { var toolType = Preferences.Instance.ExternalMergeToolType; var toolPath = Preferences.Instance.ExternalMergeToolPath; - - _repo.SetWatcherEnabled(false); await Task.Run(() => Commands.MergeTool.OpenForMerge(_repo.FullPath, toolType, toolPath, change.Path)); - _repo.SetWatcherEnabled(true); } public void ContinueMerge() From 821063e3ec196da97c75951d30c93088c127f91e Mon Sep 17 00:00:00 2001 From: Doodeletion <99095135+Doodeletion@users.noreply.github.com> Date: Tue, 11 Feb 2025 03:57:20 +0100 Subject: [PATCH 210/865] Swap selection start and end index if selection is created from bottom to top (#967) --- src/Views/TextDiffView.axaml.cs | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index 15a2a212..cc8fcfe5 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -970,8 +970,19 @@ namespace SourceGit.Views } 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); + + var startPosition = selection.StartPosition; + var endPosition = selection.EndPosition; + + if (startPosition.Line > endPosition.Line + || startPosition.Line == endPosition.Line && startPosition.Column > endPosition.Column) + { + // swap start and end + (startPosition, endPosition) = (endPosition, startPosition); + } + + var startIdx = Math.Min(startPosition.Line - 1, lines.Count - 1); + var endIdx = Math.Min(endPosition.Line - 1, lines.Count - 1); if (startIdx == endIdx) { @@ -995,15 +1006,15 @@ namespace SourceGit.Views line.Type == Models.TextDiffLineType.None) continue; - if (i == startIdx && selection.StartPosition.Column > 1) + if (i == startIdx && startPosition.Column > 1) { - builder.AppendLine(line.Content.Substring(selection.StartPosition.Column - 1)); + builder.AppendLine(line.Content.Substring(startPosition.Column - 1)); continue; } - if (i == endIdx && selection.EndPosition.Column < line.Content.Length) + if (i == endIdx && endPosition.Column < line.Content.Length) { - builder.AppendLine(line.Content.Substring(0, selection.EndPosition.Column)); + builder.AppendLine(line.Content.Substring(0, endPosition.Column)); continue; } From 10fba08e430f6f67d6c1bca7abbf9338a546b9a4 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 11 Feb 2025 11:07:33 +0800 Subject: [PATCH 211/865] code_review: PR #949 Signed-off-by: leo --- src/Views/TextDiffView.axaml.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index cc8fcfe5..28fe81a8 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -973,13 +973,9 @@ namespace SourceGit.Views var startPosition = selection.StartPosition; var endPosition = selection.EndPosition; - - if (startPosition.Line > endPosition.Line - || startPosition.Line == endPosition.Line && startPosition.Column > endPosition.Column) - { - // swap start and end + + if (startPosition.Location > endPosition.Location) (startPosition, endPosition) = (endPosition, startPosition); - } var startIdx = Math.Min(startPosition.Line - 1, lines.Count - 1); var endIdx = Math.Min(endPosition.Line - 1, lines.Count - 1); From af20ab2448a2b46dfd687c0ff95a12716d2f9543 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 11 Feb 2025 14:34:14 +0800 Subject: [PATCH 212/865] feature: add `Wait for action done` option to control whether or not to wait for the custom action execution to complete (#951) Signed-off-by: leo --- src/Commands/ExecuteCustomAction.cs | 32 ++++++++++++++++++++++++++- src/Models/CustomAction.cs | 7 ++++++ src/Resources/Locales/en_US.axaml | 1 + src/Resources/Locales/zh_CN.axaml | 1 + src/Resources/Locales/zh_TW.axaml | 1 + src/ViewModels/ExecuteCustomAction.cs | 6 ++++- src/Views/RepositoryConfigure.axaml | 4 +++- 7 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/Commands/ExecuteCustomAction.cs b/src/Commands/ExecuteCustomAction.cs index a10f5387..3a77ec01 100644 --- a/src/Commands/ExecuteCustomAction.cs +++ b/src/Commands/ExecuteCustomAction.cs @@ -8,7 +8,37 @@ namespace SourceGit.Commands { public static class ExecuteCustomAction { - public static void Run(string repo, string file, string args, Action outputHandler) + public static void Run(string repo, string file, string args) + { + var start = new ProcessStartInfo(); + start.FileName = file; + start.Arguments = args; + start.UseShellExecute = false; + start.CreateNoWindow = true; + start.WorkingDirectory = repo; + + // Force using en_US.UTF-8 locale to avoid GCM crash + if (OperatingSystem.IsLinux()) + start.Environment.Add("LANG", "en_US.UTF-8"); + + // Fix macOS `PATH` env + if (OperatingSystem.IsMacOS() && !string.IsNullOrEmpty(Native.OS.CustomPathEnv)) + start.Environment.Add("PATH", Native.OS.CustomPathEnv); + + try + { + Process.Start(start); + } + catch (Exception e) + { + Dispatcher.UIThread.Invoke(() => + { + App.RaiseException(repo, e.Message); + }); + } + } + + public static void RunAndWait(string repo, string file, string args, Action outputHandler) { var start = new ProcessStartInfo(); start.FileName = file; diff --git a/src/Models/CustomAction.cs b/src/Models/CustomAction.cs index 8452a42d..bd56d6ae 100644 --- a/src/Models/CustomAction.cs +++ b/src/Models/CustomAction.cs @@ -34,9 +34,16 @@ namespace SourceGit.Models set => SetProperty(ref _arguments, value); } + public bool WaitForExit + { + get => _waitForExit; + set => SetProperty(ref _waitForExit, value); + } + private string _name = string.Empty; private CustomActionScope _scope = CustomActionScope.Repository; private string _executable = string.Empty; private string _arguments = string.Empty; + private bool _waitForExit = true; } } diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 018b54d7..40f95793 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -158,6 +158,7 @@ Scope: Commit Repository + Wait for action done Email Address Email address GIT diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 66d1f37e..ef31972a 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -161,6 +161,7 @@ 作用目标 : 选中的提交 仓库 + 等待操作执行完成 电子邮箱 邮箱地址 GIT配置 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index f8255947..506a618f 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -161,6 +161,7 @@ 執行範圍: 選取的提交 存放庫 + 等待自訂操作退出 電子郵件 電子郵件地址 Git 設定 diff --git a/src/ViewModels/ExecuteCustomAction.cs b/src/ViewModels/ExecuteCustomAction.cs index 920b9f43..848faaaf 100644 --- a/src/ViewModels/ExecuteCustomAction.cs +++ b/src/ViewModels/ExecuteCustomAction.cs @@ -28,7 +28,11 @@ namespace SourceGit.ViewModels return Task.Run(() => { - Commands.ExecuteCustomAction.Run(_repo.FullPath, CustomAction.Executable, _args, SetProgressDescription); + if (CustomAction.WaitForExit) + Commands.ExecuteCustomAction.RunAndWait(_repo.FullPath, CustomAction.Executable, _args, SetProgressDescription); + else + Commands.ExecuteCustomAction.Run(_repo.FullPath, CustomAction.Executable, _args); + CallUIThread(() => _repo.SetWatcherEnabled(true)); return true; }); diff --git a/src/Views/RepositoryConfigure.axaml b/src/Views/RepositoryConfigure.axaml index 5e9374f9..d9383743 100644 --- a/src/Views/RepositoryConfigure.axaml +++ b/src/Views/RepositoryConfigure.axaml @@ -341,7 +341,7 @@ - + @@ -439,6 +439,8 @@ + + From 37fed935894a08b073a0c02aeebe9c9083077ecd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 11 Feb 2025 06:34:33 +0000 Subject: [PATCH 213/865] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 67ee5258..50f92a53 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-98.13%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-98.13%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-92.91%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-98.40%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.65%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-98.13%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) +[![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-98.00%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-98.00%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-92.79%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-98.26%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.52%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-98.00%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 9f7a1c80..f67ceacc 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -1,4 +1,4 @@ -### de_DE.axaml: 98.13% +### de_DE.axaml: 98.00%
@@ -11,6 +11,7 @@ - Text.ApplyStash.RestoreIndex - Text.ApplyStash.Stash - Text.Clone.RecurseSubmodules +- Text.Configure.CustomAction.WaitForExit - Text.CreateBranch.Name.WarnSpace - Text.DeleteRepositoryNode.Path - Text.DeleteRepositoryNode.TipForGroup @@ -21,7 +22,7 @@
-### es_ES.axaml: 98.13% +### es_ES.axaml: 98.00%
@@ -34,6 +35,7 @@ - Text.ApplyStash.RestoreIndex - Text.ApplyStash.Stash - Text.Clone.RecurseSubmodules +- Text.Configure.CustomAction.WaitForExit - Text.CreateBranch.Name.WarnSpace - Text.DeleteRepositoryNode.Path - Text.DeleteRepositoryNode.TipForGroup @@ -44,7 +46,7 @@
-### fr_FR.axaml: 92.91% +### fr_FR.axaml: 92.79%
@@ -57,6 +59,7 @@ - Text.ApplyStash.RestoreIndex - Text.ApplyStash.Stash - Text.Clone.RecurseSubmodules +- Text.Configure.CustomAction.WaitForExit - Text.CreateBranch.Name.WarnSpace - Text.DeleteRepositoryNode.Path - Text.DeleteRepositoryNode.TipForGroup @@ -106,7 +109,7 @@
-### it_IT.axaml: 98.40% +### it_IT.axaml: 98.26%
@@ -119,6 +122,7 @@ - Text.ApplyStash.RestoreIndex - Text.ApplyStash.Stash - Text.Clone.RecurseSubmodules +- Text.Configure.CustomAction.WaitForExit - Text.DeleteRepositoryNode.Path - Text.DeleteRepositoryNode.TipForGroup - Text.DeleteRepositoryNode.TipForRepository @@ -127,7 +131,7 @@
-### pt_BR.axaml: 92.65% +### pt_BR.axaml: 92.52%
@@ -145,6 +149,7 @@ - Text.CommitCM.MergeMultiple - Text.CommitDetail.Files.Search - Text.CommitDetail.Info.Children +- Text.Configure.CustomAction.WaitForExit - Text.Configure.IssueTracker.AddSampleGiteeIssue - Text.Configure.IssueTracker.AddSampleGiteePullRequest - Text.CreateBranch.Name.WarnSpace @@ -191,7 +196,7 @@
-### ru_RU.axaml: 98.13% +### ru_RU.axaml: 98.00%
@@ -204,6 +209,7 @@ - Text.ApplyStash.RestoreIndex - Text.ApplyStash.Stash - Text.Clone.RecurseSubmodules +- Text.Configure.CustomAction.WaitForExit - Text.CreateBranch.Name.WarnSpace - Text.DeleteRepositoryNode.Path - Text.DeleteRepositoryNode.TipForGroup From 06df27780f46ad62b14a0305635546c1b6870528 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 11 Feb 2025 14:36:46 +0800 Subject: [PATCH 214/865] localization: update `Text.Configure.CustomAction.WaitForExit` for en_US Signed-off-by: leo --- 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 40f95793..9aeaae50 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -158,7 +158,7 @@ Scope: Commit Repository - Wait for action done + Wait for action exit Email Address Email address GIT From 37e592638823681af941e99ccdb64a43cbdda7f4 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 11 Feb 2025 14:41:56 +0800 Subject: [PATCH 215/865] code_style: keep translation ordered Signed-off-by: leo --- src/Resources/Locales/de_DE.axaml | 2 +- src/Resources/Locales/en_US.axaml | 2 +- src/Resources/Locales/es_ES.axaml | 2 +- src/Resources/Locales/fr_FR.axaml | 2 +- src/Resources/Locales/it_IT.axaml | 2 +- src/Resources/Locales/pt_BR.axaml | 2 +- src/Resources/Locales/ru_RU.axaml | 2 +- src/Resources/Locales/zh_CN.axaml | 2 +- src/Resources/Locales/zh_TW.axaml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index fe961d14..e4cefbd4 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -565,6 +565,7 @@ Aufheben Im Graph ausblenden Im Graph filtern + Aktiviere '--first-parent' Option LAYOUT Horizontal Vertikal @@ -573,7 +574,6 @@ Topologie LOKALE BRANCHES Zum HEAD wechseln - Aktiviere '--first-parent' Option Erstelle Branch Nur aktuellen Branch im Graphen hervorheben Öffne in {0} diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 9aeaae50..83a9650f 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -574,6 +574,7 @@ Unset Hide in commit graph Filter in commit graph + Enable '--first-parent' Option LAYOUT Horizontal Vertical @@ -582,7 +583,6 @@ Topologically LOCAL BRANCHES Navigate to HEAD - Enable '--first-parent' Option Create Branch Only highlight current branch in graph Open in {0} diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index 3e926c63..a0f35814 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -566,6 +566,7 @@ Desestablecer Ocultar en el Gráfico de Commits Filtrar en el Gráfico de Commits + Habilitar Opción '--first-parent' DISPOSICIÓN Horizontal Vertical @@ -574,7 +575,6 @@ Topológicamente RAMAS LOCALES Navegar a HEAD - Habilitar Opción '--first-parent' Crear Rama Resaltar solo la rama actual en el gráfico Abrir en {0} diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index da20a5ee..b269424a 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -548,9 +548,9 @@ Activer l'option '--reflog' Ouvrir dans l'explorateur de fichiers Rechercher Branches/Tags/Submodules + Activer l'option '--first-parent' BRANCHES LOCALES Naviguer vers le HEAD - Activer l'option '--first-parent' Créer une branche Mettre la branche courante en surbrillance dans le graph Ouvrir dans {0} diff --git a/src/Resources/Locales/it_IT.axaml b/src/Resources/Locales/it_IT.axaml index 95f7bd1d..1d0d353e 100644 --- a/src/Resources/Locales/it_IT.axaml +++ b/src/Resources/Locales/it_IT.axaml @@ -568,6 +568,7 @@ Non impostato Nascondi nel grafico dei commit Filtra nel grafico dei commit + Abilita opzione '--first-parent' LAYOUT Orizzontale Verticale @@ -576,7 +577,6 @@ Topologicamente BRANCH LOCALI Vai a HEAD - Abilita opzione '--first-parent' Crea Branch Evidenzia nel grafico solo il branch corrente Apri in {0} diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml index dee8565b..a318cfa8 100644 --- a/src/Resources/Locales/pt_BR.axaml +++ b/src/Resources/Locales/pt_BR.axaml @@ -566,11 +566,11 @@ Desfazer Esconder no gráfico de commit Incluir no gráfico de commit + Habilitar opção '--first-parent' Data do Commit Topologicamente BRANCHES LOCAIS Navegar para HEAD - Habilitar opção '--first-parent' Criar Branch Abrir em {0} Abrir em Ferramentas Externas diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index 27a2d360..e9f03d5a 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -567,6 +567,7 @@ Скрыть в графе ревизии Фильтр в графе ревизии ОТФИЛЬТРОВАНО: + Включить опцию --first-parent РАСПОЛОЖЕНИЕ Горизонтально Вертикально @@ -575,7 +576,6 @@ Топологически ЛОКАЛЬНЫЕ ВЕТКИ Навигация по ГОЛОВЕ (HEAD) - Включить опцию --first-parent Создать ветку Выделять только текущую ветку на графике Открыть в {0} diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index ef31972a..c3932321 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -578,6 +578,7 @@ 不指定 在提交列表中隐藏 使用其对提交列表过滤 + 启用 --first-parent 过滤选项 布局方式 水平排布 竖直排布 @@ -586,7 +587,6 @@ 按拓扑排序 本地分支 定位HEAD - 启用 --first-parent 过滤选项 新建分支 提交路线图中仅高亮显示当前分支 在 {0} 中打开 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 506a618f..3e7382b8 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -577,6 +577,7 @@ 取消指定 在提交列表中隱藏 以其篩選提交列表 + 啟用 [--first-parent] 選項 佈局方式 橫向顯示 縱向顯示 @@ -585,7 +586,6 @@ 依拓撲排序 本機分支 回到 HEAD - 啟用 [--first-parent] 選項 新增分支 提交圖表中僅高亮顯示目前分支 在 {0} 中開啟 From 011a415949ebe23ef224878a0dd213b7be40b8e8 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 11 Feb 2025 15:15:27 +0800 Subject: [PATCH 216/865] enhance: add a button to clear all notifications (#950) Signed-off-by: leo --- src/Resources/Icons.axaml | 1 + src/Resources/Locales/en_US.axaml | 1 + src/Resources/Locales/zh_CN.axaml | 1 + src/Resources/Locales/zh_TW.axaml | 1 + src/ViewModels/LauncherPage.cs | 5 +++++ src/Views/LauncherPage.axaml | 20 ++++++++++++++++++-- 6 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/Resources/Icons.axaml b/src/Resources/Icons.axaml index efec7b2b..8e865660 100644 --- a/src/Resources/Icons.axaml +++ b/src/Resources/Icons.axaml @@ -12,6 +12,7 @@ M529 511c115 0 212 79 239 185h224a62 62 0 017 123l-7 0-224 0a247 247 0 01-479 0H65a62 62 0 01-7-123l7-0h224a247 247 0 01239-185zm0 124a124 124 0 100 247 124 124 0 000-247zm0-618c32 0 58 24 61 55l0 7V206c89 11 165 45 225 103a74 74 0 0122 45l0 9v87a62 62 0 01-123 7l-0-7v-65l-6-4c-43-33-97-51-163-53l-17-0c-74 0-133 18-180 54l-6 4v65a62 62 0 01-55 61l-7 0a62 62 0 01-61-55l-0-7V362c0-20 8-39 23-53 60-58 135-92 224-103V79c0-34 28-62 62-62z M512 926c-229 0-414-186-414-414S283 98 512 98s414 186 414 414-186 414-414 414zm0-73c189 0 341-153 341-341S701 171 512 171 171 323 171 512s153 341 341 341zm-6-192L284 439l52-52 171 171 171-171L728 439l-222 222z M512 57c251 0 455 204 455 455S763 967 512 967 57 763 57 512 261 57 512 57zm181 274c-11-11-29-11-40 0L512 472 371 331c-11-11-29-11-40 0-11 11-11 29 0 40L471 512 331 653c-11 11-11 29 0 40 11 11 29 11 40 0l141-141 141 141c11 11 29 11 40 0 11-11 11-29 0-40L552 512l141-141c11-11 11-29 0-40z + M591 907A85 85 0 01427 875h114a299 299 0 0050 32zM725 405c130 0 235 105 235 235s-105 235-235 235-235-105-235-235 105-235 235-235zM512 64a43 43 0 0143 43v24c126 17 229 107 264 225A298 298 0 00725 341l-4 0A235 235 0 00512 213l-5 0c-125 4-224 104-228 229l-0 6v167a211 211 0 01-26 101l-4 7-14 23h211a298 298 0 0050 85l-276-0a77 77 0 01-66-39c-13-22-14-50-2-73l2-4 22-36c10-17 16-37 17-57l0-7v-167C193 287 313 153 469 131V107a43 43 0 0139-43zm345 505L654 771a149 149 0 00202-202zM725 491a149 149 0 00-131 220l202-202A149 149 0 00725 491z M797 829a49 49 0 1049 49 49 49 0 00-49-49zm147-114A49 49 0 10992 764a49 49 0 00-49-49zM928 861a49 49 0 1049 49A49 49 0 00928 861zm-5-586L992 205 851 64l-71 71a67 67 0 00-94 0l235 235a67 67 0 000-94zm-853 128a32 32 0 00-32 50 1291 1291 0 0075 112L288 552c20 0 25 21 8 37l-93 86a1282 1282 0 00120 114l100-32c19-6 28 15 14 34l-40 55c26 19 53 36 82 53a89 89 0 00115-20 1391 1391 0 00256-485l-188-188s-306 224-595 198z M1280 704c0 141-115 256-256 256H288C129 960 0 831 0 672c0-126 80-232 192-272A327 327 0 01192 384c0-177 143-320 320-320 119 0 222 64 277 160C820 204 857 192 896 192c106 0 192 86 192 192 0 24-5 48-13 69C1192 477 1280 580 1280 704zm-493-128H656V352c0-18-14-32-32-32h-96c-18 0-32 14-32 32v224h-131c-29 0-43 34-23 55l211 211c12 12 33 12 45 0l211-211c20-20 6-55-23-55z M853 102H171C133 102 102 133 102 171v683C102 891 133 922 171 922h683C891 922 922 891 922 853V171C922 133 891 102 853 102zM390 600l-48 48L205 512l137-137 48 48L301 512l88 88zM465 819l-66-18L559 205l66 18L465 819zm218-171L634 600 723 512l-88-88 48-48L819 512 683 649z diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 83a9650f..70da2973 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -584,6 +584,7 @@ LOCAL BRANCHES Navigate to HEAD Create Branch + CLEAR NOTIFICATIONS Only highlight current branch in graph Open in {0} Open in External Tools diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index c3932321..005ef3a2 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -588,6 +588,7 @@ 本地分支 定位HEAD 新建分支 + 清空通知列表 提交路线图中仅高亮显示当前分支 在 {0} 中打开 使用外部工具打开 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 3e7382b8..fe0e4bac 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -587,6 +587,7 @@ 本機分支 回到 HEAD 新增分支 + 清空通知清單 提交圖表中僅高亮顯示目前分支 在 {0} 中開啟 使用外部工具開啟 diff --git a/src/ViewModels/LauncherPage.cs b/src/ViewModels/LauncherPage.cs index b8138aca..63cb52af 100644 --- a/src/ViewModels/LauncherPage.cs +++ b/src/ViewModels/LauncherPage.cs @@ -45,6 +45,11 @@ namespace SourceGit.ViewModels _data = repo; } + public void ClearNotifications() + { + Notifications.Clear(); + } + public void CopyPath() { if (_node.IsRepository) diff --git a/src/Views/LauncherPage.axaml b/src/Views/LauncherPage.axaml index ee4c77eb..81f504c1 100644 --- a/src/Views/LauncherPage.axaml +++ b/src/Views/LauncherPage.axaml @@ -53,7 +53,7 @@ PointerPressed="OnMaskClicked" IsVisible="{Binding Popup, Converter={x:Static ObjectConverters.IsNotNull}}"/> - + + + + - + From 1bfe1a275511a23f9a665da414ac892df66097e7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 11 Feb 2025 07:15:47 +0000 Subject: [PATCH 217/865] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 50f92a53..623347bf 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-98.00%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-98.00%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-92.79%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-98.26%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.52%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-98.00%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) +[![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-97.87%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.87%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-92.67%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-98.13%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.40%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-97.87%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 f67ceacc..d1e474d2 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -1,4 +1,4 @@ -### de_DE.axaml: 98.00% +### de_DE.axaml: 97.87%
@@ -16,13 +16,14 @@ - Text.DeleteRepositoryNode.Path - Text.DeleteRepositoryNode.TipForGroup - Text.DeleteRepositoryNode.TipForRepository +- Text.Repository.Notifications.Clear - Text.Stash.AutoRestore - Text.Stash.AutoRestore.Tip - Text.WorkingCopy.SignOff
-### es_ES.axaml: 98.00% +### es_ES.axaml: 97.87%
@@ -40,13 +41,14 @@ - Text.DeleteRepositoryNode.Path - Text.DeleteRepositoryNode.TipForGroup - Text.DeleteRepositoryNode.TipForRepository +- Text.Repository.Notifications.Clear - Text.Stash.AutoRestore - Text.Stash.AutoRestore.Tip - Text.WorkingCopy.SignOff
-### fr_FR.axaml: 92.79% +### fr_FR.axaml: 92.67%
@@ -90,6 +92,7 @@ - Text.Repository.HistoriesOrder - Text.Repository.HistoriesOrder.ByDate - Text.Repository.HistoriesOrder.Topo +- Text.Repository.Notifications.Clear - Text.Repository.Skip - Text.Repository.Tags.OrderByCreatorDate - Text.Repository.Tags.OrderByNameAsc @@ -109,7 +112,7 @@
-### it_IT.axaml: 98.26% +### it_IT.axaml: 98.13%
@@ -126,12 +129,13 @@ - Text.DeleteRepositoryNode.Path - Text.DeleteRepositoryNode.TipForGroup - Text.DeleteRepositoryNode.TipForRepository +- Text.Repository.Notifications.Clear - Text.Stash.AutoRestore - Text.Stash.AutoRestore.Tip
-### pt_BR.axaml: 92.52% +### pt_BR.axaml: 92.40%
@@ -177,6 +181,7 @@ - Text.Repository.HistoriesLayout.Horizontal - Text.Repository.HistoriesLayout.Vertical - Text.Repository.HistoriesOrder +- Text.Repository.Notifications.Clear - Text.Repository.OnlyHighlightCurrentBranchInHistories - Text.Repository.Skip - Text.Repository.Tags.OrderByCreatorDate @@ -196,7 +201,7 @@
-### ru_RU.axaml: 98.00% +### ru_RU.axaml: 97.87%
@@ -214,6 +219,7 @@ - Text.DeleteRepositoryNode.Path - Text.DeleteRepositoryNode.TipForGroup - Text.DeleteRepositoryNode.TipForRepository +- Text.Repository.Notifications.Clear - Text.Stash.AutoRestore - Text.Stash.AutoRestore.Tip - Text.WorkingCopy.SignOff From e9d16a5102351c107ca5cfc43785afc5663d9ef6 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 11 Feb 2025 16:58:10 +0800 Subject: [PATCH 218/865] project: upgrade `TextMateSharp` to `1.0.66` (#969) Signed-off-by: leo --- src/SourceGit.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SourceGit.csproj b/src/SourceGit.csproj index af8fa5b1..624804f1 100644 --- a/src/SourceGit.csproj +++ b/src/SourceGit.csproj @@ -52,8 +52,8 @@ - - + + From 21cfd17cdb8c6467ff8704d67a820ec17f29dbcd Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 11 Feb 2025 18:57:54 +0800 Subject: [PATCH 219/865] fix: do NOT quit when try to input `@` via `Alt Gr+Q` with German ISO keyboard layout (#970) Signed-off-by: leo --- src/Views/Launcher.axaml.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Views/Launcher.axaml.cs b/src/Views/Launcher.axaml.cs index b5f09d79..e3140191 100644 --- a/src/Views/Launcher.axaml.cs +++ b/src/Views/Launcher.axaml.cs @@ -120,6 +120,13 @@ namespace SourceGit.Views return; } + // Ctrl+Q quits the application (macOS use hotkeys in system menu bar) + if (!OperatingSystem.IsMacOS() && e.KeyModifiers == KeyModifiers.Control && e.Key == Key.Q) + { + App.Quit(0); + return; + } + if (e.KeyModifiers.HasFlag(OperatingSystem.IsMacOS() ? KeyModifiers.Meta : KeyModifiers.Control)) { if (e.Key == Key.W) @@ -146,13 +153,6 @@ namespace SourceGit.Views return; } - if (e.Key == Key.Q) - { - App.Quit(0); - e.Handled = true; - return; - } - if ((OperatingSystem.IsMacOS() && e.KeyModifiers.HasFlag(KeyModifiers.Alt) && e.Key == Key.Right) || (!OperatingSystem.IsMacOS() && !e.KeyModifiers.HasFlag(KeyModifiers.Shift) && e.Key == Key.Tab)) { From eea55ec56fffc10032829662c43f36f5a14cd549 Mon Sep 17 00:00:00 2001 From: AquariusStar <48148723+AquariusStar@users.noreply.github.com> Date: Wed, 12 Feb 2025 05:51:06 +0300 Subject: [PATCH 220/865] localization: update russian localization (#971) --- src/Resources/Locales/ru_RU.axaml | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index e9f03d5a..a1c40764 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -22,7 +22,9 @@ Отслеживание ветки: Отслеживание внешней ветки OpenAI Ассистент + ПЕРЕСОЗДАТЬ Использовать OpenAI для создания сообщения о ревизии + ПРИМЕНИТЬ КАК СООБЩЕНИЕ РЕВИЗИИ Исправить Ошибка Выдает ошибки и отказывается применять исправление @@ -37,6 +39,10 @@ Предупреждать Выдавать предупреждения о нескольких таких ошибках, но применять Пробел: + Отложить + Удалить после применения + Восстановить изменения индекса + Отложенный: Архивировать... Сохранить архив в: Выберите путь к архивному файлу @@ -100,6 +106,7 @@ Локальное имя: Имя репозитория. (необязательно). Родительский каталог: + Инициализировать и обновить подмодуль Адрес репозитория: ЗАКРЫТЬ Редактор @@ -131,7 +138,7 @@ АВТОР ИЗМЕНЁННЫЙ ДОЧЕРНИЙ - ИСПОЛНИТЕЛЬ + РЕВИЗОР(ИСПОЛНИТЕЛЬ) Найти все ветки с этой ревизией ВЕТКИ С ЭТОЙ РЕВИЗИЕЙ Отображаются только первые 100 изменений. Смотрите все изменения на вкладке ИЗМЕНЕНИЯ. @@ -154,15 +161,16 @@ Диапазон: Ревизия Репозиторий + Ждать для выполения выхода Адрес электронной почты Адрес электронной почты GIT - Автоматическое скачивание изменений + Автоматическая загрузка изменений Минут(а/ы) Внешний репозиторий по умолчанию ОТСЛЕЖИВАНИЕ ПРОБЛЕМ - Добавить пример правила для тем в Gitee - Добавить пример правила запроса скачивания из Gitee + Добавить пример правила для тем в Gitea + Добавить пример правила запроса скачивания из Gitea Добавить пример правила для Git Добавить пример правила Jira Добавить пример правила выдачи GitLab @@ -203,6 +211,7 @@ Отложить и применить повторно Имя новой ветки: Введите имя ветки. + Пробелы будут заменены на тире. Создать локальную ветку Создать метку... Новая метка у: @@ -226,8 +235,11 @@ Вы пытаетесь удалить несколько веток одновременно. Обязательно перепроверьте, прежде чем предпринимать какие-либо действия! Удалить внешний репозиторий Внешний репозиторий: + Path: Цель: + Все дочерние элементы будут удалены из списка. Подтвердите удаление группы + Будет удалён из списка. На диске останется. Подтвердите удаление репозитория Удалить подмодуль Путь подмодуля: @@ -577,6 +589,7 @@ ЛОКАЛЬНЫЕ ВЕТКИ Навигация по ГОЛОВЕ (HEAD) Создать ветку + ОЧИСТКА УВЕДОМЛЕНИЙ Выделять только текущую ветку на графике Открыть в {0} Открыть в расширенном инструменте @@ -585,7 +598,7 @@ ДОБАВИТЬ ВНЕШНИЙ РЕПОЗИТОРИЙ Поиск ревизии Автор - исполнитель + Ревизор Файл Сообщение SHA @@ -645,6 +658,8 @@ Подготовленные так и неподготовленные изменения выбранных файлов будут сохранены!!! ЗАПУСК Отложить + Автоматически восстанавливать после откладывания + Ваши рабочие файлы остаются неизменными, но отложенные сохранятся. Включить неотслеживаемые файлы Хранить отложенные файлы Сообщение: @@ -660,7 +675,7 @@ ОТЛОЖЕННЫЕ Статистика РЕВИЗИИ - ИСПОЛНИТЕЛИ + РЕВИЗОРЫ(ИСПОЛНИТЕЛИ) МЕСЯЦ НЕДЕЛЯ РЕВИЗИИ: @@ -722,6 +737,7 @@ ВКЛЮЧИТЬ НЕОТСЛЕЖИВАЕМЫЕ ФАЙЛЫ НЕТ ПОСЛЕДНИХ ВХОДНЫХ СООБЩЕНИЙ НЕТ ШАБЛОНОВ РЕВИЗИИ + Завершение работы ПОДГОТОВЛЕННЫЕ СНЯТЬ ПОДГОТОВЛЕННЫЙ СНЯТЬ ВСЕ ПОДГОТОВЛЕННЫЕ From 19e72f86505233a694d0041c5dbf06170a256681 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 12 Feb 2025 02:51:20 +0000 Subject: [PATCH 221/865] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 19 ++----------------- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 623347bf..eadd0cfd 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-97.87%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.87%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-92.67%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-98.13%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.40%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-97.87%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) +[![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-97.87%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.87%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-92.67%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-98.13%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.40%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 d1e474d2..86da7846 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -201,28 +201,13 @@
-### ru_RU.axaml: 97.87% +### ru_RU.axaml: 100.00%
Missing Keys -- Text.AIAssistant.Regen -- Text.AIAssistant.Use -- Text.ApplyStash -- Text.ApplyStash.DropAfterApply -- Text.ApplyStash.RestoreIndex -- Text.ApplyStash.Stash -- Text.Clone.RecurseSubmodules -- Text.Configure.CustomAction.WaitForExit -- Text.CreateBranch.Name.WarnSpace -- Text.DeleteRepositoryNode.Path -- Text.DeleteRepositoryNode.TipForGroup -- Text.DeleteRepositoryNode.TipForRepository -- Text.Repository.Notifications.Clear -- Text.Stash.AutoRestore -- Text.Stash.AutoRestore.Tip -- Text.WorkingCopy.SignOff +
From 9757678dcf18de806828d23dbd1631b97602cce4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christopher=20G=C3=B6ttfert?= <45085620+ChrisGoettfert@users.noreply.github.com> Date: Wed, 12 Feb 2025 03:59:00 +0100 Subject: [PATCH 222/865] localization: added missing german translations (#973) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Christopher Göttfert --- src/Resources/Locales/de_DE.axaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index e4cefbd4..995c113b 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -22,7 +22,9 @@ Branch verfolgen: Remote-Branch verfolgen OpenAI Assistent + Neu generieren Verwende OpenAI, um Commit-Nachrichten zu generieren + Als Commit-Nachricht verwenden Patch Fehler Fehler werfen und anwenden des Patches verweigern @@ -37,6 +39,10 @@ Warnen Gibt eine Warnung für ein paar solcher Fehler aus, aber wendet es an Leerzeichen: + Stash anwenden + Nach dem Anwenden löschen + Änderungen des Index wiederherstellen + Stash: Archivieren... Speichere Archiv in: Wähle Archivpfad aus @@ -100,6 +106,7 @@ Lokaler Name: Repository-Name. Optional. Übergeordneter Ordner: + Submodule initialisieren und aktualisieren Repository URL: SCHLIESSEN Editor @@ -202,6 +209,7 @@ Stashen & wieder anwenden Neuer Branch-Name: Branch-Namen eingeben. + Leerzeichen werden durch Bindestriche ersetzt. Lokalen Branch erstellen Tag erstellen... Neuer Tag auf: @@ -225,8 +233,11 @@ Du versuchst mehrere Branches auf einmal zu löschen. Kontrolliere noch einmal vor dem Fortfahren! Remote löschen Remote: + Pfad: Ziel: Bestätige löschen von Gruppe + Alle Nachfolger werden aus der Liste entfernt. + Dadurch wird es nur aus der Liste entfernt, nicht von der Festplatte! Bestätige löschen von Repository Lösche Submodul Submodul Pfad: @@ -574,6 +585,7 @@ Topologie LOKALE BRANCHES Zum HEAD wechseln + Aktiviere '--first-parent' Option Erstelle Branch Nur aktuellen Branch im Graphen hervorheben Öffne in {0} @@ -641,6 +653,8 @@ Pfad zum privaten SSH Schlüssel START Stash + Automatisch wiederherstellen nach dem Stashen + Die Arbeitsdateien bleiben unverändert, aber ein Stash wird gespeichert. Inklusive nicht-verfolgter Dateien Behalte gestagte Dateien Name: @@ -720,6 +734,7 @@ NICHT-VERFOLGTE DATEIEN INKLUDIEREN KEINE BISHERIGEN COMMIT-NACHRICHTEN KEINE COMMIT TEMPLATES + SignOff GESTAGED UNSTAGEN ALLES UNSTAGEN From 21e4dcffd0e301e84045c17af1aa97490fbe0bb8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 12 Feb 2025 02:59:19 +0000 Subject: [PATCH 223/865] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 16 +--------------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index eadd0cfd..f188bf25 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-97.87%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.87%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-92.67%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-98.13%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.40%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.73%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.87%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-92.67%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-98.13%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.40%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 86da7846..71ef0acf 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -1,25 +1,11 @@ -### de_DE.axaml: 97.87% +### de_DE.axaml: 99.73%
Missing Keys -- Text.AIAssistant.Regen -- Text.AIAssistant.Use -- Text.ApplyStash -- Text.ApplyStash.DropAfterApply -- Text.ApplyStash.RestoreIndex -- Text.ApplyStash.Stash -- Text.Clone.RecurseSubmodules - Text.Configure.CustomAction.WaitForExit -- Text.CreateBranch.Name.WarnSpace -- Text.DeleteRepositoryNode.Path -- Text.DeleteRepositoryNode.TipForGroup -- Text.DeleteRepositoryNode.TipForRepository - Text.Repository.Notifications.Clear -- Text.Stash.AutoRestore -- Text.Stash.AutoRestore.Tip -- Text.WorkingCopy.SignOff
From 3302bdeb2607149c0ceaa3cadb0901516bea7617 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 12 Feb 2025 21:25:57 +0800 Subject: [PATCH 224/865] localization: remove duplicated keys in de_DE Signed-off-by: leo --- src/Resources/Locales/de_DE.axaml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index 995c113b..b6458822 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -585,7 +585,6 @@ Topologie LOKALE BRANCHES Zum HEAD wechseln - Aktiviere '--first-parent' Option Erstelle Branch Nur aktuellen Branch im Graphen hervorheben Öffne in {0} From c6aedf1193114b8fa94823aecf6c28235817ea16 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 12 Feb 2025 21:29:17 +0800 Subject: [PATCH 225/865] ux: right margin of main tab bar on macOS Signed-off-by: leo --- src/Views/Launcher.axaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Views/Launcher.axaml b/src/Views/Launcher.axaml index bfabf6e5..db5aeecb 100644 --- a/src/Views/Launcher.axaml +++ b/src/Views/Launcher.axaml @@ -86,10 +86,10 @@ - + - +
From 588879eb7f8689506179e02fea6402d6b5a8ed3b Mon Sep 17 00:00:00 2001 From: "Dmitrij D. Czarkoff" Date: Thu, 13 Feb 2025 02:41:08 +0000 Subject: [PATCH 226/865] feat: change worktree presentation (#978) Present the worktree name first, then relative path to the main repo. This is more aligned with Git's own UI, and works better with UI size constrains. --- src/Commands/Worktree.cs | 2 ++ src/Models/Worktree.cs | 9 +++++---- src/Views/RemoveWorktree.axaml | 4 ++-- src/Views/Repository.axaml | 4 ++-- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/Commands/Worktree.cs b/src/Commands/Worktree.cs index 27c0e28e..b73b8573 100644 --- a/src/Commands/Worktree.cs +++ b/src/Commands/Worktree.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; namespace SourceGit.Commands { @@ -26,6 +27,7 @@ namespace SourceGit.Commands if (line.StartsWith("worktree ", StringComparison.Ordinal)) { last = new Models.Worktree() { FullPath = line.Substring(9).Trim() }; + last.RelativePath = Path.GetRelativePath(WorkingDirectory, last.FullPath); worktrees.Add(last); } else if (line.StartsWith("bare", StringComparison.Ordinal)) diff --git a/src/Models/Worktree.cs b/src/Models/Worktree.cs index f9ba14e4..bc40e320 100644 --- a/src/Models/Worktree.cs +++ b/src/Models/Worktree.cs @@ -6,6 +6,7 @@ namespace SourceGit.Models { public string Branch { get; set; } = string.Empty; public string FullPath { get; set; } = string.Empty; + public string RelativePath { get; set; } = string.Empty; public string Head { get; set; } = string.Empty; public bool IsBare { get; set; } = false; public bool IsDetached { get; set; } = false; @@ -21,15 +22,15 @@ namespace SourceGit.Models get { if (IsDetached) - return $"(deteched HEAD at {Head.Substring(10)})"; + return $"deteched HEAD at {Head.Substring(10)}"; if (Branch.StartsWith("refs/heads/", System.StringComparison.Ordinal)) - return $"({Branch.Substring(11)})"; + return Branch.Substring(11); if (Branch.StartsWith("refs/remotes/", System.StringComparison.Ordinal)) - return $"({Branch.Substring(13)})"; + return Branch.Substring(13); - return $"({Branch})"; + return Branch; } } diff --git a/src/Views/RemoveWorktree.axaml b/src/Views/RemoveWorktree.axaml index 6d7ea914..364881d2 100644 --- a/src/Views/RemoveWorktree.axaml +++ b/src/Views/RemoveWorktree.axaml @@ -18,8 +18,8 @@ - - + + () diff --git a/src/Views/Repository.axaml b/src/Views/Repository.axaml index 74f628c6..4180a054 100644 --- a/src/Views/Repository.axaml +++ b/src/Views/Repository.axaml @@ -372,8 +372,8 @@ - - + + () From 9b07034846ea097f2628930ea43ce818ca0a35a1 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 13 Feb 2025 10:46:28 +0800 Subject: [PATCH 227/865] code_review: PR #978 * Remove unnecessary parentheses since the name of relative path uses secondary foreground color already Signed-off-by: leo --- src/Views/RemoveWorktree.axaml | 2 +- src/Views/Repository.axaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Views/RemoveWorktree.axaml b/src/Views/RemoveWorktree.axaml index 364881d2..736e6e40 100644 --- a/src/Views/RemoveWorktree.axaml +++ b/src/Views/RemoveWorktree.axaml @@ -19,7 +19,7 @@ - () +
diff --git a/src/Views/Repository.axaml b/src/Views/Repository.axaml index 4180a054..4d6bc64a 100644 --- a/src/Views/Repository.axaml +++ b/src/Views/Repository.axaml @@ -373,7 +373,7 @@ - () + From 9104060d79b0c4e5f316550cab8eca267e9e15ba Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 14 Feb 2025 10:43:08 +0800 Subject: [PATCH 228/865] feature: support add custom actions for selected branch (#980) Signed-off-by: leo --- src/Models/CustomAction.cs | 1 + src/Resources/Locales/en_US.axaml | 4 ++- src/Resources/Locales/zh_CN.axaml | 4 ++- src/Resources/Locales/zh_TW.axaml | 4 ++- src/ViewModels/ExecuteCustomAction.cs | 19 ++++++++++-- src/ViewModels/Repository.cs | 42 ++++++++++++++++++++++++++- src/Views/RepositoryConfigure.axaml | 21 ++++---------- 7 files changed, 73 insertions(+), 22 deletions(-) diff --git a/src/Models/CustomAction.cs b/src/Models/CustomAction.cs index bd56d6ae..a614961a 100644 --- a/src/Models/CustomAction.cs +++ b/src/Models/CustomAction.cs @@ -6,6 +6,7 @@ namespace SourceGit.Models { Repository, Commit, + Branch, } public class CustomAction : ObservableObject diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 70da2973..f8a06f08 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -56,6 +56,7 @@ Compare with HEAD Compare with Worktree Copy Branch Name + Custom Action Delete ${0}$... Delete selected {0} branches Discard all changes @@ -152,10 +153,11 @@ Template Content: CUSTOM ACTION Arguments: - ${REPO} - Repository's path; ${SHA} - Selected commit's SHA + ${REPO} - Repository's path; ${BRANCH} - Selected branch; ${SHA} - Selected commit's SHA Executable File: Name: Scope: + Branch Commit Repository Wait for action exit diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 005ef3a2..4db909c9 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -59,6 +59,7 @@ 与当前HEAD比较 与本地工作树比较 复制分支名 + 自定义操作 删除 ${0}$... 删除选中的 {0} 个分支 放弃所有更改 @@ -155,10 +156,11 @@ 模板内容 : 自定义操作 命令行参数 : - 请使用${REPO}代替仓库路径,${SHA}代替提交哈希 + 请使用${REPO}代替仓库路径,${BRANCH}代替选中的分支,${SHA}代替提交哈希 可执行文件路径 : 名称 : 作用目标 : + 选中的分支 选中的提交 仓库 等待操作执行完成 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index fe0e4bac..167565cf 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -59,6 +59,7 @@ 與目前 HEAD 比較 與本機工作區比較 複製分支名稱 + 自訂動作 刪除 ${0}$... 刪除所選的 {0} 個分支 捨棄所有變更 @@ -155,10 +156,11 @@ 範本內容: 自訂動作 指令參數: - 使用 ${REPO} 表示存放庫路徑、${SHA} 表示所選的提交編號 + 使用 ${REPO} 表示存放庫路徑、${BRANCH} 表示所選的分支、${SHA} 表示所選的提交編號 可執行檔案路徑: 名稱: 執行範圍: + 選取的分支 選取的提交 存放庫 等待自訂操作退出 diff --git a/src/ViewModels/ExecuteCustomAction.cs b/src/ViewModels/ExecuteCustomAction.cs index 848faaaf..8e34379f 100644 --- a/src/ViewModels/ExecuteCustomAction.cs +++ b/src/ViewModels/ExecuteCustomAction.cs @@ -10,13 +10,26 @@ namespace SourceGit.ViewModels private set; } - public ExecuteCustomAction(Repository repo, Models.CustomAction action, Models.Commit commit) + public ExecuteCustomAction(Repository repo, Models.CustomAction action) { _repo = repo; _args = action.Arguments.Replace("${REPO}", _repo.FullPath); - if (commit != null) - _args = _args.Replace("${SHA}", commit.SHA); + CustomAction = action; + View = new Views.ExecuteCustomAction() { DataContext = this }; + } + public ExecuteCustomAction(Repository repo, Models.CustomAction action, Models.Branch branch) + { + _repo = repo; + _args = action.Arguments.Replace("${REPO}", _repo.FullPath).Replace("${BRANCH}", branch.FriendlyName); + CustomAction = action; + View = new Views.ExecuteCustomAction() { DataContext = this }; + } + + public ExecuteCustomAction(Repository repo, Models.CustomAction action, Models.Commit commit) + { + _repo = repo; + _args = action.Arguments.Replace("${REPO}", _repo.FullPath).Replace("${SHA}", commit.SHA); CustomAction = action; View = new Views.ExecuteCustomAction() { DataContext = this }; } diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 44de8c35..6b96255f 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -1439,7 +1439,7 @@ namespace SourceGit.ViewModels item.Click += (_, e) => { if (CanCreatePopup()) - ShowAndStartPopup(new ExecuteCustomAction(this, dup, null)); + ShowAndStartPopup(new ExecuteCustomAction(this, dup)); e.Handled = true; }; @@ -1698,6 +1698,7 @@ namespace SourceGit.ViewModels menu.Items.Add(createBranch); menu.Items.Add(createTag); menu.Items.Add(new MenuItem() { Header = "-" }); + TryToAddCustomActionsToBranchContextMenu(menu, branch); if (!IsBare) { @@ -1968,7 +1969,9 @@ namespace SourceGit.ViewModels menu.Items.Add(new MenuItem() { Header = "-" }); menu.Items.Add(archive); menu.Items.Add(new MenuItem() { Header = "-" }); + TryToAddCustomActionsToBranchContextMenu(menu, branch); menu.Items.Add(copy); + return menu; } @@ -2319,6 +2322,43 @@ namespace SourceGit.ViewModels return null; } + private void TryToAddCustomActionsToBranchContextMenu(ContextMenu menu, Models.Branch branch) + { + var actions = new List(); + foreach (var action in Settings.CustomActions) + { + if (action.Scope == Models.CustomActionScope.Branch) + actions.Add(action); + } + + if (actions.Count == 0) + return; + + var custom = new MenuItem(); + custom.Header = App.Text("BranchCM.CustomAction"); + custom.Icon = App.CreateMenuIcon("Icons.Action"); + + foreach (var action in actions) + { + var dup = action; + var item = new MenuItem(); + item.Icon = App.CreateMenuIcon("Icons.Action"); + item.Header = dup.Name; + item.Click += (_, e) => + { + if (CanCreatePopup()) + ShowAndStartPopup(new ExecuteCustomAction(this, dup, branch)); + + e.Handled = true; + }; + + custom.Items.Add(item); + } + + menu.Items.Add(custom); + menu.Items.Add(new MenuItem() { Header = "-" }); + } + private void UpdateCurrentRevisionFilesForSearchSuggestion() { _revisionFiles.Clear(); diff --git a/src/Views/RepositoryConfigure.axaml b/src/Views/RepositoryConfigure.axaml index d9383743..6b7cdc12 100644 --- a/src/Views/RepositoryConfigure.axaml +++ b/src/Views/RepositoryConfigure.axaml @@ -5,7 +5,6 @@ xmlns:m="using:SourceGit.Models" xmlns:vm="using:SourceGit.ViewModels" xmlns:v="using:SourceGit.Views" - xmlns:ac="using:Avalonia.Controls.Converters" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="SourceGit.Views.RepositoryConfigure" x:DataType="vm:RepositoryConfigure" @@ -412,20 +411,12 @@ - - - - - - - - - + + + + + + From e39351b4a77e3f179340c4a1b61ed04087a9c3fc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 14 Feb 2025 02:43:26 +0000 Subject: [PATCH 229/865] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 25 ++++++++++++++++++------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f188bf25..3829cf54 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-99.73%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.87%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-92.67%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-98.13%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.40%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.47%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.61%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-92.42%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-97.87%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.15%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.73%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 71ef0acf..84411404 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -1,15 +1,17 @@ -### de_DE.axaml: 99.73% +### de_DE.axaml: 99.47%
Missing Keys +- Text.BranchCM.CustomAction +- Text.Configure.CustomAction.Scope.Branch - Text.Configure.CustomAction.WaitForExit - Text.Repository.Notifications.Clear
-### es_ES.axaml: 97.87% +### es_ES.axaml: 97.61%
@@ -21,7 +23,9 @@ - Text.ApplyStash.DropAfterApply - Text.ApplyStash.RestoreIndex - Text.ApplyStash.Stash +- Text.BranchCM.CustomAction - Text.Clone.RecurseSubmodules +- Text.Configure.CustomAction.Scope.Branch - Text.Configure.CustomAction.WaitForExit - Text.CreateBranch.Name.WarnSpace - Text.DeleteRepositoryNode.Path @@ -34,7 +38,7 @@
-### fr_FR.axaml: 92.67% +### fr_FR.axaml: 92.42%
@@ -46,7 +50,9 @@ - Text.ApplyStash.DropAfterApply - Text.ApplyStash.RestoreIndex - Text.ApplyStash.Stash +- Text.BranchCM.CustomAction - Text.Clone.RecurseSubmodules +- Text.Configure.CustomAction.Scope.Branch - Text.Configure.CustomAction.WaitForExit - Text.CreateBranch.Name.WarnSpace - Text.DeleteRepositoryNode.Path @@ -98,7 +104,7 @@
-### it_IT.axaml: 98.13% +### it_IT.axaml: 97.87%
@@ -110,7 +116,9 @@ - Text.ApplyStash.DropAfterApply - Text.ApplyStash.RestoreIndex - Text.ApplyStash.Stash +- Text.BranchCM.CustomAction - Text.Clone.RecurseSubmodules +- Text.Configure.CustomAction.Scope.Branch - Text.Configure.CustomAction.WaitForExit - Text.DeleteRepositoryNode.Path - Text.DeleteRepositoryNode.TipForGroup @@ -121,7 +129,7 @@
-### pt_BR.axaml: 92.40% +### pt_BR.axaml: 92.15%
@@ -133,12 +141,14 @@ - Text.ApplyStash.DropAfterApply - Text.ApplyStash.RestoreIndex - Text.ApplyStash.Stash +- Text.BranchCM.CustomAction - Text.BranchCM.MergeMultiBranches - Text.Clone.RecurseSubmodules - Text.CommitCM.Merge - Text.CommitCM.MergeMultiple - Text.CommitDetail.Files.Search - Text.CommitDetail.Info.Children +- Text.Configure.CustomAction.Scope.Branch - Text.Configure.CustomAction.WaitForExit - Text.Configure.IssueTracker.AddSampleGiteeIssue - Text.Configure.IssueTracker.AddSampleGiteePullRequest @@ -187,13 +197,14 @@
-### ru_RU.axaml: 100.00% +### ru_RU.axaml: 99.73%
Missing Keys - +- Text.BranchCM.CustomAction +- Text.Configure.CustomAction.Scope.Branch
From bc66e24407629efc0f9791fe14f3f05d9f1484e3 Mon Sep 17 00:00:00 2001 From: leo Date: Sat, 15 Feb 2025 17:43:32 +0800 Subject: [PATCH 230/865] project: upgrade `AvaloniaUI` to `11.2.4` Signed-off-by: leo --- src/SourceGit.csproj | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/SourceGit.csproj b/src/SourceGit.csproj index 624804f1..7cceee7e 100644 --- a/src/SourceGit.csproj +++ b/src/SourceGit.csproj @@ -41,11 +41,11 @@ - - - - - + + + + + From 36178d5ecf00e650a59058d538d9ae2764f9b2d7 Mon Sep 17 00:00:00 2001 From: Chiahong <36815907+ChiahongHong@users.noreply.github.com> Date: Tue, 18 Feb 2025 09:26:44 +0800 Subject: [PATCH 231/865] localization: update zh_TW.axaml (#989) --- src/Resources/Locales/zh_TW.axaml | 38 +++++++++++++++---------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 167565cf..a3fe5c19 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -39,10 +39,10 @@ 警告 套用修補檔,輸出關於空白字元的警告 空白字元處理: - 套用擱置 - 在成功套用后捨棄擱置 - 恢復索引中已暫存的變更 - 已選擇擱置 : + 套用擱置變更 + 套用擱置變更後刪除 + 還原索引中已暫存的變更 (--index) + 已選擇擱置變更: 封存 (archive)... 封存檔案路徑: 選擇封存檔案的儲存路徑 @@ -107,7 +107,7 @@ 本機存放庫名稱: 本機存放庫目錄的名稱,選填。 父級目錄: - 初始化並複製子模組 + 初始化並更新子模組 遠端存放庫: 關閉 提交訊息編輯器 @@ -163,7 +163,7 @@ 選取的分支 選取的提交 存放庫 - 等待自訂操作退出 + 等待自訂動作執行結束 電子郵件 電子郵件地址 Git 設定 @@ -240,7 +240,7 @@ 目標: 所有子節點都會從清單中移除。 刪除群組確認 - 只會從清單中移除,而不會刪除磁碟中的檔案! + 只會從清單中移除,而不會刪除磁碟中的檔案! 刪除存放庫確認 刪除子模組確認 子模組路徑: @@ -265,7 +265,7 @@ 交換比對雙方 語法上色 自動換行 - 啟用基於變更區塊的導航 + 區塊切換上/下一個差異 使用外部合併工具檢視 顯示檔案的全部內容 減少可見的行數 @@ -412,7 +412,7 @@ 合併操作進行中。 正在處理 重定基底 (rebase) 操作進行中。 - 当前停止于 + 目前停止於 復原提交操作進行中。 正在復原提交 互動式重定基底 @@ -425,8 +425,8 @@ 合併分支 目標分支: 合併方式: - 合併目標: - 合併(多目標) + 合併來源: + 合併 (多個來源) 提交變更 合併策略: 目標列表: @@ -580,17 +580,17 @@ 在提交列表中隱藏 以其篩選提交列表 啟用 [--first-parent] 選項 - 佈局方式 + 版面配置 橫向顯示 縱向顯示 提交顯示順序 - 依提交時間排序 + 依時間排序 依拓撲排序 本機分支 回到 HEAD 新增分支 - 清空通知清單 - 提交圖表中僅高亮顯示目前分支 + 清除所有通知 + 在提交路線圖中僅對目前分支上色 在 {0} 中開啟 使用外部工具開啟 重新載入 @@ -616,7 +616,7 @@ 依名稱降序 排序 在終端機中開啟 - 在提交清單中使用相對時間 + 在提交列表中使用相對時間 工作區列表 新增工作區 清理 @@ -656,8 +656,8 @@ SSH 金鑰檔案 開 始 擱置變更 (stash) - 暫存後自動復原工作區 - 工作區檔案保持未修改,但暫存內容已儲存。 + 擱置變更後自動復原工作區 + 工作區檔案保持未修改,但擱置內容已儲存。 包含未追蹤的檔案 保留已暫存的變更 擱置變更訊息: @@ -729,7 +729,7 @@ 提交並推送 歷史輸入/範本 觸發點擊事件 - 提交(修改現有提交) + 提交 (修改原始提交) 自動暫存全部變更並提交 未包含任何檔案變更! 您是否仍要提交 (--allow-empty)? 檢測到衝突 From 7ae5100fcf210649e6a9f19189e88615dea1a4b7 Mon Sep 17 00:00:00 2001 From: Arun Date: Mon, 17 Feb 2025 17:25:51 -0800 Subject: [PATCH 232/865] chore: Convey the usage of monospace font only in text editor (#990) Signed-off-by: Arun (cherry picked from commit 7ec7de7b4a933a599cfffc79382a6edd13582c85) --- 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 f8a06f08..cd266666 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -465,7 +465,7 @@ Default Editor Monospace Font - Only use monospace font in text editor + Use monospace font only in text editor Theme Theme Overrides Use fixed tab width in titlebar From 14f47a9007beab39a02fc10c08eb0736e4bdc116 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 18 Feb 2025 09:50:01 +0800 Subject: [PATCH 233/865] =?UTF-8?q?ux:=20style=20for=20current=20branch=20?= =?UTF-8?q?in=20branch=20tree=20(#991=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: leo --- src/ViewModels/BranchTreeNode.cs | 4 ++-- src/Views/BranchTree.axaml | 16 +++++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/ViewModels/BranchTreeNode.cs b/src/ViewModels/BranchTreeNode.cs index 698dc7ad..5c42f729 100644 --- a/src/ViewModels/BranchTreeNode.cs +++ b/src/ViewModels/BranchTreeNode.cs @@ -40,9 +40,9 @@ namespace SourceGit.ViewModels get => Backend is Models.Branch; } - public FontWeight NameFontWeight + public bool IsCurrent { - get => Backend is Models.Branch { IsCurrent: true } ? FontWeight.Bold : FontWeight.Regular; + get => Backend is Models.Branch { IsCurrent: true }; } public string Tooltip diff --git a/src/Views/BranchTree.axaml b/src/Views/BranchTree.axaml index 0ebcdf20..b7ac725b 100644 --- a/src/Views/BranchTree.axaml +++ b/src/Views/BranchTree.axaml @@ -57,11 +57,17 @@ IsExpanded="{Binding IsExpanded}"/> - + + + + + + + + Date: Tue, 18 Feb 2025 10:04:56 +0800 Subject: [PATCH 234/865] enhance: supports remove single histories filter (#987) Signed-off-by: leo --- src/ViewModels/Repository.cs | 9 +++++++++ src/Views/Repository.axaml | 6 +++++- src/Views/Repository.axaml.cs | 8 ++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 6b96255f..19e48b13 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -826,6 +826,15 @@ namespace SourceGit.ViewModels Task.Run(RefreshCommits); } + public void RemoveHistoriesFilter(Models.Filter filter) + { + if (_settings.HistoriesFilters.Remove(filter)) + { + HistoriesFilterMode = _settings.HistoriesFilters.Count > 0 ? _settings.HistoriesFilters[0].Mode : Models.FilterMode.None; + RefreshHistoriesFilters(true); + } + } + public void UpdateBranchNodeIsExpanded(BranchTreeNode node) { if (_settings == null || !string.IsNullOrWhiteSpace(_filter)) diff --git a/src/Views/Repository.axaml b/src/Views/Repository.axaml index 4d6bc64a..30180f7d 100644 --- a/src/Views/Repository.axaml +++ b/src/Views/Repository.axaml @@ -685,7 +685,11 @@ - + + + diff --git a/src/Views/Repository.axaml.cs b/src/Views/Repository.axaml.cs index bb359040..53bb2d53 100644 --- a/src/Views/Repository.axaml.cs +++ b/src/Views/Repository.axaml.cs @@ -519,5 +519,13 @@ namespace SourceGit.Views e.Handled = true; } + + private void OnRemoveSelectedHistoriesFilter(object sender, RoutedEventArgs e) + { + if (DataContext is ViewModels.Repository repo && sender is Button { DataContext: Models.Filter filter}) + repo.RemoveHistoriesFilter(filter); + + e.Handled = true; + } } } From d401e898a287b26cac19ca907bdc8be4dcfbf250 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 18 Feb 2025 10:58:30 +0800 Subject: [PATCH 235/865] version: Release 2025.05 Signed-off-by: leo --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 4ee298df..15689348 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2025.04 \ No newline at end of file +2025.05 \ No newline at end of file From af4645a4ade086672c43a99f23aa2f2e93223d41 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 18 Feb 2025 16:27:19 +0800 Subject: [PATCH 236/865] project: upgrade `LiveChartsCore.SkiaSharpView.Avalonia` to `2.0.0-rc5.4` Signed-off-by: leo --- src/SourceGit.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SourceGit.csproj b/src/SourceGit.csproj index 7cceee7e..12e914f9 100644 --- a/src/SourceGit.csproj +++ b/src/SourceGit.csproj @@ -50,7 +50,7 @@ - + From 3d4a9b86b46f4ee09a1335532483d958edc5f0db Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 18 Feb 2025 16:54:00 +0800 Subject: [PATCH 237/865] ux: use bold font weight for current branch name (#997) Signed-off-by: leo --- src/Converters/BoolConverters.cs | 4 ++++ src/Views/BranchTree.axaml | 1 + 2 files changed, 5 insertions(+) diff --git a/src/Converters/BoolConverters.cs b/src/Converters/BoolConverters.cs index 2d738700..3563fb37 100644 --- a/src/Converters/BoolConverters.cs +++ b/src/Converters/BoolConverters.cs @@ -1,4 +1,5 @@ using Avalonia.Data.Converters; +using Avalonia.Media; namespace SourceGit.Converters { @@ -6,5 +7,8 @@ namespace SourceGit.Converters { public static readonly FuncValueConverter ToPageTabWidth = new FuncValueConverter(x => x ? 200 : double.NaN); + + public static readonly FuncValueConverter IsBoldToFontWeight = + new FuncValueConverter(x => x ? FontWeight.Bold : FontWeight.Normal); } } diff --git a/src/Views/BranchTree.axaml b/src/Views/BranchTree.axaml index b7ac725b..a01f3502 100644 --- a/src/Views/BranchTree.axaml +++ b/src/Views/BranchTree.axaml @@ -65,6 +65,7 @@ From 5d2cd8b2fa6cf94b972865bd73dae7c2c1eef278 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 18 Feb 2025 18:19:19 +0800 Subject: [PATCH 238/865] ux: new style for current branch (#998) Signed-off-by: leo --- src/Resources/Icons.axaml | 1 + src/Views/BranchTree.axaml | 17 +++++------------ src/Views/BranchTree.axaml.cs | 19 ++++++++++++------- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/Resources/Icons.axaml b/src/Resources/Icons.axaml index 8e865660..b7d9c22e 100644 --- a/src/Resources/Icons.axaml +++ b/src/Resources/Icons.axaml @@ -8,6 +8,7 @@ M757 226a143 143 0 00-55 276 96 96 0 01-88 59h-191a187 187 0 00-96 27V312a143 143 0 10-96 0v399a143 143 0 10103 2 96 96 0 0188-59h191a191 191 0 00187-151 143 143 0 00-43-279zM280 130a48 48 0 110 96 48 48 0 010-96zm0 764a48 48 0 110-96 48 48 0 010 96zM757 417a48 48 0 110-96 48 48 0 010 96z M896 128h-64V64c0-35-29-64-64-64s-64 29-64 64v64h-64c-35 0-64 29-64 64s29 64 64 64h64v64c0 35 29 64 64 64s64-29 64-64V256h64c35 0 64-29 64-64s-29-64-64-64zm-204 307C673 481 628 512 576 512H448c-47 0-90 13-128 35V372C394 346 448 275 448 192c0-106-86-192-192-192S64 86 64 192c0 83 54 154 128 180v280c-74 26-128 97-128 180c0 106 86 192 192 192s192-86 192-192c0-67-34-125-84-159c22-20 52-33 84-33h128c122 0 223-85 249-199c-19 4-37 7-57 7c-26 0-51-5-76-13zM256 128c35 0 64 29 64 64s-29 64-64 64s-64-29-64-64s29-64 64-64zm0 768c-35 0-64-29-64-64s29-64 64-64s64 29 64 64s-29 64-64 64z M512 597m-1 0a1 1 0 103 0a1 1 0 10-3 0ZM810 393 732 315 448 600 293 444 214 522l156 156 78 78 362-362z + M512 32C246 32 32 250 32 512s218 480 480 480 480-218 480-480S774 32 512 32zm269 381L496 698c-26 26-61 26-83 0L243 528c-26-26-26-61 0-83s61-26 83 0l128 128 240-240c26-26 61-26 83 0 26 19 26 54 3 80z M747 467c29 0 56 4 82 12v-363c0-47-38-84-84-84H125c-47 0-84 38-84 84v707c0 47 38 84 84 84h375a287 287 0 01-43-152c0-160 129-289 289-289zm-531-250h438c19 0 34 15 34 34s-15 34-34 34H216c-19 0-34-15-34-34s15-34 34-34zm0 179h263c19 0 34 15 34 34s-15 34-34 34H216c-19 0-34-15-34-34s15-34 34-34zm131 247h-131c-19 0-34-15-34-34s15-34 34-34h131c19 0 34 15 34 34s-15 34-34 34zM747 521c-130 0-236 106-236 236S617 992 747 992s236-106 236-236S877 521 747 521zm11 386v-65h-130c-12 0-22-10-22-22s10-22 22-22h260l-130 108zm108-192H606l130-108v65h130c12 0 22 10 22 22s-10 22-22 22z M529 511c115 0 212 79 239 185h224a62 62 0 017 123l-7 0-224 0a247 247 0 01-479 0H65a62 62 0 01-7-123l7-0h224a247 247 0 01239-185zm0 124a124 124 0 100 247 124 124 0 000-247zm0-618c32 0 58 24 61 55l0 7V206c89 11 165 45 225 103a74 74 0 0122 45l0 9v87a62 62 0 01-123 7l-0-7v-65l-6-4c-43-33-97-51-163-53l-17-0c-74 0-133 18-180 54l-6 4v65a62 62 0 01-55 61l-7 0a62 62 0 01-61-55l-0-7V362c0-20 8-39 23-53 60-58 135-92 224-103V79c0-34 28-62 62-62z M512 926c-229 0-414-186-414-414S283 98 512 98s414 186 414 414-186 414-414 414zm0-73c189 0 341-153 341-341S701 171 512 171 171 323 171 512s153 341 341 341zm-6-192L284 439l52-52 171 171 171-171L728 439l-222 222z diff --git a/src/Views/BranchTree.axaml b/src/Views/BranchTree.axaml index a01f3502..6bff4d39 100644 --- a/src/Views/BranchTree.axaml +++ b/src/Views/BranchTree.axaml @@ -57,18 +57,11 @@ IsExpanded="{Binding IsExpanded}"/> - - - - - - - - + Date: Wed, 19 Feb 2025 10:35:34 +0800 Subject: [PATCH 239/865] enhance: tag push behavior while creating and deleting (#999) - Remember the state of `Push to all remotes after created` checkbox while creating tag - Remember the state of `Delete from remote repositories` checkbox while deleting tag - Change default state of `Delete from remote repositories` to `false` Signed-off-by: leo --- src/Models/RepositorySettings.cs | 12 ++++++++++++ src/ViewModels/CreateTag.cs | 13 +++++++------ src/ViewModels/DeleteTag.cs | 9 ++++----- src/Views/CreateTag.axaml | 2 +- src/Views/DeleteTag.axaml | 2 +- 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/Models/RepositorySettings.cs b/src/Models/RepositorySettings.cs index 556c99ea..44742fb8 100644 --- a/src/Models/RepositorySettings.cs +++ b/src/Models/RepositorySettings.cs @@ -104,6 +104,18 @@ namespace SourceGit.Models set; } = false; + public bool PushToRemoteWhenCreateTag + { + get; + set; + } = true; + + public bool PushToRemoteWhenDeleteTag + { + get; + set; + } = false; + public DealWithLocalChanges DealWithLocalChangesOnCreateBranch { get; diff --git a/src/ViewModels/CreateTag.cs b/src/ViewModels/CreateTag.cs index af9dcf99..a6d7255b 100644 --- a/src/ViewModels/CreateTag.cs +++ b/src/ViewModels/CreateTag.cs @@ -39,11 +39,11 @@ namespace SourceGit.ViewModels set; } = false; - public bool PushToAllRemotes + public bool PushToRemotes { - get; - set; - } = true; + get => _repo.Settings.PushToRemoteWhenCreateTag; + set => _repo.Settings.PushToRemoteWhenCreateTag = value; + } public CreateTag(Repository repo, Models.Branch branch) { @@ -82,6 +82,7 @@ namespace SourceGit.ViewModels _repo.SetWatcherEnabled(false); ProgressDescription = "Create tag..."; + var remotes = PushToRemotes ? _repo.Remotes : null; return Task.Run(() => { bool succ; @@ -90,9 +91,9 @@ namespace SourceGit.ViewModels else succ = Commands.Tag.Add(_repo.FullPath, _tagName, _basedOn); - if (succ && PushToAllRemotes) + if (succ && remotes != null) { - foreach (var remote in _repo.Remotes) + foreach (var remote in remotes) { SetProgressDescription($"Pushing tag to remote {remote.Name} ..."); new Commands.Push(_repo.FullPath, remote.Name, _tagName, false).Exec(); diff --git a/src/ViewModels/DeleteTag.cs b/src/ViewModels/DeleteTag.cs index 7b53e798..341eb4a2 100644 --- a/src/ViewModels/DeleteTag.cs +++ b/src/ViewModels/DeleteTag.cs @@ -10,17 +10,16 @@ namespace SourceGit.ViewModels private set; } - public bool ShouldPushToRemote + public bool PushToRemotes { - get; - set; + get => _repo.Settings.PushToRemoteWhenDeleteTag; + set => _repo.Settings.PushToRemoteWhenDeleteTag = value; } public DeleteTag(Repository repo, Models.Tag tag) { _repo = repo; Target = tag; - ShouldPushToRemote = true; View = new Views.DeleteTag() { DataContext = this }; } @@ -29,9 +28,9 @@ namespace SourceGit.ViewModels _repo.SetWatcherEnabled(false); ProgressDescription = $"Deleting tag '{Target.Name}' ..."; + var remotes = PushToRemotes ? _repo.Remotes : null; return Task.Run(() => { - var remotes = ShouldPushToRemote ? _repo.Remotes : null; var succ = Commands.Tag.Delete(_repo.FullPath, Target.Name, remotes); CallUIThread(() => { diff --git a/src/Views/CreateTag.axaml b/src/Views/CreateTag.axaml index 20b6798a..55b6052f 100644 --- a/src/Views/CreateTag.axaml +++ b/src/Views/CreateTag.axaml @@ -84,7 +84,7 @@ + IsChecked="{Binding PushToRemotes, Mode=TwoWay}"/> diff --git a/src/Views/DeleteTag.axaml b/src/Views/DeleteTag.axaml index 702a7f2a..23c19d35 100644 --- a/src/Views/DeleteTag.axaml +++ b/src/Views/DeleteTag.axaml @@ -23,7 +23,7 @@ + IsChecked="{Binding PushToRemotes, Mode=TwoWay}"/> From 69d107430a2473de5a2f4fb92b2c106929882f8f Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 19 Feb 2025 10:44:51 +0800 Subject: [PATCH 240/865] project: upgrade `OpenAI` and `Azure.AI.OpenAI` to `2.2.0-beta.2` Signed-off-by: leo --- src/SourceGit.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SourceGit.csproj b/src/SourceGit.csproj index 12e914f9..4183511e 100644 --- a/src/SourceGit.csproj +++ b/src/SourceGit.csproj @@ -48,10 +48,10 @@ - + - + From c3eca0d7fdea2c28084db3732875becac6874c28 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 19 Feb 2025 18:01:16 +0800 Subject: [PATCH 241/865] refactor: OpenAI integration (#996) - Add `OpenAIResponse` to trim the `...` block - Add an `Enable Streaming` option to fix the issue that some services do not support streaming output Signed-off-by: leo --- src/Commands/GenerateCommitMessage.cs | 81 +++------------ src/Models/OpenAI.cs | 136 +++++++++++++++++++++++--- src/Resources/Locales/en_US.axaml | 1 + src/Resources/Locales/zh_CN.axaml | 1 + src/Resources/Locales/zh_TW.axaml | 7 +- src/Views/Preferences.axaml | 4 + 6 files changed, 145 insertions(+), 85 deletions(-) diff --git a/src/Commands/GenerateCommitMessage.cs b/src/Commands/GenerateCommitMessage.cs index 4b18a561..df61fdd2 100644 --- a/src/Commands/GenerateCommitMessage.cs +++ b/src/Commands/GenerateCommitMessage.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Text; -using System.Text.RegularExpressions; using System.Threading; using Avalonia.Threading; @@ -36,6 +35,8 @@ namespace SourceGit.Commands { try { + _onResponse?.Invoke("Waiting for pre-file analyzing to completed...\n\n"); + var responseBuilder = new StringBuilder(); var summaryBuilder = new StringBuilder(); foreach (var change in _changes) @@ -49,18 +50,17 @@ namespace SourceGit.Commands var rs = new GetDiffContent(_repo, new Models.DiffOption(change, false)).ReadToEnd(); if (rs.IsSuccess) { - var hasFirstValidChar = false; - var thinkingBuffer = new StringBuilder(); _service.Chat( _service.AnalyzeDiffPrompt, $"Here is the `git diff` output: {rs.StdOut}", _cancelToken, update => - ProcessChatResponse(update, ref hasFirstValidChar, thinkingBuffer, - (responseBuilder, text => - _onResponse?.Invoke( - $"Waiting for pre-file analyzing to completed...\n\n{text}")), - (summaryBuilder, null))); + { + responseBuilder.Append(update); + summaryBuilder.Append(update); + + _onResponse?.Invoke($"Waiting for pre-file analyzing to completed...\n\n{responseBuilder}"); + }); } responseBuilder.Append("\n"); @@ -74,15 +74,15 @@ namespace SourceGit.Commands var responseBody = responseBuilder.ToString(); var subjectBuilder = new StringBuilder(); - var hasSubjectFirstValidChar = false; - var subjectThinkingBuffer = new StringBuilder(); _service.Chat( _service.GenerateSubjectPrompt, $"Here are the summaries changes:\n{summaryBuilder}", _cancelToken, update => - ProcessChatResponse(update, ref hasSubjectFirstValidChar, subjectThinkingBuffer, - (subjectBuilder, text => _onResponse?.Invoke($"{text}\n\n{responseBody}")))); + { + subjectBuilder.Append(update); + _onResponse?.Invoke($"{subjectBuilder}\n\n{responseBody}"); + }); } catch (Exception e) { @@ -90,67 +90,10 @@ namespace SourceGit.Commands } } - private void ProcessChatResponse( - string update, - ref bool hasFirstValidChar, - StringBuilder thinkingBuffer, - params (StringBuilder builder, Action callback)[] outputs) - { - if (!hasFirstValidChar) - { - update = update.TrimStart(); - if (string.IsNullOrEmpty(update)) - return; - if (update.StartsWith("<", StringComparison.Ordinal)) - thinkingBuffer.Append(update); - hasFirstValidChar = true; - } - - if (thinkingBuffer.Length > 0) - thinkingBuffer.Append(update); - - if (thinkingBuffer.Length > 15) - { - var match = REG_COT.Match(thinkingBuffer.ToString()); - if (match.Success) - { - update = REG_COT.Replace(thinkingBuffer.ToString(), "").TrimStart(); - if (update.Length > 0) - { - foreach (var output in outputs) - output.builder.Append(update); - thinkingBuffer.Clear(); - } - return; - } - - match = REG_THINK_START.Match(thinkingBuffer.ToString()); - if (!match.Success) - { - foreach (var output in outputs) - output.builder.Append(thinkingBuffer); - thinkingBuffer.Clear(); - return; - } - } - - if (thinkingBuffer.Length == 0) - { - foreach (var output in outputs) - { - output.builder.Append(update); - output.callback?.Invoke(output.builder.ToString()); - } - } - } - private Models.OpenAIService _service; private string _repo; private List _changes; private CancellationToken _cancelToken; private Action _onResponse; - - private static readonly Regex REG_COT = new(@"^<(think|thought|thinking|thought_chain)>(.*?)", RegexOptions.Singleline); - private static readonly Regex REG_THINK_START = new(@"^<(think|thought|thinking|thought_chain)>", RegexOptions.Singleline); } } diff --git a/src/Models/OpenAI.cs b/src/Models/OpenAI.cs index a6648c11..264230c6 100644 --- a/src/Models/OpenAI.cs +++ b/src/Models/OpenAI.cs @@ -1,5 +1,8 @@ using System; using System.ClientModel; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; using System.Threading; using Azure.AI.OpenAI; using CommunityToolkit.Mvvm.ComponentModel; @@ -8,6 +11,91 @@ using OpenAI.Chat; namespace SourceGit.Models { + public partial class OpenAIResponse + { + public OpenAIResponse(Action onUpdate) + { + _onUpdate = onUpdate; + } + + public void Append(string text) + { + var buffer = text; + + if (_thinkTail.Length > 0) + { + _thinkTail.Append(buffer); + buffer = _thinkTail.ToString(); + _thinkTail.Clear(); + } + + buffer = REG_COT().Replace(buffer, ""); + + var startIdx = buffer.IndexOf('<', StringComparison.Ordinal); + if (startIdx >= 0) + { + if (startIdx > 0) + OnReceive(buffer.Substring(0, startIdx)); + + var endIdx = buffer.IndexOf(">", startIdx + 1, StringComparison.Ordinal); + if (endIdx <= startIdx) + { + if (buffer.Length - startIdx <= 15) + _thinkTail.Append(buffer.Substring(startIdx)); + else + OnReceive(buffer.Substring(startIdx)); + } + else if (endIdx < startIdx + 15) + { + var tag = buffer.Substring(startIdx + 1, endIdx - startIdx - 1); + if (_thinkTags.Contains(tag)) + _thinkTail.Append(buffer.Substring(startIdx)); + else + OnReceive(buffer.Substring(startIdx)); + } + else + { + OnReceive(buffer.Substring(startIdx)); + } + } + else + { + OnReceive(buffer); + } + } + + public void End() + { + if (_thinkTail.Length > 0) + { + OnReceive(_thinkTail.ToString()); + _thinkTail.Clear(); + } + } + + private void OnReceive(string text) + { + if (!_hasTrimmedStart) + { + text = text.TrimStart(); + if (string.IsNullOrEmpty(text)) + return; + + _hasTrimmedStart = true; + } + + _onUpdate.Invoke(text); + } + + [GeneratedRegex(@"<(think|thought|thinking|thought_chain)>.*?", RegexOptions.Singleline)] + private static partial Regex REG_COT(); + + private Action _onUpdate = null; + private StringBuilder _thinkTail = new StringBuilder(); + private HashSet _thinkTags = ["think", "thought", "thinking", "thought_chain"]; + private bool _hasTrimmedStart = false; + } + public class OpenAIService : ObservableObject { public string Name @@ -42,6 +130,12 @@ namespace SourceGit.Models set => SetProperty(ref _model, value); } + public bool Streaming + { + get => _streaming; + set => SetProperty(ref _streaming, value); + } + public string AnalyzeDiffPrompt { get => _analyzeDiffPrompt; @@ -89,32 +183,47 @@ namespace SourceGit.Models public void Chat(string prompt, string question, CancellationToken cancellation, Action onUpdate) { - Uri server = new(Server); - ApiKeyCredential key = new(ApiKey); - ChatClient client = null; - if (Server.Contains("openai.azure.com/", StringComparison.Ordinal)) + var server = new Uri(_server); + var key = new ApiKeyCredential(_apiKey); + var client = null as ChatClient; + if (_server.Contains("openai.azure.com/", StringComparison.Ordinal)) { var azure = new AzureOpenAIClient(server, key); - client = azure.GetChatClient(Model); + client = azure.GetChatClient(_model); } else { var openai = new OpenAIClient(key, new() { Endpoint = server }); - client = openai.GetChatClient(Model); + client = openai.GetChatClient(_model); } + var messages = new List(); + messages.Add(_model.Equals("o1-mini", StringComparison.Ordinal) ? new UserChatMessage(prompt) : new SystemChatMessage(prompt)); + messages.Add(new UserChatMessage(question)); + try { - var updates = client.CompleteChatStreaming([ - _model.Equals("o1-mini", StringComparison.Ordinal) ? new UserChatMessage(prompt) : new SystemChatMessage(prompt), - new UserChatMessage(question), - ], null, cancellation); + var rsp = new OpenAIResponse(onUpdate); - foreach (var update in updates) + if (_streaming) { - if (update.ContentUpdate.Count > 0) - onUpdate.Invoke(update.ContentUpdate[0].Text); + var updates = client.CompleteChatStreaming(messages, null, cancellation); + + foreach (var update in updates) + { + if (update.ContentUpdate.Count > 0) + rsp.Append(update.ContentUpdate[0].Text); + } } + else + { + var completion = client.CompleteChat(messages, null, cancellation); + + if (completion.Value.Content.Count > 0) + rsp.Append(completion.Value.Content[0].Text); + } + + rsp.End(); } catch { @@ -127,6 +236,7 @@ namespace SourceGit.Models private string _server; private string _apiKey; private string _model; + private bool _streaming = true; private string _analyzeDiffPrompt; private string _generateSubjectPrompt; } diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index cd266666..0da8b5ed 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -459,6 +459,7 @@ Model Name Server + Enable Streaming APPEARANCE Default Font Font Size diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 4db909c9..983775e7 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -462,6 +462,7 @@ 模型 配置名称 服务地址 + 启用流式输出 外观配置 缺省字体 字体大小 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index a3fe5c19..2a5ced45 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -456,12 +456,13 @@ {0} 年前 偏好設定 AI - 伺服器 + 分析變更差異提示詞 API 金鑰 + 產生提交訊息提示詞 模型 名稱 - 分析變更差異提示詞 - 產生提交訊息提示詞 + 伺服器 + 啟用串流輸出 外觀設定 預設字型 字型大小 diff --git a/src/Views/Preferences.axaml b/src/Views/Preferences.axaml index 1d282ad9..3bdd150a 100644 --- a/src/Views/Preferences.axaml +++ b/src/Views/Preferences.axaml @@ -616,6 +616,10 @@ Text="{Binding GenerateSubjectPrompt, Mode=TwoWay}" AcceptsReturn="true" TextWrapping="Wrap"/> + + From 68946d21400575332c784d8820ae247063865b1b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 19 Feb 2025 10:01:37 +0000 Subject: [PATCH 242/865] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 3829cf54..aca5a594 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-99.47%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.61%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-92.42%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-97.87%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.15%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.73%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) +[![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.34%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.48%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-92.30%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-97.74%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.03%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.60%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 84411404..08b7c462 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -1,4 +1,4 @@ -### de_DE.axaml: 99.47% +### de_DE.axaml: 99.34%
@@ -7,11 +7,12 @@ - Text.BranchCM.CustomAction - Text.Configure.CustomAction.Scope.Branch - Text.Configure.CustomAction.WaitForExit +- Text.Preferences.AI.Streaming - Text.Repository.Notifications.Clear
-### es_ES.axaml: 97.61% +### es_ES.axaml: 97.48%
@@ -31,6 +32,7 @@ - Text.DeleteRepositoryNode.Path - Text.DeleteRepositoryNode.TipForGroup - Text.DeleteRepositoryNode.TipForRepository +- Text.Preferences.AI.Streaming - Text.Repository.Notifications.Clear - Text.Stash.AutoRestore - Text.Stash.AutoRestore.Tip @@ -38,7 +40,7 @@
-### fr_FR.axaml: 92.42% +### fr_FR.axaml: 92.30%
@@ -67,6 +69,7 @@ - Text.MergeMultiple.CommitChanges - Text.MergeMultiple.Strategy - Text.MergeMultiple.Targets +- Text.Preferences.AI.Streaming - Text.Preferences.Appearance.FontSize - Text.Preferences.Appearance.FontSize.Default - Text.Preferences.Appearance.FontSize.Editor @@ -104,7 +107,7 @@
-### it_IT.axaml: 97.87% +### it_IT.axaml: 97.74%
@@ -123,13 +126,14 @@ - Text.DeleteRepositoryNode.Path - Text.DeleteRepositoryNode.TipForGroup - Text.DeleteRepositoryNode.TipForRepository +- Text.Preferences.AI.Streaming - Text.Repository.Notifications.Clear - Text.Stash.AutoRestore - Text.Stash.AutoRestore.Tip
-### pt_BR.axaml: 92.15% +### pt_BR.axaml: 92.03%
@@ -169,6 +173,7 @@ - Text.MergeMultiple.CommitChanges - Text.MergeMultiple.Strategy - Text.MergeMultiple.Targets +- Text.Preferences.AI.Streaming - Text.Preferences.General.DateFormat - Text.Preferences.General.ShowChildren - Text.Preferences.Git.SSLVerify @@ -197,7 +202,7 @@
-### ru_RU.axaml: 99.73% +### ru_RU.axaml: 99.60%
@@ -205,6 +210,7 @@ - Text.BranchCM.CustomAction - Text.Configure.CustomAction.Scope.Branch +- Text.Preferences.AI.Streaming
From ce16ac63eb9ef3308209f42ee94ee974a2b42957 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 19 Feb 2025 19:22:21 +0800 Subject: [PATCH 243/865] enhance: submodule bookmark inherts from parent repo (#1001) Signed-off-by: leo --- src/ViewModels/Repository.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 19e48b13..6e8a5290 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -1161,6 +1161,10 @@ namespace SourceGit.ViewModels public void OpenSubmodule(string submodule) { + var selfPage = GetOwnerPage(); + if (selfPage == null) + return; + var root = Path.GetFullPath(Path.Combine(_fullpath, submodule)); var normalizedPath = root.Replace("\\", "/"); @@ -1171,12 +1175,12 @@ namespace SourceGit.ViewModels { Id = normalizedPath, Name = Path.GetFileName(normalizedPath), - Bookmark = 0, + Bookmark = selfPage.Node.Bookmark, IsRepository = true, }; } - App.GetLauncer()?.OpenRepositoryInTab(node, null); + App.GetLauncer().OpenRepositoryInTab(node, null); } public void AddWorktree() From cbc2e46beb75edf05fb05935d87d8dfce36a539d Mon Sep 17 00:00:00 2001 From: Oleg Kosmakov <1533952+kosmakoff@users.noreply.github.com> Date: Thu, 20 Feb 2025 02:31:07 +0100 Subject: [PATCH 244/865] fix: Update unstaged filed counter when unstaged files change (#1007) * Add missing OnPropertyChanged in Cleanup * Force unstaged count to refresh --- src/ViewModels/WorkingCopy.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 7ac13dc2..60fa93c3 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -214,9 +214,11 @@ namespace SourceGit.ViewModels OnPropertyChanged(nameof(SelectedStaged)); _visibleUnstaged.Clear(); - _unstaged.Clear(); OnPropertyChanged(nameof(VisibleUnstaged)); + _unstaged.Clear(); + OnPropertyChanged(nameof(Unstaged)); + _staged.Clear(); OnPropertyChanged(nameof(Staged)); @@ -305,6 +307,7 @@ namespace SourceGit.ViewModels _isLoadingData = true; HasUnsolvedConflicts = hasConflict; VisibleUnstaged = visibleUnstaged; + OnPropertyChanged(nameof(Unstaged)); Staged = staged; SelectedUnstaged = selectedUnstaged; SelectedStaged = selectedStaged; From 0e1dfba7ef9c94e43f0cf9a9dc8bfad33d3f8df7 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 20 Feb 2025 09:34:03 +0800 Subject: [PATCH 245/865] code_review: PR #1007 Signed-off-by: leo --- src/ViewModels/WorkingCopy.cs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 60fa93c3..d87c54ec 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -109,7 +109,7 @@ namespace SourceGit.ViewModels if (_isLoadingData) return; - VisibleUnstaged = GetVisibleUnstagedChanges(); + VisibleUnstaged = GetVisibleUnstagedChanges(_unstaged); SelectedUnstaged = []; } } @@ -284,9 +284,7 @@ namespace SourceGit.ViewModels } } - _unstaged = unstaged; - - var visibleUnstaged = GetVisibleUnstagedChanges(); + var visibleUnstaged = GetVisibleUnstagedChanges(unstaged); var selectedUnstaged = new List(); foreach (var c in visibleUnstaged) { @@ -307,7 +305,7 @@ namespace SourceGit.ViewModels _isLoadingData = true; HasUnsolvedConflicts = hasConflict; VisibleUnstaged = visibleUnstaged; - OnPropertyChanged(nameof(Unstaged)); + Unstaged = unstaged; Staged = staged; SelectedUnstaged = selectedUnstaged; SelectedStaged = selectedStaged; @@ -1459,14 +1457,14 @@ namespace SourceGit.ViewModels } } - private List GetVisibleUnstagedChanges() + private List GetVisibleUnstagedChanges(List unstaged) { if (string.IsNullOrEmpty(_unstagedFilter)) - return _unstaged; + return unstaged; var visible = new List(); - foreach (var c in _unstaged) + foreach (var c in unstaged) { if (c.Path.Contains(_unstagedFilter, StringComparison.OrdinalIgnoreCase)) visible.Add(c); From 53f591bdad68afeb49a4c6d0b0ea8fc42b7a7323 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 20 Feb 2025 10:12:12 +0800 Subject: [PATCH 246/865] ux: add a warning icon when the tracking upstream of a local branch is gone (#1006) Co-authored-by: Davide Tentori --- src/Commands/QueryBranches.cs | 12 ++++++++++++ src/Models/Branch.cs | 1 + src/Resources/Locales/en_US.axaml | 1 + src/Resources/Locales/zh_CN.axaml | 1 + src/Resources/Locales/zh_TW.axaml | 1 + src/ViewModels/BranchTreeNode.cs | 8 +++++--- src/Views/BranchTree.axaml | 12 +++++++++++- 7 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/Commands/QueryBranches.cs b/src/Commands/QueryBranches.cs index 95f97214..44438cef 100644 --- a/src/Commands/QueryBranches.cs +++ b/src/Commands/QueryBranches.cs @@ -25,11 +25,22 @@ namespace SourceGit.Commands return branches; var lines = rs.StdOut.Split('\n', StringSplitOptions.RemoveEmptyEntries); + var remoteBranches = new HashSet(); foreach (var line in lines) { var b = ParseLine(line); if (b != null) + { branches.Add(b); + if (!b.IsLocal) + remoteBranches.Add(b.FullName); + } + } + + foreach (var b in branches) + { + if (b.IsLocal && !string.IsNullOrEmpty(b.Upstream)) + b.IsUpsteamGone = !remoteBranches.Contains(b.Upstream); } return branches; @@ -75,6 +86,7 @@ namespace SourceGit.Commands branch.Head = parts[1]; branch.IsCurrent = parts[2] == "*"; branch.Upstream = parts[3]; + branch.IsUpsteamGone = false; if (branch.IsLocal && !string.IsNullOrEmpty(parts[4]) && !parts[4].Equals("=", StringComparison.Ordinal)) branch.TrackStatus = new QueryTrackStatus(WorkingDirectory, branch.Name, branch.Upstream).Result(); diff --git a/src/Models/Branch.cs b/src/Models/Branch.cs index 0ba320c1..2d0ae5b2 100644 --- a/src/Models/Branch.cs +++ b/src/Models/Branch.cs @@ -34,6 +34,7 @@ namespace SourceGit.Models public string Upstream { get; set; } public BranchTrackStatus TrackStatus { get; set; } public string Remote { get; set; } + public bool IsUpsteamGone { get; set; } public string FriendlyName => IsLocal ? Name : $"{Remote}/{Name}"; } diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 0da8b5ed..dfc17dee 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -72,6 +72,7 @@ Rename ${0}$... Set Tracking Branch... Branch Compare + Invalid upstream! Bytes CANCEL Reset to This Revision diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 983775e7..115f917e 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -75,6 +75,7 @@ 重命名 ${0}$... 切换上游分支 ... 分支比较 + 跟踪的上游分支不存在或已删除! 字节 取 消 重置文件到该版本 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 2a5ced45..00933783 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -75,6 +75,7 @@ 重新命名 ${0}$... 切換上游分支... 分支比較 + 追蹤上游分支不存在或已刪除! 位元組 取 消 重設檔案為此版本 diff --git a/src/ViewModels/BranchTreeNode.cs b/src/ViewModels/BranchTreeNode.cs index 5c42f729..6c1d2e04 100644 --- a/src/ViewModels/BranchTreeNode.cs +++ b/src/ViewModels/BranchTreeNode.cs @@ -1,9 +1,6 @@ using System; using System.Collections.Generic; - using Avalonia; -using Avalonia.Media; - using CommunityToolkit.Mvvm.ComponentModel; namespace SourceGit.ViewModels @@ -45,6 +42,11 @@ namespace SourceGit.ViewModels get => Backend is Models.Branch { IsCurrent: true }; } + public bool ShowUpstreamGoneTip + { + get => Backend is Models.Branch { IsUpsteamGone: true }; + } + public string Tooltip { get => Backend is Models.Branch b ? b.FriendlyName : null; diff --git a/src/Views/BranchTree.axaml b/src/Views/BranchTree.axaml index 6bff4d39..0ac09e6c 100644 --- a/src/Views/BranchTree.axaml +++ b/src/Views/BranchTree.axaml @@ -61,7 +61,17 @@ Classes="primary" Text="{Binding Name}" FontWeight="{Binding IsCurrent, Converter={x:Static c:BoolConverters.IsBoldToFontWeight}}" - TextTrimming="CharacterEllipsis"/> + TextTrimming="CharacterEllipsis"/> + + + + + Date: Thu, 20 Feb 2025 02:14:51 +0000 Subject: [PATCH 247/865] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index aca5a594..784d0672 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-99.34%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.48%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-92.30%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-97.74%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.03%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.60%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) +[![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.20%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.35%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-92.18%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-97.61%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.91%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.47%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 08b7c462..53631bc1 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -1,10 +1,11 @@ -### de_DE.axaml: 99.34% +### de_DE.axaml: 99.20%
Missing Keys - Text.BranchCM.CustomAction +- Text.BranchUpstreamInvalid - Text.Configure.CustomAction.Scope.Branch - Text.Configure.CustomAction.WaitForExit - Text.Preferences.AI.Streaming @@ -12,7 +13,7 @@
-### es_ES.axaml: 97.48% +### es_ES.axaml: 97.35%
@@ -25,6 +26,7 @@ - Text.ApplyStash.RestoreIndex - Text.ApplyStash.Stash - Text.BranchCM.CustomAction +- Text.BranchUpstreamInvalid - Text.Clone.RecurseSubmodules - Text.Configure.CustomAction.Scope.Branch - Text.Configure.CustomAction.WaitForExit @@ -40,7 +42,7 @@
-### fr_FR.axaml: 92.30% +### fr_FR.axaml: 92.18%
@@ -53,6 +55,7 @@ - Text.ApplyStash.RestoreIndex - Text.ApplyStash.Stash - Text.BranchCM.CustomAction +- Text.BranchUpstreamInvalid - Text.Clone.RecurseSubmodules - Text.Configure.CustomAction.Scope.Branch - Text.Configure.CustomAction.WaitForExit @@ -107,7 +110,7 @@
-### it_IT.axaml: 97.74% +### it_IT.axaml: 97.61%
@@ -120,6 +123,7 @@ - Text.ApplyStash.RestoreIndex - Text.ApplyStash.Stash - Text.BranchCM.CustomAction +- Text.BranchUpstreamInvalid - Text.Clone.RecurseSubmodules - Text.Configure.CustomAction.Scope.Branch - Text.Configure.CustomAction.WaitForExit @@ -133,7 +137,7 @@
-### pt_BR.axaml: 92.03% +### pt_BR.axaml: 91.91%
@@ -147,6 +151,7 @@ - Text.ApplyStash.Stash - Text.BranchCM.CustomAction - Text.BranchCM.MergeMultiBranches +- Text.BranchUpstreamInvalid - Text.Clone.RecurseSubmodules - Text.CommitCM.Merge - Text.CommitCM.MergeMultiple @@ -202,13 +207,14 @@
-### ru_RU.axaml: 99.60% +### ru_RU.axaml: 99.47%
Missing Keys - Text.BranchCM.CustomAction +- Text.BranchUpstreamInvalid - Text.Configure.CustomAction.Scope.Branch - Text.Preferences.AI.Streaming From 507e502874a6dc6e3d4aa090519fc8a48e6c3e83 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 20 Feb 2025 10:18:46 +0800 Subject: [PATCH 248/865] fix: `Custom Action` height is not large enough to display all contents (#1004) Signed-off-by: leo --- src/Views/RepositoryConfigure.axaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Views/RepositoryConfigure.axaml b/src/Views/RepositoryConfigure.axaml index 6b7cdc12..61bc14e0 100644 --- a/src/Views/RepositoryConfigure.axaml +++ b/src/Views/RepositoryConfigure.axaml @@ -340,7 +340,7 @@ - + From 731f1055bcdc10da906eccd4345a43ba595896a3 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 20 Feb 2025 11:04:57 +0800 Subject: [PATCH 249/865] feat!: add `ptyxis` support (#1005) BREAKING CHANGE: Index of `Custom` shell/terminal Signed-off-by: leo --- src/Models/ShellOrTerminal.cs | 1 + src/Resources/Images/ShellIcons/ptyxis.png | Bin 0 -> 6930 bytes 2 files changed, 1 insertion(+) create mode 100644 src/Resources/Images/ShellIcons/ptyxis.png diff --git a/src/Models/ShellOrTerminal.cs b/src/Models/ShellOrTerminal.cs index 4f0222e8..3ada2cf9 100644 --- a/src/Models/ShellOrTerminal.cs +++ b/src/Models/ShellOrTerminal.cs @@ -57,6 +57,7 @@ namespace SourceGit.Models new ShellOrTerminal("mate-terminal", "MATE Terminal", "mate-terminal"), new ShellOrTerminal("foot", "Foot", "foot"), new ShellOrTerminal("wezterm", "WezTerm", "wezterm"), + new ShellOrTerminal("ptyxis", "Ptyxis", "ptyxis"), new ShellOrTerminal("custom", "Custom", ""), }; } diff --git a/src/Resources/Images/ShellIcons/ptyxis.png b/src/Resources/Images/ShellIcons/ptyxis.png new file mode 100644 index 0000000000000000000000000000000000000000..9202f6e115724d234fd1bf015abd705a475405a0 GIT binary patch literal 6930 zcmV+t8|~zYP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D8mCD_K~#8N?VEeB zWmjG2Kfkrsex28S-+rV!>7>&H0)zxm0-_0^j0ouHj9Q2yGm4B;fDTilC>YccsbWyE z#2OU~kP&Opp^8F59>q%_1c8u*q?0sB`jPIwkG}Vw*WPEp)>`w&KHceb-`h^61gRRn zw^r?Q);@dh_51F%zU#Mszjfg|_zoTue(=L@k1nkHwuMJ7thx~D!ir1brcd2sHm{(Ve}CGA=l`|v{;$73 zJpcQ3AN{ZGYIFSes$ag~{QB+imt${^Ua3;%`wm-1aL^ zzu_yt@yZ*&{KmID{|mRwpFMZ=hhH7t_~qaD_3!(~*Z;tyuX=1ay;y(pk2e4Md(VFN z!|Ye=R{8j9GoO3(FE7R=$H?3J?>^{V^p?Pz=Q~ty7+F4e?_nmDLy2ZN4EUh~*I-;T z*t~#M4&@ZC_S|*sA?_KRW@13cAxk>s*^hfXvo>H@RDArQuQPHb-+RR&u5K^kr3Uff z1z!mdoIb_+IHfXR;*eGpan1Z9kumsb8$}6&e27;$00%6pxO~p zJ0=|rklGUj=3IM~S6q8wAHBIQ;w<+ZInMEWPNUGwE<`;4=BKY|CGT3)t*7d-`|7K% z{Fz@n&s_BRUjRP#jt{Or>*v1zrDdXDII7E*iUZ|mY&L5v@+PNz#~}a@B&T* zr#yH?c4mUjEQm)$A)+YyBZ5u>0!3bt_j7Oxo7b3jj8lRWL3zdGOh%bIL>Ul8pbTk$ zgmO(!a3c6=vEo5#bQChI3w)p%Z1pjr=HL^rM8&49ML#9LJ>z4J$Y@6V?l^&GY%fcrmu`)cc^gKtW9&5&8kuqa7w z30iQIihO;5t7~jlAmY)XKG!hqgnTf@RTb7+ysv4^bs^D+ct9bdu|+{NlhEBe4`{q? znkJ%%IuVYVS{y1dBy(Lilo!RYmZeBBq6S_kk?eB z90Y<+j2OX*o9de&-hj2JL}OYp`N|NRRiHq3Lc(4|m_&>>MhLnQMjT!|;vYS6IdKRI zDn~vTfimtp%a4(72#YPGZ$k6k5Zm%_UvZ&+!BJJN(;(CNj-98D+6q9DF+2^ zBKXo_Gs~F=R!~+z+_cxqMaDA~LGd6)(VCy3J=-DQ9I|%LQI37}J~lVU=uYdx%g*8A zJ5Et61zLz_dWZ_hH^#Wqp-o8GX(K@hUU1TQoJNO~S%t41;uTID;8^Uox%s*$^W6sz zVbcudJ;j*}m)4Y{3AU*4IO@8g|D5AmU>)LXEpVxMpYF-+c2t2vbrL5 zHAh#@OeI$!(n!bPl$$nIH4~aNW8Py?I24V8^;jSmD7#mezQ?u%08n}A&G93RunwIl zddpqPY>f9MaVH??2I!WdOml2nQlu$fX(|P2HKC+t^~@G$h6CJrkK4IZervHK0Y)3L ztue(QM|qD@g13SW4Xv3L@k|>RD(boiQ z`w{F&07{6G7TNlU!O;z>eo4KV(Lb?*_X1wwYezLKuz5*)zKiM@y8C7kEmRvBD|a7d zUKw6|^Rv*tzQn`+^{```WU8ET(xyGzqZnsQh8c0vIyWrpeu*E|l!F457}`r+u03#o zmI;WGn5R7T2^@OdLDF=Lb#^*qOczbl&v=D6^~mvCj7vPRkrD@FqcKUhLm0)>nZu?Y zabSlv<;YTwN|Xbw;qqO}T)lTUGxHq?6lp!-fm5q^3C=k(=L?k=hgS}(n&Y<`I}%_O z2!d*yJSH1`+@ylclAal3i<;Wj)J091mk=r9cFa~aChA6%;z)~vjd8}&wRN1PS^5fS z8t=`EphJyGLZT$xxiQ~FZ2QccZ~e_*DrXHO8XF1{7_g3foMMXtv7Wl9X)h!wU(s6X zfCjH&Z8Bo)O49zA_0yZ&bH@?rv`7}aDAjnjWnN&58kC>{jqXNNlS#9(ys$CfWNb^o z=J6FBcN4<77VYH@$x@GKp-0qBaN_W$rfm#2ANnqy`?MSBwpxHNOmnuz6V}#;RHKq? zSP;z35G{1TC~R7jpPEo_)%X%9T;oJ-W|WhPS}DA5^x$8#Tmst@eg*L}{_M4rdRH5~ zqw!A!n-!E>1(DUV&9B z(oSUSr+OsoiE4c_9M!#aoa4(lDxdA##D=W+g# z;?LIm=C|k9ZC7@}js%EQCRqk&RR5y!8;xbC;gP z@7(ksS*{{5c5$nM@d|Kkuf+!N=Rsgm}SxaCY+B(EKl=Ud zf)|DNf-NlL)e#yH*Tlw>ZW|?ncQl@-lO|m5Jvc?WHK86?6q`Awuw1o&4^KLDIoBV$ zf*TGVV7}MGHy7hC;a==WfcI{?u7@Cw2~CVIgz@?a=W5yqmsvF_Kl}DKaM$SvanrtF z&^%+|D&G8@|HK~E!`Mg0V3&kW)@|AL#9%IphTfX zsI#2a!zYO180Q7=1Xp?NsG=U0l!F5A1rbf{z`7=AszvB;t}%abnL>N=y26S_iE!f7 z8lU+5SCAmWA~-j-We4m?fLM<&DzddrieW}I$*Cq2Orp_&!Fiz;=v}o$zg6<{fBZ&1 z_t0H9nkcP7ac%E1-u45p;i_;6ReSRFA^m$-86Vl?%$+CMy!$lmsMUy+1uWRCrXH5K zQHjeYxT1oxCQusVg?wd;(_cGGD+;j|0#Sro;|k9mUpvC*zH}Ev0kvxc)j6myLBNjc z@YMJGqA!eKUD=3}2!SyurKs_ECDS#%Bd9gm@hy@;&D(zd*Ld!s8wjS{dOQzg8~p0W z-ocUVG&SI?MQIHp_~~8FhPUfciOVgnEHQHlL;>D9ln8m65=0?UD+VAPjR=%SX@kvb zq9g`mAP`g>Vv?YVJnMkOsIMj!fA!I4|IY89XXeFuftx;ci&_5FXU+{aMz0eTUV$<2~>3-q_ z2~-nh?nSh^ZHmbRVnck{Je~c!>0P!=y4fe0pQW`tOSsS@T%M(K*)s9m3?___+EbsyB->?Rc6@v+Z;misYcsS7$f=9ved%H69+Ss83H8Rlp)hz6w;KCc*_+#n1i ztnwIRD7MBFXND-zC}Rkc5HmGAUmtPiuA@XoW2+ib3XuS(J)*!UO|>T&y#!!(QP1{#>t z5!cM^$LAGVz?BwqPrf!{baIm*Nl;;cRF=usfGSHdu_5bkQEc`p*ZZW$R$2e*y<`ub zq}@sYsIvl}*SOrG3J>Fo@yQL!G$(02_QZ%QHVU#+eL^qzsY|MYkT_1JuBmH^eRL6P z2`l*V8=udA`{`dIID1DAIga1`z@PJ1pZz<0XmG|utjQ)B-b2`K62 z5Oxwemo1R&n`7bH%SrYvQi;boOI4QCWkp@rSX(2JA)4zVkwJ$6Sn#6pS}>tzw6;Yt znh2KY<6WayJ7GrxocBZ~V%7)Dtmp8JGpyWtAN9CItVdY~&LOVx zx5X)vT=Vkle~4fDo*yUi>fFsozT{W_@~yo8_J1JWGlOXb6j_Ed3XH)8hH!C~nf<%T zhZF2zf+{^Kuc=P;S^eT+R=#)-KC7{{h05V34w=B#ku}P#9EDI@M_qZULB-1L4?yYh zUK&?=2kdy}N$>bMp9hYXcwY2_-%Cc#+92i5yY8bH7U#HYB*Bx^npZya$9VZu{|zw; znZ^@`Hs`hPej6XZ?~BAsJydA00?r7Xy^H8h2(dv028jadwGrcQoWy1om9s=qfJ&k! z4_Q0JmgISfLgSqy?!-t9c{V|Zs_BU$v^s69c)SR$N^!@l-np%2vOipn z%9l?D>5Gd&PCc$zUTAaZ8INZppD-FtICaNSj18up8{%5=%QycdKk?+7Nzh2+)X}dp zUi}xp%jX`vi+JxGVgv#~j0P{HyJ=s! zM6Es6*CaDBCJqoSP+Ri#5#y6*NY4x?Hbzt%L#Qo2&#|s1nvY3l+vMp4sT{f!qB;Sy zyXUY~K`|}}lxZ@_kw&!wf=)zL7x>zO15*oY|M0cnI^Wi_xR{lziFRFo?Nd58UVmFH zo-)k|dI4c4W;{&MPLo72BG7i4H@xr_yy&WD5Kgkoz|0f&(zyqFrqQBfp&n74Z3XzO+f$j2BeO5rMdIJy!&EXw{y?fD&n{Q?a%YPD{de};ivQciO~kHc*k#X@8CFQSC^SXi};Q~83F4_Pxk39 z&ru9B21hpugBa5Z2znu2dD2sTbluDz7==j;yRN|;iO>41- zww^cq@Xzu6SKL74_0)9FgPSY7{EuGGeS_nK3tgP@l#>dng31ryHV&V|fjaa;LFQye!*A8bbCJ0c0A!;Y+c7zH8#%r78>jOx0 zv=fX836qHV{foFuOoJD(^1@HQ;n1+&rQmhwSJU`e@GQfBDa8dqA2* z+2QpQyz)=p#ED`Zvou54i7AQ#tre|(bJ)7V+h$vx3`-_kBZ4r(*Ot7Ppdw8)*Cy%4 zWT!?{L!GNCg1F1^O8tnY+2z;kJKJlTX2@36VYCp!+Ws93F&5v zrinRJS;1(fPnl+fI>6?RDzAuoF*?x@8l+{2dkK?`5kliA#S0y}OEVB^1VviZhA3gRq)3oC0gj>74#oiLpy0=fl8sH0ErbSOPLkO#NlgC zT@`fqFA*(vAW;Ny%;3m6<(Ui}D#C??Xt_l+lQ2BCiG66meXslLZEd}%2b{&Oo3DG5 zGX{wby~P>AaGJaGf-PzW>5$JJ{tCApxr;pXL~|X`8YiCap}i<2WGh>kP_cB)9wy_Q z@#zs-1nt4s4y_I2%@Ni)dV3bh`zczVT|j%3(MS-W;(%zrMYPz#d2ppCTOX018K9gc zYK64g3B%I^bf<-C8+6YgZ9_EICh(fmfAghnd%(6L2;i)v#*ysmLdW0}jf4SSgu1TL z-3Z-_P%|;67dPij6T4F)XzQ4)Y!O5em9z9NTOjJj6vHv;U)nts7G$mH_9=E{E)k_4OkWd1$lM_yU`azE0dIVckDB}q`F%pMVWku~A z`rs_jy6rc9@j@H96ai(Hk<7P==2{RbRIE`ENL}NmQC$@pv@!U=V0xNpCO~U&YbmS$ zbUz`Qbag~EtSHkG(VC>yA_zmuNzsJ50)q-dW|rp&XJTw+q3}pmBfbfA3TGEvV3jAj zyvy?T~lp#u5L_wQKhor~W$yfSBJ|H#`ktnnSwEx3r-S+F(Uufr!Lm+v|Wp7%% z@c;xKJ>8^O^)u4d5n&WJ!A~#EE-@Ufy&ZzYP_C!+kFOF~h4O-}9o1lr@y+hCCI%>I ztsu~dR!AU7s4z*0NetP_CQ%rpLX9?p2@EV~jJ~F6IfW#UJ6)G}> zp(bA$F*>$|7>|h~OrSwEQ>ZO!ihP1X69f@~IlFbf39yRSIH{YcP^hRj#$@-d4ErDa z%FMZkpNAa@c=8|o%qO$9evXPliql)9-&iAkXbs~95ka(I1yCL*o?TD5g0S7?#Fy?P z@XeMt?Lo9ZH`1&$UH+_R5zTd3xb6V1r64j$q*0;5SmD@5Zbw)0$ResG zxuU0=HKl2n)eyH6g2fId2^l@OM*85H5A^@`)_?bC3mfb>1gibrFDDC&FX`-EO5CKT zTp3btW@z6eHpB~NntL~1F?hdbIqSc#irTi8U$2Z>DFXeyrjJQ_{Ie$ z!lguT>z$v!+s(9Y46OPX5VI_oxG~drF;n`!|9F0>L zCj?FrJB>ZoXXUf^WBQg*8+4$ti7@xX{glRGrq_n&9i!=e&wh@k=b~DOYDH9Q;z|z# zr#|2kb>rxNeeV7X?K_JdhrqWO!Zizfp7eqiMzjW>hEv+8|Ukf#&I;(= Date: Thu, 20 Feb 2025 11:12:29 +0800 Subject: [PATCH 250/865] enhance: prefer to use `Default Remote` in repository settings while fetching remote changes (#1008) Signed-off-by: leo --- src/ViewModels/Fetch.cs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/ViewModels/Fetch.cs b/src/ViewModels/Fetch.cs index d816d0b8..1094012e 100644 --- a/src/ViewModels/Fetch.cs +++ b/src/ViewModels/Fetch.cs @@ -38,7 +38,24 @@ namespace SourceGit.ViewModels { _repo = repo; _fetchAllRemotes = preferedRemote == null; - SelectedRemote = preferedRemote != null ? preferedRemote : _repo.Remotes[0]; + + if (preferedRemote != null) + { + SelectedRemote = preferedRemote; + } + else if (!string.IsNullOrEmpty(_repo.Settings.DefaultRemote)) + { + var def = _repo.Remotes.Find(r => r.Name == _repo.Settings.DefaultRemote); + if (def != null) + SelectedRemote = def; + else + SelectedRemote = _repo.Remotes[0]; + } + else + { + SelectedRemote = _repo.Remotes[0]; + } + View = new Views.Fetch() { DataContext = this }; } From b5feabfd37816ced5ecfa6eacb6fd820833e1651 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 20 Feb 2025 15:42:11 +0800 Subject: [PATCH 251/865] enhance: auto-set commit message while rebasing is inprogress (#1003) Signed-off-by: leo --- src/ViewModels/WorkingCopy.cs | 100 +++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 44 deletions(-) diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index d87c54ec..f1db3f3d 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -233,25 +233,10 @@ namespace SourceGit.ViewModels // Just force refresh selected changes. Dispatcher.UIThread.Invoke(() => { - if (_selectedUnstaged.Count == 1) - SetDetail(_selectedUnstaged[0], true); - else if (_selectedStaged.Count == 1) - SetDetail(_selectedStaged[0], false); - else - SetDetail(null, false); - - var inProgress = null as InProgressContext; - if (File.Exists(Path.Combine(_repo.GitDir, "CHERRY_PICK_HEAD"))) - inProgress = new CherryPickInProgress(_repo); - 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); - else if (File.Exists(Path.Combine(_repo.GitDir, "MERGE_HEAD"))) - inProgress = new MergeInProgress(_repo); - HasUnsolvedConflicts = _cached.Find(x => x.IsConflit) != null; - InProgressContext = inProgress; + + UpdateDetail(); + UpdateInProgressState(); }); return; @@ -311,32 +296,8 @@ namespace SourceGit.ViewModels SelectedStaged = selectedStaged; _isLoadingData = false; - if (selectedUnstaged.Count == 1) - SetDetail(selectedUnstaged[0], true); - else if (selectedStaged.Count == 1) - SetDetail(selectedStaged[0], false); - else - SetDetail(null, false); - - var inProgress = null as InProgressContext; - if (File.Exists(Path.Combine(_repo.GitDir, "CHERRY_PICK_HEAD"))) - inProgress = new CherryPickInProgress(_repo); - 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); - else if (File.Exists(Path.Combine(_repo.GitDir, "MERGE_HEAD"))) - inProgress = new MergeInProgress(_repo); - - InProgressContext = inProgress; - - // Try to load merge message from MERGE_MSG - if (string.IsNullOrEmpty(_commitMessage)) - { - var mergeMsgFile = Path.Combine(_repo.GitDir, "MERGE_MSG"); - if (File.Exists(mergeMsgFile)) - CommitMessage = File.ReadAllText(mergeMsgFile); - } + UpdateDetail(); + UpdateInProgressState(); }); } @@ -1488,6 +1449,57 @@ namespace SourceGit.ViewModels return rs; } + private void UpdateDetail() + { + if (_selectedUnstaged.Count == 1) + SetDetail(_selectedUnstaged[0], true); + else if (_selectedStaged.Count == 1) + SetDetail(_selectedStaged[0], false); + else + SetDetail(null, false); + } + + private void UpdateInProgressState() + { + if (string.IsNullOrEmpty(_commitMessage)) + { + var mergeMsgFile = Path.Combine(_repo.GitDir, "MERGE_MSG"); + if (File.Exists(mergeMsgFile)) + CommitMessage = File.ReadAllText(mergeMsgFile); + } + + if (File.Exists(Path.Combine(_repo.GitDir, "CHERRY_PICK_HEAD"))) + { + InProgressContext = new CherryPickInProgress(_repo); + } + else if (Directory.Exists(Path.Combine(_repo.GitDir, "rebase-merge")) || Directory.Exists(Path.Combine(_repo.GitDir, "rebase-apply"))) + { + var rebasing = new RebaseInProgress(_repo); + InProgressContext = rebasing; + + if (string.IsNullOrEmpty(_commitMessage)) + { + var rebaseMsgFile = Path.Combine(_repo.GitDir, "rebase-merge", "message"); + if (File.Exists(rebaseMsgFile)) + CommitMessage = File.ReadAllText(rebaseMsgFile); + else if (rebasing.StoppedAt != null) + CommitMessage = new Commands.QueryCommitFullMessage(_repo.FullPath, rebasing.StoppedAt.SHA).Result(); + } + } + else if (File.Exists(Path.Combine(_repo.GitDir, "REVERT_HEAD"))) + { + InProgressContext = new RevertInProgress(_repo); + } + else if (File.Exists(Path.Combine(_repo.GitDir, "MERGE_HEAD"))) + { + InProgressContext = new MergeInProgress(_repo); + } + else + { + InProgressContext = null; + } + } + private async void StageChanges(List changes, Models.Change next) { if (changes.Count == 0) From 9da2c787dbf0dbac7cc26ce777672857d40e6066 Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 21 Feb 2025 09:44:51 +0800 Subject: [PATCH 252/865] enhance: supports to configure `fetch.prune` for selected repository (#995) Signed-off-by: leo --- src/ViewModels/RepositoryConfigure.cs | 9 +++++++++ src/Views/RepositoryConfigure.axaml | 8 ++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/ViewModels/RepositoryConfigure.cs b/src/ViewModels/RepositoryConfigure.cs index a7c04937..cf23b6d8 100644 --- a/src/ViewModels/RepositoryConfigure.cs +++ b/src/ViewModels/RepositoryConfigure.cs @@ -60,6 +60,12 @@ namespace SourceGit.ViewModels set => SetProperty(ref _httpProxy, value); } + public bool EnablePruneOnFetch + { + get; + set; + } + public bool EnableAutoFetch { get => _repo.Settings.EnableAutoFetch; @@ -153,6 +159,8 @@ namespace SourceGit.ViewModels GPGUserSigningKey = signingKey; if (_cached.TryGetValue("http.proxy", out var proxy)) HttpProxy = proxy; + if (_cached.TryGetValue("fetch.prune", out var prune)) + EnablePruneOnFetch = (prune == "true"); } public void ClearHttpProxy() @@ -286,6 +294,7 @@ namespace SourceGit.ViewModels SetIfChanged("tag.gpgsign", GPGTagSigningEnabled ? "true" : "false", "false"); SetIfChanged("user.signingkey", GPGUserSigningKey, ""); SetIfChanged("http.proxy", HttpProxy, ""); + SetIfChanged("fetch.prune", EnablePruneOnFetch ? "true" : "false", "false"); } private void SetIfChanged(string key, string value, string defValue) diff --git a/src/Views/RepositoryConfigure.axaml b/src/Views/RepositoryConfigure.axaml index 61bc14e0..f6a02c49 100644 --- a/src/Views/RepositoryConfigure.axaml +++ b/src/Views/RepositoryConfigure.axaml @@ -44,7 +44,7 @@ - + - + + + From 2b4fc64c73b126fd0d94b5562be53e25dcf7b24d Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 21 Feb 2025 10:26:14 +0800 Subject: [PATCH 253/865] fix: resolve conflict with deleted files does not work (#1009) Signed-off-by: leo --- src/Commands/Add.cs | 4 +- src/ViewModels/WorkingCopy.cs | 76 ++++++++++++++++++++++++++------- src/Views/TextDiffView.axaml.cs | 2 +- 3 files changed, 64 insertions(+), 18 deletions(-) diff --git a/src/Commands/Add.cs b/src/Commands/Add.cs index e1b55b68..b2aa803d 100644 --- a/src/Commands/Add.cs +++ b/src/Commands/Add.cs @@ -12,7 +12,7 @@ namespace SourceGit.Commands Args = includeUntracked ? "add ." : "add -u ."; } - public Add(string repo, List changes) + public Add(string repo, List changes) { WorkingDirectory = repo; Context = repo; @@ -22,7 +22,7 @@ namespace SourceGit.Commands foreach (var c in changes) { builder.Append(" \""); - builder.Append(c.Path); + builder.Append(c); builder.Append("\""); } Args = builder.ToString(); diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index f1db3f3d..ce2a2ac1 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -353,38 +353,80 @@ namespace SourceGit.ViewModels public async void UseTheirs(List changes) { + _repo.SetWatcherEnabled(false); + var files = new List(); + var needStage = new List(); + foreach (var change in changes) { - if (change.IsConflit) + if (!change.IsConflit) + continue; + + if (change.WorkTree == Models.ChangeState.Deleted) + { + var fullpath = Path.Combine(_repo.FullPath, change.Path); + if (File.Exists(fullpath)) + File.Delete(fullpath); + + needStage.Add(change.Path); + } + else + { files.Add(change.Path); + } } - _repo.SetWatcherEnabled(false); - var succ = await Task.Run(() => new Commands.Checkout(_repo.FullPath).UseTheirs(files)); - if (succ) + if (files.Count > 0) { - await Task.Run(() => new Commands.Add(_repo.FullPath, changes).Exec()); + var succ = await Task.Run(() => new Commands.Checkout(_repo.FullPath).UseTheirs(files)); + if (succ) + needStage.AddRange(files); } + + if (needStage.Count > 0) + await Task.Run(() => new Commands.Add(_repo.FullPath, needStage).Exec()); + _repo.MarkWorkingCopyDirtyManually(); _repo.SetWatcherEnabled(true); } public async void UseMine(List changes) { + _repo.SetWatcherEnabled(false); + var files = new List(); + var needStage = new List(); + foreach (var change in changes) { - if (change.IsConflit) + if (!change.IsConflit) + continue; + + if (change.Index == Models.ChangeState.Deleted) + { + var fullpath = Path.Combine(_repo.FullPath, change.Path); + if (File.Exists(fullpath)) + File.Delete(fullpath); + + needStage.Add(change.Path); + } + else + { files.Add(change.Path); + } } - _repo.SetWatcherEnabled(false); - var succ = await Task.Run(() => new Commands.Checkout(_repo.FullPath).UseMine(files)); - if (succ) + if (files.Count > 0) { - await Task.Run(() => new Commands.Add(_repo.FullPath, changes).Exec()); + var succ = await Task.Run(() => new Commands.Checkout(_repo.FullPath).UseMine(files)); + if (succ) + needStage.AddRange(files); } + + if (needStage.Count > 0) + await Task.Run(() => new Commands.Add(_repo.FullPath, needStage).Exec()); + _repo.MarkWorkingCopyDirtyManually(); _repo.SetWatcherEnabled(true); } @@ -1502,7 +1544,8 @@ namespace SourceGit.ViewModels private async void StageChanges(List changes, Models.Change next) { - if (changes.Count == 0) + var count = changes.Count; + if (count == 0) return; // Use `_selectedUnstaged` instead of `SelectedUnstaged` to avoid UI refresh. @@ -1510,7 +1553,7 @@ namespace SourceGit.ViewModels IsStaging = true; _repo.SetWatcherEnabled(false); - if (changes.Count == _unstaged.Count) + if (count == _unstaged.Count) { await Task.Run(() => new Commands.Add(_repo.FullPath, _repo.IncludeUntracked).Exec()); } @@ -1527,10 +1570,13 @@ namespace SourceGit.ViewModels } else { - for (int i = 0; i < changes.Count; i += 10) + var paths = new List(); + foreach (var c in changes) + paths.Add(c.Path); + + for (int i = 0; i < count; i += 10) { - var count = Math.Min(10, changes.Count - i); - var step = changes.GetRange(i, count); + var step = paths.GetRange(i, Math.Min(10, count - i)); await Task.Run(() => new Commands.Add(_repo.FullPath, step).Exec()); } } diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index 28fe81a8..83bc47e3 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -1796,7 +1796,7 @@ namespace SourceGit.Views if (!selection.HasLeftChanges) { - new Commands.Add(repo.FullPath, [change]).Exec(); + new Commands.Add(repo.FullPath, [change.Path]).Exec(); } else { From 841276852a29c12f9da642e8d3c5f96b6cb7fce1 Mon Sep 17 00:00:00 2001 From: saxc Date: Fri, 21 Feb 2025 03:34:38 +0100 Subject: [PATCH 254/865] localization: add german translations (#1011) (cherry picked from commit fcc720480c85fe01120e555c22b6aec286ee717b) --- src/Resources/Locales/de_DE.axaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index b6458822..c16c90b5 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -59,6 +59,7 @@ Mit HEAD vergleichen Mit Worktree vergleichen Branch-Namen kopieren + Benutzerdefinierte Aktion Lösche ${0}$... Lösche alle ausgewählten {0} Branches Alle Änderungen verwerfen @@ -159,6 +160,7 @@ Ausführbare Datei: Name: Geltungsbereich: + Branch Commit Repository Email Adresse @@ -586,6 +588,7 @@ LOKALE BRANCHES Zum HEAD wechseln Erstelle Branch + BENACHRICHTIGUNGEN LÖSCHEN Nur aktuellen Branch im Graphen hervorheben Öffne in {0} Öffne in externen Tools @@ -710,7 +713,7 @@ Öffne alle Repositories Öffne Repository Öffne Terminal - Klon Standardordner erneut nach Repositories durchsuchen + Klon Standardordner erneut nach Repositories durchsuchen Suche Repositories... Sortieren Änderungen From b2ab62825ece1bb0111782f094266d1445c3a110 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 21 Feb 2025 02:48:21 +0000 Subject: [PATCH 255/865] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 784d0672..60c8543e 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-99.20%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.35%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-92.18%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-97.61%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.91%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.47%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) +[![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.60%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.35%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-92.18%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-97.61%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.91%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.47%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 53631bc1..c235ea6a 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -1,15 +1,12 @@ -### de_DE.axaml: 99.20% +### de_DE.axaml: 99.60%
Missing Keys -- Text.BranchCM.CustomAction - Text.BranchUpstreamInvalid -- Text.Configure.CustomAction.Scope.Branch - Text.Configure.CustomAction.WaitForExit - Text.Preferences.AI.Streaming -- Text.Repository.Notifications.Clear
From 9ab602788a7bfeaf05e382d876a145547cc3e73c Mon Sep 17 00:00:00 2001 From: Ikko Eltociear Ashimine Date: Mon, 24 Feb 2025 10:28:00 +0900 Subject: [PATCH 256/865] docs: update README.md (#1014) comaptible -> compatible --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 60c8543e..256070e2 100644 --- a/README.md +++ b/README.md @@ -132,7 +132,7 @@ For **Linux** users: ## OpenAI -This software supports using OpenAI or other AI service that has an OpenAI comaptible HTTP API to generate commit message. You need configurate the service in `Preference` window. +This software supports using OpenAI or other AI service that has an OpenAI compatible HTTP API to generate commit message. You need configurate the service in `Preference` window. For `OpenAI`: From fa4caa218628169d5f34076732ffa9b35ed040fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6ran=20W?= <44604769+goran-w@users.noreply.github.com> Date: Mon, 24 Feb 2025 02:32:19 +0100 Subject: [PATCH 257/865] enhance: add first/last buttons for block-nav, no wrapping (#1015) (#1016) Added 2 new buttons (only visible in block-nav mode), with new icons and new (en_US) strings (First/Last Difference). Implemented these new buttons, and disabled the automatic wrap-around for the prev/next buttons in block-nav mode. --- src/Resources/Icons.axaml | 2 ++ src/Resources/Locales/en_US.axaml | 2 ++ src/ViewModels/BlockNavigation.cs | 28 ++++++++++++++-- src/Views/DiffView.axaml | 28 ++++++++++++++++ src/Views/DiffView.axaml.cs | 14 ++++++++ src/Views/TextDiffView.axaml.cs | 56 +++++++++++++++++++++++++++++++ 6 files changed, 127 insertions(+), 3 deletions(-) diff --git a/src/Resources/Icons.axaml b/src/Resources/Icons.axaml index b7d9c22e..9426d20a 100644 --- a/src/Resources/Icons.axaml +++ b/src/Resources/Icons.axaml @@ -5,6 +5,7 @@ M71 1024V0h661L953 219V1024H71zm808-731-220-219H145V951h735V293zM439 512h-220V219h220V512zm-74-219H292v146h74v-146zm0 512h74v73h-220v-73H292v-146H218V585h147v219zm294-366h74V512H512v-73h74v-146H512V219h147v219zm74 439H512V585h220v293zm-74-219h-74v146h74v-146z M128 256h192a64 64 0 110 128H128a64 64 0 110-128zm576 192h192a64 64 0 010 128h-192a64 64 0 010-128zm-576 192h192a64 64 0 010 128H128a64 64 0 010-128zm576 0h192a64 64 0 010 128h-192a64 64 0 010-128zm0-384h192a64 64 0 010 128h-192a64 64 0 010-128zM128 448h192a64 64 0 110 128H128a64 64 0 110-128zm384-320a64 64 0 0164 64v640a64 64 0 01-128 0V192a64 64 0 0164-64z M832 64H192c-18 0-32 14-32 32v832c0 18 14 32 32 32h640c18 0 32-14 32-32V96c0-18-14-32-32-32zM736 596 624 502 506 596V131h230v318z + M509 546 780 275 871 366 509 728 147 366 238 275zM509 728h-362v128h724v-128z M757 226a143 143 0 00-55 276 96 96 0 01-88 59h-191a187 187 0 00-96 27V312a143 143 0 10-96 0v399a143 143 0 10103 2 96 96 0 0188-59h191a191 191 0 00187-151 143 143 0 00-43-279zM280 130a48 48 0 110 96 48 48 0 010-96zm0 764a48 48 0 110-96 48 48 0 010 96zM757 417a48 48 0 110-96 48 48 0 010 96z M896 128h-64V64c0-35-29-64-64-64s-64 29-64 64v64h-64c-35 0-64 29-64 64s29 64 64 64h64v64c0 35 29 64 64 64s64-29 64-64V256h64c35 0 64-29 64-64s-29-64-64-64zm-204 307C673 481 628 512 576 512H448c-47 0-90 13-128 35V372C394 346 448 275 448 192c0-106-86-192-192-192S64 86 64 192c0 83 54 154 128 180v280c-74 26-128 97-128 180c0 106 86 192 192 192s192-86 192-192c0-67-34-125-84-159c22-20 52-33 84-33h128c122 0 223-85 249-199c-19 4-37 7-57 7c-26 0-51-5-76-13zM256 128c35 0 64 29 64 64s-29 64-64 64s-64-29-64-64s29-64 64-64zm0 768c-35 0-64-29-64-64s29-64 64-64s64 29 64 64s-29 64-64 64z M512 597m-1 0a1 1 0 103 0a1 1 0 10-3 0ZM810 393 732 315 448 600 293 444 214 522l156 156 78 78 362-362z @@ -119,6 +120,7 @@ M996 452 572 28A96 96 0 00504 0H96C43 0 0 43 0 96v408a96 96 0 0028 68l424 424c37 37 98 37 136 0l408-408c37-37 37-98 0-136zM224 320c-53 0-96-43-96-96s43-96 96-96 96 43 96 96-43 96-96 96zm1028 268L844 996c-37 37-98 37-136 0l-1-1L1055 647c34-34 53-79 53-127s-19-93-53-127L663 0h97a96 96 0 0168 28l424 424c37 37 37 98 0 136z M765 118 629 239l-16 137-186 160 54 59 183-168 144 4 136-129 47-43-175-12L827 67zM489 404c-66 0-124 55-124 125s54 121 124 121c66 0 120-55 120-121H489l23-121c-8-4-16-4-23-4zM695 525c0 114-93 207-206 207s-206-94-206-207 93-207 206-207c16 0 27 0 43 4l43-207c-27-4-54-8-85-8-229 0-416 188-416 419s187 419 416 419c225 0 408-180 416-403v-12l-210-4z M144 112h736c18 0 32 14 32 32v736c0 18-14 32-32 32H144c-18 0-32-14-32-32V144c0-18 14-32 32-32zm112 211v72a9 9 0 003 7L386 509 259 615a9 9 0 00-3 7v72a9 9 0 0015 7L493 516a9 9 0 000-14l-222-186a9 9 0 00-15 7zM522 624a10 10 0 00-10 10v60a10 10 0 0010 10h237a10 10 0 0010-10v-60a10 10 0 00-10-10H522z + M170 831 513 489 855 831 960 726 512 278 64 726 170 831zM512 278h448v-128h-896v128h448z M897 673v13c0 51-42 93-93 93h-10c-1 0-2 0-2 0H220c-23 0-42 19-42 42v13c0 23 19 42 42 42h552c14 0 26 12 26 26 0 14-12 26-26 26H220c-51 0-93-42-93-93v-13c0-51 42-93 93-93h20c1-0 2-0 2-0h562c23 0 42-19 42-42v-13c0-11-5-22-13-29-8-7-17-11-28-10H660c-14 0-26-12-26-26 0-14 12-26 26-26h144c24-1 47 7 65 24 18 17 29 42 29 67zM479 98c-112 0-203 91-203 203 0 44 14 85 38 118l132 208c15 24 50 24 66 0l133-209c23-33 37-73 37-117 0-112-91-203-203-203zm0 327c-68 0-122-55-122-122s55-122 122-122 122 55 122 122-55 122-122 122z M912 800a48 48 0 1 1 0 96h-416a48 48 0 1 1 0-96h416z m-704-704A112 112 0 0 1 256 309.184V480h80a48 48 0 0 1 0 96H256v224h81.664a48 48 0 1 1 0 96H256a96 96 0 0 1-96-96V309.248A112 112 0 0 1 208 96z m704 384a48 48 0 1 1 0 96h-416a48 48 0 0 1 0-96h416z m0-320a48 48 0 1 1 0 96h-416a48 48 0 0 1 0-96h416z M30 0 30 30 0 15z diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index dfc17dee..d2d64d5c 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -252,9 +252,11 @@ File Mode Changed Ignore Whitespace Change LFS OBJECT CHANGE + First Difference Next Difference NO CHANGES OR ONLY EOL CHANGES Previous Difference + Last Difference Save as Patch Show hidden symbols Side-By-Side Diff diff --git a/src/ViewModels/BlockNavigation.cs b/src/ViewModels/BlockNavigation.cs index 709338f8..9a5a926c 100644 --- a/src/ViewModels/BlockNavigation.cs +++ b/src/ViewModels/BlockNavigation.cs @@ -101,12 +101,12 @@ namespace SourceGit.ViewModels return (_current >= 0 && _current < Blocks.Count) ? Blocks[_current] : null; } - public Block GotoNext() + public Block GotoFirst() { if (Blocks.Count == 0) return null; - Current = (_current + 1) % Blocks.Count; + Current = 0; return Blocks[_current]; } @@ -115,7 +115,29 @@ namespace SourceGit.ViewModels if (Blocks.Count == 0) return null; - Current = _current == -1 ? Blocks.Count - 1 : (_current - 1 + Blocks.Count) % Blocks.Count; + if (_current == -1) + Current = 0; + else if (_current > 0) + Current = _current - 1; + return Blocks[_current]; + } + + public Block GotoNext() + { + if (Blocks.Count == 0) + return null; + + if (_current < Blocks.Count - 1) + Current = _current + 1; + return Blocks[_current]; + } + + public Block GotoLast() + { + if (Blocks.Count == 0) + return null; + + Current = Blocks.Count - 1; return Blocks[_current]; } diff --git a/src/Views/DiffView.axaml b/src/Views/DiffView.axaml index aa75c2a0..fccb949d 100644 --- a/src/Views/DiffView.axaml +++ b/src/Views/DiffView.axaml @@ -34,6 +34,20 @@ + + + + (); + textDiff?.GotoFirstChange(); + e.Handled = true; + } + private void OnGotoPrevChange(object _, RoutedEventArgs e) { var textDiff = this.FindDescendantOfType(); @@ -24,5 +31,12 @@ namespace SourceGit.Views textDiff?.GotoNextChange(); e.Handled = true; } + + private void OnGotoLastChange(object _, RoutedEventArgs e) + { + var textDiff = this.FindDescendantOfType(); + textDiff?.GotoLastChange(); + e.Handled = true; + } } } diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index 83bc47e3..323fde03 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -543,6 +543,21 @@ namespace SourceGit.Views { } + public void GotoFirstChange() + { + var blockNavigation = BlockNavigation; + if (blockNavigation != null) + { + var prev = blockNavigation.GotoFirst(); + if (prev != null) + { + TextArea.Caret.Line = prev.Start; + ScrollToLine(prev.Start); + } + } + // NOTE: Not implemented (button hidden) for non-block navigation. + } + public void GotoPrevChange() { var blockNavigation = BlockNavigation; @@ -641,6 +656,21 @@ namespace SourceGit.Views } } + public void GotoLastChange() + { + var blockNavigation = BlockNavigation; + if (blockNavigation != null) + { + var next = blockNavigation.GotoLast(); + if (next != null) + { + TextArea.Caret.Line = next.Start; + ScrollToLine(next.Start); + } + } + // NOTE: Not implemented (button hidden) for non-block navigation. + } + public override void Render(DrawingContext context) { base.Render(context); @@ -1682,6 +1712,19 @@ namespace SourceGit.Views InitializeComponent(); } + public void GotoFirstChange() + { + var presenter = this.FindDescendantOfType(); + if (presenter == null) + return; + + presenter.GotoFirstChange(); + if (presenter is SingleSideTextDiffPresenter singleSide) + singleSide.ForceSyncScrollOffset(); + + BlockNavigationIndicator = BlockNavigation?.Indicator ?? string.Empty; + } + public void GotoPrevChange() { var presenter = this.FindDescendantOfType(); @@ -1708,6 +1751,19 @@ namespace SourceGit.Views BlockNavigationIndicator = BlockNavigation?.Indicator ?? string.Empty; } + public void GotoLastChange() + { + var presenter = this.FindDescendantOfType(); + if (presenter == null) + return; + + presenter.GotoLastChange(); + if (presenter is SingleSideTextDiffPresenter singleSide) + singleSide.ForceSyncScrollOffset(); + + BlockNavigationIndicator = BlockNavigation?.Indicator ?? string.Empty; + } + protected override void OnDataContextChanged(EventArgs e) { base.OnDataContextChanged(e); From 52a53cc6976df7ff153209ace0e78bb353e50d94 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 24 Feb 2025 01:32:32 +0000 Subject: [PATCH 258/865] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 34 ++++++++++++++++++++++++---------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 256070e2..a48af9bd 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-99.60%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.35%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-92.18%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-97.61%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.91%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.47%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) +[![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.34%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.09%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-91.93%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-97.35%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.67%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.21%25-yellow)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-99.74%25-yellow)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-99.74%25-yellow)](TRANSLATION.md) > [!NOTE] > You can find the missing keys in [TRANSLATION.md](TRANSLATION.md) diff --git a/TRANSLATION.md b/TRANSLATION.md index c235ea6a..4e96f0ac 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -1,4 +1,4 @@ -### de_DE.axaml: 99.60% +### de_DE.axaml: 99.34%
@@ -6,11 +6,13 @@ - Text.BranchUpstreamInvalid - Text.Configure.CustomAction.WaitForExit +- Text.Diff.First +- Text.Diff.Last - Text.Preferences.AI.Streaming
-### es_ES.axaml: 97.35% +### es_ES.axaml: 97.09%
@@ -31,6 +33,8 @@ - Text.DeleteRepositoryNode.Path - Text.DeleteRepositoryNode.TipForGroup - Text.DeleteRepositoryNode.TipForRepository +- Text.Diff.First +- Text.Diff.Last - Text.Preferences.AI.Streaming - Text.Repository.Notifications.Clear - Text.Stash.AutoRestore @@ -39,7 +43,7 @@
-### fr_FR.axaml: 92.18% +### fr_FR.axaml: 91.93%
@@ -60,6 +64,8 @@ - Text.DeleteRepositoryNode.Path - Text.DeleteRepositoryNode.TipForGroup - Text.DeleteRepositoryNode.TipForRepository +- Text.Diff.First +- Text.Diff.Last - Text.InProgress.CherryPick.Head - Text.InProgress.Merge.Operating - Text.InProgress.Rebase.StoppedAt @@ -107,7 +113,7 @@
-### it_IT.axaml: 97.61% +### it_IT.axaml: 97.35%
@@ -127,6 +133,8 @@ - Text.DeleteRepositoryNode.Path - Text.DeleteRepositoryNode.TipForGroup - Text.DeleteRepositoryNode.TipForRepository +- Text.Diff.First +- Text.Diff.Last - Text.Preferences.AI.Streaming - Text.Repository.Notifications.Clear - Text.Stash.AutoRestore @@ -134,7 +142,7 @@
-### pt_BR.axaml: 91.91% +### pt_BR.axaml: 91.67%
@@ -162,6 +170,8 @@ - Text.DeleteRepositoryNode.Path - Text.DeleteRepositoryNode.TipForGroup - Text.DeleteRepositoryNode.TipForRepository +- Text.Diff.First +- Text.Diff.Last - Text.Diff.UseBlockNavigation - Text.Fetch.Force - Text.FileCM.ResolveUsing @@ -204,7 +214,7 @@
-### ru_RU.axaml: 99.47% +### ru_RU.axaml: 99.21%
@@ -213,26 +223,30 @@ - Text.BranchCM.CustomAction - Text.BranchUpstreamInvalid - Text.Configure.CustomAction.Scope.Branch +- Text.Diff.First +- Text.Diff.Last - Text.Preferences.AI.Streaming
-### zh_CN.axaml: 100.00% +### zh_CN.axaml: 99.74%
Missing Keys - +- Text.Diff.First +- Text.Diff.Last
-### zh_TW.axaml: 100.00% +### zh_TW.axaml: 99.74%
Missing Keys - +- Text.Diff.First +- Text.Diff.Last
From 124bdc97f96a30ebcd0572671aed5db26bc6ee81 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 24 Feb 2025 09:37:34 +0800 Subject: [PATCH 259/865] localization: add missing keys for zh_CN and zh_TW Signed-off-by: leo --- src/Resources/Locales/en_US.axaml | 6 +++--- src/Resources/Locales/zh_CN.axaml | 2 ++ src/Resources/Locales/zh_TW.axaml | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index d2d64d5c..1a83a4da 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -250,13 +250,13 @@ OLD Copy File Mode Changed - Ignore Whitespace Change - LFS OBJECT CHANGE First Difference + Ignore Whitespace Change + Last Difference + LFS OBJECT CHANGE Next Difference NO CHANGES OR ONLY EOL CHANGES Previous Difference - Last Difference Save as Patch Show hidden symbols Side-By-Side Diff diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 115f917e..acfdefd2 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -253,7 +253,9 @@ 原始大小 复制 文件权限已变化 + 首个差异 忽略空白符号变化 + 最后一个差异 LFS对象变更 下一个差异 没有变更或仅有换行符差异 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 00933783..dd9092a4 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -253,7 +253,9 @@ 原始大小 複製 檔案權限已變更 + 第一個差異 忽略空白符號變化 + 最後一個差異 LFS 物件變更 下一個差異 沒有變更或僅有換行字元差異 From 74e5bcb7047d95e38ca116a1fe0ef2ef9c84242e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 24 Feb 2025 01:37:52 +0000 Subject: [PATCH 260/865] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index a48af9bd..a82a43b1 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-99.34%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.09%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-91.93%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-97.35%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.67%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.21%25-yellow)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-99.74%25-yellow)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-99.74%25-yellow)](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.34%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.09%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-91.93%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-97.35%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.67%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.21%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 4e96f0ac..acecf990 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -229,24 +229,22 @@
-### zh_CN.axaml: 99.74% +### zh_CN.axaml: 100.00%
Missing Keys -- Text.Diff.First -- Text.Diff.Last +
-### zh_TW.axaml: 99.74% +### zh_TW.axaml: 100.00%
Missing Keys -- Text.Diff.First -- Text.Diff.Last +
From d4341c119554835d4885dd54ba15bd7fe153cf78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20J=2E=20Mart=C3=ADnez=20M=2E?= <56406225+jjesus-dev@users.noreply.github.com> Date: Sun, 23 Feb 2025 19:45:39 -0600 Subject: [PATCH 261/865] localization: add missing spanish translations (#1017) --- src/Resources/Locales/es_ES.axaml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index a0f35814..24170683 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -22,7 +22,9 @@ Rama de Seguimiento: Seguimiento de rama remota Asistente OpenAI + RE-GENERAR Usar OpenAI para generar mensaje de commit + APLICAR CÓMO MENSAJE DE COMMIT Aplicar Patch Error Genera errores y se niega a aplicar el patch @@ -37,6 +39,10 @@ Advertencia Genera advertencias para algunos de estos errores, pero aplica Espacios en Blanco: + Aplicar Stash + Borrar después de aplicar + Restaurar los cambios del índice + Stash: Archivar... Guardar Archivo en: Seleccionar ruta del archivo @@ -53,6 +59,7 @@ Comparar con HEAD Comparar con Worktree Copiar Nombre de Rama + Acción personalizada Eliminar ${0}$... Eliminar {0} ramas seleccionadas Descartar todos los cambios @@ -68,6 +75,7 @@ Renombrar ${0}$... Establecer Rama de Seguimiento... Comparar Ramas + ¡Upstream inválido! Bytes CANCELAR Resetear a Esta Revisión @@ -100,6 +108,7 @@ Nombre Local: Nombre del repositorio. Opcional. Carpeta Padre: + Inicializar y actualizar submodulos URL del Repositorio: CERRAR Editor @@ -152,8 +161,10 @@ Archivo Ejecutable: Nombre: Alcance: + Rama Commit Repositorio + Esperar la acción de salida Dirección de Email Dirección de email GIT @@ -202,6 +213,7 @@ Stash & Reaplicar Nombre de la Nueva Rama: Introduzca el nombre de la rama. + Los espacios serán reemplazados con guiones. Crear Rama Local Crear Etiqueta... Nueva Etiqueta En: @@ -225,8 +237,11 @@ Estás intentando eliminar múltiples ramas a la vez. ¡Asegúrate de revisar antes de tomar acción! Eliminar Remoto Remoto: + Ruta: Destino: + Todos los hijos serán removidos de la lista. Confirmar Eliminación de Grupo + ¡Esto solo lo removera de la lista, no del disco! Confirmar Eliminación de Repositorio Eliminar Submódulo Ruta del Submódulo: @@ -449,6 +464,7 @@ Modelo Nombre Servidor + Activar Transmisión APARIENCIA Fuente por defecto Tamaño de fuente @@ -576,6 +592,7 @@ RAMAS LOCALES Navegar a HEAD Crear Rama + LIMPIAR NOTIFICACIONES Resaltar solo la rama actual en el gráfico Abrir en {0} Abrir en Herramientas Externas @@ -642,6 +659,8 @@ Ruta de almacenamiento de la clave privada SSH INICIAR Stash + Restaurar automáticamente después del stashing + Tus archivos de trabajo permanecen sin cambios, pero se guarda un stash. Incluir archivos no rastreados Mantener archivos staged Mensaje: @@ -721,6 +740,7 @@ INCLUIR ARCHIVOS NO RASTREADOS NO HAY MENSAJES DE ENTRADA RECIENTES NO HAY PLANTILLAS DE COMMIT + Firmar STAGED UNSTAGE UNSTAGE TODO From 89e09d842d6f632e4c2cda52a6715983b44a2c28 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 24 Feb 2025 01:45:49 +0000 Subject: [PATCH 262/865] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 22 +--------------------- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index a82a43b1..0990a39d 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-99.34%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.09%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-91.93%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-97.35%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.67%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.21%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) +[![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.34%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-99.74%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-91.93%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-97.35%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.67%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.21%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 acecf990..04e121fc 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -12,34 +12,14 @@
-### es_ES.axaml: 97.09% +### es_ES.axaml: 99.74%
Missing Keys -- Text.AIAssistant.Regen -- Text.AIAssistant.Use -- Text.ApplyStash -- Text.ApplyStash.DropAfterApply -- Text.ApplyStash.RestoreIndex -- Text.ApplyStash.Stash -- Text.BranchCM.CustomAction -- Text.BranchUpstreamInvalid -- Text.Clone.RecurseSubmodules -- Text.Configure.CustomAction.Scope.Branch -- Text.Configure.CustomAction.WaitForExit -- Text.CreateBranch.Name.WarnSpace -- Text.DeleteRepositoryNode.Path -- Text.DeleteRepositoryNode.TipForGroup -- Text.DeleteRepositoryNode.TipForRepository - Text.Diff.First - Text.Diff.Last -- Text.Preferences.AI.Streaming -- Text.Repository.Notifications.Clear -- Text.Stash.AutoRestore -- Text.Stash.AutoRestore.Tip -- Text.WorkingCopy.SignOff
From 0b7805b2ee3489de0e4b6a3b62782301fa25012b Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 24 Feb 2025 09:49:30 +0800 Subject: [PATCH 263/865] version: Release 2025.06 Signed-off-by: leo --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 15689348..bb11b3b9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2025.05 \ No newline at end of file +2025.06 \ No newline at end of file From 1d037c7c572389bd91d50a22a1105b89bf4fd5c6 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 24 Feb 2025 21:24:53 +0800 Subject: [PATCH 264/865] feature: add context menu `Save As Patch...` for selected stash (#1018) Signed-off-by: leo --- src/Commands/SaveChangesAsPatch.cs | 13 +++++++++++ src/Resources/Locales/en_US.axaml | 1 + src/Resources/Locales/zh_CN.axaml | 1 + src/Resources/Locales/zh_TW.axaml | 1 + src/ViewModels/StashesPage.cs | 37 ++++++++++++++++++++++++++++++ 5 files changed, 53 insertions(+) diff --git a/src/Commands/SaveChangesAsPatch.cs b/src/Commands/SaveChangesAsPatch.cs index 461bbfb5..b10037a1 100644 --- a/src/Commands/SaveChangesAsPatch.cs +++ b/src/Commands/SaveChangesAsPatch.cs @@ -37,6 +37,19 @@ namespace SourceGit.Commands return true; } + public static bool ProcessStashChanges(string repo, List opts, string saveTo) + { + using (var sw = File.Create(saveTo)) + { + foreach (var opt in opts) + { + if (!ProcessSingleChange(repo, opt, sw)) + return false; + } + } + return true; + } + private static bool ProcessSingleChange(string repo, Models.DiffOption opt, FileStream writer) { var starter = new ProcessStartInfo(); diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 1a83a4da..6c397ea0 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -669,6 +669,7 @@ Apply Drop Pop + Save as Patch... Drop Stash Drop: STASHES diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index acfdefd2..09c46e95 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -673,6 +673,7 @@ 应用(apply) 删除(drop) 应用并删除(pop) + 另存为补丁... 丢弃贮藏确认 丢弃贮藏 : 贮藏列表 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index dd9092a4..0eb54676 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -672,6 +672,7 @@ 套用 (apply) 刪除 (drop) 套用並刪除 (pop) + 另存為修補檔 (patch)... 捨棄擱置變更確認 捨棄擱置變更: 擱置變更 diff --git a/src/ViewModels/StashesPage.cs b/src/ViewModels/StashesPage.cs index 4a3bf933..57b30fd3 100644 --- a/src/ViewModels/StashesPage.cs +++ b/src/ViewModels/StashesPage.cs @@ -4,6 +4,7 @@ using System.IO; using System.Threading.Tasks; using Avalonia.Controls; +using Avalonia.Platform.Storage; using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; @@ -157,9 +158,45 @@ namespace SourceGit.ViewModels ev.Handled = true; }; + var patch = new MenuItem(); + patch.Header = App.Text("StashCM.SaveAsPatch"); + patch.Icon = App.CreateMenuIcon("Icons.Diff"); + patch.Click += async (_, e) => + { + var storageProvider = App.GetStorageProvider(); + if (storageProvider == null) + return; + + var options = new FilePickerSaveOptions(); + options.Title = App.Text("StashCM.SaveAsPatch"); + options.DefaultExtension = ".patch"; + options.FileTypeChoices = [new FilePickerFileType("Patch File") { Patterns = ["*.patch"] }]; + + var storageFile = await storageProvider.SaveFilePickerAsync(options); + if (storageFile != null) + { + var opts = new List(); + foreach (var c in _changes) + { + if (_untrackedChanges.Contains(c.Path)) + opts.Add(new Models.DiffOption("4b825dc642cb6eb9a060e54bf8d69288fbee4904", _selectedStash.Parents[2], c)); + else + opts.Add(new Models.DiffOption(_selectedStash.Parents[0], _selectedStash.SHA, c)); + } + + var succ = await Task.Run(() => Commands.SaveChangesAsPatch.ProcessStashChanges(_repo.FullPath, opts, storageFile.Path.LocalPath)); + if (succ) + App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess")); + } + + e.Handled = true; + }; + var menu = new ContextMenu(); menu.Items.Add(apply); menu.Items.Add(drop); + menu.Items.Add(new MenuItem { Header = "-" }); + menu.Items.Add(patch); return menu; } From 1f35e837997148049b2365484b9bbea16ef5bd56 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 24 Feb 2025 13:25:13 +0000 Subject: [PATCH 265/865] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0990a39d..e89b071c 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-99.34%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-99.74%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-91.93%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-97.35%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.67%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.21%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) +[![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.21%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-99.60%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-91.81%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-97.23%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.55%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.08%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 04e121fc..024cd035 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -1,4 +1,4 @@ -### de_DE.axaml: 99.34% +### de_DE.axaml: 99.21%
@@ -9,10 +9,11 @@ - Text.Diff.First - Text.Diff.Last - Text.Preferences.AI.Streaming +- Text.StashCM.SaveAsPatch
-### es_ES.axaml: 99.74% +### es_ES.axaml: 99.60%
@@ -20,10 +21,11 @@ - Text.Diff.First - Text.Diff.Last +- Text.StashCM.SaveAsPatch
-### fr_FR.axaml: 91.93% +### fr_FR.axaml: 91.81%
@@ -88,12 +90,13 @@ - Text.SHALinkCM.NavigateTo - Text.Stash.AutoRestore - Text.Stash.AutoRestore.Tip +- Text.StashCM.SaveAsPatch - Text.WorkingCopy.CommitToEdit - Text.WorkingCopy.SignOff
-### it_IT.axaml: 97.35% +### it_IT.axaml: 97.23%
@@ -119,10 +122,11 @@ - Text.Repository.Notifications.Clear - Text.Stash.AutoRestore - Text.Stash.AutoRestore.Tip +- Text.StashCM.SaveAsPatch
-### pt_BR.axaml: 91.67% +### pt_BR.axaml: 91.55%
@@ -189,12 +193,13 @@ - Text.SHALinkCM.NavigateTo - Text.Stash.AutoRestore - Text.Stash.AutoRestore.Tip +- Text.StashCM.SaveAsPatch - Text.WorkingCopy.CommitToEdit - Text.WorkingCopy.SignOff
-### ru_RU.axaml: 99.21% +### ru_RU.axaml: 99.08%
@@ -206,6 +211,7 @@ - Text.Diff.First - Text.Diff.Last - Text.Preferences.AI.Streaming +- Text.StashCM.SaveAsPatch
From c6747f72f9fc712229b87783bc8d8a735f119647 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 25 Feb 2025 10:53:42 +0800 Subject: [PATCH 266/865] feature: auto-select first change in commit details panel and revision/branch compare panel (#1019) Signed-off-by: leo --- src/Models/OpenAI.cs | 2 +- src/ViewModels/CommitDetail.cs | 16 ++++---- src/ViewModels/Repository.cs | 6 +++ src/ViewModels/WorkingCopy.cs | 2 +- src/Views/BranchCompare.axaml | 1 + src/Views/ChangeCollectionView.axaml.cs | 53 +++++++++++++++++++++---- src/Views/CommitChanges.axaml | 1 + src/Views/LauncherTabsSelector.axaml.cs | 6 +-- src/Views/Repository.axaml.cs | 2 +- src/Views/RevisionCompare.axaml | 1 + src/Views/TextDiffView.axaml.cs | 2 +- 11 files changed, 71 insertions(+), 21 deletions(-) diff --git a/src/Models/OpenAI.cs b/src/Models/OpenAI.cs index 264230c6..76daacd0 100644 --- a/src/Models/OpenAI.cs +++ b/src/Models/OpenAI.cs @@ -36,7 +36,7 @@ namespace SourceGit.Models { if (startIdx > 0) OnReceive(buffer.Substring(0, startIdx)); - + var endIdx = buffer.IndexOf(">", startIdx + 1, StringComparison.Ordinal); if (endIdx <= startIdx) { diff --git a/src/ViewModels/CommitDetail.cs b/src/ViewModels/CommitDetail.cs index d90e97d6..702a757c 100644 --- a/src/ViewModels/CommitDetail.cs +++ b/src/ViewModels/CommitDetail.cs @@ -25,8 +25,15 @@ namespace SourceGit.ViewModels public int ActivePageIndex { - get => _activePageIndex; - set => SetProperty(ref _activePageIndex, value); + get => _repo.CommitDetailActivePageIndex; + set + { + if (_repo.CommitDetailActivePageIndex != value) + { + _repo.CommitDetailActivePageIndex = value; + OnPropertyChanged(); + } + } } public Models.Commit Commit @@ -617,11 +624,7 @@ namespace SourceGit.ViewModels _changes = null; _revisionFiles.Clear(); - FullMessage = string.Empty; SignInfo = null; - Changes = []; - VisibleChanges = null; - SelectedChanges = null; ViewRevisionFileContent = null; Children.Clear(); RevisionFileSearchFilter = string.Empty; @@ -821,7 +824,6 @@ namespace SourceGit.ViewModels }; private Repository _repo = null; - private int _activePageIndex = 0; private Models.Commit _commit = null; private string _fullMessage = string.Empty; private Models.CommitSignInfo _signInfo = null; diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 6e8a5290..104ff60b 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -453,6 +453,12 @@ namespace SourceGit.ViewModels private set => SetProperty(ref _isAutoFetching, value); } + public int CommitDetailActivePageIndex + { + get; + set; + } = 0; + public Repository(bool isBare, string path, string gitDir) { IsBare = isBare; diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index ce2a2ac1..afaf5868 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -1466,7 +1466,7 @@ namespace SourceGit.ViewModels return unstaged; var visible = new List(); - + foreach (var c in unstaged) { if (c.Path.Contains(_unstagedFilter, StringComparison.OrdinalIgnoreCase)) diff --git a/src/Views/BranchCompare.axaml b/src/Views/BranchCompare.axaml index 04b77306..f73860c5 100644 --- a/src/Views/BranchCompare.axaml +++ b/src/Views/BranchCompare.axaml @@ -134,6 +134,7 @@
diff --git a/src/Views/ChangeCollectionView.axaml.cs b/src/Views/ChangeCollectionView.axaml.cs index d6982dda..6ef79861 100644 --- a/src/Views/ChangeCollectionView.axaml.cs +++ b/src/Views/ChangeCollectionView.axaml.cs @@ -85,6 +85,15 @@ namespace SourceGit.Views set => SetValue(ChangesProperty, value); } + public static readonly StyledProperty AutoSelectFirstChangeProperty = + AvaloniaProperty.Register(nameof(AutoSelectFirstChange), false); + + public bool AutoSelectFirstChange + { + get => GetValue(AutoSelectFirstChangeProperty); + set => SetValue(AutoSelectFirstChangeProperty, value); + } + public static readonly StyledProperty> SelectedChangesProperty = AvaloniaProperty.Register>(nameof(SelectedChanges)); @@ -205,9 +214,9 @@ namespace SourceGit.Views base.OnPropertyChanged(change); if (change.Property == ViewModeProperty) - UpdateDataSource(false); - else if (change.Property == ChangesProperty) UpdateDataSource(true); + else if (change.Property == ChangesProperty) + UpdateDataSource(false); else if (change.Property == SelectedChangesProperty) UpdateSelection(); } @@ -292,9 +301,9 @@ namespace SourceGit.Views } } - private void UpdateDataSource(bool disableEvents) + private void UpdateDataSource(bool onlyViewModeChange) { - _disableSelectionChangingEvent = disableEvents; + _disableSelectionChangingEvent = !onlyViewModeChange; var changes = Changes; if (changes == null || changes.Count == 0) @@ -324,7 +333,19 @@ namespace SourceGit.Views MakeTreeRows(rows, tree.Tree); tree.Rows.AddRange(rows); - if (selected.Count > 0) + if (!onlyViewModeChange && AutoSelectFirstChange) + { + foreach (var row in tree.Rows) + { + if (row.Change != null) + { + tree.SelectedRows.Add(row); + SetCurrentValue(SelectedChangesProperty, [row.Change]); + break; + } + } + } + else if (selected.Count > 0) { var sets = new HashSet(); foreach (var c in selected) @@ -346,16 +367,34 @@ namespace SourceGit.Views { var grid = new ViewModels.ChangeCollectionAsGrid(); grid.Changes.AddRange(changes); - if (selected.Count > 0) + + if (!onlyViewModeChange && AutoSelectFirstChange) + { + grid.SelectedChanges.Add(changes[0]); + SetCurrentValue(SelectedChangesProperty, [changes[0]]); + } + else if (selected.Count > 0) + { grid.SelectedChanges.AddRange(selected); + } + Content = grid; } else { var list = new ViewModels.ChangeCollectionAsList(); list.Changes.AddRange(changes); - if (selected.Count > 0) + + if (!onlyViewModeChange && AutoSelectFirstChange) + { + list.SelectedChanges.Add(changes[0]); + SetCurrentValue(SelectedChangesProperty, [changes[0]]); + } + else if (selected.Count > 0) + { list.SelectedChanges.AddRange(selected); + } + Content = list; } diff --git a/src/Views/CommitChanges.axaml b/src/Views/CommitChanges.axaml index 377be944..2fac9365 100644 --- a/src/Views/CommitChanges.axaml +++ b/src/Views/CommitChanges.axaml @@ -49,6 +49,7 @@ ViewMode="{Binding Source={x:Static vm:Preferences.Instance}, Path=CommitChangeViewMode}" Changes="{Binding VisibleChanges}" SelectedChanges="{Binding SelectedChanges, Mode=TwoWay}" + AutoSelectFirstChange="True" ContextRequested="OnChangeContextRequested"/>
diff --git a/src/Views/LauncherTabsSelector.axaml.cs b/src/Views/LauncherTabsSelector.axaml.cs index 01c5fa0d..61d7a966 100644 --- a/src/Views/LauncherTabsSelector.axaml.cs +++ b/src/Views/LauncherTabsSelector.axaml.cs @@ -39,7 +39,7 @@ namespace SourceGit.Views } public static readonly RoutedEvent PageSelectedEvent = - RoutedEvent.Register(nameof(PageSelected), RoutingStrategies.Tunnel | RoutingStrategies.Bubble); + RoutedEvent.Register(nameof(PageSelected), RoutingStrategies.Tunnel | RoutingStrategies.Bubble); public event EventHandler PageSelected { @@ -74,7 +74,7 @@ namespace SourceGit.Views private void OnPageSelectionChanged(object sender, SelectionChangedEventArgs e) { - if (sender is ListBox { SelectedItem : ViewModels.LauncherPage page }) + if (sender is ListBox { SelectedItem: ViewModels.LauncherPage page }) { _isProcessingSelection = true; RaiseEvent(new LauncherTabSelectedEventArgs(page)); @@ -88,7 +88,7 @@ namespace SourceGit.Views { if (_isProcessingSelection) return; - + VisiblePages.Clear(); if (Pages == null) diff --git a/src/Views/Repository.axaml.cs b/src/Views/Repository.axaml.cs index 53bb2d53..2b3b7c30 100644 --- a/src/Views/Repository.axaml.cs +++ b/src/Views/Repository.axaml.cs @@ -522,7 +522,7 @@ namespace SourceGit.Views private void OnRemoveSelectedHistoriesFilter(object sender, RoutedEventArgs e) { - if (DataContext is ViewModels.Repository repo && sender is Button { DataContext: Models.Filter filter}) + if (DataContext is ViewModels.Repository repo && sender is Button { DataContext: Models.Filter filter }) repo.RemoveHistoriesFilter(filter); e.Handled = true; diff --git a/src/Views/RevisionCompare.axaml b/src/Views/RevisionCompare.axaml index 46b667ac..73703ff1 100644 --- a/src/Views/RevisionCompare.axaml +++ b/src/Views/RevisionCompare.axaml @@ -99,6 +99,7 @@ diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index 323fde03..dccbb9b2 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -1006,7 +1006,7 @@ namespace SourceGit.Views if (startPosition.Location > endPosition.Location) (startPosition, endPosition) = (endPosition, startPosition); - + var startIdx = Math.Min(startPosition.Line - 1, lines.Count - 1); var endIdx = Math.Min(endPosition.Line - 1, lines.Count - 1); From 4d740f4731432e637ca1bb5f195ce9b307b4e805 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 25 Feb 2025 11:09:12 +0800 Subject: [PATCH 267/865] feature: auto-select the first change when selected stash changed (#1019) Signed-off-by: leo --- src/ViewModels/StashesPage.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ViewModels/StashesPage.cs b/src/ViewModels/StashesPage.cs index 57b30fd3..9e220234 100644 --- a/src/ViewModels/StashesPage.cs +++ b/src/ViewModels/StashesPage.cs @@ -89,7 +89,7 @@ namespace SourceGit.ViewModels private set { if (SetProperty(ref _changes, value)) - SelectedChange = null; + SelectedChange = value is { Count: >0 } ? value[0] : null; } } From a0786bf9cc12f6e1b29078eed8357879e023098d Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 25 Feb 2025 14:37:03 +0800 Subject: [PATCH 268/865] fix: pulling with empty repository (no local branch) crashes this app (#1020) Signed-off-by: leo --- src/ViewModels/Repository.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 104ff60b..85b819c4 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -663,6 +663,12 @@ namespace SourceGit.ViewModels return; } + if (_currentBranch == null) + { + App.RaiseException(_fullpath, "Can NOT found current branch!!!"); + return; + } + var pull = new Pull(this, null); if (autoStart && pull.SelectedBranch != null) ShowAndStartPopup(pull); From 79306ad73bbd2b6f0872cbb32d348a0b105b50e4 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 25 Feb 2025 19:50:09 +0800 Subject: [PATCH 269/865] fix: `ptyxis` does not start with given working directory (#1005) Signed-off-by: leo --- src/Native/Linux.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Native/Linux.cs b/src/Native/Linux.cs index a24f1b65..fec110b2 100644 --- a/src/Native/Linux.cs +++ b/src/Native/Linux.cs @@ -65,13 +65,16 @@ namespace SourceGit.Native { var home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); var cwd = string.IsNullOrEmpty(workdir) ? home : workdir; + var terminal = OS.ShellOrTerminal; var startInfo = new ProcessStartInfo(); startInfo.WorkingDirectory = cwd; - startInfo.FileName = OS.ShellOrTerminal; + startInfo.FileName = terminal; - if (OS.ShellOrTerminal.EndsWith("wezterm", StringComparison.OrdinalIgnoreCase)) + if (terminal.EndsWith("wezterm", StringComparison.OrdinalIgnoreCase)) startInfo.Arguments = $"start --cwd \"{cwd}\""; + else if (terminal.EndsWith("ptyxis", StringComparison.OrdinalIgnoreCase)) + startInfo.Arguments = $"--working-directory=\"{cwd}\""; try { From a7e254cac658ec288de30b490a1eaabbc4a3aa83 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 26 Feb 2025 09:50:54 +0800 Subject: [PATCH 270/865] fix: multiple bindings for `IsVisible` property of Button Signed-off-by: leo --- src/Views/DiffView.axaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Views/DiffView.axaml b/src/Views/DiffView.axaml index fccb949d..3644f8fc 100644 --- a/src/Views/DiffView.axaml +++ b/src/Views/DiffView.axaml @@ -37,7 +37,6 @@ + + - - - + + From b75676a7f8e350e27c9faf34b85e61e20707a589 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 4 Mar 2025 16:04:19 +0800 Subject: [PATCH 299/865] refactor: commit message - move issue tracker and commit hash links parsing to view models - parsing links async - make sure matched hash is a valid commit oid - disable `CHILDREN` row in submodule info panel Signed-off-by: leo --- src/Commands/IsCommitSHA.cs | 17 +++ ...cs => QueryCommitsForInteractiveRebase.cs} | 16 +- src/Models/Commit.cs | 6 +- src/Models/InteractiveRebase.cs | 6 + src/Models/RevisionFile.cs | 2 +- src/ViewModels/CommitDetail.cs | 142 +++++++++++------- src/ViewModels/DiffContext.cs | 8 +- src/ViewModels/FileHistories.cs | 12 +- src/ViewModels/InteractiveRebase.cs | 2 +- src/Views/CommitBaseInfo.axaml | 11 +- src/Views/CommitBaseInfo.axaml.cs | 33 ++-- src/Views/CommitDetail.axaml | 5 +- src/Views/CommitMessagePresenter.cs | 98 +++--------- src/Views/DiffView.axaml | 4 +- src/Views/RevisionFileContentViewer.axaml | 2 +- src/Views/RevisionFiles.axaml | 2 +- src/Views/RevisionFiles.axaml.cs | 11 +- 17 files changed, 191 insertions(+), 186 deletions(-) create mode 100644 src/Commands/IsCommitSHA.cs rename src/Commands/{QueryCommitsWithFullMessage.cs => QueryCommitsForInteractiveRebase.cs} (86%) diff --git a/src/Commands/IsCommitSHA.cs b/src/Commands/IsCommitSHA.cs new file mode 100644 index 00000000..1b0c50e3 --- /dev/null +++ b/src/Commands/IsCommitSHA.cs @@ -0,0 +1,17 @@ +namespace SourceGit.Commands +{ + public class IsCommitSHA : Command + { + public IsCommitSHA(string repo, string hash) + { + WorkingDirectory = repo; + Args = $"cat-file -t {hash}"; + } + + public bool Result() + { + var rs = ReadToEnd(); + return rs.IsSuccess && rs.StdOut.Trim().Equals("commit"); + } + } +} diff --git a/src/Commands/QueryCommitsWithFullMessage.cs b/src/Commands/QueryCommitsForInteractiveRebase.cs similarity index 86% rename from src/Commands/QueryCommitsWithFullMessage.cs rename to src/Commands/QueryCommitsForInteractiveRebase.cs index c15cdbe1..232d86e5 100644 --- a/src/Commands/QueryCommitsWithFullMessage.cs +++ b/src/Commands/QueryCommitsForInteractiveRebase.cs @@ -3,18 +3,18 @@ using System.Collections.Generic; namespace SourceGit.Commands { - public class QueryCommitsWithFullMessage : Command + public class QueryCommitsForInteractiveRebase : Command { - public QueryCommitsWithFullMessage(string repo, string args) + public QueryCommitsForInteractiveRebase(string repo, string on) { _boundary = $"----- BOUNDARY OF COMMIT {Guid.NewGuid()} -----"; WorkingDirectory = repo; Context = repo; - Args = $"log --date-order --no-show-signature --decorate=full --pretty=format:\"%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%B%n{_boundary}\" {args}"; + Args = $"log --date-order --no-show-signature --decorate=full --pretty=format:\"%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%B%n{_boundary}\" {on}..HEAD"; } - public List Result() + public List Result() { var rs = ReadToEnd(); if (!rs.IsSuccess) @@ -29,7 +29,7 @@ namespace SourceGit.Commands switch (nextPartIdx) { case 0: - _current = new Models.CommitWithMessage(); + _current = new Models.InteractiveCommit(); _current.Commit.SHA = line; _commits.Add(_current); break; @@ -52,7 +52,7 @@ namespace SourceGit.Commands _current.Commit.CommitterTime = ulong.Parse(line); break; default: - var boundary = rs.StdOut.IndexOf(_boundary, end + 1); + var boundary = rs.StdOut.IndexOf(_boundary, end + 1, StringComparison.Ordinal); if (boundary > end) { _current.Message = rs.StdOut.Substring(start, boundary - start - 1); @@ -88,8 +88,8 @@ namespace SourceGit.Commands _current.Commit.Parents.AddRange(data.Split(separator: ' ', options: StringSplitOptions.RemoveEmptyEntries)); } - private List _commits = new List(); - private Models.CommitWithMessage _current = null; + private List _commits = []; + private Models.InteractiveCommit _current = null; private string _boundary = ""; } } diff --git a/src/Models/Commit.cs b/src/Models/Commit.cs index f015130a..5c48b0c0 100644 --- a/src/Models/Commit.cs +++ b/src/Models/Commit.cs @@ -112,9 +112,9 @@ namespace SourceGit.Models } } - public class CommitWithMessage + public class CommitFullMessage { - public Commit Commit { get; set; } = new Commit(); - public string Message { get; set; } = ""; + public string Message { get; set; } = string.Empty; + public List Links { get; set; } = []; } } diff --git a/src/Models/InteractiveRebase.cs b/src/Models/InteractiveRebase.cs index 0980587a..691aadeb 100644 --- a/src/Models/InteractiveRebase.cs +++ b/src/Models/InteractiveRebase.cs @@ -12,6 +12,12 @@ namespace SourceGit.Models Drop, } + public class InteractiveCommit + { + public Commit Commit { get; set; } = new Commit(); + public string Message { get; set; } = string.Empty; + } + public class InteractiveRebaseJob { public string SHA { get; set; } = string.Empty; diff --git a/src/Models/RevisionFile.cs b/src/Models/RevisionFile.cs index f1f5265f..8cc1be2a 100644 --- a/src/Models/RevisionFile.cs +++ b/src/Models/RevisionFile.cs @@ -29,6 +29,6 @@ namespace SourceGit.Models public class RevisionSubmodule { public Commit Commit { get; set; } = null; - public string FullMessage { get; set; } = string.Empty; + public CommitFullMessage FullMessage { get; set; } = null; } } diff --git a/src/ViewModels/CommitDetail.cs b/src/ViewModels/CommitDetail.cs index 7c5aa28f..26fa37c1 100644 --- a/src/ViewModels/CommitDetail.cs +++ b/src/ViewModels/CommitDetail.cs @@ -5,7 +5,6 @@ using System.IO; using System.Text.RegularExpressions; using System.Threading.Tasks; -using Avalonia.Collections; using Avalonia.Controls; using Avalonia.Media.Imaging; using Avalonia.Platform.Storage; @@ -46,7 +45,7 @@ namespace SourceGit.ViewModels } } - public string FullMessage + public Models.CommitFullMessage FullMessage { get => _fullMessage; private set => SetProperty(ref _fullMessage, value); @@ -85,11 +84,11 @@ namespace SourceGit.ViewModels } } - public AvaloniaList Children + public List Children { - get; - private set; - } = []; + get => _children; + private set => SetProperty(ref _children, value); + } public string SearchChangeFilter { @@ -109,17 +108,12 @@ namespace SourceGit.ViewModels set => SetProperty(ref _viewRevisionFileContent, value); } - public AvaloniaList WebLinks + public List WebLinks { get; private set; } = []; - public AvaloniaList IssueTrackerRules - { - get => _repo.Settings?.IssueTrackerRules; - } - public string RevisionFileSearchFilter { get => _revisionFileSearchFilter; @@ -127,25 +121,23 @@ namespace SourceGit.ViewModels { if (SetProperty(ref _revisionFileSearchFilter, value)) { - RevisionFileSearchSuggestion.Clear(); - if (!string.IsNullOrEmpty(value)) { - if (_revisionFiles.Count == 0) + if (_revisionFiles == null) { var sha = Commit.SHA; Task.Run(() => { var files = new Commands.QueryRevisionFileNames(_repo.FullPath, sha).Result(); + var filesList = new List(); + filesList.AddRange(files); Dispatcher.UIThread.Invoke(() => { if (sha == Commit.SHA) { - _revisionFiles.Clear(); - _revisionFiles.AddRange(files); - + _revisionFiles = filesList; if (!string.IsNullOrEmpty(_revisionFileSearchFilter)) UpdateRevisionFileSearchSuggestion(); } @@ -159,23 +151,17 @@ namespace SourceGit.ViewModels } else { - IsRevisionFileSearchSuggestionOpen = false; + RevisionFileSearchSuggestion = null; GC.Collect(); } } } } - public AvaloniaList RevisionFileSearchSuggestion + public List RevisionFileSearchSuggestion { - get; - private set; - } = []; - - public bool IsRevisionFileSearchSuggestionOpen - { - get => _isRevisionFileSearchSuggestionOpen; - set => SetProperty(ref _isRevisionFileSearchSuggestionOpen, value); + get => _revisionFileSearchSuggestion; + private set => SetProperty(ref _revisionFileSearchSuggestion, value); } public CommitDetail(Repository repo) @@ -212,23 +198,17 @@ namespace SourceGit.ViewModels { _repo = null; _commit = null; - - if (_changes != null) - _changes.Clear(); - if (_visibleChanges != null) - _visibleChanges.Clear(); - if (_selectedChanges != null) - _selectedChanges.Clear(); - + _changes = null; + _visibleChanges = null; + _selectedChanges = null; _signInfo = null; _searchChangeFilter = null; _diffContext = null; _viewRevisionFileContent = null; _cancelToken = null; - WebLinks.Clear(); - _revisionFiles.Clear(); - RevisionFileSearchSuggestion.Clear(); + _revisionFiles = null; + _revisionFileSearchSuggestion = null; } public void NavigateTo(string commitSHA) @@ -251,6 +231,11 @@ namespace SourceGit.ViewModels RevisionFileSearchFilter = string.Empty; } + public void CancelRevisionFileSuggestions() + { + RevisionFileSearchSuggestion = null; + } + public Models.Commit GetParent(string sha) { return new Commands.QuerySingleCommit(_repo.FullPath, sha).Result(); @@ -322,7 +307,12 @@ namespace SourceGit.ViewModels if (commit != null) { var body = new Commands.QueryCommitFullMessage(submoduleRoot, file.SHA).Result(); - var submodule = new Models.RevisionSubmodule() { Commit = commit, FullMessage = body }; + var submodule = new Models.RevisionSubmodule() + { + Commit = commit, + FullMessage = new Models.CommitFullMessage { Message = body } + }; + Dispatcher.UIThread.Invoke(() => ViewRevisionFileContent = submodule); } else @@ -332,7 +322,7 @@ namespace SourceGit.ViewModels ViewRevisionFileContent = new Models.RevisionSubmodule() { Commit = new Models.Commit() { SHA = file.SHA }, - FullMessage = string.Empty, + FullMessage = null, }; }); } @@ -622,23 +612,22 @@ namespace SourceGit.ViewModels private void Refresh() { _changes = null; - _revisionFiles.Clear(); + _revisionFiles = null; SignInfo = null; ViewRevisionFileContent = null; - Children.Clear(); + Children = null; RevisionFileSearchFilter = string.Empty; - IsRevisionFileSearchSuggestionOpen = false; - - GC.Collect(); + RevisionFileSearchSuggestion = null; if (_commit == null) return; Task.Run(() => { - var fullMessage = new Commands.QueryCommitFullMessage(_repo.FullPath, _commit.SHA).Result(); - Dispatcher.UIThread.Invoke(() => FullMessage = fullMessage); + var message = new Commands.QueryCommitFullMessage(_repo.FullPath, _commit.SHA).Result(); + var links = ParseLinksInMessage(message); + Dispatcher.UIThread.Invoke(() => FullMessage = new Models.CommitFullMessage { Message = message, Links = links }); }); Task.Run(() => @@ -694,6 +683,49 @@ namespace SourceGit.ViewModels }); } + private List ParseLinksInMessage(string message) + { + var links = new List(); + if (_repo.Settings.IssueTrackerRules is { Count: > 0 } rules) + { + foreach (var rule in rules) + rule.Matches(links, message); + } + + var shas = REG_SHA_FORMAT().Matches(message); + for (int i = 0; i < shas.Count; i++) + { + var sha = shas[i]; + if (!sha.Success) + continue; + + var hash = sha.Groups[1].Value; + var test = new Commands.IsCommitSHA(_repo.FullPath, hash).Result(); + if (!test) + continue; + + var start = sha.Index; + var len = sha.Length; + var intersect = false; + foreach (var link in links) + { + if (link.Intersect(start, len)) + { + intersect = true; + break; + } + } + + if (!intersect) + links.Add(new Models.Hyperlink(start, len, hash, true)); + } + + if (links.Count > 0) + links.Sort((l, r) => l.Start - r.Start); + + return links; + } + private void RefreshVisibleChanges() { if (_changes == null) @@ -813,11 +845,12 @@ namespace SourceGit.ViewModels break; } - RevisionFileSearchSuggestion.Clear(); - RevisionFileSearchSuggestion.AddRange(suggestion); - IsRevisionFileSearchSuggestionOpen = suggestion.Count > 0; + RevisionFileSearchSuggestion = suggestion; } + [GeneratedRegex(@"\b([0-9a-fA-F]{6,40})\b")] + private static partial Regex REG_SHA_FORMAT(); + [GeneratedRegex(@"^version https://git-lfs.github.com/spec/v\d+\r?\noid sha256:([0-9a-f]+)\r?\nsize (\d+)[\r\n]*$")] private static partial Regex REG_LFS_FORMAT(); @@ -828,8 +861,9 @@ namespace SourceGit.ViewModels private Repository _repo = null; private Models.Commit _commit = null; - private string _fullMessage = string.Empty; + private Models.CommitFullMessage _fullMessage = null; private Models.CommitSignInfo _signInfo = null; + private List _children = null; private List _changes = null; private List _visibleChanges = null; private List _selectedChanges = null; @@ -837,8 +871,8 @@ namespace SourceGit.ViewModels private DiffContext _diffContext = null; private object _viewRevisionFileContent = null; private Commands.Command.CancelToken _cancelToken = null; - private List _revisionFiles = []; + private List _revisionFiles = null; private string _revisionFileSearchFilter = string.Empty; - private bool _isRevisionFileSearchSuggestionOpen = false; + private List _revisionFileSearchSuggestion = null; } } diff --git a/src/ViewModels/DiffContext.cs b/src/ViewModels/DiffContext.cs index b10f4b62..6dd836bf 100644 --- a/src/ViewModels/DiffContext.cs +++ b/src/ViewModels/DiffContext.cs @@ -235,13 +235,17 @@ namespace SourceGit.ViewModels if (commit != null) { var body = new Commands.QueryCommitFullMessage(repo, sha).Result(); - return new Models.RevisionSubmodule() { Commit = commit, FullMessage = body }; + return new Models.RevisionSubmodule() + { + Commit = commit, + FullMessage = new Models.CommitFullMessage { Message = body } + }; } return new Models.RevisionSubmodule() { Commit = new Models.Commit() { SHA = sha }, - FullMessage = string.Empty, + FullMessage = null, }; } diff --git a/src/ViewModels/FileHistories.cs b/src/ViewModels/FileHistories.cs index 7e248274..417b816d 100644 --- a/src/ViewModels/FileHistories.cs +++ b/src/ViewModels/FileHistories.cs @@ -123,12 +123,20 @@ namespace SourceGit.ViewModels if (commit != null) { var message = new Commands.QueryCommitFullMessage(submoduleRoot, obj.SHA).Result(); - var module = new Models.RevisionSubmodule() { Commit = commit, FullMessage = message }; + var module = new Models.RevisionSubmodule() + { + Commit = commit, + FullMessage = new Models.CommitFullMessage { Message = message } + }; Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, module)); } else { - var module = new Models.RevisionSubmodule() { Commit = new Models.Commit() { SHA = obj.SHA }, FullMessage = "" }; + var module = new Models.RevisionSubmodule() + { + Commit = new Models.Commit() { SHA = obj.SHA }, + FullMessage = null + }; Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, module)); } }); diff --git a/src/ViewModels/InteractiveRebase.cs b/src/ViewModels/InteractiveRebase.cs index 9f28fbc7..2fd2d67c 100644 --- a/src/ViewModels/InteractiveRebase.cs +++ b/src/ViewModels/InteractiveRebase.cs @@ -118,7 +118,7 @@ namespace SourceGit.ViewModels Task.Run(() => { - var commits = new Commands.QueryCommitsWithFullMessage(repoPath, $"{on.SHA}..HEAD").Result(); + var commits = new Commands.QueryCommitsForInteractiveRebase(repoPath, on.SHA).Result(); var list = new List(); foreach (var c in commits) diff --git a/src/Views/CommitBaseInfo.axaml b/src/Views/CommitBaseInfo.axaml index c92a3612..4ff8f20f 100644 --- a/src/Views/CommitBaseInfo.axaml +++ b/src/Views/CommitBaseInfo.axaml @@ -95,8 +95,8 @@ - - + + @@ -133,8 +133,8 @@ - - + + @@ -187,8 +187,7 @@ diff --git a/src/Views/CommitBaseInfo.axaml.cs b/src/Views/CommitBaseInfo.axaml.cs index ce1a7cfd..8767db9f 100644 --- a/src/Views/CommitBaseInfo.axaml.cs +++ b/src/Views/CommitBaseInfo.axaml.cs @@ -1,7 +1,7 @@ +using System.Collections.Generic; using System.Threading.Tasks; using Avalonia; -using Avalonia.Collections; using Avalonia.Controls; using Avalonia.Input; using Avalonia.Interactivity; @@ -11,13 +11,13 @@ namespace SourceGit.Views { public partial class CommitBaseInfo : UserControl { - public static readonly StyledProperty MessageProperty = - AvaloniaProperty.Register(nameof(Message), string.Empty); + public static readonly StyledProperty FullMessageProperty = + AvaloniaProperty.Register(nameof(FullMessage)); - public string Message + public Models.CommitFullMessage FullMessage { - get => GetValue(MessageProperty); - set => SetValue(MessageProperty, value); + get => GetValue(FullMessageProperty); + set => SetValue(FullMessageProperty, value); } public static readonly StyledProperty SignInfoProperty = @@ -38,28 +38,19 @@ namespace SourceGit.Views set => SetValue(SupportsContainsInProperty, value); } - public static readonly StyledProperty> WebLinksProperty = - AvaloniaProperty.Register>(nameof(WebLinks)); + public static readonly StyledProperty> WebLinksProperty = + AvaloniaProperty.Register>(nameof(WebLinks)); - public AvaloniaList WebLinks + public List WebLinks { get => GetValue(WebLinksProperty); set => SetValue(WebLinksProperty, value); } - public static readonly StyledProperty> IssueTrackerRulesProperty = - AvaloniaProperty.Register>(nameof(IssueTrackerRules)); + public static readonly StyledProperty> ChildrenProperty = + AvaloniaProperty.Register>(nameof(Children)); - public AvaloniaList IssueTrackerRules - { - get => GetValue(IssueTrackerRulesProperty); - set => SetValue(IssueTrackerRulesProperty, value); - } - - public static readonly StyledProperty> ChildrenProperty = - AvaloniaProperty.Register>(nameof(Children)); - - public AvaloniaList Children + public List Children { get => GetValue(ChildrenProperty); set => SetValue(ChildrenProperty, value); diff --git a/src/Views/CommitDetail.axaml b/src/Views/CommitDetail.axaml index d0d52473..28b21eb7 100644 --- a/src/Views/CommitDetail.axaml +++ b/src/Views/CommitDetail.axaml @@ -20,12 +20,11 @@ + Children="{Binding Children}"/> diff --git a/src/Views/CommitMessagePresenter.cs b/src/Views/CommitMessagePresenter.cs index dc8a3bb7..002beda1 100644 --- a/src/Views/CommitMessagePresenter.cs +++ b/src/Views/CommitMessagePresenter.cs @@ -1,10 +1,8 @@ using System; using System.Collections.Generic; -using System.Text.RegularExpressions; using System.Threading.Tasks; using Avalonia; -using Avalonia.Collections; using Avalonia.Controls; using Avalonia.Controls.Documents; using Avalonia.Input; @@ -13,27 +11,15 @@ using Avalonia.VisualTree; namespace SourceGit.Views { - public partial class CommitMessagePresenter : SelectableTextBlock + public class CommitMessagePresenter : SelectableTextBlock { - [GeneratedRegex(@"\b([0-9a-fA-F]{6,40})\b")] - private static partial Regex REG_SHA_FORMAT(); + public static readonly StyledProperty FullMessageProperty = + AvaloniaProperty.Register(nameof(FullMessage)); - public static readonly StyledProperty MessageProperty = - AvaloniaProperty.Register(nameof(Message)); - - public string Message + public Models.CommitFullMessage FullMessage { - get => GetValue(MessageProperty); - set => SetValue(MessageProperty, value); - } - - public static readonly StyledProperty> IssueTrackerRulesProperty = - AvaloniaProperty.Register>(nameof(IssueTrackerRules)); - - public AvaloniaList IssueTrackerRules - { - get => GetValue(IssueTrackerRulesProperty); - set => SetValue(IssueTrackerRulesProperty, value); + get => GetValue(FullMessageProperty); + set => SetValue(FullMessageProperty, value); } protected override Type StyleKeyOverride => typeof(SelectableTextBlock); @@ -42,69 +28,36 @@ namespace SourceGit.Views { base.OnPropertyChanged(change); - if (change.Property == MessageProperty || change.Property == IssueTrackerRulesProperty) + if (change.Property == FullMessageProperty) { Inlines!.Clear(); _inlineCommits.Clear(); - _matches = null; _lastHover = null; ClearHoveredIssueLink(); - var message = Message; + var message = FullMessage?.Message; if (string.IsNullOrEmpty(message)) return; - var matches = new List(); - if (IssueTrackerRules is { Count: > 0 } rules) - { - foreach (var rule in rules) - rule.Matches(matches, message); - } - - var shas = REG_SHA_FORMAT().Matches(message); - for (int i = 0; i < shas.Count; i++) - { - var sha = shas[i]; - if (!sha.Success) - continue; - - var start = sha.Index; - var len = sha.Length; - var intersect = false; - foreach (var match in matches) - { - if (match.Intersect(start, len)) - { - intersect = true; - break; - } - } - - if (!intersect) - matches.Add(new Models.Hyperlink(start, len, sha.Groups[1].Value, true)); - } - - if (matches.Count == 0) + var links = FullMessage?.Links; + if (links == null || links.Count == 0) { Inlines.Add(new Run(message)); return; } - matches.Sort((l, r) => l.Start - r.Start); - _matches = matches; - var inlines = new List(); var pos = 0; - foreach (var match in matches) + foreach (var link in links) { - if (match.Start > pos) - inlines.Add(new Run(message.Substring(pos, match.Start - pos))); + if (link.Start > pos) + inlines.Add(new Run(message.Substring(pos, link.Start - pos))); - var link = new Run(message.Substring(match.Start, match.Length)); - link.Classes.Add(match.IsCommitSHA ? "commit_link" : "issue_link"); - inlines.Add(link); + var run = new Run(message.Substring(link.Start, link.Length)); + run.Classes.Add(link.IsCommitSHA ? "commit_link" : "issue_link"); + inlines.Add(run); - pos = match.Start + match.Length; + pos = link.Start + link.Length; } if (pos < message.Length) @@ -134,7 +87,7 @@ namespace SourceGit.Views scrollViewer.LineDown(); } } - else if (_matches != null) + else if (FullMessage is { Links: { Count: > 0 } links }) { var point = e.GetPosition(this) - new Point(Padding.Left, Padding.Top); var x = Math.Min(Math.Max(point.X, 0), Math.Max(TextLayout.WidthIncludingTrailingWhitespace, 0)); @@ -142,25 +95,25 @@ namespace SourceGit.Views point = new Point(x, y); var pos = TextLayout.HitTestPoint(point).TextPosition; - foreach (var match in _matches) + foreach (var link in links) { - if (!match.Intersect(pos, 1)) + if (!link.Intersect(pos, 1)) continue; - if (match == _lastHover) + if (link == _lastHover) return; SetCurrentValue(CursorProperty, Cursor.Parse("Hand")); - _lastHover = match; - if (!match.IsCommitSHA) + _lastHover = link; + if (!link.IsCommitSHA) { - ToolTip.SetTip(this, match.Link); + ToolTip.SetTip(this, link.Link); ToolTip.SetIsOpen(this, true); } else { - ProcessHoverCommitLink(match); + ProcessHoverCommitLink(link); } return; @@ -361,7 +314,6 @@ namespace SourceGit.Views } } - private List _matches = null; private Models.Hyperlink _lastHover = null; private Dictionary _inlineCommits = new(); } diff --git a/src/Views/DiffView.axaml b/src/Views/DiffView.axaml index 3644f8fc..2842715c 100644 --- a/src/Views/DiffView.axaml +++ b/src/Views/DiffView.axaml @@ -257,7 +257,7 @@ - + @@ -271,7 +271,7 @@ - + diff --git a/src/Views/RevisionFileContentViewer.axaml b/src/Views/RevisionFileContentViewer.axaml index de8b3b75..f7599ba0 100644 --- a/src/Views/RevisionFileContentViewer.axaml +++ b/src/Views/RevisionFileContentViewer.axaml @@ -63,7 +63,7 @@ - + diff --git a/src/Views/RevisionFiles.axaml b/src/Views/RevisionFiles.axaml index 3d5cff38..6847b14b 100644 --- a/src/Views/RevisionFiles.axaml +++ b/src/Views/RevisionFiles.axaml @@ -44,7 +44,7 @@ + IsOpen="{Binding RevisionFileSearchSuggestion, Converter={x:Static c:ListConverters.IsNotNullOrEmpty}}"> 0) { SearchSuggestionBox.Focus(NavigationMethod.Tab); SearchSuggestionBox.SelectedIndex = 0; @@ -33,12 +33,7 @@ namespace SourceGit.Views } else if (e.Key == Key.Escape) { - if (vm.IsRevisionFileSearchSuggestionOpen) - { - vm.RevisionFileSearchSuggestion.Clear(); - vm.IsRevisionFileSearchSuggestionOpen = false; - } - + vm.CancelRevisionFileSuggestions(); e.Handled = true; } } @@ -57,7 +52,7 @@ namespace SourceGit.Views if (e.Key == Key.Escape) { - vm.RevisionFileSearchSuggestion.Clear(); + vm.CancelRevisionFileSuggestions(); e.Handled = true; } else if (e.Key == Key.Enter && SearchSuggestionBox.SelectedItem is string content) From 96538b9a6246ceebbb259cbdfd7abc3dc8239132 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 4 Mar 2025 16:26:14 +0800 Subject: [PATCH 300/865] fix: there's an extra line-ending while copy multiple lines from text diff view (#1049) Signed-off-by: leo --- src/Views/TextDiffView.axaml.cs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index 958e803e..30034bc6 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -1032,18 +1032,32 @@ namespace SourceGit.Views line.Type == Models.TextDiffLineType.None) continue; + // The first selected line (partial selection) if (i == startIdx && startPosition.Column > 1) { builder.AppendLine(line.Content.Substring(startPosition.Column - 1)); continue; } - if (i == endIdx && endPosition.Column < line.Content.Length) + // The selection range is larger than original source. + if (i == lines.Count - 1 && i < endIdx) { - builder.AppendLine(line.Content.Substring(0, endPosition.Column - 1)); - continue; + builder.Append(line.Content); + break; } + // For the last line (selection range is within original source) + if (i == endIdx) + { + if (endPosition.Column < line.Content.Length) + builder.Append(line.Content.Substring(0, endPosition.Column - 1)); + else + builder.Append(line.Content); + + break; + } + + // Other lines. builder.AppendLine(line.Content); } From 25e6e261a626898942eeb981f75981caab307ff0 Mon Sep 17 00:00:00 2001 From: GadflyFang Date: Tue, 4 Mar 2025 16:33:43 +0800 Subject: [PATCH 301/865] refactor: Improve key modifier checks and AltGr detection (#1051) --- src/Views/Launcher.axaml.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/Views/Launcher.axaml.cs b/src/Views/Launcher.axaml.cs index e3140191..b8c09b35 100644 --- a/src/Views/Launcher.axaml.cs +++ b/src/Views/Launcher.axaml.cs @@ -112,8 +112,19 @@ namespace SourceGit.Views // We should clear all unhandled key modifiers. _unhandledModifiers = KeyModifiers.None; + // Check for AltGr (which is detected as Ctrl+Alt) + bool isAltGr = e.KeyModifiers.HasFlag(KeyModifiers.Control) && + e.KeyModifiers.HasFlag(KeyModifiers.Alt); + + // Skip hotkey processing if AltGr is pressed + if (isAltGr) + { + base.OnKeyDown(e); + return; + } + // Ctrl+Shift+P opens preference dialog (macOS use hotkeys in system menu bar) - if (!OperatingSystem.IsMacOS() && e.KeyModifiers == (KeyModifiers.Control | KeyModifiers.Shift) && e.Key == Key.P) + if (!OperatingSystem.IsMacOS() && e is { KeyModifiers: (KeyModifiers.Control | KeyModifiers.Shift), Key: Key.P }) { App.OpenDialog(new Preferences()); e.Handled = true; @@ -243,13 +254,13 @@ namespace SourceGit.Views { _unhandledModifiers = e.KeyModifiers; - if (!_unhandledModifiers.HasFlag(KeyModifiers.Alt) && (e.Key == Key.LeftAlt || e.Key == Key.RightAlt)) + if (!_unhandledModifiers.HasFlag(KeyModifiers.Alt) && e.Key is Key.LeftAlt or Key.RightAlt) _unhandledModifiers |= KeyModifiers.Alt; - if (!_unhandledModifiers.HasFlag(KeyModifiers.Control) && (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl)) + if (!_unhandledModifiers.HasFlag(KeyModifiers.Control) && e.Key is Key.LeftCtrl or Key.RightCtrl) _unhandledModifiers |= KeyModifiers.Control; - if (!_unhandledModifiers.HasFlag(KeyModifiers.Shift) && (e.Key == Key.LeftShift || e.Key == Key.RightShift)) + if (!_unhandledModifiers.HasFlag(KeyModifiers.Shift) && e.Key is Key.LeftShift or Key.RightShift) _unhandledModifiers |= KeyModifiers.Shift; } } From 68e96f428e650cf29bde1b27276cf63456fd5530 Mon Sep 17 00:00:00 2001 From: GadflyFang Date: Tue, 4 Mar 2025 16:34:51 +0800 Subject: [PATCH 302/865] fix: validate result not update #1052 (#1053) --- src/ViewModels/Pull.cs | 2 +- src/ViewModels/Push.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ViewModels/Pull.cs b/src/ViewModels/Pull.cs index 755b58f4..ff557792 100644 --- a/src/ViewModels/Pull.cs +++ b/src/ViewModels/Pull.cs @@ -35,7 +35,7 @@ namespace SourceGit.ViewModels public Models.Branch SelectedBranch { get => _selectedBranch; - set => SetProperty(ref _selectedBranch, value); + set => SetProperty(ref _selectedBranch, value, true); } public Models.DealWithLocalChanges PreAction diff --git a/src/ViewModels/Push.cs b/src/ViewModels/Push.cs index 1f18b38e..fb06c76e 100644 --- a/src/ViewModels/Push.cs +++ b/src/ViewModels/Push.cs @@ -18,7 +18,7 @@ namespace SourceGit.ViewModels get => _selectedLocalBranch; set { - if (SetProperty(ref _selectedLocalBranch, value)) + if (SetProperty(ref _selectedLocalBranch, value, true)) AutoSelectBranchByRemote(); } } @@ -39,7 +39,7 @@ namespace SourceGit.ViewModels get => _selectedRemote; set { - if (SetProperty(ref _selectedRemote, value)) + if (SetProperty(ref _selectedRemote, value, true)) AutoSelectBranchByRemote(); } } @@ -56,7 +56,7 @@ namespace SourceGit.ViewModels get => _selectedRemoteBranch; set { - if (SetProperty(ref _selectedRemoteBranch, value)) + if (SetProperty(ref _selectedRemoteBranch, value, true)) IsSetTrackOptionVisible = value != null && _selectedLocalBranch.Upstream != value.FullName; } } From 11af5d9b29ba0f994892e336f13e119fa9c9730b Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 4 Mar 2025 16:42:32 +0800 Subject: [PATCH 303/865] code_style: use `?:` operator instead of `if ... else` statement Signed-off-by: leo --- src/Views/TextDiffView.axaml.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index 30034bc6..93d31668 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -1049,11 +1049,7 @@ namespace SourceGit.Views // For the last line (selection range is within original source) if (i == endIdx) { - if (endPosition.Column < line.Content.Length) - builder.Append(line.Content.Substring(0, endPosition.Column - 1)); - else - builder.Append(line.Content); - + builder.Append(endPosition.Column - 1 < line.Content.Length ? line.Content.Substring(0, endPosition.Column - 1) : line.Content); break; } From 2137ad9ec97c2c8aacb78773af2999a5d7f9d57b Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 4 Mar 2025 17:26:27 +0800 Subject: [PATCH 304/865] enhance: allow to configure editor tab width in preferences window (#1048) Signed-off-by: leo --- src/Resources/Locales/en_US.axaml | 1 + src/Resources/Locales/zh_CN.axaml | 1 + src/Resources/Locales/zh_TW.axaml | 1 + src/ViewModels/Preferences.cs | 7 ++++ src/Views/Blame.axaml | 1 + src/Views/Blame.axaml.cs | 19 +++++++++-- src/Views/Preferences.axaml | 35 ++++++++++++++------ src/Views/RevisionFileContentViewer.axaml | 1 + src/Views/RevisionFileContentViewer.axaml.cs | 26 +++++++++++++-- src/Views/TextDiffView.axaml | 3 ++ src/Views/TextDiffView.axaml.cs | 22 +++++++++--- 11 files changed, 98 insertions(+), 19 deletions(-) diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 5208a269..5df3ca71 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -464,6 +464,7 @@ Enable Streaming APPEARANCE Default Font + Editor Tab Width Font Size Default Editor diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 0e8b9f7d..72b434f9 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -467,6 +467,7 @@ 启用流式输出 外观配置 缺省字体 + 编辑器制表符宽度 字体大小 默认 代码编辑器 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index f4cfad08..bc9991f6 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -467,6 +467,7 @@ 啟用串流輸出 外觀設定 預設字型 + 編輯器制表符寬度 字型大小 預設 程式碼 diff --git a/src/ViewModels/Preferences.cs b/src/ViewModels/Preferences.cs index 5cd7c8a4..016fd4c4 100644 --- a/src/ViewModels/Preferences.cs +++ b/src/ViewModels/Preferences.cs @@ -111,6 +111,12 @@ namespace SourceGit.ViewModels set => SetProperty(ref _editorFontSize, value); } + public int EditorTabWidth + { + get => _editorTabWidth; + set => SetProperty(ref _editorTabWidth, value); + } + public LayoutInfo Layout { get => _layout; @@ -649,6 +655,7 @@ namespace SourceGit.ViewModels private bool _useSystemWindowFrame = false; private double _defaultFontSize = 13; private double _editorFontSize = 13; + private int _editorTabWidth = 4; private LayoutInfo _layout = new LayoutInfo(); private int _maxHistoryCommits = 20000; diff --git a/src/Views/Blame.axaml b/src/Views/Blame.axaml index 1ddb18fb..b700b580 100644 --- a/src/Views/Blame.axaml +++ b/src/Views/Blame.axaml @@ -58,6 +58,7 @@ Foreground="{DynamicResource Brush.FG1}" FontFamily="{DynamicResource Fonts.Monospace}" FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorFontSize}" + TabWidth="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorTabWidth}" BlameData="{Binding Data}"/> diff --git a/src/Views/Blame.axaml.cs b/src/Views/Blame.axaml.cs index 1784efc1..7e273998 100644 --- a/src/Views/Blame.axaml.cs +++ b/src/Views/Blame.axaml.cs @@ -260,6 +260,15 @@ namespace SourceGit.Views set => SetValue(BlameDataProperty, value); } + public static readonly StyledProperty TabWidthProperty = + AvaloniaProperty.Register(nameof(TabWidth), 4); + + public int TabWidth + { + get => GetValue(TabWidthProperty); + set => SetValue(TabWidthProperty, value); + } + protected override Type StyleKeyOverride => typeof(TextEditor); public BlameTextEditor() : base(new TextArea(), new TextDocument()) @@ -268,6 +277,10 @@ namespace SourceGit.Views ShowLineNumbers = false; WordWrap = false; + Options.IndentationSize = TabWidth; + Options.EnableHyperlinks = false; + Options.EnableEmailHyperlinks = false; + _textMate = Models.TextMateHelper.CreateForEditor(this); TextArea.LeftMargins.Add(new LineNumberMargin() { Margin = new Thickness(8, 0) }); @@ -280,8 +293,6 @@ namespace SourceGit.Views TextArea.TextView.ContextRequested += OnTextViewContextRequested; TextArea.TextView.VisualLinesChanged += OnTextViewVisualLinesChanged; TextArea.TextView.Margin = new Thickness(4, 0); - TextArea.TextView.Options.EnableHyperlinks = false; - TextArea.TextView.Options.EnableEmailHyperlinks = false; } public override void Render(DrawingContext context) @@ -350,6 +361,10 @@ namespace SourceGit.Views Text = string.Empty; } } + else if (change.Property == TabWidthProperty) + { + Options.IndentationSize = TabWidth; + } else if (change.Property.Name == "ActualThemeVariant" && change.NewValue != null) { Models.TextMateHelper.SetThemeByApp(_textMate); diff --git a/src/Views/Preferences.axaml b/src/Views/Preferences.axaml index 3bdd150a..12679e50 100644 --- a/src/Views/Preferences.axaml +++ b/src/Views/Preferences.axaml @@ -148,7 +148,7 @@ - + + Minimum="10" Maximum="18" Increment="0.5" + Height="28" + Padding="4" + BorderThickness="1" BorderBrush="{DynamicResource Brush.Border1}" + CornerRadius="3" + Value="{Binding DefaultFontSize, Mode=TwoWay}"> @@ -218,10 +218,23 @@ + + + + + - @@ -232,16 +245,16 @@ - - - diff --git a/src/Views/RevisionFileContentViewer.axaml.cs b/src/Views/RevisionFileContentViewer.axaml.cs index c74f2db2..16f4fc83 100644 --- a/src/Views/RevisionFileContentViewer.axaml.cs +++ b/src/Views/RevisionFileContentViewer.axaml.cs @@ -15,6 +15,15 @@ namespace SourceGit.Views { public class RevisionTextFileView : TextEditor { + public static readonly StyledProperty TabWidthProperty = + AvaloniaProperty.Register(nameof(TabWidth), 4); + + public int TabWidth + { + get => GetValue(TabWidthProperty); + set => SetValue(TabWidthProperty, value); + } + protected override Type StyleKeyOverride => typeof(TextEditor); public RevisionTextFileView() : base(new TextArea(), new TextDocument()) @@ -22,13 +31,16 @@ namespace SourceGit.Views IsReadOnly = true; ShowLineNumbers = true; WordWrap = false; + + Options.IndentationSize = TabWidth; + Options.EnableHyperlinks = false; + Options.EnableEmailHyperlinks = 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) @@ -69,6 +81,16 @@ namespace SourceGit.Views } } + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); + + if (change.Property == TabWidthProperty) + { + Options.IndentationSize = TabWidth; + } + } + private void OnTextViewContextRequested(object sender, ContextRequestedEventArgs e) { var selected = SelectedText; diff --git a/src/Views/TextDiffView.axaml b/src/Views/TextDiffView.axaml index 3ea7af14..7ea6b44b 100644 --- a/src/Views/TextDiffView.axaml +++ b/src/Views/TextDiffView.axaml @@ -27,6 +27,7 @@ IndicatorForeground="{DynamicResource Brush.FG2}" FontFamily="{DynamicResource Fonts.Monospace}" FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorFontSize}" + TabWidth="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorTabWidth}" UseSyntaxHighlighting="{Binding Source={x:Static vm:Preferences.Instance}, Path=UseSyntaxHighlighting}" WordWrap="{Binding Source={x:Static vm:Preferences.Instance}, Path=EnableDiffViewWordWrap}" ShowHiddenSymbols="{Binding Source={x:Static vm:Preferences.Instance}, Path=ShowHiddenSymbolsInDiffView}" @@ -59,6 +60,7 @@ IndicatorForeground="{DynamicResource Brush.FG2}" FontFamily="{DynamicResource Fonts.Monospace}" FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorFontSize}" + TabWidth="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorTabWidth}" UseSyntaxHighlighting="{Binding Source={x:Static vm:Preferences.Instance}, Path=UseSyntaxHighlighting}" WordWrap="False" ShowHiddenSymbols="{Binding Source={x:Static vm:Preferences.Instance}, Path=ShowHiddenSymbolsInDiffView}" @@ -81,6 +83,7 @@ IndicatorForeground="{DynamicResource Brush.FG2}" FontFamily="{DynamicResource Fonts.Monospace}" FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorFontSize}" + TabWidth="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorTabWidth}" UseSyntaxHighlighting="{Binding Source={x:Static vm:Preferences.Instance}, Path=UseSyntaxHighlighting}" WordWrap="False" ShowHiddenSymbols="{Binding Source={x:Static vm:Preferences.Instance}, Path=ShowHiddenSymbolsInDiffView}" diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index 93d31668..630be1b2 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -475,6 +475,15 @@ namespace SourceGit.Views set => SetValue(ShowHiddenSymbolsProperty, value); } + public static readonly StyledProperty TabWidthProperty = + AvaloniaProperty.Register(nameof(TabWidth), 4); + + public int TabWidth + { + get => GetValue(TabWidthProperty); + set => SetValue(TabWidthProperty, value); + } + public static readonly StyledProperty EnableChunkSelectionProperty = AvaloniaProperty.Register(nameof(EnableChunkSelection)); @@ -519,12 +528,13 @@ namespace SourceGit.Views ShowLineNumbers = false; BorderThickness = new Thickness(0); + Options.IndentationSize = TabWidth; + Options.EnableHyperlinks = false; + Options.EnableEmailHyperlinks = false; + _lineStyleTransformer = new LineStyleTransformer(this); TextArea.TextView.Margin = new Thickness(2, 0); - TextArea.TextView.Options.EnableHyperlinks = false; - TextArea.TextView.Options.EnableEmailHyperlinks = false; - TextArea.TextView.BackgroundRenderers.Add(new LineBackgroundRenderer(this)); TextArea.TextView.LineTransformers.Add(_lineStyleTransformer); } @@ -734,10 +744,14 @@ namespace SourceGit.Views } else if (change.Property == ShowHiddenSymbolsProperty) { - var val = change.NewValue is true; + var val = ShowHiddenSymbols; Options.ShowTabs = val; Options.ShowSpaces = val; } + else if (change.Property == TabWidthProperty) + { + Options.IndentationSize = TabWidth; + } else if (change.Property == FileNameProperty) { Models.TextMateHelper.SetGrammarByFileName(_textMate, FileName); From 5af856b9da238d552e8be47fbc002af7efae0742 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 4 Mar 2025 09:26:48 +0000 Subject: [PATCH 305/865] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index dae76783..849407b3 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-99.21%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-99.87%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-91.80%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-%E2%88%9A-brightgreen)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.53%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.07%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) +[![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.08%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-99.74%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-91.68%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-99.87%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.41%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-98.94%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 716ddd3a..8a7bd378 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -1,4 +1,4 @@ -### de_DE.axaml: 99.21% +### de_DE.axaml: 99.08%
@@ -9,21 +9,23 @@ - Text.Diff.First - Text.Diff.Last - Text.Preferences.AI.Streaming +- Text.Preferences.Appearance.EditorTabWidth - Text.StashCM.SaveAsPatch
-### es_ES.axaml: 99.87% +### es_ES.axaml: 99.74%
Missing Keys +- Text.Preferences.Appearance.EditorTabWidth - Text.StashCM.SaveAsPatch
-### fr_FR.axaml: 91.80% +### fr_FR.axaml: 91.68%
@@ -56,6 +58,7 @@ - Text.MergeMultiple.Strategy - Text.MergeMultiple.Targets - Text.Preferences.AI.Streaming +- Text.Preferences.Appearance.EditorTabWidth - Text.Preferences.Appearance.FontSize - Text.Preferences.Appearance.FontSize.Default - Text.Preferences.Appearance.FontSize.Editor @@ -94,17 +97,17 @@
-### it_IT.axaml: 100.00% +### it_IT.axaml: 99.87%
Missing Keys - +- Text.Preferences.Appearance.EditorTabWidth
-### pt_BR.axaml: 91.53% +### pt_BR.axaml: 91.41%
@@ -148,6 +151,7 @@ - Text.MergeMultiple.Strategy - Text.MergeMultiple.Targets - Text.Preferences.AI.Streaming +- Text.Preferences.Appearance.EditorTabWidth - Text.Preferences.General.DateFormat - Text.Preferences.General.ShowChildren - Text.Preferences.Git.SSLVerify @@ -177,7 +181,7 @@
-### ru_RU.axaml: 99.07% +### ru_RU.axaml: 98.94%
@@ -189,6 +193,7 @@ - Text.Diff.First - Text.Diff.Last - Text.Preferences.AI.Streaming +- Text.Preferences.Appearance.EditorTabWidth - Text.StashCM.SaveAsPatch
From e28f8611ef74bf259096b322d6c91531bc4ceeac Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 4 Mar 2025 17:39:07 +0800 Subject: [PATCH 306/865] ux: re-design the layout for `Interactive Rebase` window that tries to fix issue #1037 Signed-off-by: leo --- src/Views/InteractiveRebase.axaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Views/InteractiveRebase.axaml b/src/Views/InteractiveRebase.axaml index f031479b..a4c4dc8e 100644 --- a/src/Views/InteractiveRebase.axaml +++ b/src/Views/InteractiveRebase.axaml @@ -65,6 +65,7 @@ + @@ -77,7 +78,7 @@ - + Date: Tue, 4 Mar 2025 18:02:29 +0800 Subject: [PATCH 307/865] code_style: re-order `CommitDetail` properties Signed-off-by: leo --- src/ViewModels/CommitDetail.cs | 105 +++++++++++++++++---------------- 1 file changed, 54 insertions(+), 51 deletions(-) diff --git a/src/ViewModels/CommitDetail.cs b/src/ViewModels/CommitDetail.cs index 26fa37c1..21931181 100644 --- a/src/ViewModels/CommitDetail.cs +++ b/src/ViewModels/CommitDetail.cs @@ -16,12 +16,6 @@ namespace SourceGit.ViewModels { public partial class CommitDetail : ObservableObject { - public DiffContext DiffContext - { - get => _diffContext; - private set => SetProperty(ref _diffContext, value); - } - public int ActivePageIndex { get => _repo.CommitDetailActivePageIndex; @@ -57,6 +51,18 @@ namespace SourceGit.ViewModels private set => SetProperty(ref _signInfo, value); } + public List WebLinks + { + get; + private set; + } = []; + + public List Children + { + get => _children; + private set => SetProperty(ref _children, value); + } + public List Changes { get => _changes; @@ -84,10 +90,10 @@ namespace SourceGit.ViewModels } } - public List Children + public DiffContext DiffContext { - get => _children; - private set => SetProperty(ref _children, value); + get => _diffContext; + private set => SetProperty(ref _diffContext, value); } public string SearchChangeFilter @@ -108,53 +114,13 @@ namespace SourceGit.ViewModels set => SetProperty(ref _viewRevisionFileContent, value); } - public List WebLinks - { - get; - private set; - } = []; - public string RevisionFileSearchFilter { get => _revisionFileSearchFilter; set { if (SetProperty(ref _revisionFileSearchFilter, value)) - { - if (!string.IsNullOrEmpty(value)) - { - if (_revisionFiles == null) - { - var sha = Commit.SHA; - - Task.Run(() => - { - var files = new Commands.QueryRevisionFileNames(_repo.FullPath, sha).Result(); - var filesList = new List(); - filesList.AddRange(files); - - Dispatcher.UIThread.Invoke(() => - { - if (sha == Commit.SHA) - { - _revisionFiles = filesList; - if (!string.IsNullOrEmpty(_revisionFileSearchFilter)) - UpdateRevisionFileSearchSuggestion(); - } - }); - }); - } - else - { - UpdateRevisionFileSearchSuggestion(); - } - } - else - { - RevisionFileSearchSuggestion = null; - GC.Collect(); - } - } + RefreshRevisionSearchSuggestion(); } } @@ -832,7 +798,44 @@ namespace SourceGit.ViewModels menu.Items.Add(new MenuItem() { Header = "-" }); } - private void UpdateRevisionFileSearchSuggestion() + private void RefreshRevisionSearchSuggestion() + { + if (!string.IsNullOrEmpty(_revisionFileSearchFilter)) + { + if (_revisionFiles == null) + { + var sha = Commit.SHA; + + Task.Run(() => + { + var files = new Commands.QueryRevisionFileNames(_repo.FullPath, sha).Result(); + var filesList = new List(); + filesList.AddRange(files); + + Dispatcher.UIThread.Invoke(() => + { + if (sha == Commit.SHA) + { + _revisionFiles = filesList; + if (!string.IsNullOrEmpty(_revisionFileSearchFilter)) + CalcRevisionFileSearchSuggestion(); + } + }); + }); + } + else + { + CalcRevisionFileSearchSuggestion(); + } + } + else + { + RevisionFileSearchSuggestion = null; + GC.Collect(); + } + } + + private void CalcRevisionFileSearchSuggestion() { var suggestion = new List(); foreach (var file in _revisionFiles) From 792e61b24f8ed6b18dc6d77d7125312baca99a77 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 4 Mar 2025 18:23:13 +0800 Subject: [PATCH 308/865] ux: re-design the layout for `Interactive Rebase` window that tries to fix issue #1037 Signed-off-by: leo --- src/Views/InteractiveRebase.axaml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Views/InteractiveRebase.axaml b/src/Views/InteractiveRebase.axaml index a4c4dc8e..b4499ddc 100644 --- a/src/Views/InteractiveRebase.axaml +++ b/src/Views/InteractiveRebase.axaml @@ -60,7 +60,7 @@ SelectedItem="{Binding SelectedItem, Mode=OneWayToSource}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto"> - + - + - + - + - + - + - - + + - + From 71d0b69eee5d48f0118d0c8bd8029a7bf73497bc Mon Sep 17 00:00:00 2001 From: GadflyFang Date: Tue, 4 Mar 2025 19:51:36 +0800 Subject: [PATCH 309/865] fix: prevent kill apt process by accident (#1054) --- build/resources/deb/DEBIAN/preinst | 8 ++++---- build/resources/deb/DEBIAN/prerm | 9 ++++----- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/build/resources/deb/DEBIAN/preinst b/build/resources/deb/DEBIAN/preinst index edcf9088..a93f8090 100755 --- a/build/resources/deb/DEBIAN/preinst +++ b/build/resources/deb/DEBIAN/preinst @@ -12,10 +12,10 @@ set -e case "$1" in install|upgrade) # Check if SourceGit is running and stop it - if pidof -q sourcegit || pgrep -f sourcegit > /dev/null; then - echo "SourceGit is running, stopping it..." - killall sourcegit 2>/dev/null || pkill -f sourcegit 2>/dev/null || true - # Wait for SourceGit to exit + if pgrep -f '/opt/sourcegit/sourcegit' > /dev/null; then + echo "Stopping running SourceGit instance..." + pkill -f '/opt/sourcegit/sourcegit' || true + # Give the process a moment to terminate sleep 1 fi ;; diff --git a/build/resources/deb/DEBIAN/prerm b/build/resources/deb/DEBIAN/prerm index 8ecd4b8d..c2c9e4f0 100755 --- a/build/resources/deb/DEBIAN/prerm +++ b/build/resources/deb/DEBIAN/prerm @@ -15,11 +15,10 @@ set -e case "$1" in remove|upgrade|deconfigure) - # Check if SourceGit is running and stop it - if pidof -q sourcegit || pgrep -f sourcegit > /dev/null; then - echo "SourceGit is running, stopping it before removal..." - killall sourcegit 2>/dev/null || pkill -f sourcegit 2>/dev/null || true - # Wait for SourceGit to exit + if pgrep -f '/opt/sourcegit/sourcegit' > /dev/null; then + echo "Stopping running SourceGit instance..." + pkill -f '/opt/sourcegit/sourcegit' || true + # Give the process a moment to terminate sleep 1 fi ;; From 5e898a809e0b8171a4349371690f5ce491a486ba Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 5 Mar 2025 09:30:38 +0800 Subject: [PATCH 310/865] enhance: check commit hash after intersect testing Signed-off-by: leo --- src/ViewModels/CommitDetail.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ViewModels/CommitDetail.cs b/src/ViewModels/CommitDetail.cs index 21931181..32827db3 100644 --- a/src/ViewModels/CommitDetail.cs +++ b/src/ViewModels/CommitDetail.cs @@ -665,11 +665,6 @@ namespace SourceGit.ViewModels if (!sha.Success) continue; - var hash = sha.Groups[1].Value; - var test = new Commands.IsCommitSHA(_repo.FullPath, hash).Result(); - if (!test) - continue; - var start = sha.Index; var len = sha.Length; var intersect = false; @@ -682,7 +677,12 @@ namespace SourceGit.ViewModels } } - if (!intersect) + if (intersect) + continue; + + var hash = sha.Groups[1].Value; + var isCommitSHA = new Commands.IsCommitSHA(_repo.FullPath, hash).Result(); + if (isCommitSHA) links.Add(new Models.Hyperlink(start, len, hash, true)); } From 269903503fe77029ec8db1e16121a3b6e830027d Mon Sep 17 00:00:00 2001 From: GadflyFang Date: Wed, 5 Mar 2025 09:36:32 +0800 Subject: [PATCH 311/865] feat: Add commit Tooltip in Blame (#1055) Fixes #993 --- src/ViewModels/Blame.cs | 5 ++++ src/Views/Blame.axaml | 19 ++++++++++++-- src/Views/Blame.axaml.cs | 45 ++++++++++++++++++++++++++------- src/Views/TextDiffView.axaml.cs | 8 +++--- 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/src/ViewModels/Blame.cs b/src/ViewModels/Blame.cs index 253626bc..7ee39550 100644 --- a/src/ViewModels/Blame.cs +++ b/src/ViewModels/Blame.cs @@ -57,6 +57,11 @@ namespace SourceGit.ViewModels } } + public Models.Commit GetCommitInfo(string commitSHA) + { + return new Commands.QuerySingleCommit(_repo, commitSHA).Result(); + } + private readonly string _repo; private Models.BlameData _data = null; } diff --git a/src/Views/Blame.axaml b/src/Views/Blame.axaml index b700b580..4d050bb5 100644 --- a/src/Views/Blame.axaml +++ b/src/Views/Blame.axaml @@ -2,6 +2,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:m="using:SourceGit.Models" xmlns:vm="using:SourceGit.ViewModels" xmlns:v="using:SourceGit.Views" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" @@ -59,8 +60,22 @@ FontFamily="{DynamicResource Fonts.Monospace}" FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorFontSize}" TabWidth="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorTabWidth}" - BlameData="{Binding Data}"/> - + BlameData="{Binding Data}"> + + + + + + + + + + + + + + + + { + var commit = blame.GetCommitInfo(info.CommitSHA); + if (commit == null) + return; + + Dispatcher.UIThread.Invoke(() => + { + if (IsEffectivelyVisible && IsPointerOver) + { + ToolTip.SetTip(this, commit); + ToolTip.SetIsOpen(this, true); + } + }); + }); + } + return; } } - } - Cursor = Cursor.Default; + Cursor = Cursor.Default; + ToolTip.SetIsOpen(this, false); + } } protected override void OnPointerPressed(PointerPressedEventArgs e) @@ -230,9 +257,9 @@ namespace SourceGit.Views private readonly BlameTextEditor _editor = null; } - public class VerticalSeperatorMargin : AbstractMargin + public class VerticalSeparatorMargin : AbstractMargin { - public VerticalSeperatorMargin(BlameTextEditor editor) + public VerticalSeparatorMargin(BlameTextEditor editor) { _editor = editor; } @@ -284,9 +311,9 @@ namespace SourceGit.Views _textMate = Models.TextMateHelper.CreateForEditor(this); TextArea.LeftMargins.Add(new LineNumberMargin() { Margin = new Thickness(8, 0) }); - TextArea.LeftMargins.Add(new VerticalSeperatorMargin(this)); + TextArea.LeftMargins.Add(new VerticalSeparatorMargin(this)); TextArea.LeftMargins.Add(new CommitInfoMargin(this) { Margin = new Thickness(8, 0) }); - TextArea.LeftMargins.Add(new VerticalSeperatorMargin(this)); + TextArea.LeftMargins.Add(new VerticalSeparatorMargin(this)); TextArea.Caret.PositionChanged += OnTextAreaCaretPositionChanged; TextArea.LayoutUpdated += OnTextAreaLayoutUpdated; TextArea.PointerWheelChanged += OnTextAreaPointerWheelChanged; diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index 630be1b2..925c7622 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -60,7 +60,7 @@ namespace SourceGit.Views public class ThemedTextDiffPresenter : TextEditor { - public class VerticalSeperatorMargin : AbstractMargin + public class VerticalSeparatorMargin : AbstractMargin { public override void Render(DrawingContext context) { @@ -1085,9 +1085,9 @@ namespace SourceGit.Views public CombinedTextDiffPresenter() : base(new TextArea(), new TextDocument()) { TextArea.LeftMargins.Add(new LineNumberMargin(false, true)); - TextArea.LeftMargins.Add(new VerticalSeperatorMargin()); + TextArea.LeftMargins.Add(new VerticalSeparatorMargin()); TextArea.LeftMargins.Add(new LineNumberMargin(false, false)); - TextArea.LeftMargins.Add(new VerticalSeperatorMargin()); + TextArea.LeftMargins.Add(new VerticalSeparatorMargin()); TextArea.LeftMargins.Add(new LineModifyTypeMargin()); } @@ -1286,7 +1286,7 @@ namespace SourceGit.Views public SingleSideTextDiffPresenter() : base(new TextArea(), new TextDocument()) { TextArea.LeftMargins.Add(new LineNumberMargin(true, false)); - TextArea.LeftMargins.Add(new VerticalSeperatorMargin()); + TextArea.LeftMargins.Add(new VerticalSeparatorMargin()); TextArea.LeftMargins.Add(new LineModifyTypeMargin()); } From fb8d4a2542063a76cff6d41b8fc2ad02de3afa0c Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 5 Mar 2025 09:54:23 +0800 Subject: [PATCH 312/865] code_review: PR #1055 - since the author and time are already shown in the blame view, use the full message as tooltip is better. - cache the commit message in `ViewModels.Blame` since the `Tooltip` of control may change. - querying commit message synchronously (it's very fast) to avoid similar issues in commit details panel. Signed-off-by: leo --- src/ViewModels/Blame.cs | 13 ++++++++++--- src/Views/Blame.axaml | 17 +---------------- src/Views/Blame.axaml.cs | 30 ++++++------------------------ 3 files changed, 17 insertions(+), 43 deletions(-) diff --git a/src/ViewModels/Blame.cs b/src/ViewModels/Blame.cs index 7ee39550..7cfa8eac 100644 --- a/src/ViewModels/Blame.cs +++ b/src/ViewModels/Blame.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading.Tasks; using Avalonia.Threading; @@ -57,12 +58,18 @@ namespace SourceGit.ViewModels } } - public Models.Commit GetCommitInfo(string commitSHA) + public string GetCommitMessage(string sha) { - return new Commands.QuerySingleCommit(_repo, commitSHA).Result(); + if (_commitMessages.TryGetValue(sha, out var msg)) + return msg; + + msg = new Commands.QueryCommitFullMessage(_repo, sha).Result(); + _commitMessages[sha] = msg; + return msg; } private readonly string _repo; private Models.BlameData _data = null; + private Dictionary _commitMessages = new Dictionary(); } } diff --git a/src/Views/Blame.axaml b/src/Views/Blame.axaml index 4d050bb5..d5c3fd22 100644 --- a/src/Views/Blame.axaml +++ b/src/Views/Blame.axaml @@ -2,7 +2,6 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:m="using:SourceGit.Models" xmlns:vm="using:SourceGit.ViewModels" xmlns:v="using:SourceGit.Views" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" @@ -60,21 +59,7 @@ FontFamily="{DynamicResource Fonts.Monospace}" FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorFontSize}" TabWidth="{Binding Source={x:Static vm:Preferences.Instance}, Path=EditorTabWidth}" - BlameData="{Binding Data}"> - - - - - - - - - - - - - - + BlameData="{Binding Data}"/> - { - var commit = blame.GetCommitInfo(info.CommitSHA); - if (commit == null) - return; - - Dispatcher.UIThread.Invoke(() => - { - if (IsEffectivelyVisible && IsPointerOver) - { - ToolTip.SetTip(this, commit); - ToolTip.SetIsOpen(this, true); - } - }); - }); + var msg = blame.GetCommitMessage(info.CommitSHA); + ToolTip.SetTip(this, msg); + ToolTip.SetIsOpen(this, true); } return; From 991ebe40824f9d42b4fabff69c2a30b1e00e98e9 Mon Sep 17 00:00:00 2001 From: Gadfly Date: Wed, 5 Mar 2025 09:55:55 +0800 Subject: [PATCH 313/865] ci: set ubuntu:20.04 (#1056) --- .github/workflows/build.yml | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d4117364..bcb32580 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,14 +19,25 @@ jobs: os: macos-latest runtime: osx-arm64 - name : Linux - os: ubuntu-20.04 + os: ubuntu-latest runtime: linux-x64 + container: ubuntu:20.04 - name : Linux (arm64) - os: ubuntu-20.04 + os: ubuntu-latest runtime: linux-arm64 + container: ubuntu:20.04 name: Build ${{ matrix.name }} runs-on: ${{ matrix.os }} + container: ${{ matrix.container || '' }} steps: + - name: Install common CLI tools + if: ${{ startsWith(matrix.runtime, 'linux-') }} + run: | + export DEBIAN_FRONTEND=noninteractive + ln -fs /usr/share/zoneinfo/Etc/UTC /etc/localtime + apt-get update + apt-get install -y sudo + sudo apt-get install -y curl wget git unzip zip libicu66 tzdata clang - name: Checkout sources uses: actions/checkout@v4 - name: Setup .NET @@ -47,7 +58,7 @@ jobs: if: ${{ matrix.runtime == 'linux-arm64' }} run: | sudo apt-get update - sudo apt-get install clang llvm gcc-aarch64-linux-gnu zlib1g-dev:arm64 + sudo apt-get install -y llvm gcc-aarch64-linux-gnu zlib1g-dev:arm64 - name: Build run: dotnet build -c Release - name: Publish From 81bbe11345522e6ace161747e294c77c3a6f1a81 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 5 Mar 2025 17:06:45 +0800 Subject: [PATCH 314/865] code_style: rename some variables in `ParseLinksInMessage` Signed-off-by: leo --- src/ViewModels/CommitDetail.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/ViewModels/CommitDetail.cs b/src/ViewModels/CommitDetail.cs index 32827db3..a4f3f595 100644 --- a/src/ViewModels/CommitDetail.cs +++ b/src/ViewModels/CommitDetail.cs @@ -658,15 +658,15 @@ namespace SourceGit.ViewModels rule.Matches(links, message); } - var shas = REG_SHA_FORMAT().Matches(message); - for (int i = 0; i < shas.Count; i++) + var matches = REG_SHA_FORMAT().Matches(message); + for (int i = 0; i < matches.Count; i++) { - var sha = shas[i]; - if (!sha.Success) + var match = matches[i]; + if (!match.Success) continue; - var start = sha.Index; - var len = sha.Length; + var start = match.Index; + var len = match.Length; var intersect = false; foreach (var link in links) { @@ -680,10 +680,10 @@ namespace SourceGit.ViewModels if (intersect) continue; - var hash = sha.Groups[1].Value; - var isCommitSHA = new Commands.IsCommitSHA(_repo.FullPath, hash).Result(); + var sha = match.Groups[1].Value; + var isCommitSHA = new Commands.IsCommitSHA(_repo.FullPath, sha).Result(); if (isCommitSHA) - links.Add(new Models.Hyperlink(start, len, hash, true)); + links.Add(new Models.Hyperlink(start, len, sha, true)); } if (links.Count > 0) From 78c0d8d3344c3315a5a8b022fb893124c703d71a Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 6 Mar 2025 10:37:50 +0800 Subject: [PATCH 315/865] fix: both `--tags` and `--no-tags` are used in `git pull` command Signed-off-by: leo --- src/Commands/Pull.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Commands/Pull.cs b/src/Commands/Pull.cs index a4efa4b6..35a6289a 100644 --- a/src/Commands/Pull.cs +++ b/src/Commands/Pull.cs @@ -11,10 +11,11 @@ namespace SourceGit.Commands Context = repo; TraitErrorAsOutput = true; SSHKey = new Config(repo).Get($"remote.{remote}.sshkey"); - Args = "pull --verbose --progress --tags "; + Args = "pull --verbose --progress "; if (useRebase) - Args += "--rebase "; + Args += "--rebase=true "; + if (noTags) Args += "--no-tags "; From aa0d4b42969271dbc9f42edaadac4d521e09f634 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 6 Mar 2025 11:50:22 +0800 Subject: [PATCH 316/865] ux: adjust column width of commit hash and time after font size changed (#994) Signed-off-by: leo --- src/Views/Histories.axaml | 10 +++++----- src/Views/InteractiveRebase.axaml | 22 +++++++++++++++++++--- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/Views/Histories.axaml b/src/Views/Histories.axaml index 5cde532f..40b2636f 100644 --- a/src/Views/Histories.axaml +++ b/src/Views/Histories.axaml @@ -24,7 +24,7 @@ - + - - + + @@ -121,8 +121,8 @@ - - + + diff --git a/src/Views/InteractiveRebase.axaml b/src/Views/InteractiveRebase.axaml index b4499ddc..1ef2b6cd 100644 --- a/src/Views/InteractiveRebase.axaml +++ b/src/Views/InteractiveRebase.axaml @@ -59,7 +59,8 @@ SelectionMode="Single" SelectedItem="{Binding SelectedItem, Mode=OneWayToSource}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" - ScrollViewer.VerticalScrollBarVisibility="Auto"> + ScrollViewer.VerticalScrollBarVisibility="Auto" + Grid.IsSharedSizeScope="True"> + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + diff --git a/src/Views/Preferences.axaml.cs b/src/Views/Preferences.axaml.cs index 8f9917be..324d2375 100644 --- a/src/Views/Preferences.axaml.cs +++ b/src/Views/Preferences.axaml.cs @@ -103,6 +103,15 @@ namespace SourceGit.Views set => SetValue(SelectedOpenAIServiceProperty, value); } + public static readonly StyledProperty SelectedCustomActionProperty = + AvaloniaProperty.Register(nameof(SelectedCustomAction)); + + public Models.CustomAction SelectedCustomAction + { + get => GetValue(SelectedCustomActionProperty); + set => SetValue(SelectedCustomActionProperty, value); + } + public Preferences() { var pref = ViewModels.Preferences.Instance; @@ -368,6 +377,40 @@ namespace SourceGit.Views e.Handled = true; } + private void OnAddCustomAction(object sender, RoutedEventArgs e) + { + var action = new Models.CustomAction() { Name = "Unnamed Action (Global)" }; + ViewModels.Preferences.Instance.CustomActions.Add(action); + SelectedCustomAction = action; + + e.Handled = true; + } + + private async void SelectExecutableForCustomAction(object sender, RoutedEventArgs e) + { + var options = new FilePickerOpenOptions() + { + FileTypeFilter = [new FilePickerFileType("Executable file(script)") { Patterns = ["*.*"] }], + AllowMultiple = false, + }; + + var selected = await StorageProvider.OpenFilePickerAsync(options); + if (selected.Count == 1 && sender is Button { DataContext: Models.CustomAction action }) + action.Executable = selected[0].Path.LocalPath; + + e.Handled = true; + } + + private void OnRemoveSelectedCustomAction(object sender, RoutedEventArgs e) + { + if (SelectedCustomAction == null) + return; + + ViewModels.Preferences.Instance.CustomActions.Remove(SelectedCustomAction); + SelectedCustomAction = null; + e.Handled = true; + } + private void UpdateGitVersion() { GitVersion = Native.OS.GitVersionString; From cf8cff6b64eb78c96800ce5dbf46e75ebe2e9903 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 10 Mar 2025 21:30:04 +0800 Subject: [PATCH 339/865] code_style: add `ViewModels.Repository.GetCustomAction(scope)` Signed-off-by: leo --- src/ViewModels/Histories.cs | 12 +-------- src/ViewModels/Repository.cs | 47 ++++++++++++++++-------------------- 2 files changed, 22 insertions(+), 37 deletions(-) diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs index 301cbb3c..707e8c43 100644 --- a/src/ViewModels/Histories.cs +++ b/src/ViewModels/Histories.cs @@ -694,17 +694,7 @@ namespace SourceGit.ViewModels menu.Items.Add(archive); menu.Items.Add(new MenuItem() { Header = "-" }); - var actions = new List(); - foreach (var action in Preferences.Instance.CustomActions) - { - if (action.Scope == Models.CustomActionScope.Commit) - actions.Add(action); - } - foreach (var action in _repo.Settings.CustomActions) - { - if (action.Scope == Models.CustomActionScope.Commit) - actions.Add(action); - } + var actions = _repo.GetCustomActions(Models.CustomActionScope.Commit); if (actions.Count > 0) { var custom = new MenuItem(); diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 5d2778c9..96d0b36c 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -943,6 +943,25 @@ namespace SourceGit.ViewModels _workingCopy?.AbortMerge(); } + public List GetCustomActions(Models.CustomActionScope scope) + { + var actions = new List(); + + foreach (var act in Preferences.Instance.CustomActions) + { + if (act.Scope == scope) + actions.Add(act); + } + + foreach (var act in _settings.CustomActions) + { + if (act.Scope == scope) + actions.Add(act); + } + + return actions; + } + public void RefreshBranches() { var branches = new Commands.QueryBranches(_fullpath).Result(); @@ -1443,22 +1462,10 @@ namespace SourceGit.ViewModels public ContextMenu CreateContextMenuForCustomAction() { - var actions = new List(); - foreach (var action in Preferences.Instance.CustomActions) - { - if (action.Scope == Models.CustomActionScope.Repository) - actions.Add(action); - } - - foreach (var action in _settings.CustomActions) - { - if (action.Scope == Models.CustomActionScope.Repository) - actions.Add(action); - } - var menu = new ContextMenu(); menu.Placement = PlacementMode.BottomEdgeAlignedLeft; + var actions = GetCustomActions(Models.CustomActionScope.Repository); if (actions.Count > 0) { foreach (var action in actions) @@ -2355,19 +2362,7 @@ namespace SourceGit.ViewModels private void TryToAddCustomActionsToBranchContextMenu(ContextMenu menu, Models.Branch branch) { - var actions = new List(); - foreach (var action in Preferences.Instance.CustomActions) - { - if (action.Scope == Models.CustomActionScope.Branch) - actions.Add(action); - } - - foreach (var action in Settings.CustomActions) - { - if (action.Scope == Models.CustomActionScope.Branch) - actions.Add(action); - } - + var actions = GetCustomActions(Models.CustomActionScope.Branch); if (actions.Count == 0) return; From f496d15f70a7ae5395170f6289bce511129baeff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B8=D1=85=D0=B0=D0=B8=D0=BB=20=D0=A3=D1=81=D0=BE?= =?UTF-8?q?=D1=86=D0=BA=D0=B8=D0=B9?= Date: Mon, 10 Mar 2025 20:15:29 +0300 Subject: [PATCH 340/865] update russian localization --- src/Resources/Locales/ru_RU.axaml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index b15a769b..ff24912e 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -11,9 +11,9 @@ • Исходный код можно найти по адресу Бесплатный графический клиент Git с исходным кодом Добавить рабочий каталог - Что проверить: - Существующую ветку - Создать новую ветку + Переключиться на: + ветку из списка + создать новую ветку Расположение: Путь к рабочему каталогу (поддерживается относительный путь) Имя ветки: @@ -126,7 +126,7 @@ Сбросить ${0}$ сюда Отменить ревизию Изменить комментарий - Сохранить как patch-файл... + Сохранить как заплатки... Объединить с предыдущей ревизией Объединить все следующие ревизии с этим ИЗМЕНЕНИЯ @@ -167,7 +167,7 @@ Адрес электронной почты Адрес электронной почты GIT - Автоматическая загрузка изменений + Автозагрузка изменений Минут(а/ы) Внешний репозиторий по умолчанию ОТСЛЕЖИВАНИЕ ПРОБЛЕМ @@ -218,15 +218,15 @@ Создать метку... Новая метка у: GPG подпись - Сообщение с меткой: + Сообщение с меткой: Необязательно. Имя метки: Рекомендуемый формат: v1.0.0-alpha Выложить на все внешние репозитории после создания Создать новую метку Вид: - Аннотированный - Лёгкий + С примечаниями + Простой Удерживайте Ctrl, чтобы начать сразу Вырезать Удалить ветку @@ -237,7 +237,7 @@ Вы пытаетесь удалить несколько веток одновременно. Обязательно перепроверьте, прежде чем предпринимать какие-либо действия! Удалить внешний репозиторий Внешний репозиторий: - Path: + Путь: Цель: Все дочерние элементы будут удалены из списка. Подтвердите удаление группы @@ -262,7 +262,7 @@ НИКАКИХ ИЗМЕНЕНИЙ ИЛИ МЕНЯЕТСЯ ТОЛЬКО EOL Предыдущее различие Сохранить как заплатку - Различие бок о бок + Различие рядом ПОДМОДУЛЬ НОВЫЙ Обмен @@ -553,7 +553,7 @@ Редактировать внешний репозиторий Имя: Имя внешнего репозитория - Адрес репозитория: + Адрес: Адрес внешнего репозитория git Копировать адрес Удалить... @@ -693,8 +693,8 @@ Копировать относительный путь Извлечение вложенных подмодулей Открыть подмодуль репозитория - Относительный путь: - Относительный каталог для хранения подмодуля. + Каталог: + Относительный путь для хранения подмодуля. Удалить подмодуль ОК Копировать имя метки From 5f2bd8ad943c3fb5af83d95ec2e1bb0483653b87 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 11 Mar 2025 09:27:32 +0800 Subject: [PATCH 341/865] ux: layout for `Preferences` window Signed-off-by: leo --- src/Views/Preferences.axaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Views/Preferences.axaml b/src/Views/Preferences.axaml index 236deb1f..7bc83b10 100644 --- a/src/Views/Preferences.axaml +++ b/src/Views/Preferences.axaml @@ -422,7 +422,7 @@ - + From 54d49a9edafbec871f4c862011bedbcf21b7e51e Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 11 Mar 2025 09:36:13 +0800 Subject: [PATCH 342/865] fix: app crashes when close a repository on read-only drive (#1080) Signed-off-by: leo --- src/ViewModels/Repository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 96d0b36c..31de381a 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -518,7 +518,7 @@ namespace SourceGit.ViewModels { File.WriteAllText(Path.Combine(_gitDir, "sourcegit.settings"), settingsSerialized); } - catch (DirectoryNotFoundException) + catch { // Ignore } From f23e3478e625362bc23fc428757139e57d270fea Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 11 Mar 2025 11:41:37 +0800 Subject: [PATCH 343/865] fix: do not save preference in design mode Signed-off-by: leo --- src/Views/ConfigureWorkspace.axaml.cs | 4 +++- src/Views/Launcher.axaml.cs | 4 +++- src/Views/Preferences.axaml.cs | 6 +++++- src/Views/RepositoryConfigure.axaml.cs | 4 +++- src/Views/WorkingCopy.axaml.cs | 1 - 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/Views/ConfigureWorkspace.axaml.cs b/src/Views/ConfigureWorkspace.axaml.cs index 012c2e85..9e458f6f 100644 --- a/src/Views/ConfigureWorkspace.axaml.cs +++ b/src/Views/ConfigureWorkspace.axaml.cs @@ -11,8 +11,10 @@ namespace SourceGit.Views protected override void OnClosing(WindowClosingEventArgs e) { - ViewModels.Preferences.Instance.Save(); base.OnClosing(e); + + if (!Design.IsDesignMode) + ViewModels.Preferences.Instance.Save(); } } } diff --git a/src/Views/Launcher.axaml.cs b/src/Views/Launcher.axaml.cs index b8c09b35..9ccec78c 100644 --- a/src/Views/Launcher.axaml.cs +++ b/src/Views/Launcher.axaml.cs @@ -273,8 +273,10 @@ namespace SourceGit.Views protected override void OnClosing(WindowClosingEventArgs e) { - (DataContext as ViewModels.Launcher)?.Quit(Width, Height); base.OnClosing(e); + + if (!Design.IsDesignMode && DataContext is ViewModels.Launcher launcher) + launcher.Quit(Width, Height); } private void OnOpenWorkspaceMenu(object sender, RoutedEventArgs e) diff --git a/src/Views/Preferences.axaml.cs b/src/Views/Preferences.axaml.cs index 324d2375..73b2e995 100644 --- a/src/Views/Preferences.axaml.cs +++ b/src/Views/Preferences.axaml.cs @@ -169,6 +169,11 @@ namespace SourceGit.Views protected override void OnClosing(WindowClosingEventArgs e) { + base.OnClosing(e); + + if (Design.IsDesignMode) + return; + var config = new Commands.Config(null).ListAll(); SetIfChanged(config, "user.name", DefaultUser, ""); SetIfChanged(config, "user.email", DefaultEmail, ""); @@ -199,7 +204,6 @@ namespace SourceGit.Views } ViewModels.Preferences.Instance.Save(); - base.OnClosing(e); } private async void SelectThemeOverrideFile(object _, RoutedEventArgs e) diff --git a/src/Views/RepositoryConfigure.axaml.cs b/src/Views/RepositoryConfigure.axaml.cs index 3faba5ee..455731aa 100644 --- a/src/Views/RepositoryConfigure.axaml.cs +++ b/src/Views/RepositoryConfigure.axaml.cs @@ -13,8 +13,10 @@ namespace SourceGit.Views protected override void OnClosing(WindowClosingEventArgs e) { - (DataContext as ViewModels.RepositoryConfigure)?.Save(); base.OnClosing(e); + + if (!Design.IsDesignMode && DataContext is ViewModels.RepositoryConfigure configure) + configure.Save(); } private async void SelectExecutableForCustomAction(object sender, RoutedEventArgs e) diff --git a/src/Views/WorkingCopy.axaml.cs b/src/Views/WorkingCopy.axaml.cs index dfaad858..4ae4d779 100644 --- a/src/Views/WorkingCopy.axaml.cs +++ b/src/Views/WorkingCopy.axaml.cs @@ -1,7 +1,6 @@ using Avalonia.Controls; using Avalonia.Input; using Avalonia.Interactivity; -using Avalonia.VisualTree; namespace SourceGit.Views { From 471452646b48c58b6bf64a069e777ba6fe0d9afa Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 11 Mar 2025 16:53:51 +0800 Subject: [PATCH 344/865] refactor: use `System.Threading.CancellationToken` instead of `SourceGit.Commands.Command.CancelToken` to cancel fetching information of selected commit Signed-off-by: leo --- src/Commands/Command.cs | 48 ++++++++++++++-------------------- src/ViewModels/CommitDetail.cs | 35 ++++++++++++++----------- 2 files changed, 40 insertions(+), 43 deletions(-) diff --git a/src/Commands/Command.cs b/src/Commands/Command.cs index a3e6673b..cedaf674 100644 --- a/src/Commands/Command.cs +++ b/src/Commands/Command.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Text; using System.Text.RegularExpressions; +using System.Threading; using Avalonia.Threading; @@ -10,11 +11,6 @@ namespace SourceGit.Commands { public partial class Command { - public class CancelToken - { - public bool Requested { get; set; } = false; - } - public class ReadToEndResult { public bool IsSuccess { get; set; } = false; @@ -30,7 +26,7 @@ namespace SourceGit.Commands } public string Context { get; set; } = string.Empty; - public CancelToken Cancel { get; set; } = null; + public CancellationToken CancellationToken { get; set; } = CancellationToken.None; public string WorkingDirectory { get; set; } = null; public EditorType Editor { get; set; } = EditorType.CoreEditor; // Only used in Exec() mode public string SSHKey { get; set; } = string.Empty; @@ -43,36 +39,15 @@ namespace SourceGit.Commands var start = CreateGitStartInfo(); var errs = new List(); var proc = new Process() { StartInfo = start }; - var isCancelled = false; proc.OutputDataReceived += (_, e) => { - if (Cancel != null && Cancel.Requested) - { - isCancelled = true; - proc.CancelErrorRead(); - proc.CancelOutputRead(); - if (!proc.HasExited) - proc.Kill(true); - return; - } - if (e.Data != null) OnReadline(e.Data); }; proc.ErrorDataReceived += (_, e) => { - if (Cancel != null && Cancel.Requested) - { - isCancelled = true; - proc.CancelErrorRead(); - proc.CancelOutputRead(); - if (!proc.HasExited) - proc.Kill(true); - return; - } - if (string.IsNullOrEmpty(e.Data)) { errs.Add(string.Empty); @@ -97,9 +72,25 @@ namespace SourceGit.Commands errs.Add(e.Data); }; + var dummy = null as Process; try { proc.Start(); + + // It not safe, please only use `CancellationToken` in readonly commands. + if (CancellationToken.CanBeCanceled) + { + dummy = proc; + CancellationToken.Register(() => + { + if (dummy is { HasExited: false }) + { + dummy.CancelErrorRead(); + dummy.CancelOutputRead(); + dummy.Kill(); + } + }); + } } catch (Exception e) { @@ -113,10 +104,11 @@ namespace SourceGit.Commands proc.BeginErrorReadLine(); proc.WaitForExit(); + dummy = null; int exitCode = proc.ExitCode; proc.Close(); - if (!isCancelled && exitCode != 0) + if (!CancellationToken.IsCancellationRequested && exitCode != 0) { if (RaiseError) { diff --git a/src/ViewModels/CommitDetail.cs b/src/ViewModels/CommitDetail.cs index 456e99f8..c6ef8367 100644 --- a/src/ViewModels/CommitDetail.cs +++ b/src/ViewModels/CommitDetail.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Text.RegularExpressions; +using System.Threading; using System.Threading.Tasks; using Avalonia.Controls; @@ -171,7 +172,7 @@ namespace SourceGit.ViewModels _searchChangeFilter = null; _diffContext = null; _viewRevisionFileContent = null; - _cancelToken = null; + _cancellationSource = null; WebLinks.Clear(); _revisionFiles = null; _revisionFileSearchSuggestion = null; @@ -589,32 +590,36 @@ namespace SourceGit.ViewModels if (_commit == null) return; + if (_cancellationSource is { IsCancellationRequested: false }) + _cancellationSource.Cancel(); + + _cancellationSource = new CancellationTokenSource(); + var token = _cancellationSource.Token; + Task.Run(() => { var message = new Commands.QueryCommitFullMessage(_repo.FullPath, _commit.SHA).Result(); var links = ParseLinksInMessage(message); - Dispatcher.UIThread.Invoke(() => FullMessage = new Models.CommitFullMessage { Message = message, Links = links }); + + if (!token.IsCancellationRequested) + Dispatcher.UIThread.Invoke(() => FullMessage = new Models.CommitFullMessage { Message = message, Links = links }); }); Task.Run(() => { var signInfo = new Commands.QueryCommitSignInfo(_repo.FullPath, _commit.SHA, !_repo.HasAllowedSignersFile).Result(); - Dispatcher.UIThread.Invoke(() => SignInfo = signInfo); + if (!token.IsCancellationRequested) + Dispatcher.UIThread.Invoke(() => SignInfo = signInfo); }); - if (_cancelToken != null) - _cancelToken.Requested = true; - - _cancelToken = new Commands.Command.CancelToken(); - if (Preferences.Instance.ShowChildren) { Task.Run(() => { var max = Preferences.Instance.MaxHistoryCommits; - var cmdChildren = new Commands.QueryCommitChildren(_repo.FullPath, _commit.SHA, max) { Cancel = _cancelToken }; - var children = cmdChildren.Result(); - if (!cmdChildren.Cancel.Requested) + var cmd = new Commands.QueryCommitChildren(_repo.FullPath, _commit.SHA, max) { CancellationToken = token }; + var children = cmd.Result(); + if (!token.IsCancellationRequested) Dispatcher.UIThread.Post(() => Children = children); }); } @@ -622,8 +627,8 @@ namespace SourceGit.ViewModels Task.Run(() => { var parent = _commit.Parents.Count == 0 ? "4b825dc642cb6eb9a060e54bf8d69288fbee4904" : _commit.Parents[0]; - var cmdChanges = new Commands.CompareRevisions(_repo.FullPath, parent, _commit.SHA) { Cancel = _cancelToken }; - var changes = cmdChanges.Result(); + var cmd = new Commands.CompareRevisions(_repo.FullPath, parent, _commit.SHA) { CancellationToken = token }; + var changes = cmd.Result(); var visible = changes; if (!string.IsNullOrWhiteSpace(_searchChangeFilter)) { @@ -635,7 +640,7 @@ namespace SourceGit.ViewModels } } - if (!cmdChanges.Cancel.Requested) + if (!token.IsCancellationRequested) { Dispatcher.UIThread.Post(() => { @@ -873,7 +878,7 @@ namespace SourceGit.ViewModels private string _searchChangeFilter = string.Empty; private DiffContext _diffContext = null; private object _viewRevisionFileContent = null; - private Commands.Command.CancelToken _cancelToken = null; + private CancellationTokenSource _cancellationSource = null; private List _revisionFiles = null; private string _revisionFileSearchFilter = string.Empty; private List _revisionFileSearchSuggestion = null; From 2fc03025eef98c6641e8045232256691675ce7db Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 11 Mar 2025 19:52:50 +0800 Subject: [PATCH 345/865] fix: file suggestion popup did not show while searching commit by file path Signed-off-by: leo --- src/ViewModels/Repository.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 31de381a..ebf9210e 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -321,7 +321,7 @@ namespace SourceGit.ViewModels set { if (SetProperty(ref _searchCommitFilter, value) && - _searchCommitFilterType == 3 && + _searchCommitFilterType == 4 && !string.IsNullOrEmpty(value) && value.Length >= 2 && _revisionFiles.Count > 0) @@ -2395,14 +2395,14 @@ namespace SourceGit.ViewModels { _revisionFiles.Clear(); - if (_searchCommitFilterType == 3) + if (_searchCommitFilterType == 4) { Task.Run(() => { var files = new Commands.QueryRevisionFileNames(_fullpath, "HEAD").Result(); Dispatcher.UIThread.Invoke(() => { - if (_searchCommitFilterType != 3) + if (_searchCommitFilterType != 4) return; _revisionFiles.AddRange(files); From 91c5c96afc3a070ca8b491a3e992ef5dbcb70d54 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 11 Mar 2025 20:05:05 +0800 Subject: [PATCH 346/865] fix: accessing `dummy` in multi-threads throws exception Signed-off-by: leo --- src/Commands/Command.cs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/Commands/Command.cs b/src/Commands/Command.cs index cedaf674..5197de11 100644 --- a/src/Commands/Command.cs +++ b/src/Commands/Command.cs @@ -73,6 +73,7 @@ namespace SourceGit.Commands }; var dummy = null as Process; + var dummyProcLock = new object(); try { proc.Start(); @@ -83,11 +84,10 @@ namespace SourceGit.Commands dummy = proc; CancellationToken.Register(() => { - if (dummy is { HasExited: false }) + lock (dummyProcLock) { - dummy.CancelErrorRead(); - dummy.CancelOutputRead(); - dummy.Kill(); + if (dummy is { HasExited: false }) + dummy.Kill(); } }); } @@ -104,7 +104,14 @@ namespace SourceGit.Commands proc.BeginErrorReadLine(); proc.WaitForExit(); - dummy = null; + if (dummy != null) + { + lock (dummyProcLock) + { + dummy = null; + } + } + int exitCode = proc.ExitCode; proc.Close(); From fa4d9d24e9ab5f1dfd8bf8f75fadddd8b903a23c Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 11 Mar 2025 20:22:32 +0800 Subject: [PATCH 347/865] enhance: hide suggestion popups when window is deactived (#963) Signed-off-by: leo --- src/Views/Repository.axaml | 10 ++++++++-- src/Views/RevisionFiles.axaml | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/Views/Repository.axaml b/src/Views/Repository.axaml index 30180f7d..bfa5a5e1 100644 --- a/src/Views/Repository.axaml +++ b/src/Views/Repository.axaml @@ -421,8 +421,14 @@ + HorizontalOffset="-8" VerticalAlignment="-8"> + + + + + + + + HorizontalOffset="-8" VerticalAlignment="-8"> + + + + + + + Date: Tue, 11 Mar 2025 20:55:39 +0800 Subject: [PATCH 348/865] refactor: rewrite searching commit by file path Signed-off-by: leo --- src/ViewModels/Repository.cs | 112 +++++++++++++++------------------- src/Views/Repository.axaml | 4 +- src/Views/Repository.axaml.cs | 13 +--- 3 files changed, 53 insertions(+), 76 deletions(-) diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index ebf9210e..9e10390a 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -271,14 +271,13 @@ namespace SourceGit.ViewModels { SearchedCommits = new List(); SearchCommitFilter = string.Empty; - SearchCommitFilterSuggestion.Clear(); - IsSearchCommitSuggestionOpen = false; - _revisionFiles.Clear(); + MatchedFilesForSearching = null; + _worktreeFiles = null; if (value) { SelectedViewIndex = 0; - UpdateCurrentRevisionFilesForSearchSuggestion(); + CalcWorktreeFilesForSearching(); } } } @@ -307,7 +306,7 @@ namespace SourceGit.ViewModels { if (SetProperty(ref _searchCommitFilterType, value)) { - UpdateCurrentRevisionFilesForSearchSuggestion(); + CalcWorktreeFilesForSearching(); if (!string.IsNullOrEmpty(_searchCommitFilter)) StartSearchCommits(); @@ -320,47 +319,22 @@ namespace SourceGit.ViewModels get => _searchCommitFilter; set { - if (SetProperty(ref _searchCommitFilter, value) && - _searchCommitFilterType == 4 && - !string.IsNullOrEmpty(value) && - value.Length >= 2 && - _revisionFiles.Count > 0) + if (SetProperty(ref _searchCommitFilter, value)) { - var suggestion = new List(); - foreach (var file in _revisionFiles) - { - if (file.Contains(value, StringComparison.OrdinalIgnoreCase) && file.Length != value.Length) - { - suggestion.Add(file); - if (suggestion.Count > 100) - break; - } - } - - SearchCommitFilterSuggestion.Clear(); - SearchCommitFilterSuggestion.AddRange(suggestion); - IsSearchCommitSuggestionOpen = SearchCommitFilterSuggestion.Count > 0; - } - else if (SearchCommitFilterSuggestion.Count > 0) - { - SearchCommitFilterSuggestion.Clear(); - IsSearchCommitSuggestionOpen = false; + if (_searchCommitFilterType == 4 && value is { Length: > 2 }) + CalcMatchedFilesForSearching(); + else if (_matchedFilesForSearching is { }) + MatchedFilesForSearching = null; } } } - public bool IsSearchCommitSuggestionOpen + public List MatchedFilesForSearching { - get => _isSearchCommitSuggestionOpen; - set => SetProperty(ref _isSearchCommitSuggestionOpen, value); + get => _matchedFilesForSearching; + private set => SetProperty(ref _matchedFilesForSearching, value); } - public AvaloniaList SearchCommitFilterSuggestion - { - get; - private set; - } = new AvaloniaList(); - public List SearchedCommits { get => _searchedCommits; @@ -551,8 +525,8 @@ namespace SourceGit.ViewModels _visibleSubmodules.Clear(); _searchedCommits.Clear(); - _revisionFiles.Clear(); - SearchCommitFilterSuggestion.Clear(); + _worktreeFiles = null; + _matchedFilesForSearching = null; } public bool CanCreatePopup() @@ -723,6 +697,11 @@ namespace SourceGit.ViewModels SearchCommitFilter = string.Empty; } + public void ClearMatchedFilesForSearching() + { + MatchedFilesForSearching = null; + } + public void StartSearchCommits() { if (_histories == null) @@ -730,8 +709,7 @@ namespace SourceGit.ViewModels IsSearchLoadingVisible = true; SearchResultSelectedCommit = null; - IsSearchCommitSuggestionOpen = false; - SearchCommitFilterSuggestion.Clear(); + MatchedFilesForSearching = null; Task.Run(() => { @@ -2391,9 +2369,9 @@ namespace SourceGit.ViewModels menu.Items.Add(new MenuItem() { Header = "-" }); } - private void UpdateCurrentRevisionFilesForSearchSuggestion() + private void CalcWorktreeFilesForSearching() { - _revisionFiles.Clear(); + _worktreeFiles = null; if (_searchCommitFilterType == 4) { @@ -2405,30 +2383,36 @@ namespace SourceGit.ViewModels if (_searchCommitFilterType != 4) return; - _revisionFiles.AddRange(files); + _worktreeFiles = new List(); + foreach (var f in files) + _worktreeFiles.Add(f); - if (!string.IsNullOrEmpty(_searchCommitFilter) && _searchCommitFilter.Length > 2 && _revisionFiles.Count > 0) - { - var suggestion = new List(); - foreach (var file in _revisionFiles) - { - if (file.Contains(_searchCommitFilter, StringComparison.OrdinalIgnoreCase) && file.Length != _searchCommitFilter.Length) - { - suggestion.Add(file); - if (suggestion.Count > 100) - break; - } - } - - SearchCommitFilterSuggestion.Clear(); - SearchCommitFilterSuggestion.AddRange(suggestion); - IsSearchCommitSuggestionOpen = SearchCommitFilterSuggestion.Count > 0; - } + if (_searchCommitFilter is { Length: > 2 }) + CalcMatchedFilesForSearching(); }); }); } } + private void CalcMatchedFilesForSearching() + { + if (_worktreeFiles == null || _worktreeFiles.Count == 0) + return; + + var matched = new List(); + foreach (var file in _worktreeFiles) + { + if (file.Contains(_searchCommitFilter, StringComparison.OrdinalIgnoreCase) && file.Length != _searchCommitFilter.Length) + { + matched.Add(file); + if (matched.Count > 100) + break; + } + } + + MatchedFilesForSearching = matched; + } + private void AutoFetchImpl(object sender) { if (!_settings.EnableAutoFetch || _isAutoFetching) @@ -2475,13 +2459,13 @@ namespace SourceGit.ViewModels private bool _isSearching = false; private bool _isSearchLoadingVisible = false; - private bool _isSearchCommitSuggestionOpen = false; private int _searchCommitFilterType = 3; private bool _onlySearchCommitsInCurrentBranch = false; private string _searchCommitFilter = string.Empty; private List _searchedCommits = new List(); private Models.Commit _searchResultSelectedCommit = null; - private List _revisionFiles = new List(); + private List _worktreeFiles = null; + private List _matchedFilesForSearching = null; private string _filter = string.Empty; private object _lockRemotes = new object(); diff --git a/src/Views/Repository.axaml b/src/Views/Repository.axaml index bfa5a5e1..9caac015 100644 --- a/src/Views/Repository.axaml +++ b/src/Views/Repository.axaml @@ -424,7 +424,7 @@ HorizontalOffset="-8" VerticalAlignment="-8"> - + @@ -434,7 +434,7 @@ diff --git a/src/Views/Repository.axaml.cs b/src/Views/Repository.axaml.cs index 2b3b7c30..00218a85 100644 --- a/src/Views/Repository.axaml.cs +++ b/src/Views/Repository.axaml.cs @@ -134,7 +134,7 @@ namespace SourceGit.Views } else if (e.Key == Key.Down) { - if (repo.IsSearchCommitSuggestionOpen) + if (repo.MatchedFilesForSearching is { Count: > 0 }) { SearchSuggestionBox.Focus(NavigationMethod.Tab); SearchSuggestionBox.SelectedIndex = 0; @@ -144,12 +144,7 @@ namespace SourceGit.Views } else if (e.Key == Key.Escape) { - if (repo.IsSearchCommitSuggestionOpen) - { - repo.SearchCommitFilterSuggestion.Clear(); - repo.IsSearchCommitSuggestionOpen = false; - } - + repo.ClearMatchedFilesForSearching(); e.Handled = true; } } @@ -369,9 +364,7 @@ namespace SourceGit.Views if (e.Key == Key.Escape) { - repo.IsSearchCommitSuggestionOpen = false; - repo.SearchCommitFilterSuggestion.Clear(); - + repo.ClearMatchedFilesForSearching(); e.Handled = true; } else if (e.Key == Key.Enter && SearchSuggestionBox.SelectedItem is string content) From f5d6e1264d6e587c3ac6b90a9df3e0df30650f9e Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 11 Mar 2025 23:01:34 +0800 Subject: [PATCH 349/865] refactor: use `List` instead of `AvaloniaList` since it is not used for bindings Signed-off-by: leo --- src/ViewModels/Repository.cs | 10 ++++++---- src/ViewModels/WorkingCopy.cs | 32 ++++++++++++++------------------ 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 9e10390a..59ab6a1b 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -6,7 +6,6 @@ using System.Text.Json; using System.Threading; using System.Threading.Tasks; -using Avalonia.Collections; using Avalonia.Controls; using Avalonia.Media; using Avalonia.Media.Imaging; @@ -1221,23 +1220,26 @@ namespace SourceGit.ViewModels App.GetLauncer()?.OpenRepositoryInTab(node, null); } - public AvaloniaList GetPreferedOpenAIServices() + public List GetPreferedOpenAIServices() { var services = Preferences.Instance.OpenAIServices; if (services == null || services.Count == 0) return []; if (services.Count == 1) - return services; + return [services[0]]; var prefered = _settings.PreferedOpenAIService; + var all = new List(); foreach (var service in services) { if (service.Name.Equals(prefered, StringComparison.Ordinal)) return [service]; + + all.Add(service); } - return services; + return all; } public ContextMenu CreateContextMenuForGitFlow() diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 35db11b9..f9ddb288 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -1452,28 +1452,24 @@ namespace SourceGit.ViewModels App.OpenDialog(dialog); return null; } - else + + var menu = new ContextMenu() { Placement = PlacementMode.TopEdgeAlignedLeft }; + foreach (var service in services) { - var menu = new ContextMenu() { Placement = PlacementMode.TopEdgeAlignedLeft }; - - foreach (var service in services) + var dup = service; + var item = new MenuItem(); + item.Header = service.Name; + item.Click += (_, e) => { - var dup = service; + var dialog = new Views.AIAssistant(dup, _repo.FullPath, this, _staged); + App.OpenDialog(dialog); + e.Handled = true; + }; - var item = new MenuItem(); - item.Header = service.Name; - item.Click += (_, e) => - { - var dialog = new Views.AIAssistant(dup, _repo.FullPath, this, _staged); - App.OpenDialog(dialog); - e.Handled = true; - }; - - menu.Items.Add(item); - } - - return menu; + menu.Items.Add(item); } + + return menu; } private List GetVisibleUnstagedChanges(List unstaged) From 231f3bf6688485be75a5295f5307e115889e5296 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 12 Mar 2025 10:11:00 +0800 Subject: [PATCH 350/865] enhance: use `--ancestry-path=` to reduce unnecessary outpus while querying children commits Signed-off-by: leo --- src/Commands/QueryCommitChildren.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Commands/QueryCommitChildren.cs b/src/Commands/QueryCommitChildren.cs index d1bced52..6a6ed909 100644 --- a/src/Commands/QueryCommitChildren.cs +++ b/src/Commands/QueryCommitChildren.cs @@ -9,7 +9,7 @@ namespace SourceGit.Commands WorkingDirectory = repo; Context = repo; _commit = commit; - Args = $"rev-list -{max} --parents --branches --remotes ^{commit}"; + Args = $"rev-list -{max} --parents --branches --remotes --ancestry-path={commit} ^{commit}"; } public List Result() From ee7ccc0391ee5e7e03f5f8d9cf496804170cda4a Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 12 Mar 2025 11:05:19 +0800 Subject: [PATCH 351/865] refactor: re-write commit searching (part 2) Signed-off-by: leo --- src/Models/Commit.cs | 1 + src/ViewModels/Histories.cs | 12 ++-- src/ViewModels/Repository.cs | 132 +++++++++++++++++------------------ src/Views/Repository.axaml | 2 +- 4 files changed, 73 insertions(+), 74 deletions(-) diff --git a/src/Models/Commit.cs b/src/Models/Commit.cs index 5c48b0c0..72ce54bd 100644 --- a/src/Models/Commit.cs +++ b/src/Models/Commit.cs @@ -8,6 +8,7 @@ namespace SourceGit.Models { public enum CommitSearchMethod { + BySHA = 0, ByAuthor, ByCommitter, ByMessage, diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs index 707e8c43..0e67915c 100644 --- a/src/ViewModels/Histories.cs +++ b/src/ViewModels/Histories.cs @@ -148,14 +148,14 @@ namespace SourceGit.ViewModels { if (commits.Count == 0) { - _repo.SearchResultSelectedCommit = null; + _repo.SelectedSearchedCommit = null; DetailContext = null; } else if (commits.Count == 1) { var commit = (commits[0] as Models.Commit)!; - if (_repo.SearchResultSelectedCommit == null || _repo.SearchResultSelectedCommit.SHA != commit.SHA) - _repo.SearchResultSelectedCommit = _repo.SearchedCommits.Find(x => x.SHA == commit.SHA); + if (_repo.SelectedSearchedCommit == null || _repo.SelectedSearchedCommit.SHA != commit.SHA) + _repo.SelectedSearchedCommit = _repo.SearchedCommits.Find(x => x.SHA == commit.SHA); AutoSelectedCommit = commit; NavigationId = _navigationId + 1; @@ -173,7 +173,7 @@ namespace SourceGit.ViewModels } else if (commits.Count == 2) { - _repo.SearchResultSelectedCommit = null; + _repo.SelectedSearchedCommit = null; var end = commits[0] as Models.Commit; var start = commits[1] as Models.Commit; @@ -181,7 +181,7 @@ namespace SourceGit.ViewModels } else { - _repo.SearchResultSelectedCommit = null; + _repo.SelectedSearchedCommit = null; DetailContext = commits.Count; } } @@ -599,7 +599,7 @@ namespace SourceGit.ViewModels var head = _commits.Find(x => x.SHA == current.Head); if (head == null) { - _repo.SearchResultSelectedCommit = null; + _repo.SelectedSearchedCommit = null; head = new Commands.QuerySingleCommit(_repo.FullPath, current.Head).Result(); if (head != null) DetailContext = new RevisionCompare(_repo.FullPath, commit, head); diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 59ab6a1b..c7557356 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -268,16 +268,19 @@ namespace SourceGit.ViewModels { if (SetProperty(ref _isSearching, value)) { - SearchedCommits = new List(); - SearchCommitFilter = string.Empty; - MatchedFilesForSearching = null; - _worktreeFiles = null; - if (value) { SelectedViewIndex = 0; CalcWorktreeFilesForSearching(); } + else + { + SearchedCommits = new List(); + SelectedSearchedCommit = null; + SearchCommitFilter = string.Empty; + MatchedFilesForSearching = null; + _worktreeFiles = null; + } } } } @@ -306,7 +309,6 @@ namespace SourceGit.ViewModels if (SetProperty(ref _searchCommitFilterType, value)) { CalcWorktreeFilesForSearching(); - if (!string.IsNullOrEmpty(_searchCommitFilter)) StartSearchCommits(); } @@ -318,13 +320,8 @@ namespace SourceGit.ViewModels get => _searchCommitFilter; set { - if (SetProperty(ref _searchCommitFilter, value)) - { - if (_searchCommitFilterType == 4 && value is { Length: > 2 }) - CalcMatchedFilesForSearching(); - else if (_matchedFilesForSearching is { }) - MatchedFilesForSearching = null; - } + if (SetProperty(ref _searchCommitFilter, value) && IsSearchingCommitsByFilePath()) + CalcMatchedFilesForSearching(); } } @@ -340,6 +337,16 @@ namespace SourceGit.ViewModels set => SetProperty(ref _searchedCommits, value); } + public Models.Commit SelectedSearchedCommit + { + get => _selectedSearchedCommit; + set + { + if (SetProperty(ref _selectedSearchedCommit, value) && value != null) + NavigateToCommit(value.SHA); + } + } + public bool IsLocalBranchGroupExpanded { get => _settings.IsLocalBranchesExpandedInSideBar; @@ -410,16 +417,6 @@ namespace SourceGit.ViewModels get => _workingCopy?.InProgressContext; } - public Models.Commit SearchResultSelectedCommit - { - get => _searchResultSelectedCommit; - set - { - if (SetProperty(ref _searchResultSelectedCommit, value) && value != null) - NavigateToCommit(value.SHA); - } - } - public bool IsAutoFetching { get => _isAutoFetching; @@ -523,6 +520,7 @@ namespace SourceGit.ViewModels _submodules.Clear(); _visibleSubmodules.Clear(); _searchedCommits.Clear(); + _selectedSearchedCommit = null; _worktreeFiles = null; _matchedFilesForSearching = null; @@ -707,32 +705,22 @@ namespace SourceGit.ViewModels return; IsSearchLoadingVisible = true; - SearchResultSelectedCommit = null; + SelectedSearchedCommit = null; MatchedFilesForSearching = null; Task.Run(() => { - var visible = new List(); + var visible = null as List; + var method = (Models.CommitSearchMethod)_searchCommitFilterType; - switch (_searchCommitFilterType) + if (method == Models.CommitSearchMethod.BySHA) { - case 0: - var commit = new Commands.QuerySingleCommit(_fullpath, _searchCommitFilter).Result(); - if (commit != null) - visible.Add(commit); - break; - case 1: - visible = new Commands.QueryCommits(_fullpath, _searchCommitFilter, Models.CommitSearchMethod.ByAuthor, _onlySearchCommitsInCurrentBranch).Result(); - break; - case 2: - 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; + var commit = new Commands.QuerySingleCommit(_fullpath, _searchCommitFilter).Result(); + visible = commit == null ? [] : [commit]; + } + else + { + visible = new Commands.QueryCommits(_fullpath, _searchCommitFilter, method, _onlySearchCommitsInCurrentBranch).Result(); } Dispatcher.UIThread.Invoke(() => @@ -1636,7 +1624,7 @@ namespace SourceGit.ViewModels compareWithWorktree.Icon = App.CreateMenuIcon("Icons.Compare"); compareWithWorktree.Click += (_, _) => { - SearchResultSelectedCommit = null; + SelectedSearchedCommit = null; if (_histories != null) { @@ -1918,7 +1906,7 @@ namespace SourceGit.ViewModels compareWithWorktree.Icon = App.CreateMenuIcon("Icons.Compare"); compareWithWorktree.Click += (_, _) => { - SearchResultSelectedCommit = null; + SelectedSearchedCommit = null; if (_histories != null) { @@ -2371,35 +2359,45 @@ namespace SourceGit.ViewModels menu.Items.Add(new MenuItem() { Header = "-" }); } + private bool IsSearchingCommitsByFilePath() + { + return _isSearching && _searchCommitFilterType == (int)Models.CommitSearchMethod.ByFile; + } + private void CalcWorktreeFilesForSearching() { - _worktreeFiles = null; - - if (_searchCommitFilterType == 4) + if (!IsSearchingCommitsByFilePath()) { - Task.Run(() => - { - var files = new Commands.QueryRevisionFileNames(_fullpath, "HEAD").Result(); - Dispatcher.UIThread.Invoke(() => - { - if (_searchCommitFilterType != 4) - return; - - _worktreeFiles = new List(); - foreach (var f in files) - _worktreeFiles.Add(f); - - if (_searchCommitFilter is { Length: > 2 }) - CalcMatchedFilesForSearching(); - }); - }); + _worktreeFiles = null; + MatchedFilesForSearching = null; + GC.Collect(); + return; } + + Task.Run(() => + { + var files = new Commands.QueryRevisionFileNames(_fullpath, "HEAD").Result(); + Dispatcher.UIThread.Invoke(() => + { + if (!IsSearchingCommitsByFilePath()) + return; + + _worktreeFiles = new List(); + foreach (var f in files) + _worktreeFiles.Add(f); + + CalcMatchedFilesForSearching(); + }); + }); } private void CalcMatchedFilesForSearching() { - if (_worktreeFiles == null || _worktreeFiles.Count == 0) + if (_worktreeFiles == null || _worktreeFiles.Count == 0 || _searchCommitFilter.Length < 3) + { + MatchedFilesForSearching = null; return; + } var matched = new List(); foreach (var file in _worktreeFiles) @@ -2461,11 +2459,11 @@ namespace SourceGit.ViewModels private bool _isSearching = false; private bool _isSearchLoadingVisible = false; - private int _searchCommitFilterType = 3; + private int _searchCommitFilterType = (int)Models.CommitSearchMethod.ByMessage; private bool _onlySearchCommitsInCurrentBranch = false; private string _searchCommitFilter = string.Empty; private List _searchedCommits = new List(); - private Models.Commit _searchResultSelectedCommit = null; + private Models.Commit _selectedSearchedCommit = null; private List _worktreeFiles = null; private List _matchedFilesForSearching = null; diff --git a/src/Views/Repository.axaml b/src/Views/Repository.axaml index 9caac015..1d94e9b2 100644 --- a/src/Views/Repository.axaml +++ b/src/Views/Repository.axaml @@ -504,7 +504,7 @@ Margin="0,8,0,0" ItemsSource="{Binding SearchedCommits}" SelectionMode="Single" - SelectedItem="{Binding SearchResultSelectedCommit, Mode=TwoWay}" + SelectedItem="{Binding SelectedSearchedCommit, Mode=TwoWay}" BorderThickness="1" BorderBrush="{DynamicResource Brush.Border2}" Background="{DynamicResource Brush.Contents}" From bb2284c4c91d4c95ddbc3bb0d5c0d3c951b2e756 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 12 Mar 2025 11:53:24 +0800 Subject: [PATCH 352/865] refactor: re-write commit searching (part 3) Signed-off-by: leo --- src/Commands/QueryRevisionFileNames.cs | 16 +++++++++++----- src/ViewModels/CommitDetail.cs | 5 +---- src/ViewModels/Repository.cs | 12 +++--------- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/Commands/QueryRevisionFileNames.cs b/src/Commands/QueryRevisionFileNames.cs index d2d69614..c6fd7373 100644 --- a/src/Commands/QueryRevisionFileNames.cs +++ b/src/Commands/QueryRevisionFileNames.cs @@ -1,4 +1,6 @@ -namespace SourceGit.Commands +using System.Collections.Generic; + +namespace SourceGit.Commands { public class QueryRevisionFileNames : Command { @@ -9,13 +11,17 @@ Args = $"ls-tree -r -z --name-only {revision}"; } - public string[] Result() + public List Result() { var rs = ReadToEnd(); - if (rs.IsSuccess) - return rs.StdOut.Split('\0', System.StringSplitOptions.RemoveEmptyEntries); + if (!rs.IsSuccess) + return []; - return []; + var lines = rs.StdOut.Split('\0', System.StringSplitOptions.RemoveEmptyEntries); + var outs = new List(); + foreach (var line in lines) + outs.Add(line); + return outs; } } } diff --git a/src/ViewModels/CommitDetail.cs b/src/ViewModels/CommitDetail.cs index c6ef8367..34ac8308 100644 --- a/src/ViewModels/CommitDetail.cs +++ b/src/ViewModels/CommitDetail.cs @@ -814,14 +814,11 @@ namespace SourceGit.ViewModels Task.Run(() => { var files = new Commands.QueryRevisionFileNames(_repo.FullPath, sha).Result(); - var filesList = new List(); - filesList.AddRange(files); - Dispatcher.UIThread.Invoke(() => { if (sha == Commit.SHA) { - _revisionFiles = filesList; + _revisionFiles = files; if (!string.IsNullOrEmpty(_revisionFileSearchFilter)) CalcRevisionFileSearchSuggestion(); } diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index c7557356..97c52d8e 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -2376,17 +2376,11 @@ namespace SourceGit.ViewModels Task.Run(() => { - var files = new Commands.QueryRevisionFileNames(_fullpath, "HEAD").Result(); + _worktreeFiles = new Commands.QueryRevisionFileNames(_fullpath, "HEAD").Result(); Dispatcher.UIThread.Invoke(() => { - if (!IsSearchingCommitsByFilePath()) - return; - - _worktreeFiles = new List(); - foreach (var f in files) - _worktreeFiles.Add(f); - - CalcMatchedFilesForSearching(); + if (IsSearchingCommitsByFilePath()) + CalcMatchedFilesForSearching(); }); }); } From 0476a825efffa277e751eeb8352ed9c93d41f1c5 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 12 Mar 2025 14:58:59 +0800 Subject: [PATCH 353/865] code_style: move some code from `Histories.axaml` to separate files Signed-off-by: leo --- src/Views/CommitGraph.cs | 228 +++++++++ src/Views/CommitStatusIndicator.cs | 90 ++++ src/Views/CommitSubjectPresenter.cs | 189 ++++++++ src/Views/CommitTimeTextBlock.cs | 163 +++++++ src/Views/Histories.axaml | 12 +- src/Views/Histories.axaml.cs | 695 ++-------------------------- 6 files changed, 705 insertions(+), 672 deletions(-) create mode 100644 src/Views/CommitGraph.cs create mode 100644 src/Views/CommitStatusIndicator.cs create mode 100644 src/Views/CommitSubjectPresenter.cs create mode 100644 src/Views/CommitTimeTextBlock.cs diff --git a/src/Views/CommitGraph.cs b/src/Views/CommitGraph.cs new file mode 100644 index 00000000..015eaca5 --- /dev/null +++ b/src/Views/CommitGraph.cs @@ -0,0 +1,228 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Media; +using Avalonia.VisualTree; + +namespace SourceGit.Views +{ + public class CommitGraph : Control + { + public static readonly StyledProperty GraphProperty = + AvaloniaProperty.Register(nameof(Graph)); + + public Models.CommitGraph Graph + { + get => GetValue(GraphProperty); + set => SetValue(GraphProperty, value); + } + + public static readonly StyledProperty DotBrushProperty = + AvaloniaProperty.Register(nameof(DotBrush), Brushes.Transparent); + + public IBrush DotBrush + { + get => GetValue(DotBrushProperty); + set => SetValue(DotBrushProperty, value); + } + + public static readonly StyledProperty OnlyHighlightCurrentBranchProperty = + AvaloniaProperty.Register(nameof(OnlyHighlightCurrentBranch), true); + + public bool OnlyHighlightCurrentBranch + { + get => GetValue(OnlyHighlightCurrentBranchProperty); + set => SetValue(OnlyHighlightCurrentBranchProperty, value); + } + + static CommitGraph() + { + AffectsRender(GraphProperty, DotBrushProperty, OnlyHighlightCurrentBranchProperty); + } + + public override void Render(DrawingContext context) + { + base.Render(context); + + var graph = Graph; + if (graph == null) + return; + + var histories = this.FindAncestorOfType(); + if (histories == null) + return; + + var list = histories.CommitListContainer; + if (list == null) + return; + + // Calculate drawing area. + double width = Bounds.Width - 273 - histories.AuthorNameColumnWidth.Value; + double height = Bounds.Height; + double startY = list.Scroll?.Offset.Y ?? 0; + double endY = startY + height + 28; + + // Apply scroll offset and clip. + using (context.PushClip(new Rect(0, 0, width, height))) + using (context.PushTransform(Matrix.CreateTranslation(0, -startY))) + { + // Draw contents + DrawCurves(context, graph, startY, endY); + DrawAnchors(context, graph, startY, endY); + } + } + + private void DrawCurves(DrawingContext context, Models.CommitGraph graph, double top, double bottom) + { + var grayedPen = new Pen(new SolidColorBrush(Colors.Gray, 0.4), Models.CommitGraph.Pens[0].Thickness); + var onlyHighlightCurrentBranch = OnlyHighlightCurrentBranch; + + if (onlyHighlightCurrentBranch) + { + foreach (var link in graph.Links) + { + if (link.IsMerged) + continue; + if (link.End.Y < top) + continue; + if (link.Start.Y > bottom) + break; + + var geo = new StreamGeometry(); + using (var ctx = geo.Open()) + { + ctx.BeginFigure(link.Start, false); + ctx.QuadraticBezierTo(link.Control, link.End); + } + + context.DrawGeometry(null, grayedPen, geo); + } + } + + foreach (var line in graph.Paths) + { + var last = line.Points[0]; + var size = line.Points.Count; + + if (line.Points[size - 1].Y < top) + continue; + if (last.Y > bottom) + break; + + var geo = new StreamGeometry(); + var pen = Models.CommitGraph.Pens[line.Color]; + + using (var ctx = geo.Open()) + { + var started = false; + var ended = false; + for (int i = 1; i < size; i++) + { + var cur = line.Points[i]; + if (cur.Y < top) + { + last = cur; + continue; + } + + if (!started) + { + ctx.BeginFigure(last, false); + started = true; + } + + if (cur.Y > bottom) + { + cur = new Point(cur.X, bottom); + ended = true; + } + + if (cur.X > last.X) + { + ctx.QuadraticBezierTo(new Point(cur.X, last.Y), cur); + } + else if (cur.X < last.X) + { + if (i < size - 1) + { + var midY = (last.Y + cur.Y) / 2; + ctx.CubicBezierTo(new Point(last.X, midY + 4), new Point(cur.X, midY - 4), cur); + } + else + { + ctx.QuadraticBezierTo(new Point(last.X, cur.Y), cur); + } + } + else + { + ctx.LineTo(cur); + } + + if (ended) + break; + last = cur; + } + } + + if (!line.IsMerged && onlyHighlightCurrentBranch) + context.DrawGeometry(null, grayedPen, geo); + else + context.DrawGeometry(null, pen, geo); + } + + foreach (var link in graph.Links) + { + if (onlyHighlightCurrentBranch && !link.IsMerged) + continue; + if (link.End.Y < top) + continue; + if (link.Start.Y > bottom) + break; + + var geo = new StreamGeometry(); + using (var ctx = geo.Open()) + { + ctx.BeginFigure(link.Start, false); + ctx.QuadraticBezierTo(link.Control, link.End); + } + + context.DrawGeometry(null, Models.CommitGraph.Pens[link.Color], geo); + } + } + + private void DrawAnchors(DrawingContext context, Models.CommitGraph graph, double top, double bottom) + { + var dotFill = DotBrush; + var dotFillPen = new Pen(dotFill, 2); + var grayedPen = new Pen(Brushes.Gray, Models.CommitGraph.Pens[0].Thickness); + var onlyHighlightCurrentBranch = OnlyHighlightCurrentBranch; + + foreach (var dot in graph.Dots) + { + if (dot.Center.Y < top) + continue; + if (dot.Center.Y > bottom) + break; + + var pen = Models.CommitGraph.Pens[dot.Color]; + if (!dot.IsMerged && onlyHighlightCurrentBranch) + pen = grayedPen; + + switch (dot.Type) + { + case Models.CommitGraph.DotType.Head: + context.DrawEllipse(dotFill, pen, dot.Center, 6, 6); + context.DrawEllipse(pen.Brush, null, dot.Center, 3, 3); + break; + case Models.CommitGraph.DotType.Merge: + context.DrawEllipse(pen.Brush, null, dot.Center, 6, 6); + context.DrawLine(dotFillPen, new Point(dot.Center.X, dot.Center.Y - 3), new Point(dot.Center.X, dot.Center.Y + 3)); + context.DrawLine(dotFillPen, new Point(dot.Center.X - 3, dot.Center.Y), new Point(dot.Center.X + 3, dot.Center.Y)); + break; + default: + context.DrawEllipse(dotFill, pen, dot.Center, 3, 3); + break; + } + } + } + } +} diff --git a/src/Views/CommitStatusIndicator.cs b/src/Views/CommitStatusIndicator.cs new file mode 100644 index 00000000..c2f4184e --- /dev/null +++ b/src/Views/CommitStatusIndicator.cs @@ -0,0 +1,90 @@ +using System; + +using Avalonia; +using Avalonia.Controls; +using Avalonia.Media; + +namespace SourceGit.Views +{ + public class CommitStatusIndicator : Control + { + public static readonly StyledProperty CurrentBranchProperty = + AvaloniaProperty.Register(nameof(CurrentBranch)); + + public Models.Branch CurrentBranch + { + get => GetValue(CurrentBranchProperty); + set => SetValue(CurrentBranchProperty, value); + } + + public static readonly StyledProperty AheadBrushProperty = + AvaloniaProperty.Register(nameof(AheadBrush)); + + public IBrush AheadBrush + { + get => GetValue(AheadBrushProperty); + set => SetValue(AheadBrushProperty, value); + } + + public static readonly StyledProperty BehindBrushProperty = + AvaloniaProperty.Register(nameof(BehindBrush)); + + public IBrush BehindBrush + { + get => GetValue(BehindBrushProperty); + set => SetValue(BehindBrushProperty, value); + } + + enum Status + { + Normal, + Ahead, + Behind, + } + + public override void Render(DrawingContext context) + { + if (_status == Status.Normal) + return; + + context.DrawEllipse(_status == Status.Ahead ? AheadBrush : BehindBrush, null, new Rect(0, 0, 5, 5)); + } + + protected override Size MeasureOverride(Size availableSize) + { + if (DataContext is Models.Commit commit && CurrentBranch is not null) + { + var sha = commit.SHA; + var track = CurrentBranch.TrackStatus; + + if (track.Ahead.Contains(sha)) + _status = Status.Ahead; + else if (track.Behind.Contains(sha)) + _status = Status.Behind; + else + _status = Status.Normal; + } + else + { + _status = Status.Normal; + } + + return _status == Status.Normal ? new Size(0, 0) : new Size(9, 5); + } + + protected override void OnDataContextChanged(EventArgs e) + { + base.OnDataContextChanged(e); + InvalidateMeasure(); + } + + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); + if (change.Property == CurrentBranchProperty) + InvalidateMeasure(); + } + + private Status _status = Status.Normal; + } +} diff --git a/src/Views/CommitSubjectPresenter.cs b/src/Views/CommitSubjectPresenter.cs new file mode 100644 index 00000000..32f6838d --- /dev/null +++ b/src/Views/CommitSubjectPresenter.cs @@ -0,0 +1,189 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using Avalonia; +using Avalonia.Collections; +using Avalonia.Controls; +using Avalonia.Controls.Documents; +using Avalonia.Input; +using Avalonia.Media; +using Avalonia.Media.TextFormatting; + +namespace SourceGit.Views +{ + public partial class CommitSubjectPresenter : TextBlock + { + public static readonly StyledProperty SubjectProperty = + AvaloniaProperty.Register(nameof(Subject)); + + public string Subject + { + get => GetValue(SubjectProperty); + set => SetValue(SubjectProperty, value); + } + + public static readonly StyledProperty> IssueTrackerRulesProperty = + AvaloniaProperty.Register>(nameof(IssueTrackerRules)); + + public AvaloniaList IssueTrackerRules + { + get => GetValue(IssueTrackerRulesProperty); + set => SetValue(IssueTrackerRulesProperty, value); + } + + protected override Type StyleKeyOverride => typeof(TextBlock); + + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); + + if (change.Property == SubjectProperty || change.Property == IssueTrackerRulesProperty) + { + Inlines!.Clear(); + _matches = null; + ClearHoveredIssueLink(); + + var subject = Subject; + if (string.IsNullOrEmpty(subject)) + return; + + var keywordMatch = REG_KEYWORD_FORMAT1().Match(subject); + if (!keywordMatch.Success) + keywordMatch = REG_KEYWORD_FORMAT2().Match(subject); + + var rules = IssueTrackerRules ?? []; + var matches = new List(); + foreach (var rule in rules) + rule.Matches(matches, subject); + + if (matches.Count == 0) + { + if (keywordMatch.Success) + { + Inlines.Add(new Run(subject.Substring(0, keywordMatch.Length)) { FontWeight = FontWeight.Bold }); + Inlines.Add(new Run(subject.Substring(keywordMatch.Length))); + } + else + { + Inlines.Add(new Run(subject)); + } + return; + } + + matches.Sort((l, r) => l.Start - r.Start); + _matches = matches; + + var inlines = new List(); + var pos = 0; + foreach (var match in matches) + { + if (match.Start > pos) + { + if (keywordMatch.Success && pos < keywordMatch.Length) + { + if (keywordMatch.Length < match.Start) + { + inlines.Add(new Run(subject.Substring(pos, keywordMatch.Length - pos)) { FontWeight = FontWeight.Bold }); + inlines.Add(new Run(subject.Substring(keywordMatch.Length, match.Start - keywordMatch.Length))); + } + else + { + inlines.Add(new Run(subject.Substring(pos, match.Start - pos)) { FontWeight = FontWeight.Bold }); + } + } + else + { + inlines.Add(new Run(subject.Substring(pos, match.Start - pos))); + } + } + + var link = new Run(subject.Substring(match.Start, match.Length)); + link.Classes.Add("issue_link"); + inlines.Add(link); + + pos = match.Start + match.Length; + } + + if (pos < subject.Length) + { + if (keywordMatch.Success && pos < keywordMatch.Length) + { + inlines.Add(new Run(subject.Substring(pos, keywordMatch.Length - pos)) { FontWeight = FontWeight.Bold }); + inlines.Add(new Run(subject.Substring(keywordMatch.Length))); + } + else + { + inlines.Add(new Run(subject.Substring(pos))); + } + } + + Inlines.AddRange(inlines); + } + } + + protected override void OnPointerMoved(PointerEventArgs e) + { + base.OnPointerMoved(e); + + if (_matches != null) + { + var point = e.GetPosition(this) - new Point(Padding.Left, Padding.Top); + var x = Math.Min(Math.Max(point.X, 0), Math.Max(TextLayout.WidthIncludingTrailingWhitespace, 0)); + var y = Math.Min(Math.Max(point.Y, 0), Math.Max(TextLayout.Height, 0)); + point = new Point(x, y); + + var textPosition = TextLayout.HitTestPoint(point).TextPosition; + foreach (var match in _matches) + { + if (!match.Intersect(textPosition, 1)) + continue; + + if (match == _lastHover) + return; + + _lastHover = match; + SetCurrentValue(CursorProperty, Cursor.Parse("Hand")); + ToolTip.SetTip(this, match.Link); + ToolTip.SetIsOpen(this, true); + e.Handled = true; + return; + } + + ClearHoveredIssueLink(); + } + } + + protected override void OnPointerPressed(PointerPressedEventArgs e) + { + base.OnPointerPressed(e); + + if (_lastHover != null) + Native.OS.OpenBrowser(_lastHover.Link); + } + + protected override void OnPointerExited(PointerEventArgs e) + { + base.OnPointerExited(e); + ClearHoveredIssueLink(); + } + + private void ClearHoveredIssueLink() + { + if (_lastHover != null) + { + ToolTip.SetTip(this, null); + SetCurrentValue(CursorProperty, Cursor.Parse("Arrow")); + _lastHover = null; + } + } + + [GeneratedRegex(@"^\[[\w\s]+\]")] + private static partial Regex REG_KEYWORD_FORMAT1(); + + [GeneratedRegex(@"^\S+([\<\(][\w\s_\-\*,]+[\>\)])?\!?\s?:\s")] + private static partial Regex REG_KEYWORD_FORMAT2(); + + private List _matches = null; + private Models.Hyperlink _lastHover = null; + } +} diff --git a/src/Views/CommitTimeTextBlock.cs b/src/Views/CommitTimeTextBlock.cs new file mode 100644 index 00000000..6947f7f2 --- /dev/null +++ b/src/Views/CommitTimeTextBlock.cs @@ -0,0 +1,163 @@ +using System; + +using Avalonia; +using Avalonia.Controls; +using Avalonia.Interactivity; +using Avalonia.Threading; + +namespace SourceGit.Views +{ + public class CommitTimeTextBlock : TextBlock + { + public static readonly StyledProperty ShowAsDateTimeProperty = + AvaloniaProperty.Register(nameof(ShowAsDateTime), true); + + public bool ShowAsDateTime + { + get => GetValue(ShowAsDateTimeProperty); + set => SetValue(ShowAsDateTimeProperty, value); + } + + public static readonly StyledProperty DateTimeFormatProperty = + AvaloniaProperty.Register(nameof(DateTimeFormat), 0); + + public int DateTimeFormat + { + get => GetValue(DateTimeFormatProperty); + set => SetValue(DateTimeFormatProperty, value); + } + + public static readonly StyledProperty UseAuthorTimeProperty = + AvaloniaProperty.Register(nameof(UseAuthorTime), true); + + public bool UseAuthorTime + { + get => GetValue(UseAuthorTimeProperty); + set => SetValue(UseAuthorTimeProperty, value); + } + + protected override Type StyleKeyOverride => typeof(TextBlock); + + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); + + if (change.Property == UseAuthorTimeProperty) + { + SetCurrentValue(TextProperty, GetDisplayText()); + } + else if (change.Property == ShowAsDateTimeProperty) + { + SetCurrentValue(TextProperty, GetDisplayText()); + + if (ShowAsDateTime) + StopTimer(); + else + StartTimer(); + } + else if (change.Property == DateTimeFormatProperty) + { + if (ShowAsDateTime) + SetCurrentValue(TextProperty, GetDisplayText()); + } + } + + protected override void OnLoaded(RoutedEventArgs e) + { + base.OnLoaded(e); + + if (!ShowAsDateTime) + StartTimer(); + } + + protected override void OnUnloaded(RoutedEventArgs e) + { + base.OnUnloaded(e); + StopTimer(); + } + + protected override void OnDataContextChanged(EventArgs e) + { + base.OnDataContextChanged(e); + SetCurrentValue(TextProperty, GetDisplayText()); + } + + private void StartTimer() + { + if (_refreshTimer != null) + return; + + _refreshTimer = DispatcherTimer.Run(() => + { + Dispatcher.UIThread.Invoke(() => + { + var text = GetDisplayText(); + if (!text.Equals(Text, StringComparison.Ordinal)) + Text = text; + }); + + return true; + }, TimeSpan.FromSeconds(10)); + } + + private void StopTimer() + { + if (_refreshTimer != null) + { + _refreshTimer.Dispose(); + _refreshTimer = null; + } + } + + private string GetDisplayText() + { + var commit = DataContext as Models.Commit; + if (commit == null) + return string.Empty; + + if (ShowAsDateTime) + return UseAuthorTime ? commit.AuthorTimeStr : commit.CommitterTimeStr; + + var timestamp = UseAuthorTime ? commit.AuthorTime : commit.CommitterTime; + var now = DateTime.Now; + var localTime = DateTime.UnixEpoch.AddSeconds(timestamp).ToLocalTime(); + var span = now - localTime; + if (span.TotalMinutes < 1) + return App.Text("Period.JustNow"); + + if (span.TotalHours < 1) + return App.Text("Period.MinutesAgo", (int)span.TotalMinutes); + + if (span.TotalDays < 1) + return App.Text("Period.HoursAgo", (int)span.TotalHours); + + var lastDay = now.AddDays(-1).Date; + if (localTime >= lastDay) + return App.Text("Period.Yesterday"); + + if ((localTime.Year == now.Year && localTime.Month == now.Month) || span.TotalDays < 28) + { + var diffDay = now.Date - localTime.Date; + return App.Text("Period.DaysAgo", (int)diffDay.TotalDays); + } + + var lastMonth = now.AddMonths(-1).Date; + if (localTime.Year == lastMonth.Year && localTime.Month == lastMonth.Month) + return App.Text("Period.LastMonth"); + + if (localTime.Year == now.Year || localTime > now.AddMonths(-11)) + { + var diffMonth = (12 + now.Month - localTime.Month) % 12; + return App.Text("Period.MonthsAgo", diffMonth); + } + + var diffYear = now.Year - localTime.Year; + if (diffYear == 1) + return App.Text("Period.LastYear"); + + return App.Text("Period.YearsAgo", diffYear); + } + + private IDisposable _refreshTimer = null; + } +} diff --git a/src/Views/Histories.axaml b/src/Views/Histories.axaml index 40b2636f..583e17c1 100644 --- a/src/Views/Histories.axaml +++ b/src/Views/Histories.axaml @@ -10,18 +10,18 @@ x:Class="SourceGit.Views.Histories" x:DataType="vm:Histories" x:Name="ThisControl"> - - + + - + - + - + @@ -264,5 +264,5 @@ - + diff --git a/src/Views/Histories.axaml.cs b/src/Views/Histories.axaml.cs index 8b5142ad..62c283e5 100644 --- a/src/Views/Histories.axaml.cs +++ b/src/Views/Histories.axaml.cs @@ -1,24 +1,18 @@ using System; -using System.Collections.Generic; using System.Text; -using System.Text.RegularExpressions; using Avalonia; using Avalonia.Collections; using Avalonia.Controls; -using Avalonia.Controls.Documents; using Avalonia.Input; -using Avalonia.Interactivity; -using Avalonia.Media; -using Avalonia.Threading; using Avalonia.VisualTree; namespace SourceGit.Views { - public class LayoutableGrid : Grid + public class HistoriesLayout : Grid { public static readonly StyledProperty UseHorizontalProperty = - AvaloniaProperty.Register(nameof(UseHorizontal)); + AvaloniaProperty.Register(nameof(UseHorizontal)); public bool UseHorizontal { @@ -28,17 +22,20 @@ namespace SourceGit.Views protected override Type StyleKeyOverride => typeof(Grid); - static LayoutableGrid() - { - UseHorizontalProperty.Changed.AddClassHandler((o, _) => o.RefreshLayout()); - } - public override void ApplyTemplate() { base.ApplyTemplate(); RefreshLayout(); } + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); + + if (change.Property == UseHorizontalProperty) + RefreshLayout(); + } + private void RefreshLayout() { if (UseHorizontal) @@ -74,639 +71,6 @@ namespace SourceGit.Views } } - public class CommitStatusIndicator : Control - { - public static readonly StyledProperty CurrentBranchProperty = - AvaloniaProperty.Register(nameof(CurrentBranch)); - - public Models.Branch CurrentBranch - { - get => GetValue(CurrentBranchProperty); - set => SetValue(CurrentBranchProperty, value); - } - - public static readonly StyledProperty AheadBrushProperty = - AvaloniaProperty.Register(nameof(AheadBrush)); - - public IBrush AheadBrush - { - get => GetValue(AheadBrushProperty); - set => SetValue(AheadBrushProperty, value); - } - - public static readonly StyledProperty BehindBrushProperty = - AvaloniaProperty.Register(nameof(BehindBrush)); - - public IBrush BehindBrush - { - get => GetValue(BehindBrushProperty); - set => SetValue(BehindBrushProperty, value); - } - - enum Status - { - Normal, - Ahead, - Behind, - } - - public override void Render(DrawingContext context) - { - if (_status == Status.Normal) - return; - - context.DrawEllipse(_status == Status.Ahead ? AheadBrush : BehindBrush, null, new Rect(0, 0, 5, 5)); - } - - protected override Size MeasureOverride(Size availableSize) - { - if (DataContext is Models.Commit commit && CurrentBranch is not null) - { - var sha = commit.SHA; - var track = CurrentBranch.TrackStatus; - - if (track.Ahead.Contains(sha)) - _status = Status.Ahead; - else if (track.Behind.Contains(sha)) - _status = Status.Behind; - else - _status = Status.Normal; - } - else - { - _status = Status.Normal; - } - - return _status == Status.Normal ? new Size(0, 0) : new Size(9, 5); - } - - protected override void OnDataContextChanged(EventArgs e) - { - base.OnDataContextChanged(e); - InvalidateMeasure(); - } - - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) - { - base.OnPropertyChanged(change); - if (change.Property == CurrentBranchProperty) - InvalidateMeasure(); - } - - private Status _status = Status.Normal; - } - - public partial class CommitSubjectPresenter : TextBlock - { - public static readonly StyledProperty SubjectProperty = - AvaloniaProperty.Register(nameof(Subject)); - - public string Subject - { - get => GetValue(SubjectProperty); - set => SetValue(SubjectProperty, value); - } - - public static readonly StyledProperty> IssueTrackerRulesProperty = - AvaloniaProperty.Register>(nameof(IssueTrackerRules)); - - public AvaloniaList IssueTrackerRules - { - get => GetValue(IssueTrackerRulesProperty); - set => SetValue(IssueTrackerRulesProperty, value); - } - - protected override Type StyleKeyOverride => typeof(TextBlock); - - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) - { - base.OnPropertyChanged(change); - - if (change.Property == SubjectProperty || change.Property == IssueTrackerRulesProperty) - { - Inlines!.Clear(); - _matches = null; - ClearHoveredIssueLink(); - - var subject = Subject; - if (string.IsNullOrEmpty(subject)) - return; - - var keywordMatch = REG_KEYWORD_FORMAT1().Match(subject); - if (!keywordMatch.Success) - keywordMatch = REG_KEYWORD_FORMAT2().Match(subject); - - var rules = IssueTrackerRules ?? []; - var matches = new List(); - foreach (var rule in rules) - rule.Matches(matches, subject); - - if (matches.Count == 0) - { - if (keywordMatch.Success) - { - Inlines.Add(new Run(subject.Substring(0, keywordMatch.Length)) { FontWeight = FontWeight.Bold }); - Inlines.Add(new Run(subject.Substring(keywordMatch.Length))); - } - else - { - Inlines.Add(new Run(subject)); - } - return; - } - - matches.Sort((l, r) => l.Start - r.Start); - _matches = matches; - - var inlines = new List(); - var pos = 0; - foreach (var match in matches) - { - if (match.Start > pos) - { - if (keywordMatch.Success && pos < keywordMatch.Length) - { - if (keywordMatch.Length < match.Start) - { - inlines.Add(new Run(subject.Substring(pos, keywordMatch.Length - pos)) { FontWeight = FontWeight.Bold }); - inlines.Add(new Run(subject.Substring(keywordMatch.Length, match.Start - keywordMatch.Length))); - } - else - { - inlines.Add(new Run(subject.Substring(pos, match.Start - pos)) { FontWeight = FontWeight.Bold }); - } - } - else - { - inlines.Add(new Run(subject.Substring(pos, match.Start - pos))); - } - } - - var link = new Run(subject.Substring(match.Start, match.Length)); - link.Classes.Add("issue_link"); - inlines.Add(link); - - pos = match.Start + match.Length; - } - - if (pos < subject.Length) - { - if (keywordMatch.Success && pos < keywordMatch.Length) - { - inlines.Add(new Run(subject.Substring(pos, keywordMatch.Length - pos)) { FontWeight = FontWeight.Bold }); - inlines.Add(new Run(subject.Substring(keywordMatch.Length))); - } - else - { - inlines.Add(new Run(subject.Substring(pos))); - } - } - - Inlines.AddRange(inlines); - } - } - - protected override void OnPointerMoved(PointerEventArgs e) - { - base.OnPointerMoved(e); - - if (_matches != null) - { - var point = e.GetPosition(this) - new Point(Padding.Left, Padding.Top); - var x = Math.Min(Math.Max(point.X, 0), Math.Max(TextLayout.WidthIncludingTrailingWhitespace, 0)); - var y = Math.Min(Math.Max(point.Y, 0), Math.Max(TextLayout.Height, 0)); - point = new Point(x, y); - - var textPosition = TextLayout.HitTestPoint(point).TextPosition; - foreach (var match in _matches) - { - if (!match.Intersect(textPosition, 1)) - continue; - - if (match == _lastHover) - return; - - _lastHover = match; - SetCurrentValue(CursorProperty, Cursor.Parse("Hand")); - ToolTip.SetTip(this, match.Link); - ToolTip.SetIsOpen(this, true); - e.Handled = true; - return; - } - - ClearHoveredIssueLink(); - } - } - - protected override void OnPointerPressed(PointerPressedEventArgs e) - { - base.OnPointerPressed(e); - - if (_lastHover != null) - Native.OS.OpenBrowser(_lastHover.Link); - } - - protected override void OnPointerExited(PointerEventArgs e) - { - base.OnPointerExited(e); - ClearHoveredIssueLink(); - } - - private void ClearHoveredIssueLink() - { - if (_lastHover != null) - { - ToolTip.SetTip(this, null); - SetCurrentValue(CursorProperty, Cursor.Parse("Arrow")); - _lastHover = null; - } - } - - [GeneratedRegex(@"^\[[\w\s]+\]")] - private static partial Regex REG_KEYWORD_FORMAT1(); - - [GeneratedRegex(@"^\S+([\<\(][\w\s_\-\*,]+[\>\)])?\!?\s?:\s")] - private static partial Regex REG_KEYWORD_FORMAT2(); - - private List _matches = null; - private Models.Hyperlink _lastHover = null; - } - - public class CommitTimeTextBlock : TextBlock - { - public static readonly StyledProperty ShowAsDateTimeProperty = - AvaloniaProperty.Register(nameof(ShowAsDateTime), true); - - public bool ShowAsDateTime - { - get => GetValue(ShowAsDateTimeProperty); - set => SetValue(ShowAsDateTimeProperty, value); - } - - public static readonly StyledProperty DateTimeFormatProperty = - AvaloniaProperty.Register(nameof(DateTimeFormat), 0); - - public int DateTimeFormat - { - get => GetValue(DateTimeFormatProperty); - set => SetValue(DateTimeFormatProperty, value); - } - - public static readonly StyledProperty UseAuthorTimeProperty = - AvaloniaProperty.Register(nameof(UseAuthorTime), true); - - public bool UseAuthorTime - { - get => GetValue(UseAuthorTimeProperty); - set => SetValue(UseAuthorTimeProperty, value); - } - - protected override Type StyleKeyOverride => typeof(TextBlock); - - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) - { - base.OnPropertyChanged(change); - - if (change.Property == UseAuthorTimeProperty) - { - SetCurrentValue(TextProperty, GetDisplayText()); - } - else if (change.Property == ShowAsDateTimeProperty) - { - SetCurrentValue(TextProperty, GetDisplayText()); - - if (ShowAsDateTime) - StopTimer(); - else - StartTimer(); - } - else if (change.Property == DateTimeFormatProperty) - { - if (ShowAsDateTime) - SetCurrentValue(TextProperty, GetDisplayText()); - } - } - - protected override void OnLoaded(RoutedEventArgs e) - { - base.OnLoaded(e); - - if (!ShowAsDateTime) - StartTimer(); - } - - protected override void OnUnloaded(RoutedEventArgs e) - { - base.OnUnloaded(e); - StopTimer(); - } - - protected override void OnDataContextChanged(EventArgs e) - { - base.OnDataContextChanged(e); - SetCurrentValue(TextProperty, GetDisplayText()); - } - - private void StartTimer() - { - if (_refreshTimer != null) - return; - - _refreshTimer = DispatcherTimer.Run(() => - { - Dispatcher.UIThread.Invoke(() => - { - var text = GetDisplayText(); - if (!text.Equals(Text, StringComparison.Ordinal)) - Text = text; - }); - - return true; - }, TimeSpan.FromSeconds(10)); - } - - private void StopTimer() - { - if (_refreshTimer != null) - { - _refreshTimer.Dispose(); - _refreshTimer = null; - } - } - - private string GetDisplayText() - { - var commit = DataContext as Models.Commit; - if (commit == null) - return string.Empty; - - if (ShowAsDateTime) - return UseAuthorTime ? commit.AuthorTimeStr : commit.CommitterTimeStr; - - var timestamp = UseAuthorTime ? commit.AuthorTime : commit.CommitterTime; - var now = DateTime.Now; - var localTime = DateTime.UnixEpoch.AddSeconds(timestamp).ToLocalTime(); - var span = now - localTime; - if (span.TotalMinutes < 1) - return App.Text("Period.JustNow"); - - if (span.TotalHours < 1) - return App.Text("Period.MinutesAgo", (int)span.TotalMinutes); - - if (span.TotalDays < 1) - return App.Text("Period.HoursAgo", (int)span.TotalHours); - - var lastDay = now.AddDays(-1).Date; - if (localTime >= lastDay) - return App.Text("Period.Yesterday"); - - if ((localTime.Year == now.Year && localTime.Month == now.Month) || span.TotalDays < 28) - { - var diffDay = now.Date - localTime.Date; - return App.Text("Period.DaysAgo", (int)diffDay.TotalDays); - } - - var lastMonth = now.AddMonths(-1).Date; - if (localTime.Year == lastMonth.Year && localTime.Month == lastMonth.Month) - return App.Text("Period.LastMonth"); - - if (localTime.Year == now.Year || localTime > now.AddMonths(-11)) - { - var diffMonth = (12 + now.Month - localTime.Month) % 12; - return App.Text("Period.MonthsAgo", diffMonth); - } - - var diffYear = now.Year - localTime.Year; - if (diffYear == 1) - return App.Text("Period.LastYear"); - - return App.Text("Period.YearsAgo", diffYear); - } - - private IDisposable _refreshTimer = null; - } - - public class CommitGraph : Control - { - public static readonly StyledProperty GraphProperty = - AvaloniaProperty.Register(nameof(Graph)); - - public Models.CommitGraph Graph - { - get => GetValue(GraphProperty); - set => SetValue(GraphProperty, value); - } - - public static readonly StyledProperty DotBrushProperty = - AvaloniaProperty.Register(nameof(DotBrush), Brushes.Transparent); - - public IBrush DotBrush - { - get => GetValue(DotBrushProperty); - set => SetValue(DotBrushProperty, value); - } - - public static readonly StyledProperty OnlyHighlightCurrentBranchProperty = - AvaloniaProperty.Register(nameof(OnlyHighlightCurrentBranch), true); - - public bool OnlyHighlightCurrentBranch - { - get => GetValue(OnlyHighlightCurrentBranchProperty); - set => SetValue(OnlyHighlightCurrentBranchProperty, value); - } - - static CommitGraph() - { - AffectsRender(GraphProperty, DotBrushProperty, OnlyHighlightCurrentBranchProperty); - } - - public override void Render(DrawingContext context) - { - base.Render(context); - - var graph = Graph; - if (graph == null) - return; - - var histories = this.FindAncestorOfType(); - if (histories == null) - return; - - var list = histories.CommitListContainer; - if (list == null) - return; - - // Calculate drawing area. - double width = Bounds.Width - 273 - histories.AuthorNameColumnWidth.Value; - double height = Bounds.Height; - double startY = list.Scroll?.Offset.Y ?? 0; - double endY = startY + height + 28; - - // Apply scroll offset and clip. - using (context.PushClip(new Rect(0, 0, width, height))) - using (context.PushTransform(Matrix.CreateTranslation(0, -startY))) - { - // Draw contents - DrawCurves(context, graph, startY, endY); - DrawAnchors(context, graph, startY, endY); - } - } - - private void DrawCurves(DrawingContext context, Models.CommitGraph graph, double top, double bottom) - { - var grayedPen = new Pen(new SolidColorBrush(Colors.Gray, 0.4), Models.CommitGraph.Pens[0].Thickness); - var onlyHighlightCurrentBranch = OnlyHighlightCurrentBranch; - - if (onlyHighlightCurrentBranch) - { - foreach (var link in graph.Links) - { - if (link.IsMerged) - continue; - if (link.End.Y < top) - continue; - if (link.Start.Y > bottom) - break; - - var geo = new StreamGeometry(); - using (var ctx = geo.Open()) - { - ctx.BeginFigure(link.Start, false); - ctx.QuadraticBezierTo(link.Control, link.End); - } - - context.DrawGeometry(null, grayedPen, geo); - } - } - - foreach (var line in graph.Paths) - { - var last = line.Points[0]; - var size = line.Points.Count; - - if (line.Points[size - 1].Y < top) - continue; - if (last.Y > bottom) - break; - - var geo = new StreamGeometry(); - var pen = Models.CommitGraph.Pens[line.Color]; - - using (var ctx = geo.Open()) - { - var started = false; - var ended = false; - for (int i = 1; i < size; i++) - { - var cur = line.Points[i]; - if (cur.Y < top) - { - last = cur; - continue; - } - - if (!started) - { - ctx.BeginFigure(last, false); - started = true; - } - - if (cur.Y > bottom) - { - cur = new Point(cur.X, bottom); - ended = true; - } - - if (cur.X > last.X) - { - ctx.QuadraticBezierTo(new Point(cur.X, last.Y), cur); - } - else if (cur.X < last.X) - { - if (i < size - 1) - { - var midY = (last.Y + cur.Y) / 2; - ctx.CubicBezierTo(new Point(last.X, midY + 4), new Point(cur.X, midY - 4), cur); - } - else - { - ctx.QuadraticBezierTo(new Point(last.X, cur.Y), cur); - } - } - else - { - ctx.LineTo(cur); - } - - if (ended) - break; - last = cur; - } - } - - if (!line.IsMerged && onlyHighlightCurrentBranch) - context.DrawGeometry(null, grayedPen, geo); - else - context.DrawGeometry(null, pen, geo); - } - - foreach (var link in graph.Links) - { - if (onlyHighlightCurrentBranch && !link.IsMerged) - continue; - if (link.End.Y < top) - continue; - if (link.Start.Y > bottom) - break; - - var geo = new StreamGeometry(); - using (var ctx = geo.Open()) - { - ctx.BeginFigure(link.Start, false); - ctx.QuadraticBezierTo(link.Control, link.End); - } - - context.DrawGeometry(null, Models.CommitGraph.Pens[link.Color], geo); - } - } - - private void DrawAnchors(DrawingContext context, Models.CommitGraph graph, double top, double bottom) - { - var dotFill = DotBrush; - var dotFillPen = new Pen(dotFill, 2); - var grayedPen = new Pen(Brushes.Gray, Models.CommitGraph.Pens[0].Thickness); - var onlyHighlightCurrentBranch = OnlyHighlightCurrentBranch; - - foreach (var dot in graph.Dots) - { - if (dot.Center.Y < top) - continue; - if (dot.Center.Y > bottom) - break; - - var pen = Models.CommitGraph.Pens[dot.Color]; - if (!dot.IsMerged && onlyHighlightCurrentBranch) - pen = grayedPen; - - switch (dot.Type) - { - case Models.CommitGraph.DotType.Head: - context.DrawEllipse(dotFill, pen, dot.Center, 6, 6); - context.DrawEllipse(pen.Brush, null, dot.Center, 3, 3); - break; - case Models.CommitGraph.DotType.Merge: - context.DrawEllipse(pen.Brush, null, dot.Center, 6, 6); - context.DrawLine(dotFillPen, new Point(dot.Center.X, dot.Center.Y - 3), new Point(dot.Center.X, dot.Center.Y + 3)); - context.DrawLine(dotFillPen, new Point(dot.Center.X - 3, dot.Center.Y), new Point(dot.Center.X + 3, dot.Center.Y)); - break; - default: - context.DrawEllipse(dotFill, pen, dot.Center, 3, 3); - break; - } - } - } - } - public partial class Histories : UserControl { public static readonly StyledProperty AuthorNameColumnWidthProperty = @@ -754,36 +118,34 @@ namespace SourceGit.Views set => SetValue(NavigationIdProperty, value); } - static Histories() - { - NavigationIdProperty.Changed.AddClassHandler((h, _) => - { - if (h.DataContext == null) - return; - - // Force scroll selected item (current head) into view. see issue #58 - var list = h.CommitListContainer; - if (list != null && list.SelectedItems.Count == 1) - list.ScrollIntoView(list.SelectedIndex); - }); - - AuthorNameColumnWidthProperty.Changed.AddClassHandler((h, _) => - { - h.CommitGraph.InvalidateVisual(); - }); - } - public Histories() { InitializeComponent(); } + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); + + if (change.Property == NavigationIdProperty) + { + if (DataContext is ViewModels.Histories) + { + var list = CommitListContainer; + if (list != null && list.SelectedItems.Count == 1) + list.ScrollIntoView(list.SelectedIndex); + } + } + } + private void OnCommitListLayoutUpdated(object _1, EventArgs _2) { var y = CommitListContainer.Scroll?.Offset.Y ?? 0; - if (y != _lastScrollY) + var authorNameColumnWidth = AuthorNameColumnWidth.Value; + if (y != _lastScrollY || authorNameColumnWidth != _lastAuthorNameColumnWidth) { _lastScrollY = y; + _lastAuthorNameColumnWidth = authorNameColumnWidth; CommitGraph.InvalidateVisual(); } } @@ -863,5 +225,6 @@ namespace SourceGit.Views } private double _lastScrollY = 0; + private double _lastAuthorNameColumnWidth = 0; } } From 77d8afe056963fe23f78b15660948fcbb8bd1c91 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 12 Mar 2025 15:10:43 +0800 Subject: [PATCH 354/865] refactor: reduce the times to call `RefreshLayout` Signed-off-by: leo --- src/Views/Histories.axaml.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Views/Histories.axaml.cs b/src/Views/Histories.axaml.cs index 62c283e5..f7055dfa 100644 --- a/src/Views/Histories.axaml.cs +++ b/src/Views/Histories.axaml.cs @@ -22,9 +22,8 @@ namespace SourceGit.Views protected override Type StyleKeyOverride => typeof(Grid); - public override void ApplyTemplate() + public HistoriesLayout() { - base.ApplyTemplate(); RefreshLayout(); } From eaa322dfabd9b91eb4afe360a68645b874f16ed8 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 12 Mar 2025 17:57:31 +0800 Subject: [PATCH 355/865] enhance: re-design commit search result display (#1083) Signed-off-by: leo --- src/Models/Commit.cs | 1 + src/Views/Repository.axaml | 49 ++++++++++++++++++++++---------------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/Models/Commit.cs b/src/Models/Commit.cs index 72ce54bd..0bad8376 100644 --- a/src/Models/Commit.cs +++ b/src/Models/Commit.cs @@ -36,6 +36,7 @@ namespace SourceGit.Models public string AuthorTimeStr => DateTime.UnixEpoch.AddSeconds(AuthorTime).ToLocalTime().ToString(DateTimeFormat.Actived.DateTime); public string CommitterTimeStr => DateTime.UnixEpoch.AddSeconds(CommitterTime).ToLocalTime().ToString(DateTimeFormat.Actived.DateTime); public string AuthorTimeShortStr => DateTime.UnixEpoch.AddSeconds(AuthorTime).ToLocalTime().ToString(DateTimeFormat.Actived.DateOnly); + public string CommitterTimeShortStr => DateTime.UnixEpoch.AddSeconds(CommitterTime).ToLocalTime().ToString(DateTimeFormat.Actived.DateOnly); public bool IsMerged { get; set; } = false; public bool IsCommitterVisible => !Author.Equals(Committer) || AuthorTime != CommitterTime; diff --git a/src/Views/Repository.axaml b/src/Views/Repository.axaml index 1d94e9b2..c8bbde5f 100644 --- a/src/Views/Repository.axaml +++ b/src/Views/Repository.axaml @@ -482,13 +482,13 @@ Padding="4,0" Background="Transparent" BorderThickness="0" - SelectedIndex="{Binding SearchCommitFilterType, Mode=TwoWay}"> + SelectedIndex="{Binding SearchCommitFilterType, Mode=TwoWay}"> - - - - - + + + + + @@ -496,12 +496,13 @@ Margin="4,0,0,0" IsChecked="{Binding OnlySearchCommitsInCurrentBranch, Mode=TwoWay}" IsVisible="{Binding SearchCommitFilterType, Converter={x:Static c:IntConverters.IsGreaterThanZero}}"> - +
+ ScrollViewer.VerticalScrollBarVisibility="Auto" + Grid.IsSharedSizeScope="True"> @@ -527,18 +530,22 @@ - - - - - - - - - - - - + + + + + + + + + + From e4f5c34e0cbe62345e370e723d47b00aacddc626 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 12 Mar 2025 17:58:57 +0800 Subject: [PATCH 356/865] code_style: remove whitespaces Signed-off-by: leo --- src/Views/Repository.axaml | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Views/Repository.axaml b/src/Views/Repository.axaml index c8bbde5f..b16447fa 100644 --- a/src/Views/Repository.axaml +++ b/src/Views/Repository.axaml @@ -86,7 +86,7 @@ - + - + + VerticalContentAlignment="Center"> - @@ -428,7 +428,7 @@ - + + SelectedIndex="{Binding SearchCommitFilterType, Mode=TwoWay}"> @@ -562,7 +562,7 @@ - + - + @@ -649,7 +649,7 @@ - + From f07832c38553cf35b4f7bc521290cc16507e954d Mon Sep 17 00:00:00 2001 From: Morgan Courbet Date: Wed, 12 Mar 2025 15:37:28 +0100 Subject: [PATCH 357/865] docs: fix typo in README.md (cherry picked from commit 59fd2aaab144aa8313ecbfcb5457457359fa0c4f) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4086a641..399916c9 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ For **Windows** users: ``` > [!NOTE] > `winget` will install this software as a commandline tool. You need run `SourceGit` from console or `Win+R` at the first time. Then you can add it to the taskbar. -* You can install the latest stable by `scoope` with follow commands: +* You can install the latest stable by `scoop` with follow commands: ```shell scoop bucket add extras scoop install sourcegit From 7331167be2ca09e0fc9378934fad18c48062d329 Mon Sep 17 00:00:00 2001 From: Gadfly Date: Thu, 13 Mar 2025 09:38:08 +0800 Subject: [PATCH 358/865] fix: schedule DWM frame extension to next render frame on Windows 10 (#1087) The DwmExtendFrameIntoClientArea call needs to be posted to the next render frame to ensure the window handle is fully initialized and avoid potential race conditions. --- src/Native/Windows.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/Native/Windows.cs b/src/Native/Windows.cs index 11b6bd13..eb354f10 100644 --- a/src/Native/Windows.cs +++ b/src/Native/Windows.cs @@ -8,6 +8,7 @@ using System.Text; using Avalonia; using Avalonia.Controls; +using Avalonia.Threading; namespace SourceGit.Native { @@ -214,12 +215,17 @@ namespace SourceGit.Native private void FixWindowFrameOnWin10(Window w) { - var platformHandle = w.TryGetPlatformHandle(); - if (platformHandle == null) - return; + // Schedule the DWM frame extension to run in the next render frame + // to ensure proper timing with the window initialization sequence + Dispatcher.UIThread.InvokeAsync(() => + { + var platformHandle = w.TryGetPlatformHandle(); + if (platformHandle == null) + return; - var margins = new MARGINS { cxLeftWidth = 1, cxRightWidth = 1, cyTopHeight = 1, cyBottomHeight = 1 }; - DwmExtendFrameIntoClientArea(platformHandle.Handle, ref margins); + var margins = new MARGINS { cxLeftWidth = 1, cxRightWidth = 1, cyTopHeight = 1, cyBottomHeight = 1 }; + DwmExtendFrameIntoClientArea(platformHandle.Handle, ref margins); + }, DispatcherPriority.Render); } #region EXTERNAL_EDITOR_FINDER From e430e847ff957e23c9e146197f6ce8690730645e Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 13 Mar 2025 09:49:25 +0800 Subject: [PATCH 359/865] enhance: auto convert spaces with dashes while renaming a branch (#1088) Signed-off-by: leo --- src/ViewModels/RenameBranch.cs | 21 ++++++++++++++++----- src/Views/CreateBranch.axaml | 12 ++---------- src/Views/RenameBranch.axaml | 10 +++++++++- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/ViewModels/RenameBranch.cs b/src/ViewModels/RenameBranch.cs index bd0b4664..0679a5b5 100644 --- a/src/ViewModels/RenameBranch.cs +++ b/src/ViewModels/RenameBranch.cs @@ -12,7 +12,7 @@ namespace SourceGit.ViewModels } [Required(ErrorMessage = "Branch name is required!!!")] - [RegularExpression(@"^[\w\-/\.#]+$", ErrorMessage = "Bad branch name format!")] + [RegularExpression(@"^[\w \-/\.#]+$", ErrorMessage = "Bad branch name format!")] [CustomValidation(typeof(RenameBranch), nameof(ValidateBranchName))] public string Name { @@ -32,9 +32,10 @@ namespace SourceGit.ViewModels { if (ctx.ObjectInstance is RenameBranch rename) { + var fixedName = rename.FixName(name); foreach (var b in rename._repo.Branches) { - if (b.IsLocal && b != rename.Target && b.Name == name) + if (b.IsLocal && b != rename.Target && b.Name == fixedName) { return new ValidationResult("A branch with same name already exists!!!"); } @@ -46,7 +47,8 @@ namespace SourceGit.ViewModels public override Task Sure() { - if (_name == Target.Name) + var fixedName = FixName(_name); + if (fixedName == Target.Name) return null; _repo.SetWatcherEnabled(false); @@ -55,7 +57,7 @@ namespace SourceGit.ViewModels return Task.Run(() => { var oldName = Target.FullName; - var succ = Commands.Branch.Rename(_repo.FullPath, Target.Name, _name); + var succ = Commands.Branch.Rename(_repo.FullPath, Target.Name, fixedName); CallUIThread(() => { if (succ) @@ -65,7 +67,7 @@ namespace SourceGit.ViewModels if (filter.Type == Models.FilterType.LocalBranch && filter.Pattern.Equals(oldName, StringComparison.Ordinal)) { - filter.Pattern = $"refs/heads/{_name}"; + filter.Pattern = $"refs/heads/{fixedName}"; break; } } @@ -78,6 +80,15 @@ namespace SourceGit.ViewModels }); } + private string FixName(string name) + { + if (!name.Contains(' ')) + return name; + + var parts = name.Split(' ', StringSplitOptions.RemoveEmptyEntries); + return string.Join("-", parts); + } + private readonly Repository _repo; private string _name; } diff --git a/src/Views/CreateBranch.axaml b/src/Views/CreateBranch.axaml index ec56ff20..b757bd78 100644 --- a/src/Views/CreateBranch.axaml +++ b/src/Views/CreateBranch.axaml @@ -14,15 +14,7 @@ - - - - - - - - - + - + @@ -11,7 +12,7 @@ - + + + + + + From 0e261cffd20a39847f4a6377715eecb7a8c307aa Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 13 Mar 2025 10:21:54 +0800 Subject: [PATCH 360/865] refactor: rewrite the way to deal with uncommitted local changes when checkout/pull/create branch (#1085) Signed-off-by: leo --- src/Models/DealWithLocalChanges.cs | 9 ------ 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/Checkout.cs | 17 ++++++----- src/ViewModels/CheckoutCommit.cs | 20 ++++++------- src/ViewModels/CreateBranch.cs | 19 +++++++----- src/ViewModels/Pull.cs | 16 +++++----- src/Views/Checkout.axaml | 22 +++++--------- src/Views/Checkout.axaml.cs | 47 ------------------------------ src/Views/CheckoutCommit.axaml | 12 ++++---- src/Views/CreateBranch.axaml | 18 ++++-------- src/Views/CreateBranch.axaml.cs | 47 ------------------------------ src/Views/Pull.axaml | 22 +++++--------- src/Views/Pull.axaml.cs | 47 ------------------------------ 21 files changed, 63 insertions(+), 260 deletions(-) delete mode 100644 src/Models/DealWithLocalChanges.cs diff --git a/src/Models/DealWithLocalChanges.cs b/src/Models/DealWithLocalChanges.cs deleted file mode 100644 index f308a90c..00000000 --- a/src/Models/DealWithLocalChanges.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace SourceGit.Models -{ - public enum DealWithLocalChanges - { - DoNothing, - StashAndReaply, - Discard, - } -} diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index 1d0ca895..759e3a53 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -90,7 +90,6 @@ Branch: Lokale Änderungen: Verwerfen - Nichts tun Stashen & wieder anwenden Cherry Pick Quelle an Commit-Nachricht anhängen @@ -206,7 +205,6 @@ Erstellten Branch auschecken Lokale Änderungen: Verwerfen - Nichts tun Stashen & wieder anwenden Neuer Branch-Name: Branch-Namen eingeben. @@ -517,7 +515,6 @@ Lokaler Branch: Lokale Änderungen: Verwerfen - Nichts tun Stashen & wieder anwenden Ohne Tags fetchen Remote: diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 5df3ca71..90125de8 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -88,7 +88,6 @@ Branch: Local Changes: Discard - Do Nothing Stash & Reapply Cherry Pick Append source to commit message @@ -205,7 +204,6 @@ Check out the created branch Local Changes: Discard - Do Nothing Stash & Reapply New Branch Name: Enter branch name. @@ -520,7 +518,6 @@ Into: Local Changes: Discard - Do Nothing Stash & Reapply Fetch without tags Remote: diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index 4073f512..bcf09e1a 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -91,7 +91,6 @@ Rama: Cambios Locales: Descartar - No Hacer Nada Stash & Reaplicar Cherry Pick Añadir fuente al mensaje de commit @@ -208,7 +207,6 @@ Checkout de la rama creada Cambios Locales: Descartar - No Hacer Nada Stash & Reaplicar Nombre de la Nueva Rama: Introduzca el nombre de la rama. @@ -524,7 +522,6 @@ En: Cambios Locales: Descartar - No Hacer Nada Stash & Reaplicar Fetch sin etiquetas Remoto: diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index 59fe00a8..76405b21 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -83,7 +83,6 @@ Branche : Changements locaux : Annuler - Ne rien faire Mettre en stash et réappliquer Cherry-Pick de ce commit Ajouter la source au message de commit @@ -198,7 +197,6 @@ Récupérer la branche créée Changements locaux : Rejeter - Ne rien faire Stash & Réappliquer Nom de la nouvelle branche : Entrez le nom de la branche. @@ -492,7 +490,6 @@ Dans : Changements locaux : Rejeter - Ne rien faire Stash & Réappliquer Fetch sans les tags Dépôt distant : diff --git a/src/Resources/Locales/it_IT.axaml b/src/Resources/Locales/it_IT.axaml index 6e99decf..f944689c 100644 --- a/src/Resources/Locales/it_IT.axaml +++ b/src/Resources/Locales/it_IT.axaml @@ -91,7 +91,6 @@ Branch: Modifiche Locali: Scarta - Non fare nulla Stasha e Ripristina Cherry Pick Aggiungi sorgente al messaggio di commit @@ -208,7 +207,6 @@ Checkout del Branch Creato Modifiche Locali: Scarta - Non Fare Nulla Stasha e Ripristina Nome Nuovo Branch: Inserisci il nome del branch. @@ -523,7 +521,6 @@ In: Modifiche Locali: Scarta - Non fare nulla Stasha e Riapplica Recupera senza tag Remoto: diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml index 78445bfb..ebff746c 100644 --- a/src/Resources/Locales/pt_BR.axaml +++ b/src/Resources/Locales/pt_BR.axaml @@ -107,7 +107,6 @@ Branch: Alterações Locais: Descartar - Nada Stash & Reaplicar Cherry-Pick Adicionar origem à mensagem de commit @@ -215,7 +214,6 @@ Checar o branch criado Alterações Locais: Descartar - Não Fazer Nada Guardar & Reaplicar Nome do Novo Branch: Insira o nome do branch. @@ -506,7 +504,6 @@ Para: Alterações Locais: Descartar - Não Fazer Nada Guardar & Reaplicar Buscar sem tags Remoto: diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index ff24912e..6815bbeb 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -91,7 +91,6 @@ Ветка: Локальные изменения: Отклонить - Ничего не делать Отложить и примненить повторно Частичный выбор Добавить источник для ревизии сообщения @@ -209,7 +208,6 @@ Проверить созданную ветку Локальные изменения: Отклонить - Ничего не делать Отложить и применить повторно Имя новой ветки: Введите имя ветки. @@ -524,7 +522,6 @@ В: Локальные изменения: Отклонить - Ничего не делать Отложить и применить повторно Забрать без меток Внешний репозиторий: diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 72b434f9..cf796805 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -91,7 +91,6 @@ 目标分支 : 未提交更改 : 丢弃更改 - 不做处理 贮藏并自动恢复 挑选提交 提交信息中追加来源信息 @@ -208,7 +207,6 @@ 完成后切换到新分支 未提交更改 : 丢弃更改 - 不做处理 贮藏并自动恢复 新分支名 : 填写分支名称。 @@ -524,7 +522,6 @@ 本地分支 : 未提交更改 : 丢弃更改 - 不做处理 贮藏并自动恢复 不拉取远程标签 远程 : diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index bc9991f6..539001bd 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -91,7 +91,6 @@ 目標分支: 未提交變更: 捨棄變更 - 不做處理 擱置變更並自動復原 揀選提交 提交資訊中追加來源資訊 @@ -208,7 +207,6 @@ 完成後切換到新分支 未提交變更: 捨棄變更 - 不做處理 擱置變更並自動復原 新分支名稱: 輸入分支名稱。 @@ -523,7 +521,6 @@ 本機分支: 未提交變更: 捨棄變更 - 不做處理 擱置變更並自動復原 不拉取遠端標籤 遠端: diff --git a/src/ViewModels/Checkout.cs b/src/ViewModels/Checkout.cs index 9376741d..3334eba4 100644 --- a/src/ViewModels/Checkout.cs +++ b/src/ViewModels/Checkout.cs @@ -9,16 +9,17 @@ namespace SourceGit.ViewModels get; } - public Models.DealWithLocalChanges PreAction + public bool DiscardLocalChanges { get; set; - } = Models.DealWithLocalChanges.DoNothing; + } public Checkout(Repository repo, string branch) { _repo = repo; Branch = branch; + DiscardLocalChanges = false; View = new Views.Checkout() { DataContext = this }; } @@ -33,7 +34,12 @@ namespace SourceGit.ViewModels var needPopStash = false; if (changes > 0) { - if (PreAction == Models.DealWithLocalChanges.StashAndReaply) + if (DiscardLocalChanges) + { + SetProgressDescription("Discard local changes ..."); + Commands.Discard.All(_repo.FullPath, false); + } + else { SetProgressDescription("Stash local changes ..."); var succ = new Commands.Stash(_repo.FullPath).Push("CHECKOUT_AUTO_STASH"); @@ -45,11 +51,6 @@ namespace SourceGit.ViewModels needPopStash = true; } - else if (PreAction == Models.DealWithLocalChanges.Discard) - { - SetProgressDescription("Discard local changes ..."); - Commands.Discard.All(_repo.FullPath, false); - } } SetProgressDescription("Checkout branch ..."); diff --git a/src/ViewModels/CheckoutCommit.cs b/src/ViewModels/CheckoutCommit.cs index ddc0a0c6..1876a425 100644 --- a/src/ViewModels/CheckoutCommit.cs +++ b/src/ViewModels/CheckoutCommit.cs @@ -9,16 +9,17 @@ namespace SourceGit.ViewModels get; } - public bool AutoStash + public bool DiscardLocalChanges { - get => _autoStash; - set => SetProperty(ref _autoStash, value); + get; + set; } public CheckoutCommit(Repository repo, Models.Commit commit) { _repo = repo; Commit = commit; + DiscardLocalChanges = false; View = new Views.CheckoutCommit() { DataContext = this }; } @@ -33,7 +34,12 @@ namespace SourceGit.ViewModels var needPopStash = false; if (changes > 0) { - if (AutoStash) + if (DiscardLocalChanges) + { + SetProgressDescription("Discard local changes ..."); + Commands.Discard.All(_repo.FullPath, false); + } + else { SetProgressDescription("Stash local changes ..."); var succ = new Commands.Stash(_repo.FullPath).Push("CHECKOUT_AUTO_STASH"); @@ -45,11 +51,6 @@ namespace SourceGit.ViewModels needPopStash = true; } - else - { - SetProgressDescription("Discard local changes ..."); - Commands.Discard.All(_repo.FullPath, false); - } } SetProgressDescription("Checkout commit ..."); @@ -67,6 +68,5 @@ namespace SourceGit.ViewModels } private readonly Repository _repo = null; - private bool _autoStash = true; } } diff --git a/src/ViewModels/CreateBranch.cs b/src/ViewModels/CreateBranch.cs index 01bff031..37db0065 100644 --- a/src/ViewModels/CreateBranch.cs +++ b/src/ViewModels/CreateBranch.cs @@ -19,11 +19,11 @@ namespace SourceGit.ViewModels get; } - public Models.DealWithLocalChanges PreAction + public bool DiscardLocalChanges { get; set; - } = Models.DealWithLocalChanges.DoNothing; + } public bool CheckoutAfterCreated { @@ -47,6 +47,7 @@ namespace SourceGit.ViewModels } BasedOn = branch; + DiscardLocalChanges = false; View = new Views.CreateBranch() { DataContext = this }; } @@ -56,6 +57,7 @@ namespace SourceGit.ViewModels _baseOnRevision = commit.SHA; BasedOn = commit; + DiscardLocalChanges = false; View = new Views.CreateBranch() { DataContext = this }; } @@ -65,6 +67,7 @@ namespace SourceGit.ViewModels _baseOnRevision = tag.SHA; BasedOn = tag; + DiscardLocalChanges = false; View = new Views.CreateBranch() { DataContext = this }; } @@ -98,7 +101,12 @@ namespace SourceGit.ViewModels var needPopStash = false; if (changes > 0) { - if (PreAction == Models.DealWithLocalChanges.StashAndReaply) + if (DiscardLocalChanges) + { + SetProgressDescription("Discard local changes..."); + Commands.Discard.All(_repo.FullPath, false); + } + else { SetProgressDescription("Stash local changes"); succ = new Commands.Stash(_repo.FullPath).Push("CREATE_BRANCH_AUTO_STASH"); @@ -110,11 +118,6 @@ namespace SourceGit.ViewModels needPopStash = true; } - else if (PreAction == Models.DealWithLocalChanges.Discard) - { - SetProgressDescription("Discard local changes..."); - Commands.Discard.All(_repo.FullPath, false); - } } SetProgressDescription($"Create new branch '{fixedName}'"); diff --git a/src/ViewModels/Pull.cs b/src/ViewModels/Pull.cs index ff557792..62d68834 100644 --- a/src/ViewModels/Pull.cs +++ b/src/ViewModels/Pull.cs @@ -38,11 +38,11 @@ namespace SourceGit.ViewModels set => SetProperty(ref _selectedBranch, value, true); } - public Models.DealWithLocalChanges PreAction + public bool DiscardLocalChanges { get; set; - } = Models.DealWithLocalChanges.DoNothing; + } public bool UseRebase { @@ -124,7 +124,12 @@ namespace SourceGit.ViewModels var needPopStash = false; if (changes > 0) { - if (PreAction == Models.DealWithLocalChanges.StashAndReaply) + if (DiscardLocalChanges) + { + SetProgressDescription("Discard local changes ..."); + Commands.Discard.All(_repo.FullPath, false); + } + else { SetProgressDescription("Stash local changes..."); var succ = new Commands.Stash(_repo.FullPath).Push("PULL_AUTO_STASH"); @@ -136,11 +141,6 @@ namespace SourceGit.ViewModels needPopStash = true; } - else if (PreAction == Models.DealWithLocalChanges.Discard) - { - SetProgressDescription("Discard local changes ..."); - Commands.Discard.All(_repo.FullPath, false); - } } bool rs; diff --git a/src/Views/Checkout.axaml b/src/Views/Checkout.axaml index eb1c9de0..3cdfd94e 100644 --- a/src/Views/Checkout.axaml +++ b/src/Views/Checkout.axaml @@ -18,7 +18,7 @@ - + - - + - - + Content="{DynamicResource Text.CreateBranch.LocalChanges.StashAndReply}" + IsChecked="{Binding !DiscardLocalChanges, Mode=TwoWay}"/> + diff --git a/src/Views/Checkout.axaml.cs b/src/Views/Checkout.axaml.cs index da6e6b31..f8398a1d 100644 --- a/src/Views/Checkout.axaml.cs +++ b/src/Views/Checkout.axaml.cs @@ -1,5 +1,4 @@ using Avalonia.Controls; -using Avalonia.Interactivity; namespace SourceGit.Views { @@ -9,51 +8,5 @@ namespace SourceGit.Views { InitializeComponent(); } - - protected override void OnLoaded(RoutedEventArgs e) - { - base.OnLoaded(e); - - var vm = DataContext as ViewModels.Checkout; - if (vm == null) - return; - - switch (vm.PreAction) - { - case Models.DealWithLocalChanges.DoNothing: - RadioDoNothing.IsChecked = true; - break; - case Models.DealWithLocalChanges.StashAndReaply: - RadioStashAndReply.IsChecked = true; - break; - default: - RadioDiscard.IsChecked = true; - break; - } - } - - private void OnLocalChangeActionIsCheckedChanged(object sender, RoutedEventArgs e) - { - var vm = DataContext as ViewModels.Checkout; - if (vm == null) - return; - - if (RadioDoNothing.IsChecked == true) - { - if (vm.PreAction != Models.DealWithLocalChanges.DoNothing) - vm.PreAction = Models.DealWithLocalChanges.DoNothing; - return; - } - - if (RadioStashAndReply.IsChecked == true) - { - if (vm.PreAction != Models.DealWithLocalChanges.StashAndReaply) - vm.PreAction = Models.DealWithLocalChanges.StashAndReaply; - return; - } - - if (vm.PreAction != Models.DealWithLocalChanges.Discard) - vm.PreAction = Models.DealWithLocalChanges.Discard; - } } } diff --git a/src/Views/CheckoutCommit.axaml b/src/Views/CheckoutCommit.axaml index 3ee3943f..9b418823 100644 --- a/src/Views/CheckoutCommit.axaml +++ b/src/Views/CheckoutCommit.axaml @@ -30,16 +30,16 @@ + Margin="0,0,8,0" + IsChecked="{Binding !DiscardLocalChanges, Mode=TwoWay}"/> + GroupName="LocalChanges"/> - - - - + Content="{DynamicResource Text.CreateBranch.LocalChanges.StashAndReply}" + IsChecked="{Binding !DiscardLocalChanges, Mode=TwoWay}"/> + diff --git a/src/Views/CreateBranch.axaml.cs b/src/Views/CreateBranch.axaml.cs index 6499e1c7..6626871b 100644 --- a/src/Views/CreateBranch.axaml.cs +++ b/src/Views/CreateBranch.axaml.cs @@ -1,5 +1,4 @@ using Avalonia.Controls; -using Avalonia.Interactivity; namespace SourceGit.Views { @@ -9,51 +8,5 @@ namespace SourceGit.Views { InitializeComponent(); } - - protected override void OnLoaded(RoutedEventArgs e) - { - base.OnLoaded(e); - - var vm = DataContext as ViewModels.CreateBranch; - if (vm == null) - return; - - switch (vm.PreAction) - { - case Models.DealWithLocalChanges.DoNothing: - RadioDoNothing.IsChecked = true; - break; - case Models.DealWithLocalChanges.StashAndReaply: - RadioStashAndReply.IsChecked = true; - break; - default: - RadioDiscard.IsChecked = true; - break; - } - } - - private void OnLocalChangeActionIsCheckedChanged(object sender, RoutedEventArgs e) - { - var vm = DataContext as ViewModels.CreateBranch; - if (vm == null) - return; - - if (RadioDoNothing.IsChecked == true) - { - if (vm.PreAction != Models.DealWithLocalChanges.DoNothing) - vm.PreAction = Models.DealWithLocalChanges.DoNothing; - return; - } - - if (RadioStashAndReply.IsChecked == true) - { - if (vm.PreAction != Models.DealWithLocalChanges.StashAndReaply) - vm.PreAction = Models.DealWithLocalChanges.StashAndReaply; - return; - } - - if (vm.PreAction != Models.DealWithLocalChanges.Discard) - vm.PreAction = Models.DealWithLocalChanges.Discard; - } } } diff --git a/src/Views/Pull.axaml b/src/Views/Pull.axaml index 3e1f96d9..67121826 100644 --- a/src/Views/Pull.axaml +++ b/src/Views/Pull.axaml @@ -22,7 +22,7 @@ - + - - - + Content="{DynamicResource Text.Pull.LocalChanges.StashAndReply}" + IsChecked="{Binding !DiscardLocalChanges, Mode=TwoWay}"/> + - + diff --git a/src/Views/Pull.axaml.cs b/src/Views/Pull.axaml.cs index 3003f02c..c6b4923e 100644 --- a/src/Views/Pull.axaml.cs +++ b/src/Views/Pull.axaml.cs @@ -1,5 +1,4 @@ using Avalonia.Controls; -using Avalonia.Interactivity; namespace SourceGit.Views { @@ -9,51 +8,5 @@ namespace SourceGit.Views { InitializeComponent(); } - - protected override void OnLoaded(RoutedEventArgs e) - { - base.OnLoaded(e); - - var vm = DataContext as ViewModels.Pull; - if (vm == null) - return; - - switch (vm.PreAction) - { - case Models.DealWithLocalChanges.DoNothing: - RadioDoNothing.IsChecked = true; - break; - case Models.DealWithLocalChanges.StashAndReaply: - RadioStashAndReply.IsChecked = true; - break; - default: - RadioDiscard.IsChecked = true; - break; - } - } - - private void OnLocalChangeActionIsCheckedChanged(object sender, RoutedEventArgs e) - { - var vm = DataContext as ViewModels.Pull; - if (vm == null) - return; - - if (RadioDoNothing.IsChecked == true) - { - if (vm.PreAction != Models.DealWithLocalChanges.DoNothing) - vm.PreAction = Models.DealWithLocalChanges.DoNothing; - return; - } - - if (RadioStashAndReply.IsChecked == true) - { - if (vm.PreAction != Models.DealWithLocalChanges.StashAndReaply) - vm.PreAction = Models.DealWithLocalChanges.StashAndReaply; - return; - } - - if (vm.PreAction != Models.DealWithLocalChanges.Discard) - vm.PreAction = Models.DealWithLocalChanges.Discard; - } } } From 519bdf1ddc1bb7bba6fb0187d1d9d208797115e6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 13 Mar 2025 02:22:09 +0000 Subject: [PATCH 361/865] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 399916c9..cc37aae9 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-99.08%25-yellow)](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-91.68%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-99.87%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.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-99.07%25-yellow)](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-91.64%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-99.87%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.38%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 a5abbbba..155e031a 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -1,4 +1,4 @@ -### de_DE.axaml: 99.08% +### de_DE.axaml: 99.07%
@@ -24,7 +24,7 @@
-### fr_FR.axaml: 91.68% +### fr_FR.axaml: 91.64%
@@ -106,7 +106,7 @@
-### pt_BR.axaml: 91.41% +### pt_BR.axaml: 91.38%
From b9b684a83d58740d2bd802e08ad83746fcb97359 Mon Sep 17 00:00:00 2001 From: Gadfly Date: Thu, 13 Mar 2025 15:05:30 +0800 Subject: [PATCH 362/865] fix: improve font string processing in SetFonts method (#1092) --- src/App.axaml.cs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/App.axaml.cs b/src/App.axaml.cs index 25e32323..504981f7 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -181,6 +181,9 @@ namespace SourceGit app._fontsOverrides = null; } + defaultFont = ProcessFontString(defaultFont); + monospaceFont = ProcessFontString(monospaceFont); + var resDic = new ResourceDictionary(); if (!string.IsNullOrEmpty(defaultFont)) resDic.Add("Fonts.Default", new FontFamily(defaultFont)); @@ -437,6 +440,28 @@ namespace SourceGit return true; } + private static string ProcessFontString(string input) + { + if (string.IsNullOrEmpty(input)) return string.Empty; + + var parts = input.Split(','); + var result = new StringBuilder(); + var isFirst = true; + + foreach (var part in parts) + { + var trimmed = part.Trim(); + if (!string.IsNullOrEmpty(trimmed)) + { + if (!isFirst) result.Append(','); + result.Append(trimmed); + isFirst = false; + } + } + + return result.ToString(); + } + private bool TryLaunchAsCoreEditor(IClassicDesktopStyleApplicationLifetime desktop) { var args = desktop.Args; From 9560496c7bf9cec50f98f19d8b37dbe98d71fcf9 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 13 Mar 2025 15:17:20 +0800 Subject: [PATCH 363/865] code_review: PR #1092 - Remove `SourceGit.ViewModels.Preference.FixFontFamilyName` (it is not necessary any more) - Use `string.Join` instead of `StringBuilder` to make the logic more clear Signed-off-by: leo --- src/App.axaml.cs | 24 +++++++++------------ src/ViewModels/Preferences.cs | 40 ++++------------------------------- 2 files changed, 14 insertions(+), 50 deletions(-) diff --git a/src/App.axaml.cs b/src/App.axaml.cs index 504981f7..79eeda4e 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -181,8 +181,8 @@ namespace SourceGit app._fontsOverrides = null; } - defaultFont = ProcessFontString(defaultFont); - monospaceFont = ProcessFontString(monospaceFont); + defaultFont = FixFontFamilyName(defaultFont); + monospaceFont = FixFontFamilyName(monospaceFont); var resDic = new ResourceDictionary(); if (!string.IsNullOrEmpty(defaultFont)) @@ -440,26 +440,22 @@ namespace SourceGit return true; } - private static string ProcessFontString(string input) + private static string FixFontFamilyName(string input) { - if (string.IsNullOrEmpty(input)) return string.Empty; + if (string.IsNullOrEmpty(input)) + return string.Empty; var parts = input.Split(','); - var result = new StringBuilder(); - var isFirst = true; + var trimmed = new List(); foreach (var part in parts) { - var trimmed = part.Trim(); - if (!string.IsNullOrEmpty(trimmed)) - { - if (!isFirst) result.Append(','); - result.Append(trimmed); - isFirst = false; - } + var t = part.Trim(); + if (!string.IsNullOrEmpty(t)) + trimmed.Add(t); } - return result.ToString(); + return trimmed.Count > 0 ? string.Join(',', trimmed) : string.Empty; } private bool TryLaunchAsCoreEditor(IClassicDesktopStyleApplicationLifetime desktop) diff --git a/src/ViewModels/Preferences.cs b/src/ViewModels/Preferences.cs index dae90517..0b1d841e 100644 --- a/src/ViewModels/Preferences.cs +++ b/src/ViewModels/Preferences.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using Avalonia.Collections; @@ -66,9 +65,8 @@ namespace SourceGit.ViewModels get => _defaultFontFamily; set { - var name = FixFontFamilyName(value); - if (SetProperty(ref _defaultFontFamily, name) && !_isLoading) - App.SetFonts(_defaultFontFamily, _monospaceFontFamily, _onlyUseMonoFontInEditor); + if (SetProperty(ref _defaultFontFamily, value) && !_isLoading) + App.SetFonts(value, _monospaceFontFamily, _onlyUseMonoFontInEditor); } } @@ -77,9 +75,8 @@ namespace SourceGit.ViewModels get => _monospaceFontFamily; set { - var name = FixFontFamilyName(value); - if (SetProperty(ref _monospaceFontFamily, name) && !_isLoading) - App.SetFonts(_defaultFontFamily, _monospaceFontFamily, _onlyUseMonoFontInEditor); + if (SetProperty(ref _monospaceFontFamily, value) && !_isLoading) + App.SetFonts(_defaultFontFamily, value, _onlyUseMonoFontInEditor); } } @@ -620,35 +617,6 @@ namespace SourceGit.ViewModels return changed; } - private string FixFontFamilyName(string name) - { - var trimmed = name.Trim(); - if (string.IsNullOrEmpty(trimmed)) - return string.Empty; - - var builder = new StringBuilder(); - var lastIsSpace = false; - for (int i = 0; i < trimmed.Length; i++) - { - var c = trimmed[i]; - if (char.IsWhiteSpace(c)) - { - if (lastIsSpace) - continue; - - lastIsSpace = true; - } - else - { - lastIsSpace = false; - } - - builder.Append(c); - } - - return builder.ToString(); - } - private static Preferences _instance = null; private static bool _isLoading = false; From 67f4330dd4799c4358be3852a566207aae30cb3f Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 13 Mar 2025 15:23:43 +0800 Subject: [PATCH 364/865] code_style: arrange methods in `App.axaml.cs` Signed-off-by: leo --- src/App.axaml.cs | 90 ++++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/src/App.axaml.cs b/src/App.axaml.cs index 79eeda4e..f59d35db 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -77,6 +77,31 @@ namespace SourceGit Native.OS.SetupApp(builder); return builder; } + + private static void LogException(Exception ex) + { + if (ex == null) + return; + + var builder = new StringBuilder(); + builder.Append($"Crash::: {ex.GetType().FullName}: {ex.Message}\n\n"); + builder.Append("----------------------------\n"); + builder.Append($"Version: {Assembly.GetExecutingAssembly().GetName().Version}\n"); + builder.Append($"OS: {Environment.OSVersion}\n"); + builder.Append($"Framework: {AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName}\n"); + builder.Append($"Source: {ex.Source}\n"); + builder.Append($"Thread Name: {Thread.CurrentThread.Name ?? "Unnamed"}\n"); + builder.Append($"User: {Environment.UserName}\n"); + builder.Append($"App Start Time: {Process.GetCurrentProcess().StartTime}\n"); + builder.Append($"Exception Time: {DateTime.Now}\n"); + builder.Append($"Memory Usage: {Process.GetCurrentProcess().PrivateMemorySize64 / 1024 / 1024} MB\n"); + builder.Append($"---------------------------\n\n"); + builder.Append(ex); + + var time = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"); + var file = Path.Combine(Native.OS.DataDir, $"crash_{time}.log"); + File.WriteAllText(file, builder.ToString()); + } #endregion #region Utility Functions @@ -181,8 +206,8 @@ namespace SourceGit app._fontsOverrides = null; } - defaultFont = FixFontFamilyName(defaultFont); - monospaceFont = FixFontFamilyName(monospaceFont); + defaultFont = app.FixFontFamilyName(defaultFont); + monospaceFont = app.FixFontFamilyName(monospaceFont); var resDic = new ResourceDictionary(); if (!string.IsNullOrEmpty(defaultFont)) @@ -328,31 +353,6 @@ namespace SourceGit } #endregion - private static void LogException(Exception ex) - { - if (ex == null) - return; - - var builder = new StringBuilder(); - builder.Append($"Crash::: {ex.GetType().FullName}: {ex.Message}\n\n"); - builder.Append("----------------------------\n"); - builder.Append($"Version: {Assembly.GetExecutingAssembly().GetName().Version}\n"); - builder.Append($"OS: {Environment.OSVersion}\n"); - builder.Append($"Framework: {AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName}\n"); - builder.Append($"Source: {ex.Source}\n"); - builder.Append($"Thread Name: {Thread.CurrentThread.Name ?? "Unnamed"}\n"); - builder.Append($"User: {Environment.UserName}\n"); - builder.Append($"App Start Time: {Process.GetCurrentProcess().StartTime}\n"); - builder.Append($"Exception Time: {DateTime.Now}\n"); - builder.Append($"Memory Usage: {Process.GetCurrentProcess().PrivateMemorySize64 / 1024 / 1024} MB\n"); - builder.Append($"---------------------------\n\n"); - builder.Append(ex); - - var time = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"); - var file = Path.Combine(Native.OS.DataDir, $"crash_{time}.log"); - File.WriteAllText(file, builder.ToString()); - } - private static bool TryLaunchAsRebaseTodoEditor(string[] args, out int exitCode) { exitCode = -1; @@ -440,24 +440,6 @@ namespace SourceGit return true; } - private static string FixFontFamilyName(string input) - { - if (string.IsNullOrEmpty(input)) - return string.Empty; - - var parts = input.Split(','); - var trimmed = new List(); - - foreach (var part in parts) - { - var t = part.Trim(); - if (!string.IsNullOrEmpty(t)) - trimmed.Add(t); - } - - return trimmed.Count > 0 ? string.Join(',', trimmed) : string.Empty; - } - private bool TryLaunchAsCoreEditor(IClassicDesktopStyleApplicationLifetime desktop) { var args = desktop.Args; @@ -567,6 +549,24 @@ namespace SourceGit }); } + private string FixFontFamilyName(string input) + { + if (string.IsNullOrEmpty(input)) + return string.Empty; + + var parts = input.Split(','); + var trimmed = new List(); + + foreach (var part in parts) + { + var t = part.Trim(); + if (!string.IsNullOrEmpty(t)) + trimmed.Add(t); + } + + return trimmed.Count > 0 ? string.Join(',', trimmed) : string.Empty; + } + private ViewModels.Launcher _launcher = null; private ResourceDictionary _activeLocale = null; private ResourceDictionary _themeOverrides = null; From 9645b65db669af8fa2b5b24df0e2765d0d576182 Mon Sep 17 00:00:00 2001 From: Michael Pakhantsov Date: Fri, 14 Mar 2025 03:26:59 +0200 Subject: [PATCH 365/865] Explicitly provided fully qualified reference for the git branch, becase can be exists a tag and a branch with identical names (#1093) Fix push command for branch deletion Updated the `push` command to use `--delete refs/heads/{name}` instead of `--delete {name}` for clearer branch reference when deleting a remote branch. Co-authored-by: Michael Pakhantsov --- src/Commands/Branch.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Commands/Branch.cs b/src/Commands/Branch.cs index 391aeeb2..d56dfa97 100644 --- a/src/Commands/Branch.cs +++ b/src/Commands/Branch.cs @@ -62,7 +62,7 @@ if (exists) { cmd.SSHKey = new Config(repo).Get($"remote.{remote}.sshkey"); - cmd.Args = $"push {remote} --delete {name}"; + cmd.Args = $"push {remote} --delete refs/heads/{name}"; } else { From c8bee2f6ba9f611e125126b7729a91ebdb2b7d31 Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 14 Mar 2025 09:36:34 +0800 Subject: [PATCH 366/865] code_review: PR #1093 Merge deleting branch and tag on remote into `SourceGit.Commands.Push(repo, remote, refname, isDelete)` Signed-off-by: leo --- src/Commands/Branch.cs | 17 +++++------------ src/Commands/Push.cs | 4 ++-- src/Commands/Tag.cs | 4 +--- src/ViewModels/CreateTag.cs | 2 +- src/ViewModels/PushTag.cs | 7 ++++--- 5 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/Commands/Branch.cs b/src/Commands/Branch.cs index d56dfa97..2dc8a98d 100644 --- a/src/Commands/Branch.cs +++ b/src/Commands/Branch.cs @@ -54,21 +54,14 @@ public static bool DeleteRemote(string repo, string remote, string name) { + bool exists = new Remote(repo).HasBranch(remote, name); + if (exists) + return new Push(repo, remote, $"refs/heads/{name}", true).Exec(); + var cmd = new Command(); cmd.WorkingDirectory = repo; cmd.Context = repo; - - bool exists = new Remote(repo).HasBranch(remote, name); - if (exists) - { - cmd.SSHKey = new Config(repo).Get($"remote.{remote}.sshkey"); - cmd.Args = $"push {remote} --delete refs/heads/{name}"; - } - else - { - cmd.Args = $"branch -D -r {remote}/{name}"; - } - + cmd.Args = $"branch -D -r {remote}/{name}"; return cmd.Exec(); } } diff --git a/src/Commands/Push.cs b/src/Commands/Push.cs index 69b859ab..dc81f606 100644 --- a/src/Commands/Push.cs +++ b/src/Commands/Push.cs @@ -26,7 +26,7 @@ namespace SourceGit.Commands Args += $"{remote} {local}:{remoteBranch}"; } - public Push(string repo, string remote, string tag, bool isDelete) + public Push(string repo, string remote, string refname, bool isDelete) { WorkingDirectory = repo; Context = repo; @@ -36,7 +36,7 @@ namespace SourceGit.Commands if (isDelete) Args += "--delete "; - Args += $"{remote} refs/tags/{tag}"; + Args += $"{remote} {refname}"; } protected override void OnReadline(string line) diff --git a/src/Commands/Tag.cs b/src/Commands/Tag.cs index fa11e366..23dbb11c 100644 --- a/src/Commands/Tag.cs +++ b/src/Commands/Tag.cs @@ -48,9 +48,7 @@ namespace SourceGit.Commands if (remotes != null) { foreach (var r in remotes) - { - new Push(repo, r.Name, name, true).Exec(); - } + new Push(repo, r.Name, $"refs/tags/{name}", true).Exec(); } return true; diff --git a/src/ViewModels/CreateTag.cs b/src/ViewModels/CreateTag.cs index a6d7255b..86ae7118 100644 --- a/src/ViewModels/CreateTag.cs +++ b/src/ViewModels/CreateTag.cs @@ -96,7 +96,7 @@ namespace SourceGit.ViewModels foreach (var remote in remotes) { SetProgressDescription($"Pushing tag to remote {remote.Name} ..."); - new Commands.Push(_repo.FullPath, remote.Name, _tagName, false).Exec(); + new Commands.Push(_repo.FullPath, remote.Name, $"refs/tags/{_tagName}", false).Exec(); } } diff --git a/src/ViewModels/PushTag.cs b/src/ViewModels/PushTag.cs index 54673fbe..de2941d2 100644 --- a/src/ViewModels/PushTag.cs +++ b/src/ViewModels/PushTag.cs @@ -43,13 +43,14 @@ namespace SourceGit.ViewModels return Task.Run(() => { - bool succ = true; + var succ = true; + var tag = $"refs/tags/{Target.Name}"; if (_pushAllRemotes) { foreach (var remote in _repo.Remotes) { SetProgressDescription($"Pushing tag to remote {remote.Name} ..."); - succ = new Commands.Push(_repo.FullPath, remote.Name, Target.Name, false).Exec(); + succ = new Commands.Push(_repo.FullPath, remote.Name, tag, false).Exec(); if (!succ) break; } @@ -57,7 +58,7 @@ namespace SourceGit.ViewModels else { SetProgressDescription($"Pushing tag to remote {SelectedRemote.Name} ..."); - succ = new Commands.Push(_repo.FullPath, SelectedRemote.Name, Target.Name, false).Exec(); + succ = new Commands.Push(_repo.FullPath, SelectedRemote.Name, tag, false).Exec(); } CallUIThread(() => _repo.SetWatcherEnabled(true)); From c3e1fb93b6fcd42b5156c999371e1f4f61537fb5 Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 14 Mar 2025 10:54:09 +0800 Subject: [PATCH 367/865] refactor: fix maxOS `PATH` env Signed-off-by: leo --- src/Commands/Command.cs | 4 ---- src/Commands/ExecuteCustomAction.cs | 8 -------- src/Native/MacOS.cs | 15 ++++++++++++++- src/Native/OS.cs | 6 ------ 4 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/Commands/Command.cs b/src/Commands/Command.cs index 5197de11..0fef1235 100644 --- a/src/Commands/Command.cs +++ b/src/Commands/Command.cs @@ -198,10 +198,6 @@ namespace SourceGit.Commands start.Environment.Add("LC_ALL", "C"); } - // Fix macOS `PATH` env - if (OperatingSystem.IsMacOS() && !string.IsNullOrEmpty(Native.OS.CustomPathEnv)) - start.Environment.Add("PATH", Native.OS.CustomPathEnv); - // Force using this app as git editor. switch (Editor) { diff --git a/src/Commands/ExecuteCustomAction.cs b/src/Commands/ExecuteCustomAction.cs index 894637a5..000c8fd1 100644 --- a/src/Commands/ExecuteCustomAction.cs +++ b/src/Commands/ExecuteCustomAction.cs @@ -17,10 +17,6 @@ namespace SourceGit.Commands start.CreateNoWindow = true; start.WorkingDirectory = repo; - // Fix macOS `PATH` env - if (OperatingSystem.IsMacOS() && !string.IsNullOrEmpty(Native.OS.CustomPathEnv)) - start.Environment.Add("PATH", Native.OS.CustomPathEnv); - try { Process.Start(start); @@ -44,10 +40,6 @@ namespace SourceGit.Commands start.StandardErrorEncoding = Encoding.UTF8; start.WorkingDirectory = repo; - // Fix macOS `PATH` env - if (OperatingSystem.IsMacOS() && !string.IsNullOrEmpty(Native.OS.CustomPathEnv)) - start.Environment.Add("PATH", Native.OS.CustomPathEnv); - var proc = new Process() { StartInfo = start }; var builder = new StringBuilder(); diff --git a/src/Native/MacOS.cs b/src/Native/MacOS.cs index 633ef5eb..123b160b 100644 --- a/src/Native/MacOS.cs +++ b/src/Native/MacOS.cs @@ -18,9 +18,22 @@ namespace SourceGit.Native DisableDefaultApplicationMenuItems = true, }); + // Fix `PATH` env on macOS. + var path = Environment.GetEnvironmentVariable("PATH"); + if (string.IsNullOrEmpty(path)) + path = "/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"; + else if (!path.Contains("/opt/homebrew/", StringComparison.Ordinal)) + path = "/opt/homebrew/bin:/opt/homebrew/sbin:" + path; + var customPathFile = Path.Combine(OS.DataDir, "PATH"); if (File.Exists(customPathFile)) - OS.CustomPathEnv = File.ReadAllText(customPathFile).Trim(); + { + var env = File.ReadAllText(customPathFile).Trim(); + if (!string.IsNullOrEmpty(env)) + path = env; + } + + Environment.SetEnvironmentVariable("PATH", path); } public string FindGitExecutable() diff --git a/src/Native/OS.cs b/src/Native/OS.cs index 3a688654..f11d1e7f 100644 --- a/src/Native/OS.cs +++ b/src/Native/OS.cs @@ -31,12 +31,6 @@ namespace SourceGit.Native private set; } = string.Empty; - public static string CustomPathEnv - { - get; - set; - } = string.Empty; - public static string GitExecutable { get => _gitExecutable; From db504241eae8fc93813b4eca2ddbdab3c52306b8 Mon Sep 17 00:00:00 2001 From: Asurada <43401755+ousugo@users.noreply.github.com> Date: Fri, 14 Mar 2025 16:57:03 +0800 Subject: [PATCH 368/865] feat: add translation for "1 hour ago" in multiple languages (#1096) --- src/Resources/Locales/de_DE.axaml | 1 + src/Resources/Locales/en_US.axaml | 1 + 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 | 1 + src/Resources/Locales/zh_TW.axaml | 1 + src/Views/CommitTimeTextBlock.cs | 5 ++++- 10 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index 759e3a53..aff8ffc5 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -443,6 +443,7 @@ Einfügen Gerade eben Vor {0} Minuten + Vor 1 Stunde Vor {0} Stunden Gestern Vor {0} Tagen diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 90125de8..818bd9bb 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -444,6 +444,7 @@ Paste Just now {0} minutes ago + 1 hour ago {0} hours ago Yesterday {0} days ago diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index bcf09e1a..e909a14e 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -447,6 +447,7 @@ Pegar Justo ahora Hace {0} minutos + Hace 1 hora Hace {0} horas Ayer Hace {0} días diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index 76405b21..aecea9ad 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -422,6 +422,7 @@ Coller A l'instant il y a {0} minutes + il y a 1 heure il y a {0} heures Hier il y a {0} jours diff --git a/src/Resources/Locales/it_IT.axaml b/src/Resources/Locales/it_IT.axaml index f944689c..4dcc8771 100644 --- a/src/Resources/Locales/it_IT.axaml +++ b/src/Resources/Locales/it_IT.axaml @@ -448,6 +448,7 @@ Incolla Proprio ora {0} minuti fa + 1 ora fa {0} ore fa Ieri {0} giorni fa diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml index ebff746c..b146bf0e 100644 --- a/src/Resources/Locales/pt_BR.axaml +++ b/src/Resources/Locales/pt_BR.axaml @@ -435,6 +435,7 @@ Colar Agora mesmo {0} minutos atrás + 1 hora atrás {0} horas atrás Ontem {0} dias atrás diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index 6815bbeb..07fb7c94 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -448,6 +448,7 @@ Вставить Сейчас {0} минут назад + 1 час назад {0} часов назад Вчера {0} дней назад diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index cf796805..2d160ad2 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -447,6 +447,7 @@ 粘贴 刚刚 {0}分钟前 + 1小时前 {0}小时前 昨天 {0}天前 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 539001bd..e50a600d 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -447,6 +447,7 @@ 貼上 剛剛 {0} 分鐘前 + 1 小時前 {0} 小時前 昨天 {0} 天前 diff --git a/src/Views/CommitTimeTextBlock.cs b/src/Views/CommitTimeTextBlock.cs index 6947f7f2..db63e8a6 100644 --- a/src/Views/CommitTimeTextBlock.cs +++ b/src/Views/CommitTimeTextBlock.cs @@ -129,7 +129,10 @@ namespace SourceGit.Views return App.Text("Period.MinutesAgo", (int)span.TotalMinutes); if (span.TotalDays < 1) - return App.Text("Period.HoursAgo", (int)span.TotalHours); + { + var hours = (int)span.TotalHours; + return hours == 1 ? App.Text("Period.HourAgo") : App.Text("Period.HoursAgo", hours); + } var lastDay = now.AddDays(-1).Date; if (localTime >= lastDay) From a46e52582fd9f8e5930fe76bec86386380d4cf7a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 14 Mar 2025 08:57:15 +0000 Subject: [PATCH 369/865] 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 cc37aae9..c932ec8a 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-99.07%25-yellow)](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-91.64%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-99.87%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.38%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.07%25-yellow)](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-91.66%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-99.87%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.39%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 155e031a..e3f9d2a1 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -24,7 +24,7 @@
-### fr_FR.axaml: 91.64% +### fr_FR.axaml: 91.66%
@@ -106,7 +106,7 @@
-### pt_BR.axaml: 91.38% +### pt_BR.axaml: 91.39%
From 66517fd4bf1ed05bd91a1002cfc9d9a508559131 Mon Sep 17 00:00:00 2001 From: Gadfly Date: Sun, 16 Mar 2025 11:23:42 +0800 Subject: [PATCH 370/865] enhance: add tooltips to various UI elements for better accessibility (#1097) * enhance: add tooltips to various UI elements for better accessibility * refactor: simplify user string conversion --- src/Models/User.cs | 5 +++++ src/Views/ChangeCollectionView.axaml | 13 ++++++++++--- src/Views/DiffView.axaml | 2 +- src/Views/Histories.axaml | 11 +++++++++-- src/Views/RevisionFiles.axaml | 2 +- 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/Models/User.cs b/src/Models/User.cs index 850bcf2f..066ab747 100644 --- a/src/Models/User.cs +++ b/src/Models/User.cs @@ -43,6 +43,11 @@ namespace SourceGit.Models return _caches.GetOrAdd(data, key => new User(key)); } + public override string ToString() + { + return $"{Name} <{Email}>"; + } + private static ConcurrentDictionary _caches = new ConcurrentDictionary(); private readonly int _hash; } diff --git a/src/Views/ChangeCollectionView.axaml b/src/Views/ChangeCollectionView.axaml index 6ce3d033..2b0f5bfa 100644 --- a/src/Views/ChangeCollectionView.axaml +++ b/src/Views/ChangeCollectionView.axaml @@ -39,7 +39,8 @@ + DoubleTapped="OnRowDoubleTapped" + ToolTip.Tip="{Binding FullPath}"> - + - + - + diff --git a/src/Views/Histories.axaml b/src/Views/Histories.axaml index 583e17c1..afe2c1b7 100644 --- a/src/Views/Histories.axaml +++ b/src/Views/Histories.axaml @@ -126,7 +126,11 @@ - + - + - + From 84979b20b330144a0dea8ea41ae48986943e079c Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 17 Mar 2025 09:32:31 +0800 Subject: [PATCH 371/865] ux: force using `VertialAlignment="Center"` for sign info of commit (#1098) Signed-off-by: leo --- src/Views/CommitBaseInfo.axaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Views/CommitBaseInfo.axaml b/src/Views/CommitBaseInfo.axaml index 4ff8f20f..692d04b8 100644 --- a/src/Views/CommitBaseInfo.axaml +++ b/src/Views/CommitBaseInfo.axaml @@ -80,10 +80,10 @@ - - - - + + + + From 34f86189895c74e7ddd798ead684782f4263ff49 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 17 Mar 2025 09:37:40 +0800 Subject: [PATCH 372/865] version: Release 2025.09 Signed-off-by: leo --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index a75bd422..23993bfb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2025.08 \ No newline at end of file +2025.09 \ No newline at end of file From 7caa03a09bbc7770cbf85ba8d16f23a9aa077864 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 17 Mar 2025 09:57:52 +0800 Subject: [PATCH 373/865] project: upgrade `AvaloniaEdit` to `11.2.0` Signed-off-by: leo --- src/SourceGit.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SourceGit.csproj b/src/SourceGit.csproj index 34e4eab2..3578d59f 100644 --- a/src/SourceGit.csproj +++ b/src/SourceGit.csproj @@ -46,8 +46,8 @@ - - + + From 450dadf76ce582b3f1e59dd56f822d7c1f194c86 Mon Sep 17 00:00:00 2001 From: Gadfly Date: Mon, 17 Mar 2025 10:12:44 +0800 Subject: [PATCH 374/865] feat: Add JSP grammar support and improve TextMateHelper file type handling (#1100) - Extend grammar support by allowing multiple file extensions per grammar and adding JSP file type handling. - Add a new JSON grammar file for JavaServer Pages (JSP) syntax highlighting. --- src/Models/TextMateHelper.cs | 22 +- src/Resources/Grammars/jsp.json | 1206 +++++++++++++++++++++++++++++++ 2 files changed, 1218 insertions(+), 10 deletions(-) create mode 100644 src/Resources/Grammars/jsp.json diff --git a/src/Models/TextMateHelper.cs b/src/Models/TextMateHelper.cs index 0eb5e489..b7efae72 100644 --- a/src/Models/TextMateHelper.cs +++ b/src/Models/TextMateHelper.cs @@ -21,10 +21,11 @@ namespace SourceGit.Models { private static readonly ExtraGrammar[] s_extraGrammars = [ - new ExtraGrammar("source.toml", ".toml", "toml.json"), - new ExtraGrammar("source.kotlin", ".kotlin", "kotlin.json"), - new ExtraGrammar("source.hx", ".hx", "haxe.json"), - new ExtraGrammar("source.hxml", ".hxml", "hxml.json"), + new ExtraGrammar("source.toml", [".toml"], "toml.json"), + new ExtraGrammar("source.kotlin", [".kotlin", ".kt", ".kts"], "kotlin.json"), + new ExtraGrammar("source.hx", [".hx"], "haxe.json"), + new ExtraGrammar("source.hxml", [".hxml"], "hxml.json"), + new ExtraGrammar("text.html.jsp", [".jsp", ".jspf", ".tag"], "jsp.json"), ]; public static string GetScope(string file, RegistryOptions reg) @@ -36,13 +37,14 @@ namespace SourceGit.Models extension = ".xml"; else if (extension == ".command") extension = ".sh"; - else if (extension == ".kt" || extension == ".kts") - extension = ".kotlin"; foreach (var grammar in s_extraGrammars) { - if (grammar.Extension.Equals(extension, StringComparison.OrdinalIgnoreCase)) - return grammar.Scope; + foreach (var ext in grammar.Extensions) + { + if (ext.Equals(extension, StringComparison.OrdinalIgnoreCase)) + return grammar.Scope; + } } return reg.GetScopeByExtension(extension); @@ -71,10 +73,10 @@ namespace SourceGit.Models return reg.GetGrammar(scopeName); } - private record ExtraGrammar(string Scope, string Extension, string File) + private record ExtraGrammar(string Scope, List Extensions, string File) { public readonly string Scope = Scope; - public readonly string Extension = Extension; + public readonly List Extensions = Extensions; public readonly string File = File; } } diff --git a/src/Resources/Grammars/jsp.json b/src/Resources/Grammars/jsp.json new file mode 100644 index 00000000..f0067748 --- /dev/null +++ b/src/Resources/Grammars/jsp.json @@ -0,0 +1,1206 @@ +{ + "information_for_contributors": [ + "This file has been copied from https://github.com/J0hnMilt0n/vscode-jsp/blob/b33b7e4d47f3b5f4b82e93dfcadd180149153d02/syntaxes/jsp.tmLanguage.json" + ], + "fileTypes": [ + "jsp", + "jspf", + "tag" + ], + "injections": { + "text.html.jsp - (meta.embedded.block.jsp | meta.embedded.line.jsp | meta.tag | comment), meta.tag string.quoted": { + "patterns": [ + { + "include": "#comment" + }, + { + "include": "#declaration" + }, + { + "include": "#expression" + }, + { + "include": "#el_expression" + }, + { + "include": "#tags" + }, + { + "begin": "(^\\s*)(?=<%(?=\\s))", + "beginCaptures": { + "0": { + "name": "punctuation.whitespace.embedded.leading.erb" + } + }, + "end": "(?!\\G)(\\s*$\\n)?", + "endCaptures": { + "0": { + "name": "punctuation.whitespace.embedded.trailing.erb" + } + }, + "patterns": [ + { + "include": "#scriptlet" + } + ] + }, + { + "include": "#scriptlet" + } + ] + } + }, + "keyEquivalent": "^~J", + "name": "JavaServer Pages", + "patterns": [ + { + "include": "#xml_tags" + }, + { + "include": "text.html.basic" + } + ], + "repository": { + "comment": { + "begin": "<%--", + "captures": { + "0": { + "name": "punctuation.definition.comment.jsp" + } + }, + "end": "--%>", + "name": "comment.block.jsp" + }, + "declaration": { + "begin": "<%!", + "beginCaptures": { + "0": { + "name": "punctuation.section.embedded.begin.jsp" + } + }, + "contentName": "source.java", + "end": "(%)>", + "endCaptures": { + "0": { + "name": "punctuation.section.embedded.end.jsp" + }, + "1": { + "name": "source.java" + } + }, + "name": "meta.embedded.line.declaration.jsp", + "patterns": [ + { + "include": "source.java" + } + ] + }, + "el_expression": { + "begin": "\\$\\{", + "beginCaptures": { + "0": { + "name": "punctuation.section.embedded.begin.jsp" + } + }, + "contentName": "source.java", + "end": "(\\})", + "endCaptures": { + "0": { + "name": "punctuation.section.embedded.end.jsp" + }, + "1": { + "name": "source.java" + } + }, + "name": "meta.embedded.line.el_expression.jsp", + "patterns": [ + { + "include": "source.java" + } + ] + }, + "expression": { + "begin": "<%=", + "beginCaptures": { + "0": { + "name": "punctuation.section.embedded.begin.jsp" + } + }, + "contentName": "source.java", + "end": "(%)>", + "endCaptures": { + "0": { + "name": "punctuation.section.embedded.end.jsp" + }, + "1": { + "name": "source.java" + } + }, + "name": "meta.embedded.line.expression.jsp", + "patterns": [ + { + "include": "source.java" + } + ] + }, + "scriptlet": { + "begin": "<%", + "beginCaptures": { + "0": { + "name": "punctuation.section.embedded.begin.jsp" + } + }, + "contentName": "source.java", + "end": "(%)>", + "endCaptures": { + "0": { + "name": "punctuation.section.embedded.end.jsp" + }, + "1": { + "name": "source.java" + } + }, + "name": "meta.embedded.block.scriptlet.jsp", + "patterns": [ + { + "match": "\\{", + "name": "punctuation.section.scope.begin.java" + }, + { + "match": "\\}", + "name": "punctuation.section.scope.end.java" + }, + { + "include": "source.java" + } + ] + }, + "tags": { + "begin": "(<%@)\\s*(?=(attribute|include|page|tag|taglib|variable)\\s)", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.jsp" + } + }, + "end": "%>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.jsp" + } + }, + "name": "meta.tag.template.include.jsp", + "patterns": [ + { + "begin": "\\G(attribute)(?=\\s)", + "captures": { + "1": { + "name": "keyword.control.attribute.jsp" + } + }, + "end": "(?=%>)", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(name|required|fragment|rtexprvalue|type|description)(=)((\")[^\"]*(\"))" + } + ] + }, + { + "begin": "\\G(include)(?=\\s)", + "captures": { + "1": { + "name": "keyword.control.include.jsp" + } + }, + "end": "(?=%>)", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(file)(=)((\")[^\"]*(\"))" + } + ] + }, + { + "begin": "\\G(page)(?=\\s)", + "captures": { + "1": { + "name": "keyword.control.page.jsp" + } + }, + "end": "(?=%>)", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(language|extends|import|session|buffer|autoFlush|isThreadSafe|info|errorPage|isErrorPage|contentType|pageEncoding|isElIgnored)(=)((\")[^\"]*(\"))" + } + ] + }, + { + "begin": "\\G(tag)(?=\\s)", + "captures": { + "1": { + "name": "keyword.control.tag.jsp" + } + }, + "end": "(?=%>)", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(display-name|body-content|dynamic-attributes|small-icon|large-icon|description|example|language|import|pageEncoding|isELIgnored)(=)((\")[^\"]*(\"))" + } + ] + }, + { + "begin": "\\G(taglib)(?=\\s)", + "captures": { + "1": { + "name": "keyword.control.taglib.jsp" + } + }, + "end": "(?=%>)", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(uri|tagdir|prefix)(=)((\")[^\"]*(\"))" + } + ] + }, + { + "begin": "\\G(variable)(?=\\s)", + "captures": { + "1": { + "name": "keyword.control.variable.jsp" + } + }, + "end": "(?=%>)", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(name-given|alias|variable-class|declare|scope|description)(=)((\")[^\"]*(\"))" + } + ] + } + ] + }, + "xml_tags": { + "patterns": [ + { + "begin": "(^\\s*)(?=)", + "beginCaptures": { + "0": { + "name": "punctuation.whitespace.embedded.leading.erb" + } + }, + "end": "(?!\\G)(\\s*$\\n)?", + "endCaptures": { + "0": { + "name": "punctuation.whitespace.embedded.trailing.erb" + } + }, + "patterns": [ + { + "include": "#embedded" + } + ] + }, + { + "include": "#embedded" + }, + { + "include": "#directive" + }, + { + "include": "#actions" + } + ], + "repository": { + "actions": { + "patterns": [ + { + "begin": "(", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.jsp" + } + }, + "name": "meta.tag.template.attribute.jsp", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(name|trim)(=)((\")[^\"]*(\"))" + } + ] + }, + { + "captures": { + "1": { + "name": "punctuation.definition.tag.begin.jsp" + }, + "2": { + "name": "entity.name.tag.jsp" + }, + "3": { + "name": "punctuation.definition.tag.end.jsp" + } + }, + "match": "()", + "name": "meta.tag.template.body.jsp" + }, + { + "begin": "(", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.jsp" + } + }, + "name": "meta.tag.template.element.jsp", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(name)(=)((\")[^\"]*(\"))" + } + ] + }, + { + "begin": "(<)(jsp:doBody)\\b", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.jsp" + }, + "2": { + "name": "entity.name.tag.jsp" + } + }, + "end": "/>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.jsp" + } + }, + "name": "meta.tag.template.dobody.jsp", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(var|varReader|scope)(=)((\")[^\"]*(\"))" + } + ] + }, + { + "begin": "(", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.jsp" + } + }, + "name": "meta.tag.template.forward.jsp", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(page)(=)((\")[^\"]*(\"))" + } + ] + }, + { + "begin": "(<)(jsp:param)\\b", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.jsp" + }, + "2": { + "name": "entity.name.tag.jsp" + } + }, + "end": "/>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.jsp" + } + }, + "name": "meta.tag.template.param.jsp", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(name|value)(=)((\")[^\"]*(\"))" + } + ] + }, + { + "begin": "(<)(jsp:getProperty)\\b", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.jsp" + }, + "2": { + "name": "entity.name.tag.jsp" + } + }, + "end": "/>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.jsp" + } + }, + "name": "meta.tag.template.getproperty.jsp", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(name|property)(=)((\")[^\"]*(\"))" + } + ] + }, + { + "begin": "(", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.jsp" + } + }, + "name": "meta.tag.template.include.jsp", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(page|flush)(=)((\")[^\"]*(\"))" + } + ] + }, + { + "begin": "(<)(jsp:invoke)\\b", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.jsp" + }, + "2": { + "name": "entity.name.tag.jsp" + } + }, + "end": "/>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.jsp" + } + }, + "name": "meta.tag.template.invoke.jsp", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(fragment|var|varReader|scope)(=)((\")[^\"]*(\"))" + } + ] + }, + { + "begin": "(<)(jsp:output)\\b", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.jsp" + }, + "2": { + "name": "entity.name.tag.jsp" + } + }, + "end": "/>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.jsp" + } + }, + "name": "meta.tag.template.output.jsp", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(omit-xml-declaration|doctype-root-element|doctype-system|doctype-public)(=)((\")[^\"]*(\"))" + } + ] + }, + { + "begin": "(", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.jsp" + } + }, + "name": "meta.tag.template.plugin.jsp", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(type|code|codebase|name|archive|align|height|hspace|jreversion|nspluginurl|iepluginurl)(=)((\")[^\"]*(\"))" + } + ] + }, + { + "captures": { + "1": { + "name": "punctuation.definition.tag.begin.jsp" + }, + "2": { + "name": "entity.name.tag.jsp" + }, + "3": { + "name": "punctuation.definition.tag.end.jsp" + } + }, + "end": ">", + "match": "()", + "name": "meta.tag.template.fallback.jsp" + }, + { + "begin": "(", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.jsp" + } + }, + "name": "meta.tag.template.root.jsp", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(xmlns|version|xmlns:taglibPrefix)(=)((\")[^\"]*(\"))" + } + ] + }, + { + "begin": "(<)(jsp:setProperty)\\b", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.jsp" + }, + "2": { + "name": "entity.name.tag.jsp" + } + }, + "end": "/>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.jsp" + } + }, + "name": "meta.tag.template.setproperty.jsp", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(name|property|value)(=)((\")[^\"]*(\"))" + } + ] + }, + { + "captures": { + "1": { + "name": "punctuation.definition.tag.begin.jsp" + }, + "2": { + "name": "entity.name.tag.jsp" + }, + "3": { + "name": "punctuation.definition.tag.end.jsp" + } + }, + "end": ">", + "match": "()", + "name": "meta.tag.template.text.jsp" + }, + { + "begin": "(", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.jsp" + } + }, + "name": "meta.tag.template.usebean.jsp", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(id|scope|class|type|beanName)(=)((\")[^\"]*(\"))" + } + ] + } + ] + }, + "directive": { + "begin": "(<)(jsp:directive\\.(?=(attribute|include|page|tag|variable)\\s))", + "beginCaptures": { + "1": { + "name": "punctuation.definition.tag.begin.jsp" + }, + "2": { + "name": "entity.name.tag.jsp" + } + }, + "end": "/>", + "endCaptures": { + "0": { + "name": "punctuation.definition.tag.end.jsp" + } + }, + "name": "meta.tag.template.$3.jsp", + "patterns": [ + { + "begin": "\\G(attribute)(?=\\s)", + "captures": { + "1": { + "name": "entity.name.tag.jsp" + } + }, + "end": "(?=/>)", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(name|required|fragment|rtexprvalue|type|description)(=)((\")[^\"]*(\"))" + } + ] + }, + { + "begin": "\\G(include)(?=\\s)", + "captures": { + "1": { + "name": "entity.name.tag.jsp" + } + }, + "end": "(?=/>)", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(file)(=)((\")[^\"]*(\"))" + } + ] + }, + { + "begin": "\\G(page)(?=\\s)", + "captures": { + "1": { + "name": "entity.name.tag.jsp" + } + }, + "end": "(?=/>)", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(language|extends|import|session|buffer|autoFlush|isThreadSafe|info|errorPage|isErrorPage|contentType|pageEncoding|isElIgnored)(=)((\")[^\"]*(\"))" + } + ] + }, + { + "begin": "\\G(tag)(?=\\s)", + "captures": { + "1": { + "name": "entity.name.tag.jsp" + } + }, + "end": "(?=/>)", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(display-name|body-content|dynamic-attributes|small-icon|large-icon|description|example|language|import|pageEncoding|isELIgnored)(=)((\")[^\"]*(\"))" + } + ] + }, + { + "begin": "\\G(variable)(?=\\s)", + "captures": { + "1": { + "name": "entity.name.tag.jsp" + } + }, + "end": "(?=/>)", + "patterns": [ + { + "captures": { + "1": { + "name": "entity.other.attribute-name.jsp" + }, + "2": { + "name": "punctuation.separator.key-value.jsp" + }, + "3": { + "name": "string.quoted.double.jsp" + }, + "4": { + "name": "punctuation.definition.string.begin.jsp" + }, + "5": { + "name": "punctuation.definition.string.end.jsp" + } + }, + "match": "(name-given|alias|variable-class|declare|scope|description)(=)((\")[^\"]*(\"))" + } + ] + } + ] + }, + "embedded": { + "begin": "(<)(jsp:(declaration|expression|scriptlet))(>)", + "beginCaptures": { + "0": { + "name": "meta.tag.template.$3.jsp" + }, + "1": { + "name": "punctuation.definition.tag.begin.jsp" + }, + "2": { + "name": "entity.name.tag.jsp" + }, + "4": { + "name": "punctuation.definition.tag.end.jsp" + } + }, + "contentName": "source.java", + "end": "((<)/)(jsp:\\3)(>)", + "endCaptures": { + "0": { + "name": "meta.tag.template.$4.jsp" + }, + "1": { + "name": "punctuation.definition.tag.begin.jsp" + }, + "2": { + "name": "source.java" + }, + "3": { + "name": "entity.name.tag.jsp" + }, + "4": { + "name": "punctuation.definition.tag.end.jsp" + } + }, + "name": "meta.embedded.block.jsp", + "patterns": [ + { + "include": "source.java" + } + ] + } + } + } + }, + "scopeName": "text.html.jsp", + "uuid": "FFF2D8D5-6282-45DF-A508-5C254E29FFC2" +} From 6273c01d7125304e4098f473050ac831c26d6317 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 17 Mar 2025 10:55:54 +0800 Subject: [PATCH 375/865] fix: `git rev-list` raises errors after selected commit in `Histories` page (#1101) Signed-off-by: leo --- src/Commands/QueryCommitChildren.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Commands/QueryCommitChildren.cs b/src/Commands/QueryCommitChildren.cs index 6a6ed909..31fb34f8 100644 --- a/src/Commands/QueryCommitChildren.cs +++ b/src/Commands/QueryCommitChildren.cs @@ -9,7 +9,7 @@ namespace SourceGit.Commands WorkingDirectory = repo; Context = repo; _commit = commit; - Args = $"rev-list -{max} --parents --branches --remotes --ancestry-path={commit} ^{commit}"; + Args = $"rev-list -{max} --parents --branches --remotes --ancestry-path ^{commit}"; } public List Result() From 4b41029768fd7a808e13d57c579dd88e7e7d8dae Mon Sep 17 00:00:00 2001 From: Gadfly Date: Mon, 17 Mar 2025 11:31:50 +0800 Subject: [PATCH 376/865] fix: use better JSP grammar file and add licensing information (#1102) --- src/Resources/Grammars/haxe.json | 6 +- src/Resources/Grammars/hxml.json | 6 +- src/Resources/Grammars/jsp.json | 1226 ++-------------------------- src/Resources/Grammars/kotlin.json | 6 +- src/Resources/Grammars/toml.json | 5 +- 5 files changed, 76 insertions(+), 1173 deletions(-) diff --git a/src/Resources/Grammars/haxe.json b/src/Resources/Grammars/haxe.json index 12acc538..3f78154d 100644 --- a/src/Resources/Grammars/haxe.json +++ b/src/Resources/Grammars/haxe.json @@ -1,7 +1,9 @@ { "information_for_contributors": [ "This file has been copied from https://github.com/vshaxe/haxe-TmLanguage/blob/ddad8b4c6d0781ac20be0481174ec1be772c5da5/haxe.tmLanguage", - "and converted to JSON using https://marketplace.visualstudio.com/items?itemName=pedro-w.tmlanguage" + "and converted to JSON using https://marketplace.visualstudio.com/items?itemName=pedro-w.tmlanguage", + "The original file was licensed under the MIT License", + "https://github.com/vshaxe/haxe-TmLanguage/blob/ddad8b4c6d0781ac20be0481174ec1be772c5da5/LICENSE.md" ], "fileTypes": [ "hx", @@ -2485,4 +2487,4 @@ "name": "variable.other.hx" } } -} \ No newline at end of file +} diff --git a/src/Resources/Grammars/hxml.json b/src/Resources/Grammars/hxml.json index 829c403e..3be42577 100644 --- a/src/Resources/Grammars/hxml.json +++ b/src/Resources/Grammars/hxml.json @@ -1,7 +1,9 @@ { "information_for_contributors": [ "This file has been copied from https://github.com/vshaxe/haxe-TmLanguage/blob/ddad8b4c6d0781ac20be0481174ec1be772c5da5/hxml.tmLanguage", - "and converted to JSON using https://marketplace.visualstudio.com/items?itemName=pedro-w.tmlanguage" + "and converted to JSON using https://marketplace.visualstudio.com/items?itemName=pedro-w.tmlanguage", + "The original file was licensed under the MIT License", + "https://github.com/vshaxe/haxe-TmLanguage/blob/ddad8b4c6d0781ac20be0481174ec1be772c5da5/LICENSE.md" ], "fileTypes": [ "hxml" @@ -67,4 +69,4 @@ ], "scopeName": "source.hxml", "uuid": "CB1B853A-C4C8-42C3-BA70-1B1605BE51C1" -} \ No newline at end of file +} diff --git a/src/Resources/Grammars/jsp.json b/src/Resources/Grammars/jsp.json index f0067748..2fbfd97c 100644 --- a/src/Resources/Grammars/jsp.json +++ b/src/Resources/Grammars/jsp.json @@ -1,1206 +1,100 @@ { "information_for_contributors": [ - "This file has been copied from https://github.com/J0hnMilt0n/vscode-jsp/blob/b33b7e4d47f3b5f4b82e93dfcadd180149153d02/syntaxes/jsp.tmLanguage.json" + "This file has been copied from https://github.com/samuel-weinhardt/vscode-jsp-lang/blob/0e89ecdb13650dbbe5a1e85b47b2e1530bf2f355/syntaxes/jsp.tmLanguage.json", + "The original file was licensed under the MIT License", + "https://github.com/samuel-weinhardt/vscode-jsp-lang/blob/0e89ecdb13650dbbe5a1e85b47b2e1530bf2f355/LICENSE" ], - "fileTypes": [ - "jsp", - "jspf", - "tag" + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "name": "Jakarta Server Pages", + "fileTypes": ["jsp", "jspf", "tag"], + "scopeName": "text.html.jsp", + "patterns": [ + { "include": "#comment" }, + { "include": "#directive" }, + { "include": "#expression" }, + { "include": "text.html.derivative" } ], "injections": { - "text.html.jsp - (meta.embedded.block.jsp | meta.embedded.line.jsp | meta.tag | comment), meta.tag string.quoted": { + "L:text.html.jsp -comment -meta.tag.directive.jsp -meta.tag.scriptlet.jsp": { "patterns": [ - { - "include": "#comment" - }, - { - "include": "#declaration" - }, - { - "include": "#expression" - }, - { - "include": "#el_expression" - }, - { - "include": "#tags" - }, - { - "begin": "(^\\s*)(?=<%(?=\\s))", - "beginCaptures": { - "0": { - "name": "punctuation.whitespace.embedded.leading.erb" - } - }, - "end": "(?!\\G)(\\s*$\\n)?", - "endCaptures": { - "0": { - "name": "punctuation.whitespace.embedded.trailing.erb" - } - }, - "patterns": [ - { - "include": "#scriptlet" - } - ] - }, - { - "include": "#scriptlet" - } - ] + { "include": "#scriptlet" } + ], + "comment": "allow scriptlets anywhere except comments and nested" + }, + "L:meta.attribute (string.quoted.single.html | string.quoted.double.html) -string.template.expression.jsp": { + "patterns": [ + { "include": "#expression" }, + { "include": "text.html.derivative" } + ], + "comment": "allow expressions and tags within HTML attributes (not nested)" } }, - "keyEquivalent": "^~J", - "name": "JavaServer Pages", - "patterns": [ - { - "include": "#xml_tags" - }, - { - "include": "text.html.basic" - } - ], "repository": { "comment": { + "name": "comment.block.jsp", "begin": "<%--", - "captures": { - "0": { - "name": "punctuation.definition.comment.jsp" - } - }, - "end": "--%>", - "name": "comment.block.jsp" + "end": "--%>" }, - "declaration": { - "begin": "<%!", + "directive": { + "name": "meta.tag.directive.jsp", + "begin": "(<)(%@)", + "end": "(%)(>)", "beginCaptures": { - "0": { - "name": "punctuation.section.embedded.begin.jsp" - } + "1": { "name": "punctuation.definition.tag.jsp" }, + "2": { "name": "entity.name.tag.jsp" } }, - "contentName": "source.java", - "end": "(%)>", "endCaptures": { - "0": { - "name": "punctuation.section.embedded.end.jsp" - }, - "1": { - "name": "source.java" - } + "1": { "name": "entity.name.tag.jsp" }, + "2": { "name": "punctuation.definition.tag.jsp" } }, - "name": "meta.embedded.line.declaration.jsp", "patterns": [ { - "include": "source.java" - } - ] - }, - "el_expression": { - "begin": "\\$\\{", - "beginCaptures": { - "0": { - "name": "punctuation.section.embedded.begin.jsp" - } - }, - "contentName": "source.java", - "end": "(\\})", - "endCaptures": { - "0": { - "name": "punctuation.section.embedded.end.jsp" + "match": "\\b(attribute|include|page|tag|taglib|variable)\\b(?!\\s*=)", + "name": "keyword.control.directive.jsp" }, - "1": { - "name": "source.java" - } - }, - "name": "meta.embedded.line.el_expression.jsp", - "patterns": [ - { - "include": "source.java" - } - ] - }, - "expression": { - "begin": "<%=", - "beginCaptures": { - "0": { - "name": "punctuation.section.embedded.begin.jsp" - } - }, - "contentName": "source.java", - "end": "(%)>", - "endCaptures": { - "0": { - "name": "punctuation.section.embedded.end.jsp" - }, - "1": { - "name": "source.java" - } - }, - "name": "meta.embedded.line.expression.jsp", - "patterns": [ - { - "include": "source.java" - } + { "include": "text.html.basic#attribute" } ] }, "scriptlet": { - "begin": "<%", + "name": "meta.tag.scriptlet.jsp", + "contentName": "meta.embedded.block.java", + "begin": "(<)(%[\\s!=])", + "end": "(%)(>)", "beginCaptures": { - "0": { - "name": "punctuation.section.embedded.begin.jsp" - } + "1": { "name": "punctuation.definition.tag.jsp" }, + "2": { "name": "entity.name.tag.jsp" } }, - "contentName": "source.java", - "end": "(%)>", "endCaptures": { - "0": { - "name": "punctuation.section.embedded.end.jsp" - }, - "1": { - "name": "source.java" - } + "1": { "name": "entity.name.tag.jsp" }, + "2": { "name": "punctuation.definition.tag.jsp" } }, - "name": "meta.embedded.block.scriptlet.jsp", "patterns": [ { - "match": "\\{", - "name": "punctuation.section.scope.begin.java" + "match": "\\{(?=\\s*(%>|$))", + "comment": "consume trailing curly brackets for fragmented scriptlets" }, - { - "match": "\\}", - "name": "punctuation.section.scope.end.java" - }, - { - "include": "source.java" - } + { "include": "source.java" } ] }, - "tags": { - "begin": "(<%@)\\s*(?=(attribute|include|page|tag|taglib|variable)\\s)", + "expression": { + "name": "string.template.expression.jsp", + "contentName": "meta.embedded.block.java", + "begin": "[$#]\\{", + "end": "\\}", "beginCaptures": { - "1": { - "name": "punctuation.definition.tag.begin.jsp" - } + "0": { "name": "punctuation.definition.template-expression.begin.jsp" } }, - "end": "%>", "endCaptures": { - "0": { - "name": "punctuation.definition.tag.end.jsp" - } + "0": { "name": "punctuation.definition.template-expression.end.jsp" } }, - "name": "meta.tag.template.include.jsp", "patterns": [ - { - "begin": "\\G(attribute)(?=\\s)", - "captures": { - "1": { - "name": "keyword.control.attribute.jsp" - } - }, - "end": "(?=%>)", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(name|required|fragment|rtexprvalue|type|description)(=)((\")[^\"]*(\"))" - } - ] - }, - { - "begin": "\\G(include)(?=\\s)", - "captures": { - "1": { - "name": "keyword.control.include.jsp" - } - }, - "end": "(?=%>)", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(file)(=)((\")[^\"]*(\"))" - } - ] - }, - { - "begin": "\\G(page)(?=\\s)", - "captures": { - "1": { - "name": "keyword.control.page.jsp" - } - }, - "end": "(?=%>)", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(language|extends|import|session|buffer|autoFlush|isThreadSafe|info|errorPage|isErrorPage|contentType|pageEncoding|isElIgnored)(=)((\")[^\"]*(\"))" - } - ] - }, - { - "begin": "\\G(tag)(?=\\s)", - "captures": { - "1": { - "name": "keyword.control.tag.jsp" - } - }, - "end": "(?=%>)", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(display-name|body-content|dynamic-attributes|small-icon|large-icon|description|example|language|import|pageEncoding|isELIgnored)(=)((\")[^\"]*(\"))" - } - ] - }, - { - "begin": "\\G(taglib)(?=\\s)", - "captures": { - "1": { - "name": "keyword.control.taglib.jsp" - } - }, - "end": "(?=%>)", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(uri|tagdir|prefix)(=)((\")[^\"]*(\"))" - } - ] - }, - { - "begin": "\\G(variable)(?=\\s)", - "captures": { - "1": { - "name": "keyword.control.variable.jsp" - } - }, - "end": "(?=%>)", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(name-given|alias|variable-class|declare|scope|description)(=)((\")[^\"]*(\"))" - } - ] - } + { "include": "#escape" }, + { "include": "source.java" } ] }, - "xml_tags": { - "patterns": [ - { - "begin": "(^\\s*)(?=)", - "beginCaptures": { - "0": { - "name": "punctuation.whitespace.embedded.leading.erb" - } - }, - "end": "(?!\\G)(\\s*$\\n)?", - "endCaptures": { - "0": { - "name": "punctuation.whitespace.embedded.trailing.erb" - } - }, - "patterns": [ - { - "include": "#embedded" - } - ] - }, - { - "include": "#embedded" - }, - { - "include": "#directive" - }, - { - "include": "#actions" - } - ], - "repository": { - "actions": { - "patterns": [ - { - "begin": "(", - "endCaptures": { - "0": { - "name": "punctuation.definition.tag.end.jsp" - } - }, - "name": "meta.tag.template.attribute.jsp", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(name|trim)(=)((\")[^\"]*(\"))" - } - ] - }, - { - "captures": { - "1": { - "name": "punctuation.definition.tag.begin.jsp" - }, - "2": { - "name": "entity.name.tag.jsp" - }, - "3": { - "name": "punctuation.definition.tag.end.jsp" - } - }, - "match": "()", - "name": "meta.tag.template.body.jsp" - }, - { - "begin": "(", - "endCaptures": { - "0": { - "name": "punctuation.definition.tag.end.jsp" - } - }, - "name": "meta.tag.template.element.jsp", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(name)(=)((\")[^\"]*(\"))" - } - ] - }, - { - "begin": "(<)(jsp:doBody)\\b", - "beginCaptures": { - "1": { - "name": "punctuation.definition.tag.begin.jsp" - }, - "2": { - "name": "entity.name.tag.jsp" - } - }, - "end": "/>", - "endCaptures": { - "0": { - "name": "punctuation.definition.tag.end.jsp" - } - }, - "name": "meta.tag.template.dobody.jsp", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(var|varReader|scope)(=)((\")[^\"]*(\"))" - } - ] - }, - { - "begin": "(", - "endCaptures": { - "0": { - "name": "punctuation.definition.tag.end.jsp" - } - }, - "name": "meta.tag.template.forward.jsp", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(page)(=)((\")[^\"]*(\"))" - } - ] - }, - { - "begin": "(<)(jsp:param)\\b", - "beginCaptures": { - "1": { - "name": "punctuation.definition.tag.begin.jsp" - }, - "2": { - "name": "entity.name.tag.jsp" - } - }, - "end": "/>", - "endCaptures": { - "0": { - "name": "punctuation.definition.tag.end.jsp" - } - }, - "name": "meta.tag.template.param.jsp", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(name|value)(=)((\")[^\"]*(\"))" - } - ] - }, - { - "begin": "(<)(jsp:getProperty)\\b", - "beginCaptures": { - "1": { - "name": "punctuation.definition.tag.begin.jsp" - }, - "2": { - "name": "entity.name.tag.jsp" - } - }, - "end": "/>", - "endCaptures": { - "0": { - "name": "punctuation.definition.tag.end.jsp" - } - }, - "name": "meta.tag.template.getproperty.jsp", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(name|property)(=)((\")[^\"]*(\"))" - } - ] - }, - { - "begin": "(", - "endCaptures": { - "0": { - "name": "punctuation.definition.tag.end.jsp" - } - }, - "name": "meta.tag.template.include.jsp", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(page|flush)(=)((\")[^\"]*(\"))" - } - ] - }, - { - "begin": "(<)(jsp:invoke)\\b", - "beginCaptures": { - "1": { - "name": "punctuation.definition.tag.begin.jsp" - }, - "2": { - "name": "entity.name.tag.jsp" - } - }, - "end": "/>", - "endCaptures": { - "0": { - "name": "punctuation.definition.tag.end.jsp" - } - }, - "name": "meta.tag.template.invoke.jsp", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(fragment|var|varReader|scope)(=)((\")[^\"]*(\"))" - } - ] - }, - { - "begin": "(<)(jsp:output)\\b", - "beginCaptures": { - "1": { - "name": "punctuation.definition.tag.begin.jsp" - }, - "2": { - "name": "entity.name.tag.jsp" - } - }, - "end": "/>", - "endCaptures": { - "0": { - "name": "punctuation.definition.tag.end.jsp" - } - }, - "name": "meta.tag.template.output.jsp", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(omit-xml-declaration|doctype-root-element|doctype-system|doctype-public)(=)((\")[^\"]*(\"))" - } - ] - }, - { - "begin": "(", - "endCaptures": { - "0": { - "name": "punctuation.definition.tag.end.jsp" - } - }, - "name": "meta.tag.template.plugin.jsp", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(type|code|codebase|name|archive|align|height|hspace|jreversion|nspluginurl|iepluginurl)(=)((\")[^\"]*(\"))" - } - ] - }, - { - "captures": { - "1": { - "name": "punctuation.definition.tag.begin.jsp" - }, - "2": { - "name": "entity.name.tag.jsp" - }, - "3": { - "name": "punctuation.definition.tag.end.jsp" - } - }, - "end": ">", - "match": "()", - "name": "meta.tag.template.fallback.jsp" - }, - { - "begin": "(", - "endCaptures": { - "0": { - "name": "punctuation.definition.tag.end.jsp" - } - }, - "name": "meta.tag.template.root.jsp", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(xmlns|version|xmlns:taglibPrefix)(=)((\")[^\"]*(\"))" - } - ] - }, - { - "begin": "(<)(jsp:setProperty)\\b", - "beginCaptures": { - "1": { - "name": "punctuation.definition.tag.begin.jsp" - }, - "2": { - "name": "entity.name.tag.jsp" - } - }, - "end": "/>", - "endCaptures": { - "0": { - "name": "punctuation.definition.tag.end.jsp" - } - }, - "name": "meta.tag.template.setproperty.jsp", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(name|property|value)(=)((\")[^\"]*(\"))" - } - ] - }, - { - "captures": { - "1": { - "name": "punctuation.definition.tag.begin.jsp" - }, - "2": { - "name": "entity.name.tag.jsp" - }, - "3": { - "name": "punctuation.definition.tag.end.jsp" - } - }, - "end": ">", - "match": "()", - "name": "meta.tag.template.text.jsp" - }, - { - "begin": "(", - "endCaptures": { - "0": { - "name": "punctuation.definition.tag.end.jsp" - } - }, - "name": "meta.tag.template.usebean.jsp", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(id|scope|class|type|beanName)(=)((\")[^\"]*(\"))" - } - ] - } - ] - }, - "directive": { - "begin": "(<)(jsp:directive\\.(?=(attribute|include|page|tag|variable)\\s))", - "beginCaptures": { - "1": { - "name": "punctuation.definition.tag.begin.jsp" - }, - "2": { - "name": "entity.name.tag.jsp" - } - }, - "end": "/>", - "endCaptures": { - "0": { - "name": "punctuation.definition.tag.end.jsp" - } - }, - "name": "meta.tag.template.$3.jsp", - "patterns": [ - { - "begin": "\\G(attribute)(?=\\s)", - "captures": { - "1": { - "name": "entity.name.tag.jsp" - } - }, - "end": "(?=/>)", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(name|required|fragment|rtexprvalue|type|description)(=)((\")[^\"]*(\"))" - } - ] - }, - { - "begin": "\\G(include)(?=\\s)", - "captures": { - "1": { - "name": "entity.name.tag.jsp" - } - }, - "end": "(?=/>)", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(file)(=)((\")[^\"]*(\"))" - } - ] - }, - { - "begin": "\\G(page)(?=\\s)", - "captures": { - "1": { - "name": "entity.name.tag.jsp" - } - }, - "end": "(?=/>)", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(language|extends|import|session|buffer|autoFlush|isThreadSafe|info|errorPage|isErrorPage|contentType|pageEncoding|isElIgnored)(=)((\")[^\"]*(\"))" - } - ] - }, - { - "begin": "\\G(tag)(?=\\s)", - "captures": { - "1": { - "name": "entity.name.tag.jsp" - } - }, - "end": "(?=/>)", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(display-name|body-content|dynamic-attributes|small-icon|large-icon|description|example|language|import|pageEncoding|isELIgnored)(=)((\")[^\"]*(\"))" - } - ] - }, - { - "begin": "\\G(variable)(?=\\s)", - "captures": { - "1": { - "name": "entity.name.tag.jsp" - } - }, - "end": "(?=/>)", - "patterns": [ - { - "captures": { - "1": { - "name": "entity.other.attribute-name.jsp" - }, - "2": { - "name": "punctuation.separator.key-value.jsp" - }, - "3": { - "name": "string.quoted.double.jsp" - }, - "4": { - "name": "punctuation.definition.string.begin.jsp" - }, - "5": { - "name": "punctuation.definition.string.end.jsp" - } - }, - "match": "(name-given|alias|variable-class|declare|scope|description)(=)((\")[^\"]*(\"))" - } - ] - } - ] - }, - "embedded": { - "begin": "(<)(jsp:(declaration|expression|scriptlet))(>)", - "beginCaptures": { - "0": { - "name": "meta.tag.template.$3.jsp" - }, - "1": { - "name": "punctuation.definition.tag.begin.jsp" - }, - "2": { - "name": "entity.name.tag.jsp" - }, - "4": { - "name": "punctuation.definition.tag.end.jsp" - } - }, - "contentName": "source.java", - "end": "((<)/)(jsp:\\3)(>)", - "endCaptures": { - "0": { - "name": "meta.tag.template.$4.jsp" - }, - "1": { - "name": "punctuation.definition.tag.begin.jsp" - }, - "2": { - "name": "source.java" - }, - "3": { - "name": "entity.name.tag.jsp" - }, - "4": { - "name": "punctuation.definition.tag.end.jsp" - } - }, - "name": "meta.embedded.block.jsp", - "patterns": [ - { - "include": "source.java" - } - ] - } - } + "escape": { + "match": "\\\\.", + "name": "constant.character.escape.jsp" } - }, - "scopeName": "text.html.jsp", - "uuid": "FFF2D8D5-6282-45DF-A508-5C254E29FFC2" + } } diff --git a/src/Resources/Grammars/kotlin.json b/src/Resources/Grammars/kotlin.json index e8f844d0..2857f717 100644 --- a/src/Resources/Grammars/kotlin.json +++ b/src/Resources/Grammars/kotlin.json @@ -1,6 +1,8 @@ { "information_for_contributors": [ - "This file has been copied from https://github.com/eclipse/buildship/blob/6bb773e7692f913dec27105129ebe388de34e68b/org.eclipse.buildship.kotlindsl.provider/kotlin.tmLanguage.json" + "This file has been copied from https://github.com/eclipse/buildship/blob/6bb773e7692f913dec27105129ebe388de34e68b/org.eclipse.buildship.kotlindsl.provider/kotlin.tmLanguage.json", + "The original file was licensed under the Eclipse Public License, Version 1.0", + "https://github.com/eclipse-buildship/buildship/blob/6bb773e7692f913dec27105129ebe388de34e68b/README.md" ], "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", "name": "Kotlin", @@ -698,4 +700,4 @@ "name": "variable.language.this.kotlin" } } -} \ No newline at end of file +} diff --git a/src/Resources/Grammars/toml.json b/src/Resources/Grammars/toml.json index 86c2ef87..6be4678f 100644 --- a/src/Resources/Grammars/toml.json +++ b/src/Resources/Grammars/toml.json @@ -3,7 +3,10 @@ "scopeName": "source.toml", "uuid": "8b4e5008-c50d-11ea-a91b-54ee75aeeb97", "information_for_contributors": [ - "Originally was maintained by aster (galaster@foxmail.com). This notice is only kept here for the record, please don't send e-mails about bugs and other issues." + "Originally was maintained by aster (galaster@foxmail.com). This notice is only kept here for the record, please don't send e-mails about bugs and other issues.", + "This file has been copied from https://github.com/kkiyama117/coc-toml/blob/main/toml.tmLanguage.json", + "The original file was licensed under the MIT License", + "https://github.com/kkiyama117/coc-toml/blob/main/LICENSE" ], "patterns": [ { From a480ba0139f0f5c792a722b017ca6bcfcb70d389 Mon Sep 17 00:00:00 2001 From: Gadfly Date: Mon, 17 Mar 2025 11:41:13 +0800 Subject: [PATCH 377/865] docs: Add third-party components and licenses section (cherry picked from commit 95c697248755f7b6de4d2d0bfdaa9de1e572c9f6) --- README.md | 4 ++++ THIRD-PARTY-LICENSES.md | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 THIRD-PARTY-LICENSES.md diff --git a/README.md b/README.md index c932ec8a..670456c2 100644 --- a/README.md +++ b/README.md @@ -201,3 +201,7 @@ dotnet run --project src/SourceGit.csproj Thanks to all the people who contribute. [![Contributors](https://contrib.rocks/image?repo=sourcegit-scm/sourcegit&columns=20)](https://github.com/sourcegit-scm/sourcegit/graphs/contributors) + +## Third-Party Components + +For detailed license information, see [THIRD-PARTY-LICENSES.md](THIRD-PARTY-LICENSES.md). diff --git a/THIRD-PARTY-LICENSES.md b/THIRD-PARTY-LICENSES.md new file mode 100644 index 00000000..6188ad8b --- /dev/null +++ b/THIRD-PARTY-LICENSES.md @@ -0,0 +1,38 @@ +# Third-Party Licenses + +This project incorporates components from the following third parties: + +## haxe-TmLanguage + +- **Source**: https://github.com/vshaxe/haxe-TmLanguage +- **Commit**: ddad8b4c6d0781ac20be0481174ec1be772c5da5 +- **License**: MIT License +- **License Link**: https://github.com/vshaxe/haxe-TmLanguage/blob/ddad8b4c6d0781ac20be0481174ec1be772c5da5/LICENSE.md + +## coc-toml + +- **Source**: https://github.com/kkiyama117/coc-toml +- **Commit**: aac3e0c65955c03314b2733041b19f903b7cc447 +- **License**: MIT License +- **License Link**: https://github.com/kkiyama117/coc-toml/blob/aac3e0c65955c03314b2733041b19f903b7cc447/LICENSE + +## eclipse-buildship + +- **Source**: https://github.com/eclipse/buildship +- **Commit**: 6bb773e7692f913dec27105129ebe388de34e68b +- **License**: Eclipse Public License 1.0 +- **License Link**: https://github.com/eclipse-buildship/buildship/blob/6bb773e7692f913dec27105129ebe388de34e68b/README.md + +## vscode-jsp-lang + +- **Source**: https://github.com/samuel-weinhardt/vscode-jsp-lang +- **Commit**: 0e89ecdb13650dbbe5a1e85b47b2e1530bf2f355 +- **License**: MIT License +- **License Link**: https://github.com/samuel-weinhardt/vscode-jsp-lang/blob/0e89ecdb13650dbbe5a1e85b47b2e1530bf2f355/LICENSE + +## JetBrainsMono + +- **Source**: https://github.com/JetBrains/JetBrainsMono +- **Commit**: v2.304 +- **License**: SIL Open Font License, Version 1.1 +- **License Link**: https://github.com/JetBrains/JetBrainsMono/blob/v2.304/OFL.txt From 8f8385072c7a0ef1bb527c93921d335d38edfc94 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 17 Mar 2025 11:56:33 +0800 Subject: [PATCH 378/865] doc: add third-party components Signed-off-by: leo --- THIRD-PARTY-LICENSES.md | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/THIRD-PARTY-LICENSES.md b/THIRD-PARTY-LICENSES.md index 6188ad8b..e4e0e07b 100644 --- a/THIRD-PARTY-LICENSES.md +++ b/THIRD-PARTY-LICENSES.md @@ -2,6 +2,48 @@ This project incorporates components from the following third parties: +## AvaloniaUI + +- **Source**: https://github.com/AvaloniaUI/Avalonia +- **Version**: 11.2.5 +- **License**: MIT License +- **License Link**: https://github.com/AvaloniaUI/Avalonia/blob/master/licence.md + +## AvaloniaEdit + +- **Source**: https://github.com/AvaloniaUI/AvaloniaEdit +- **Version**: 11.2.0 +- **License**: MIT License +- **License Link**: https://github.com/AvaloniaUI/AvaloniaEdit/blob/master/LICENSE + +## LiveChartsCore.SkiaSharpView.Avalonia + +- **Source**: https://github.com/beto-rodriguez/LiveCharts2 +- **Version**: 2.0.0-rc5.4 +- **License**: MIT License +- **License Link**: https://github.com/beto-rodriguez/LiveCharts2/blob/master/LICENSE + +## TextMateSharp + +- **Source**: https://github.com/danipen/TextMateSharp +- **Version**: 1.0.66 +- **License**: MIT License +- **License Link**: https://github.com/danipen/TextMateSharp/blob/master/LICENSE.md + +## OpenAI .NET SDK + +- **Source**: https://github.com/openai/openai-dotnet +- **Version**: 2.2.0-beta2 +- **License**: MIT License +- **License Link**: https://github.com/openai/openai-dotnet/blob/main/LICENSE + +## Azure.AI.OpenAI + +- **Source**: https://github.com/Azure/azure-sdk-for-net +- **Version**: 2.2.0-beta2 +- **License**: MIT License +- **License Link**: https://github.com/Azure/azure-sdk-for-net/blob/main/LICENSE.txt + ## haxe-TmLanguage - **Source**: https://github.com/vshaxe/haxe-TmLanguage @@ -36,3 +78,4 @@ This project incorporates components from the following third parties: - **Commit**: v2.304 - **License**: SIL Open Font License, Version 1.1 - **License Link**: https://github.com/JetBrains/JetBrainsMono/blob/v2.304/OFL.txt + From 99a45335feb91dc588baabab01676d4abe4eb880 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 17 Mar 2025 12:01:29 +0800 Subject: [PATCH 379/865] doc: group third-party components by types Signed-off-by: leo --- THIRD-PARTY-LICENSES.md | 73 ++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/THIRD-PARTY-LICENSES.md b/THIRD-PARTY-LICENSES.md index e4e0e07b..722414b2 100644 --- a/THIRD-PARTY-LICENSES.md +++ b/THIRD-PARTY-LICENSES.md @@ -2,80 +2,85 @@ This project incorporates components from the following third parties: -## AvaloniaUI +## Packages + +### AvaloniaUI - **Source**: https://github.com/AvaloniaUI/Avalonia - **Version**: 11.2.5 - **License**: MIT License - **License Link**: https://github.com/AvaloniaUI/Avalonia/blob/master/licence.md -## AvaloniaEdit +### AvaloniaEdit - **Source**: https://github.com/AvaloniaUI/AvaloniaEdit - **Version**: 11.2.0 - **License**: MIT License - **License Link**: https://github.com/AvaloniaUI/AvaloniaEdit/blob/master/LICENSE -## LiveChartsCore.SkiaSharpView.Avalonia +### LiveChartsCore.SkiaSharpView.Avalonia - **Source**: https://github.com/beto-rodriguez/LiveCharts2 - **Version**: 2.0.0-rc5.4 - **License**: MIT License - **License Link**: https://github.com/beto-rodriguez/LiveCharts2/blob/master/LICENSE -## TextMateSharp +### TextMateSharp - **Source**: https://github.com/danipen/TextMateSharp - **Version**: 1.0.66 - **License**: MIT License - **License Link**: https://github.com/danipen/TextMateSharp/blob/master/LICENSE.md -## OpenAI .NET SDK +### OpenAI .NET SDK - **Source**: https://github.com/openai/openai-dotnet - **Version**: 2.2.0-beta2 - **License**: MIT License - **License Link**: https://github.com/openai/openai-dotnet/blob/main/LICENSE -## Azure.AI.OpenAI +### Azure.AI.OpenAI - **Source**: https://github.com/Azure/azure-sdk-for-net - **Version**: 2.2.0-beta2 - **License**: MIT License - **License Link**: https://github.com/Azure/azure-sdk-for-net/blob/main/LICENSE.txt -## haxe-TmLanguage +## Fonts -- **Source**: https://github.com/vshaxe/haxe-TmLanguage -- **Commit**: ddad8b4c6d0781ac20be0481174ec1be772c5da5 -- **License**: MIT License -- **License Link**: https://github.com/vshaxe/haxe-TmLanguage/blob/ddad8b4c6d0781ac20be0481174ec1be772c5da5/LICENSE.md - -## coc-toml - -- **Source**: https://github.com/kkiyama117/coc-toml -- **Commit**: aac3e0c65955c03314b2733041b19f903b7cc447 -- **License**: MIT License -- **License Link**: https://github.com/kkiyama117/coc-toml/blob/aac3e0c65955c03314b2733041b19f903b7cc447/LICENSE - -## eclipse-buildship - -- **Source**: https://github.com/eclipse/buildship -- **Commit**: 6bb773e7692f913dec27105129ebe388de34e68b -- **License**: Eclipse Public License 1.0 -- **License Link**: https://github.com/eclipse-buildship/buildship/blob/6bb773e7692f913dec27105129ebe388de34e68b/README.md - -## vscode-jsp-lang - -- **Source**: https://github.com/samuel-weinhardt/vscode-jsp-lang -- **Commit**: 0e89ecdb13650dbbe5a1e85b47b2e1530bf2f355 -- **License**: MIT License -- **License Link**: https://github.com/samuel-weinhardt/vscode-jsp-lang/blob/0e89ecdb13650dbbe5a1e85b47b2e1530bf2f355/LICENSE - -## JetBrainsMono +### JetBrainsMono - **Source**: https://github.com/JetBrains/JetBrainsMono - **Commit**: v2.304 - **License**: SIL Open Font License, Version 1.1 - **License Link**: https://github.com/JetBrains/JetBrainsMono/blob/v2.304/OFL.txt +## Gramar Files + +### haxe-TmLanguage + +- **Source**: https://github.com/vshaxe/haxe-TmLanguage +- **Commit**: ddad8b4c6d0781ac20be0481174ec1be772c5da5 +- **License**: MIT License +- **License Link**: https://github.com/vshaxe/haxe-TmLanguage/blob/ddad8b4c6d0781ac20be0481174ec1be772c5da5/LICENSE.md + +### coc-toml + +- **Source**: https://github.com/kkiyama117/coc-toml +- **Commit**: aac3e0c65955c03314b2733041b19f903b7cc447 +- **License**: MIT License +- **License Link**: https://github.com/kkiyama117/coc-toml/blob/aac3e0c65955c03314b2733041b19f903b7cc447/LICENSE + +### eclipse-buildship + +- **Source**: https://github.com/eclipse/buildship +- **Commit**: 6bb773e7692f913dec27105129ebe388de34e68b +- **License**: Eclipse Public License 1.0 +- **License Link**: https://github.com/eclipse-buildship/buildship/blob/6bb773e7692f913dec27105129ebe388de34e68b/README.md + +### vscode-jsp-lang + +- **Source**: https://github.com/samuel-weinhardt/vscode-jsp-lang +- **Commit**: 0e89ecdb13650dbbe5a1e85b47b2e1530bf2f355 +- **License**: MIT License +- **License Link**: https://github.com/samuel-weinhardt/vscode-jsp-lang/blob/0e89ecdb13650dbbe5a1e85b47b2e1530bf2f355/LICENSE From 10fd0f9d15d0d58f0f27c5128c97b9abbdaea161 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 17 Mar 2025 12:02:32 +0800 Subject: [PATCH 380/865] doc: fix typo Signed-off-by: leo --- THIRD-PARTY-LICENSES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/THIRD-PARTY-LICENSES.md b/THIRD-PARTY-LICENSES.md index 722414b2..2338263c 100644 --- a/THIRD-PARTY-LICENSES.md +++ b/THIRD-PARTY-LICENSES.md @@ -55,7 +55,7 @@ This project incorporates components from the following third parties: - **License**: SIL Open Font License, Version 1.1 - **License Link**: https://github.com/JetBrains/JetBrainsMono/blob/v2.304/OFL.txt -## Gramar Files +## Grammar Files ### haxe-TmLanguage From ddfc868df3c20acd77a74d4c12ecaf07c22c6c04 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 17 Mar 2025 15:08:49 +0800 Subject: [PATCH 381/865] ux: re-design merge option style Signed-off-by: leo --- src/Models/MergeMode.cs | 2 +- src/ViewModels/Merge.cs | 10 +++++----- src/Views/Merge.axaml | 27 ++++++++++++++++++++++----- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/Models/MergeMode.cs b/src/Models/MergeMode.cs index 15e3f7e9..e4389b32 100644 --- a/src/Models/MergeMode.cs +++ b/src/Models/MergeMode.cs @@ -6,7 +6,7 @@ [ new MergeMode("Default", "Fast-forward if possible", ""), new MergeMode("No Fast-forward", "Always create a merge commit", "--no-ff"), - new MergeMode("Squash", "Use '--squash'", "--squash"), + new MergeMode("Squash", "Squash merge", "--squash"), new MergeMode("Don't commit", "Merge without commit", "--no-ff --no-commit"), ]; diff --git a/src/ViewModels/Merge.cs b/src/ViewModels/Merge.cs index 174bb1e1..bde9b66d 100644 --- a/src/ViewModels/Merge.cs +++ b/src/ViewModels/Merge.cs @@ -15,7 +15,7 @@ namespace SourceGit.ViewModels get; } - public Models.MergeMode SelectedMode + public Models.MergeMode Mode { get; set; @@ -28,7 +28,7 @@ namespace SourceGit.ViewModels Source = source; Into = into; - SelectedMode = AutoSelectMergeMode(); + Mode = AutoSelectMergeMode(); View = new Views.Merge() { DataContext = this }; } @@ -39,7 +39,7 @@ namespace SourceGit.ViewModels Source = source; Into = into; - SelectedMode = AutoSelectMergeMode(); + Mode = AutoSelectMergeMode(); View = new Views.Merge() { DataContext = this }; } @@ -50,7 +50,7 @@ namespace SourceGit.ViewModels Source = source; Into = into; - SelectedMode = AutoSelectMergeMode(); + Mode = AutoSelectMergeMode(); View = new Views.Merge() { DataContext = this }; } @@ -61,7 +61,7 @@ namespace SourceGit.ViewModels return Task.Run(() => { - new Commands.Merge(_repo.FullPath, _sourceName, SelectedMode.Arg, SetProgressDescription).Exec(); + new Commands.Merge(_repo.FullPath, _sourceName, Mode.Arg, SetProgressDescription).Exec(); CallUIThread(() => _repo.SetWatcherEnabled(true)); return true; }); diff --git a/src/Views/Merge.axaml b/src/Views/Merge.axaml index 805ac6d0..b7c76b6b 100644 --- a/src/Views/Merge.axaml +++ b/src/Views/Merge.axaml @@ -60,15 +60,32 @@ Height="28" Padding="8,0" VerticalAlignment="Center" HorizontalAlignment="Stretch" ItemsSource="{Binding Source={x:Static m:MergeMode.Supported}}" - SelectedItem="{Binding SelectedMode, Mode=TwoWay}"> + SelectedItem="{Binding Mode, Mode=TwoWay}" + Grid.IsSharedSizeScope="True"> - - - - + + + + + + + + + + + + + + + + + + + + From cdd1926e2f2eb4be2c1ee381c2e567787ea79599 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 17 Mar 2025 15:30:32 +0800 Subject: [PATCH 382/865] refactor: rewrite `git apply` implementation - Do not translate commandline options for `git` - Re-design combox layout for `git apply` popup Signed-off-by: leo --- src/Models/ApplyWhiteSpaceMode.cs | 12 ++++++++++-- src/Resources/Locales/de_DE.axaml | 8 -------- src/Resources/Locales/en_US.axaml | 8 -------- src/Resources/Locales/es_ES.axaml | 8 -------- src/Resources/Locales/fr_FR.axaml | 8 -------- src/Resources/Locales/it_IT.axaml | 8 -------- src/Resources/Locales/pt_BR.axaml | 8 -------- src/Resources/Locales/ru_RU.axaml | 8 -------- src/Resources/Locales/zh_CN.axaml | 8 -------- src/Resources/Locales/zh_TW.axaml | 8 -------- src/ViewModels/Apply.cs | 20 ++------------------ src/Views/Apply.axaml | 31 ++++++++++++++++++++++++------- 12 files changed, 36 insertions(+), 99 deletions(-) diff --git a/src/Models/ApplyWhiteSpaceMode.cs b/src/Models/ApplyWhiteSpaceMode.cs index 6fbce0b2..aad45f57 100644 --- a/src/Models/ApplyWhiteSpaceMode.cs +++ b/src/Models/ApplyWhiteSpaceMode.cs @@ -2,14 +2,22 @@ { public class ApplyWhiteSpaceMode { + public static readonly ApplyWhiteSpaceMode[] Supported = + [ + new ApplyWhiteSpaceMode("No Warn", "Turns off the trailing whitespace warning", "nowarn"), + new ApplyWhiteSpaceMode("Warn", "Outputs warnings for a few such errors, but applies", "warn"), + new ApplyWhiteSpaceMode("Error", "Raise errors and refuses to apply the patch", "error"), + new ApplyWhiteSpaceMode("Error All", "Similar to 'error', but shows more", "error-all"), + ]; + public string Name { get; set; } public string Desc { get; set; } public string Arg { get; set; } public ApplyWhiteSpaceMode(string n, string d, string a) { - Name = App.Text(n); - Desc = App.Text(d); + Name = n; + Desc = d; Arg = a; } } diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index aff8ffc5..31dc1d9b 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -25,18 +25,10 @@ Verwende OpenAI, um Commit-Nachrichten zu generieren Als Commit-Nachricht verwenden Patch - Fehler - Fehler werfen und anwenden des Patches verweigern - Alle Fehler - Ähnlich wie 'Fehler', zeigt aber mehr an Patch-Datei: Wähle die anzuwendende .patch-Datei Ignoriere Leerzeichenänderungen - Keine Warnungen - Keine Warnung vor Leerzeichen am Zeilenende Patch anwenden - Warnen - Gibt eine Warnung für ein paar solcher Fehler aus, aber wendet es an Leerzeichen: Stash anwenden Nach dem Anwenden löschen diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 818bd9bb..b1f83836 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -22,18 +22,10 @@ Use AI to generate commit message APPLY AS COMMIT MESSAGE Patch - Error - Raise errors and refuses to apply the patch - Error All - Similar to 'error', but shows more Patch File: Select .patch file to apply Ignore whitespace changes - No Warn - Turns off the trailing whitespace warning Apply Patch - Warn - Outputs warnings for a few such errors, but applies Whitespace: Apply Stash Delete after applying diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index e909a14e..6bf38df1 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -25,18 +25,10 @@ Usar OpenAI para generar mensaje de commit APLICAR CÓMO MENSAJE DE COMMIT Aplicar Parche - Error - Genera errores y se niega a aplicar el parche - Error Todo - Similar a 'error', pero muestra más Archivo del Parche: Seleccionar archivo .patch para aplicar Ignorar cambios de espacios en blanco - Sin Advertencia - Desactiva la advertencia de espacios en blanco al final Aplicar Parche - Advertencia - Genera advertencias para algunos de estos errores, pero aplica Espacios en Blanco: Aplicar Stash Borrar después de aplicar diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index aecea9ad..ebb3ba89 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -23,18 +23,10 @@ Assistant IA Utiliser l'IA pour générer un message de commit Appliquer - Erreur - Soulever les erreurs et refuser d'appliquer le patch - Toutes les erreurs - Similaire à 'Erreur', mais plus détaillé Fichier de patch : Selectionner le fichier .patch à appliquer Ignorer les changements d'espaces blancs - Pas d'avertissement - Désactiver l'avertissement sur les espaces blancs terminaux Appliquer le patch - Avertissement - Affiche des avertissements pour ce type d'erreurs tout en appliquant le patch Espaces blancs : Archiver... Enregistrer l'archive sous : diff --git a/src/Resources/Locales/it_IT.axaml b/src/Resources/Locales/it_IT.axaml index 4dcc8771..ebfd3939 100644 --- a/src/Resources/Locales/it_IT.axaml +++ b/src/Resources/Locales/it_IT.axaml @@ -25,18 +25,10 @@ Usa AI per generare il messaggio di commit APPLICA COME MESSAGGIO DI COMMIT Applica - Errore - Genera errori e si rifiuta di applicare la patch - Tutti gli errori - Simile a 'errore', ma mostra di più File Patch: Seleziona file .patch da applicare Ignora modifiche agli spazi - Nessun avviso - Disattiva l'avviso sugli spazi finali Applica Patch - Avviso - Mostra avvisi per alcuni errori, ma applica comunque Spazi: Applica lo stash Rimuovi dopo aver applicato diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml index b146bf0e..b4677840 100644 --- a/src/Resources/Locales/pt_BR.axaml +++ b/src/Resources/Locales/pt_BR.axaml @@ -48,18 +48,10 @@ Assietente IA Utilizar IA para gerar mensagem de commit Patch - Erro - Erros levantados e se recusa a aplicar o patch - Erro Total - Semelhante a 'erro', mas mostra mais Arquivo de Patch: Selecione o arquivo .patch para aplicar Ignorar mudanças de espaço em branco - Sem Aviso - Desativa o aviso de espaço em branco no final Aplicar Patch - Aviso - Emite avisos para alguns erros, mas aplica Espaço em Branco: Arquivar... Salvar Arquivo Como: diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index 07fb7c94..b2ba2158 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -25,18 +25,10 @@ Использовать OpenAI для создания сообщения о ревизии ПРИМЕНИТЬ КАК СООБЩЕНИЕ РЕВИЗИИ Исправить - Ошибка - Выдает ошибки и отказывается применять заплатку - Все ошибки - Аналогично «ошибке», но показывает больше Файл заплатки: Выберите файл .patch для применения Игнорировать изменения пробелов - Нет предупреждений - Отключить предупреждения о пробелах в конце Применить заплатку - Предупреждать - Выдавать предупреждения о нескольких таких ошибках, но применять Пробел: Отложить Удалить после применения diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 2d160ad2..768061dd 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -25,18 +25,10 @@ 使用AI助手生成提交信息 应用本次生成 应用补丁(apply) - 错误 - 输出错误,并终止应用补丁 - 更多错误 - 与【错误】级别相似,但输出内容更多 补丁文件 : 选择补丁文件 忽略空白符号 - 忽略 - 关闭所有警告 应用补丁 - 警告 - 应用补丁,输出关于空白符的警告 空白符号处理 : 应用贮藏 在成功应用后丢弃该贮藏 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index e50a600d..6d63c1ee 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -25,18 +25,10 @@ 使用 AI 產生提交訊息 套用為提交訊息 套用修補檔 (apply patch) - 錯誤 - 輸出錯誤,並中止套用修補檔 - 更多錯誤 - 與 [錯誤] 級別相似,但輸出更多內容 修補檔: 選擇修補檔 忽略空白符號 - 忽略 - 關閉所有警告 套用修補檔 - 警告 - 套用修補檔,輸出關於空白字元的警告 空白字元處理: 套用擱置變更 套用擱置變更後刪除 diff --git a/src/ViewModels/Apply.cs b/src/ViewModels/Apply.cs index 09567761..60001476 100644 --- a/src/ViewModels/Apply.cs +++ b/src/ViewModels/Apply.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; using System.IO; using System.Threading.Tasks; @@ -21,12 +20,6 @@ namespace SourceGit.ViewModels set => SetProperty(ref _ignoreWhiteSpace, value); } - public List WhiteSpaceModes - { - get; - private set; - } - public Models.ApplyWhiteSpaceMode SelectedWhiteSpaceMode { get; @@ -37,23 +30,14 @@ namespace SourceGit.ViewModels { _repo = repo; - WhiteSpaceModes = new List { - new Models.ApplyWhiteSpaceMode("Apply.NoWarn", "Apply.NoWarn.Desc", "nowarn"), - new Models.ApplyWhiteSpaceMode("Apply.Warn", "Apply.Warn.Desc", "warn"), - new Models.ApplyWhiteSpaceMode("Apply.Error", "Apply.Error.Desc", "error"), - new Models.ApplyWhiteSpaceMode("Apply.ErrorAll", "Apply.ErrorAll.Desc", "error-all") - }; - SelectedWhiteSpaceMode = WhiteSpaceModes[0]; - + SelectedWhiteSpaceMode = Models.ApplyWhiteSpaceMode.Supported[0]; View = new Views.Apply() { DataContext = this }; } public static ValidationResult ValidatePatchFile(string file, ValidationContext _) { if (File.Exists(file)) - { return ValidationResult.Success; - } return new ValidationResult($"File '{file}' can NOT be found!!!"); } diff --git a/src/Views/Apply.axaml b/src/Views/Apply.axaml index a5100cd6..6c2478bb 100644 --- a/src/Views/Apply.axaml +++ b/src/Views/Apply.axaml @@ -39,17 +39,34 @@ + IsEnabled="{Binding !IgnoreWhiteSpace}" + Grid.IsSharedSizeScope="True"> - - - - - + + + + + + + + + + + + + + + + + + + + + Date: Mon, 17 Mar 2025 07:30:48 +0000 Subject: [PATCH 383/865] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 670456c2..f9216874 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-99.07%25-yellow)](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-91.66%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-99.87%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.39%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.06%25-yellow)](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-91.57%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-99.87%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.30%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 e3f9d2a1..ae9f4777 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -1,4 +1,4 @@ -### de_DE.axaml: 99.07% +### de_DE.axaml: 99.06%
@@ -24,7 +24,7 @@
-### fr_FR.axaml: 91.66% +### fr_FR.axaml: 91.57%
@@ -106,7 +106,7 @@
-### pt_BR.axaml: 91.39% +### pt_BR.axaml: 91.30%
From cea8a90680a46a9bf54e0b1649af1f4607138e4b Mon Sep 17 00:00:00 2001 From: Gadfly Date: Mon, 17 Mar 2025 15:56:13 +0800 Subject: [PATCH 384/865] refactor: use $GIT_COMMON_DIR instead of cut $GIT_DIR/worktrees (#1103) --- src/Commands/QueryGitCommonDir.cs | 26 ++++++++++++++++++++++++++ src/Models/IRepository.cs | 1 + src/Models/Watcher.cs | 6 +----- src/Resources/Locales/de_DE.axaml | 2 +- src/Resources/Locales/en_US.axaml | 2 +- src/Resources/Locales/es_ES.axaml | 2 +- src/Resources/Locales/fr_FR.axaml | 2 +- src/Resources/Locales/it_IT.axaml | 2 +- src/Resources/Locales/pt_BR.axaml | 2 +- src/Resources/Locales/ru_RU.axaml | 2 +- src/Resources/Locales/zh_CN.axaml | 2 +- src/Resources/Locales/zh_TW.axaml | 2 +- src/ViewModels/Launcher.cs | 6 +++++- src/ViewModels/Repository.cs | 10 +++++++++- 14 files changed, 51 insertions(+), 16 deletions(-) create mode 100644 src/Commands/QueryGitCommonDir.cs diff --git a/src/Commands/QueryGitCommonDir.cs b/src/Commands/QueryGitCommonDir.cs new file mode 100644 index 00000000..1076243e --- /dev/null +++ b/src/Commands/QueryGitCommonDir.cs @@ -0,0 +1,26 @@ +using System.IO; + +namespace SourceGit.Commands +{ + public class QueryGitCommonDir : Command + { + public QueryGitCommonDir(string workDir) + { + WorkingDirectory = workDir; + Args = "rev-parse --git-common-dir"; + RaiseError = false; + } + + public string Result() + { + var rs = ReadToEnd().StdOut; + if (string.IsNullOrEmpty(rs)) + return null; + + rs = rs.Trim(); + if (Path.IsPathRooted(rs)) + return rs; + return Path.GetFullPath(Path.Combine(WorkingDirectory, rs)); + } + } +} diff --git a/src/Models/IRepository.cs b/src/Models/IRepository.cs index 12b1adba..90409c2f 100644 --- a/src/Models/IRepository.cs +++ b/src/Models/IRepository.cs @@ -4,6 +4,7 @@ { string FullPath { get; set; } string GitDir { get; set; } + string GitCommonDir { get; set; } void RefreshBranches(); void RefreshWorktrees(); diff --git a/src/Models/Watcher.cs b/src/Models/Watcher.cs index d0ccdea5..320f31d6 100644 --- a/src/Models/Watcher.cs +++ b/src/Models/Watcher.cs @@ -24,11 +24,7 @@ namespace SourceGit.Models _wcWatcher.EnableRaisingEvents = true; // If this repository is a worktree repository, just watch the main repository's gitdir. - var gitDirNormalized = _repo.GitDir.Replace("\\", "/"); - var worktreeIdx = gitDirNormalized.IndexOf(".git/worktrees/", StringComparison.Ordinal); - var repoWatchDir = _repo.GitDir; - if (worktreeIdx > 0) - repoWatchDir = _repo.GitDir.Substring(0, worktreeIdx + 4); + var repoWatchDir = _repo.GitCommonDir.Replace("\\", "/"); _repoWatcher = new FileSystemWatcher(); _repoWatcher.Path = repoWatchDir; diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index 31dc1d9b..2ebc1ae7 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -501,7 +501,7 @@ Remote löschen Ziel: Worktrees löschen - Worktree Informationen in `$GIT_DIR/worktrees` löschen + Worktree Informationen in `$GIT_COMMON_DIR/worktrees` löschen Pull Remote-Branch: Alle Branches fetchen diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index b1f83836..4401e8bc 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -504,7 +504,7 @@ Prune Remote Target: Prune Worktrees - Prune worktree information in `$GIT_DIR/worktrees` + Prune worktree information in `$GIT_COMMON_DIR/worktrees` Pull Remote Branch: Fetch all branches diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index 6bf38df1..f57ee230 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -508,7 +508,7 @@ Podar Remoto Destino: Podar Worktrees - Podar información de worktree en `$GIT_DIR/worktrees` + Podar información de worktree en `$GIT_COMMON_DIR/worktrees` Pull Rama Remota: Fetch todas las ramas diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index ebb3ba89..94df8d66 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -476,7 +476,7 @@ Élaguer une branche distant Cible : Élaguer les Worktrees - Élaguer les information de worktree dans `$GIT_DIR/worktrees` + Élaguer les information de worktree dans `$GIT_COMMON_DIR/worktrees` Pull Branche distante : Fetch toutes les branches diff --git a/src/Resources/Locales/it_IT.axaml b/src/Resources/Locales/it_IT.axaml index ebfd3939..8e6f73fa 100644 --- a/src/Resources/Locales/it_IT.axaml +++ b/src/Resources/Locales/it_IT.axaml @@ -507,7 +507,7 @@ Potatura Remota Destinazione: Potatura Worktrees - Potatura delle informazioni di worktree in `$GIT_DIR/worktrees` + Potatura delle informazioni di worktree in `$GIT_COMMON_DIR/worktrees` Scarica Branch Remoto: Recupera tutti i branch diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml index b4677840..c03e39d2 100644 --- a/src/Resources/Locales/pt_BR.axaml +++ b/src/Resources/Locales/pt_BR.axaml @@ -490,7 +490,7 @@ Prunar Remoto Alvo: Podar Worktrees - Podar informações de worktree em `$GIT_DIR/worktrees` + Podar informações de worktree em `$GIT_COMMON_DIR/worktrees` Puxar Branch Remoto: Buscar todos os branches diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index b2ba2158..3273ac07 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -508,7 +508,7 @@ Удалить внешний репозиторий Цель: Удалить рабочий каталог - Информация об обрезке рабочего каталога в «$GIT_DIR/worktrees» + Информация об обрезке рабочего каталога в «$GIT_COMMON_DIR/worktrees» Забрать Ветка внешнего репозитория: Извлечь все ветки diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 768061dd..2a8d08b5 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -508,7 +508,7 @@ 清理远程已删除分支 目标 : 清理工作树 - 清理在`$GIT_DIR/worktrees`中的无效工作树信息 + 清理在`$GIT_COMMON_DIR/worktrees`中的无效工作树信息 拉回(pull) 拉取分支 : 拉取远程中的所有分支变更 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 6d63c1ee..5bb68782 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -507,7 +507,7 @@ 清理遠端已刪除分支 目標: 清理工作區 - 清理在 `$GIT_DIR/worktrees` 中的無效工作區資訊 + 清理在 `$GIT_COMMON_DIR/worktrees` 中的無效工作區資訊 拉取 (pull) 拉取分支: 拉取遠端中的所有分支 diff --git a/src/ViewModels/Launcher.cs b/src/ViewModels/Launcher.cs index 06479394..4307665d 100644 --- a/src/ViewModels/Launcher.cs +++ b/src/ViewModels/Launcher.cs @@ -282,6 +282,7 @@ namespace SourceGit.ViewModels var isBare = new Commands.IsBareRepository(node.Id).Result(); var gitDir = node.Id; + var gitCommonDir = gitDir; if (!isBare) { gitDir = new Commands.QueryGitDir(node.Id).Result(); @@ -291,9 +292,12 @@ namespace SourceGit.ViewModels App.RaiseException(ctx, "Given path is not a valid git repository!"); return; } + gitCommonDir = new Commands.QueryGitCommonDir(node.Id).Result(); + if (string.IsNullOrEmpty(gitCommonDir)) + gitCommonDir = gitDir; } - var repo = new Repository(isBare, node.Id, gitDir); + var repo = new Repository(isBare, node.Id, gitDir, gitCommonDir); repo.Open(); if (page == null) diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 97c52d8e..5cc933e9 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -45,6 +45,12 @@ namespace SourceGit.ViewModels set => SetProperty(ref _gitDir, value); } + public string GitCommonDir + { + get => _gitCommonDir; + set => SetProperty(ref _gitCommonDir, value); + } + public Models.RepositorySettings Settings { get => _settings; @@ -429,11 +435,12 @@ namespace SourceGit.ViewModels set; } = 0; - public Repository(bool isBare, string path, string gitDir) + public Repository(bool isBare, string path, string gitDir, string gitCommonDir) { IsBare = isBare; FullPath = path; GitDir = gitDir; + GitCommonDir = gitCommonDir; } public void Open() @@ -2437,6 +2444,7 @@ namespace SourceGit.ViewModels private string _fullpath = string.Empty; private string _gitDir = string.Empty; + private string _gitCommonDir = string.Empty; private Models.RepositorySettings _settings = null; private Models.FilterMode _historiesFilterMode = Models.FilterMode.None; private bool _hasAllowedSignersFile = false; From b4ab4afd3ab8eded049ea7b4849d821f64d14273 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 17 Mar 2025 16:17:20 +0800 Subject: [PATCH 385/865] code_review: PR #1103 Since we only use `$GIT_COMMON_DIR` in filesystem watcher, it is unnecessary to store this value in `Repository`, and we can query the `$GIT_COMMON_DIR` only when it looks like a worktree Signed-off-by: leo --- src/Models/IRepository.cs | 3 +-- src/Models/Watcher.cs | 5 +---- src/ViewModels/Launcher.cs | 6 +----- src/ViewModels/Repository.cs | 19 +++++++++++++------ 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/Models/IRepository.cs b/src/Models/IRepository.cs index 90409c2f..9283266e 100644 --- a/src/Models/IRepository.cs +++ b/src/Models/IRepository.cs @@ -3,8 +3,7 @@ public interface IRepository { string FullPath { get; set; } - string GitDir { get; set; } - string GitCommonDir { get; set; } + string GitDirForWatcher { get; } void RefreshBranches(); void RefreshWorktrees(); diff --git a/src/Models/Watcher.cs b/src/Models/Watcher.cs index 320f31d6..d419363a 100644 --- a/src/Models/Watcher.cs +++ b/src/Models/Watcher.cs @@ -23,11 +23,8 @@ namespace SourceGit.Models _wcWatcher.Deleted += OnWorkingCopyChanged; _wcWatcher.EnableRaisingEvents = true; - // If this repository is a worktree repository, just watch the main repository's gitdir. - var repoWatchDir = _repo.GitCommonDir.Replace("\\", "/"); - _repoWatcher = new FileSystemWatcher(); - _repoWatcher.Path = repoWatchDir; + _repoWatcher.Path = _repo.GitDirForWatcher; _repoWatcher.Filter = "*"; _repoWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName; _repoWatcher.IncludeSubdirectories = true; diff --git a/src/ViewModels/Launcher.cs b/src/ViewModels/Launcher.cs index 4307665d..06479394 100644 --- a/src/ViewModels/Launcher.cs +++ b/src/ViewModels/Launcher.cs @@ -282,7 +282,6 @@ namespace SourceGit.ViewModels var isBare = new Commands.IsBareRepository(node.Id).Result(); var gitDir = node.Id; - var gitCommonDir = gitDir; if (!isBare) { gitDir = new Commands.QueryGitDir(node.Id).Result(); @@ -292,12 +291,9 @@ namespace SourceGit.ViewModels App.RaiseException(ctx, "Given path is not a valid git repository!"); return; } - gitCommonDir = new Commands.QueryGitCommonDir(node.Id).Result(); - if (string.IsNullOrEmpty(gitCommonDir)) - gitCommonDir = gitDir; } - var repo = new Repository(isBare, node.Id, gitDir, gitCommonDir); + var repo = new Repository(isBare, node.Id, gitDir); repo.Open(); if (page == null) diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 5cc933e9..85665634 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -45,10 +45,19 @@ namespace SourceGit.ViewModels set => SetProperty(ref _gitDir, value); } - public string GitCommonDir + public string GitDirForWatcher { - get => _gitCommonDir; - set => SetProperty(ref _gitCommonDir, value); + get + { + // Only try to get `$GIT_COMMON_DIR` if this repository looks like a worktree. + if (_gitDir.Replace("\\", "/").IndexOf(".git/worktrees/", StringComparison.Ordinal) > 0) + { + var commonDir = new Commands.QueryGitCommonDir(_fullpath).Result(); + return string.IsNullOrEmpty(commonDir) ? _gitDir : commonDir; + } + + return _gitDir; + } } public Models.RepositorySettings Settings @@ -435,12 +444,11 @@ namespace SourceGit.ViewModels set; } = 0; - public Repository(bool isBare, string path, string gitDir, string gitCommonDir) + public Repository(bool isBare, string path, string gitDir) { IsBare = isBare; FullPath = path; GitDir = gitDir; - GitCommonDir = gitCommonDir; } public void Open() @@ -2444,7 +2452,6 @@ namespace SourceGit.ViewModels private string _fullpath = string.Empty; private string _gitDir = string.Empty; - private string _gitCommonDir = string.Empty; private Models.RepositorySettings _settings = null; private Models.FilterMode _historiesFilterMode = Models.FilterMode.None; private bool _hasAllowedSignersFile = false; From 7031693489d6c92da2db74393f690aba6d1b3da7 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 17 Mar 2025 16:29:56 +0800 Subject: [PATCH 386/865] refactor: pass dirs to watcher directly Signed-off-by: leo --- src/Models/IRepository.cs | 3 --- src/Models/Watcher.cs | 6 +++--- src/ViewModels/Repository.cs | 26 ++++++++++---------------- 3 files changed, 13 insertions(+), 22 deletions(-) diff --git a/src/Models/IRepository.cs b/src/Models/IRepository.cs index 9283266e..0224d81f 100644 --- a/src/Models/IRepository.cs +++ b/src/Models/IRepository.cs @@ -2,9 +2,6 @@ { public interface IRepository { - string FullPath { get; set; } - string GitDirForWatcher { get; } - void RefreshBranches(); void RefreshWorktrees(); void RefreshTags(); diff --git a/src/Models/Watcher.cs b/src/Models/Watcher.cs index d419363a..3ccecad4 100644 --- a/src/Models/Watcher.cs +++ b/src/Models/Watcher.cs @@ -8,12 +8,12 @@ namespace SourceGit.Models { public class Watcher : IDisposable { - public Watcher(IRepository repo) + public Watcher(IRepository repo, string fullpath, string gitDir) { _repo = repo; _wcWatcher = new FileSystemWatcher(); - _wcWatcher.Path = _repo.FullPath; + _wcWatcher.Path = fullpath; _wcWatcher.Filter = "*"; _wcWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.CreationTime; _wcWatcher.IncludeSubdirectories = true; @@ -24,7 +24,7 @@ namespace SourceGit.Models _wcWatcher.EnableRaisingEvents = true; _repoWatcher = new FileSystemWatcher(); - _repoWatcher.Path = _repo.GitDirForWatcher; + _repoWatcher.Path = gitDir; _repoWatcher.Filter = "*"; _repoWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName; _repoWatcher.IncludeSubdirectories = true; diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 85665634..4f2f3ca3 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -45,21 +45,6 @@ namespace SourceGit.ViewModels set => SetProperty(ref _gitDir, value); } - public string GitDirForWatcher - { - get - { - // Only try to get `$GIT_COMMON_DIR` if this repository looks like a worktree. - if (_gitDir.Replace("\\", "/").IndexOf(".git/worktrees/", StringComparison.Ordinal) > 0) - { - var commonDir = new Commands.QueryGitCommonDir(_fullpath).Result(); - return string.IsNullOrEmpty(commonDir) ? _gitDir : commonDir; - } - - return _gitDir; - } - } - public Models.RepositorySettings Settings { get => _settings; @@ -472,7 +457,16 @@ namespace SourceGit.ViewModels try { - _watcher = new Models.Watcher(this); + // For worktrees, we need to watch the $GIT_COMMON_DIR instead of the $GIT_DIR. + var gitDirForWatcher = _gitDir; + if (_gitDir.Replace("\\", "/").IndexOf(".git/worktrees/", StringComparison.Ordinal) > 0) + { + var commonDir = new Commands.QueryGitCommonDir(_fullpath).Result(); + if (!string.IsNullOrEmpty(commonDir)) + gitDirForWatcher = commonDir; + } + + _watcher = new Models.Watcher(this, _fullpath, gitDirForWatcher); } catch (Exception ex) { From 3e8bba0d0bd3e16057791a8df6fc95e2897a8a40 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 17 Mar 2025 17:06:26 +0800 Subject: [PATCH 387/865] ux: re-design `About` page Signed-off-by: leo --- src/Resources/Icons.axaml | 1 + src/Resources/Locales/de_DE.axaml | 5 ---- src/Resources/Locales/en_US.axaml | 5 ---- src/Resources/Locales/es_ES.axaml | 5 ---- src/Resources/Locales/fr_FR.axaml | 5 ---- src/Resources/Locales/it_IT.axaml | 5 ---- src/Resources/Locales/pt_BR.axaml | 5 ---- src/Resources/Locales/ru_RU.axaml | 5 ---- src/Resources/Locales/zh_CN.axaml | 5 ---- src/Resources/Locales/zh_TW.axaml | 5 ---- src/Views/About.axaml | 45 +++++++++++-------------------- src/Views/About.axaml.cs | 26 +++--------------- 12 files changed, 21 insertions(+), 96 deletions(-) diff --git a/src/Resources/Icons.axaml b/src/Resources/Icons.axaml index 9426d20a..66589440 100644 --- a/src/Resources/Icons.axaml +++ b/src/Resources/Icons.axaml @@ -54,6 +54,7 @@ M939 94v710L512 998 85 805V94h-64A21 21 0 010 73v-0C0 61 10 51 21 51h981c12 0 21 10 21 21v0c0 12-10 21-21 21h-64zm-536 588L512 624l109 58c6 3 13 4 20 3a32 32 0 0026-37l-21-122 88-87c5-5 8-11 9-18a32 32 0 00-27-37l-122-18-54-111a32 32 0 00-57 0l-54 111-122 18c-7 1-13 4-18 9a33 33 0 001 46l88 87-21 122c-1 7-0 14 3 20a32 32 0 0043 14z M236 542a32 32 0 109 63l86-12a180 180 0 0022 78l-71 47a32 32 0 1035 53l75-50a176 176 0 00166 40L326 529zM512 16C238 16 16 238 16 512s222 496 496 496 496-222 496-496S786 16 512 16zm0 896c-221 0-400-179-400-400a398 398 0 0186-247l561 561A398 398 0 01512 912zm314-154L690 622a179 179 0 004-29l85 12a32 32 0 109-63l-94-13v-49l94-13a32 32 0 10-9-63l-87 12a180 180 0 00-20-62l71-47A32 32 0 10708 252l-75 50a181 181 0 00-252 10l-115-115A398 398 0 01512 112c221 0 400 179 400 400a398 398 0 01-86 247z M884 159l-18-18a43 43 0 00-38-12l-235 43a166 166 0 00-101 60L400 349a128 128 0 00-148 47l-120 171a21 21 0 005 29l17 12a128 128 0 00178-32l27-38 124 124-38 27a128 128 0 00-32 178l12 17a21 21 0 0029 5l171-120a128 128 0 0047-148l117-92A166 166 0 00853 431l43-235a43 43 0 00-12-38zm-177 249a64 64 0 110-90 64 64 0 010 90zm-373 312a21 21 0 010 30l-139 139a21 21 0 01-30 0l-30-30a21 21 0 010-30l139-139a21 21 0 0130 0z + M525 0C235 0 0 235 0 525c0 232 150 429 359 498 26 5 36-11 36-25 0-12-1-54-1-97-146 31-176-63-176-63-23-61-58-76-58-76-48-32 3-32 3-32 53 3 81 54 81 54 47 80 123 57 153 43 4-34 18-57 33-70-116-12-239-57-239-259 0-57 21-104 54-141-5-13-23-67 5-139 0 0 44-14 144 54 42-11 87-17 131-17s90 6 131 17C756 203 801 217 801 217c29 72 10 126 5 139 34 37 54 83 54 141 0 202-123 246-240 259 19 17 36 48 36 97 0 70-1 127-1 144 0 14 10 30 36 25 209-70 359-266 359-498C1050 235 814 0 525 0z M590 74 859 342V876c0 38-31 68-68 68H233c-38 0-68-31-68-68V142c0-38 31-68 68-68h357zm-12 28H233a40 40 0 00-40 38L193 142v734a40 40 0 0038 40L233 916h558a40 40 0 0040-38L831 876V354L578 102zM855 371h-215c-46 0-83-36-84-82l0-2V74h28v213c0 30 24 54 54 55l2 0h215v28zM57 489m28 0 853 0q28 0 28 28l0 284q0 28-28 28l-853 0q-28 0-28-28l0-284q0-28 28-28ZM157 717c15 0 29-6 37-13v-51h-41v22h17v18c-2 2-6 3-10 3-21 0-30-13-30-34 0-21 12-34 28-34 9 0 15 4 20 9l14-17C184 610 172 603 156 603c-29 0-54 21-54 57 0 37 24 56 54 56zM245 711v-108h-34v108h34zm69 0v-86H341V603H262v22h28V711h24zM393 711v-108h-34v108h34zm66 6c15 0 29-6 37-13v-51h-41v22h17v18c-2 2-6 3-10 3-21 0-30-13-30-34 0-21 12-34 28-34 9 0 15 4 20 9l14-17C485 610 474 603 458 603c-29 0-54 21-54 57 0 37 24 56 54 56zm88-6v-36c0-13-2-28-3-40h1l10 24 25 52H603v-108h-23v36c0 13 2 28 3 40h-1l-10-24L548 603H523v108h23zM677 717c30 0 51-22 51-57 0-36-21-56-51-56-30 0-51 20-51 56 0 36 21 57 51 57zm3-23c-16 0-26-12-26-32 0-19 10-31 26-31 16 0 26 11 26 31S696 694 680 694zm93 17v-38h13l21 38H836l-25-43c12-5 19-15 19-31 0-26-20-34-44-34H745v108h27zm16-51H774v-34h15c16 0 25 4 25 16s-9 18-25 18zM922 711v-22h-43v-23h35v-22h-35V625h41V603H853v108h68z M30 271l241 0 0-241-241 0 0 241zM392 271l241 0 0-241-241 0 0 241zM753 30l0 241 241 0 0-241-241 0zM30 632l241 0 0-241-241 0 0 241zM392 632l241 0 0-241-241 0 0 241zM753 632l241 0 0-241-241 0 0 241zM30 994l241 0 0-241-241 0 0 241zM392 994l241 0 0-241-241 0 0 241zM753 994l241 0 0-241-241 0 0 241z M0 512M1024 512M512 0M512 1024M955 323q0 23-16 39l-414 414-78 78q-16 16-39 16t-39-16l-78-78-207-207q-16-16-16-39t16-39l78-78q16-16 39-16t39 16l168 169 375-375q16-16 39-16t39 16l78 78q16 16 16 39z diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index 2ebc1ae7..7144ef43 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -4,11 +4,6 @@ Info Über SourceGit - • Erstellt mit - • Grafik gerendert durch - • Texteditor von - • Monospace-Schriftarten von - • Quelltext findest du auf Open Source & freier Git GUI Client Worktree hinzufügen Was auschecken: diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 4401e8bc..312d4945 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -1,11 +1,6 @@ About About SourceGit - • Build with - • Chart is rendered by - • TextEditor from - • Monospace fonts come from - • Source code can be found at Opensource & Free Git GUI Client Add Worktree What to Checkout: diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index f57ee230..e7e953e5 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -4,11 +4,6 @@ Acerca de Acerca de SourceGit - • Construido con - • El gráfico es renderizado por - • Editor de texto de - • Las fuentes monoespaciadas provienen de - • El código fuente se puede encontrar en Cliente Git GUI de código abierto y gratuito Agregar Worktree Qué Checkout: diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index 94df8d66..f3a71390 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -4,11 +4,6 @@ À propos À propos de SourceGit - • Compilé avec - • Le graphique est rendu par - • TextEditor de - • Les polices Monospace proviennent de - • Le code source est disponible sur Client Git Open Source et Gratuit Ajouter un Worktree Que récupérer : diff --git a/src/Resources/Locales/it_IT.axaml b/src/Resources/Locales/it_IT.axaml index 8e6f73fa..782d6e78 100644 --- a/src/Resources/Locales/it_IT.axaml +++ b/src/Resources/Locales/it_IT.axaml @@ -4,11 +4,6 @@ Informazioni Informazioni su SourceGit - • Creato con - • Il grafico è reso da - • Editor di testo da - • I font monospaziati provengono da - • Il codice sorgente è disponibile su Client GUI Git open source e gratuito Aggiungi Worktree Di cosa fare il checkout: diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml index c03e39d2..e811cf3e 100644 --- a/src/Resources/Locales/pt_BR.axaml +++ b/src/Resources/Locales/pt_BR.axaml @@ -29,11 +29,6 @@ Sobre Sobre o SourceGit - • Construído com - • Gráfico desenhado por - • Editor de Texto de - • Fontes monoespaçadas de - • Código-fonte pode ser encontrado em Cliente Git GUI Livre e de Código Aberto Adicionar Worktree O que Checar: diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index 3273ac07..99948eca 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -4,11 +4,6 @@ О программе О SourceGit - • Сборка с - • Диаграмма отображается с помощью - • Текстовый редактор от - • Моноширинные шрифты взяты из - • Исходный код можно найти по адресу Бесплатный графический клиент Git с исходным кодом Добавить рабочий каталог Переключиться на: diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 2a8d08b5..aae292f3 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -4,11 +4,6 @@ 关于软件 关于本软件 - • 项目依赖于 - • 图表绘制组件来自 - • 文本编辑器使用 - • 等宽字体来自于 - • 项目源代码地址 开源免费的Git客户端 新增工作树 检出分支方式 : diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 5bb68782..97c96c6c 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -4,11 +4,6 @@ 關於 關於 SourceGit - • 專案依賴於 - • 圖表繪製元件來自 - • 文字編輯器使用 - • 等寬字型來自於 - • 專案原始碼網址 開源免費的 Git 客戶端 新增工作區 簽出分支方式: diff --git a/src/Views/About.axaml b/src/Views/About.axaml index ecdf156e..28529b63 100644 --- a/src/Views/About.axaml +++ b/src/Views/About.axaml @@ -3,12 +3,12 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:v="using:SourceGit.Views" - mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" + mc:Ignorable="d" d:DesignWidth="520" d:DesignHeight="230" x:Class="SourceGit.Views.About" x:Name="ThisControl" Icon="/App.ico" Title="{DynamicResource Text.About}" - SizeToContent="WidthAndHeight" + Width="520" Height="230" CanResize="False" WindowStartupLocation="CenterScreen"> @@ -34,7 +34,7 @@ IsVisible="{OnPlatform True, macOS=False}"/> - + - - + + - + - + + - - - - - - - - - - - - - - - - - - - - - - + + + + diff --git a/src/Views/About.axaml.cs b/src/Views/About.axaml.cs index 631df0f9..d393f94c 100644 --- a/src/Views/About.axaml.cs +++ b/src/Views/About.axaml.cs @@ -1,5 +1,5 @@ using System.Reflection; -using Avalonia.Input; +using Avalonia.Interactivity; namespace SourceGit.Views { @@ -19,31 +19,13 @@ namespace SourceGit.Views TxtCopyright.Text = copyright.Copyright; } - private void OnVisitAvaloniaUI(object _, PointerPressedEventArgs e) + private void OnVisitWebsite(object _, RoutedEventArgs e) { - Native.OS.OpenBrowser("https://www.avaloniaui.net/"); + Native.OS.OpenBrowser("https://sourcegit-scm.github.io/"); e.Handled = true; } - private void OnVisitAvaloniaEdit(object _, PointerPressedEventArgs e) - { - Native.OS.OpenBrowser("https://github.com/AvaloniaUI/AvaloniaEdit"); - e.Handled = true; - } - - private void OnVisitJetBrainsMonoFont(object _, PointerPressedEventArgs e) - { - Native.OS.OpenBrowser("https://www.jetbrains.com/lp/mono/"); - e.Handled = true; - } - - private void OnVisitLiveCharts2(object _, PointerPressedEventArgs e) - { - Native.OS.OpenBrowser("https://livecharts.dev/"); - e.Handled = true; - } - - private void OnVisitSourceCode(object _, PointerPressedEventArgs e) + private void OnVisitSourceCode(object _, RoutedEventArgs e) { Native.OS.OpenBrowser("https://github.com/sourcegit-scm/sourcegit"); e.Handled = true; From 5845ef3eb64bb5651737685bb25403d169e033c6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 17 Mar 2025 09:06:42 +0000 Subject: [PATCH 388/865] 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 f9216874..13887a13 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-99.06%25-yellow)](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-91.57%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-99.87%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.30%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.06%25-yellow)](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-91.51%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-99.87%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.24%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 ae9f4777..b1e1f2c8 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -24,7 +24,7 @@
-### fr_FR.axaml: 91.57% +### fr_FR.axaml: 91.51%
@@ -106,7 +106,7 @@
-### pt_BR.axaml: 91.30% +### pt_BR.axaml: 91.24%
From 398b14695ce9900e4b712b54e1ddf987953ac23f Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 17 Mar 2025 17:10:42 +0800 Subject: [PATCH 389/865] enhance: the git dir of worktree's owner repository may not named `.git` Signed-off-by: leo --- src/ViewModels/Repository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 4f2f3ca3..f1c43e7c 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -459,7 +459,7 @@ namespace SourceGit.ViewModels { // For worktrees, we need to watch the $GIT_COMMON_DIR instead of the $GIT_DIR. var gitDirForWatcher = _gitDir; - if (_gitDir.Replace("\\", "/").IndexOf(".git/worktrees/", StringComparison.Ordinal) > 0) + if (_gitDir.Replace("\\", "/").IndexOf("/worktrees/", StringComparison.Ordinal) > 0) { var commonDir = new Commands.QueryGitCommonDir(_fullpath).Result(); if (!string.IsNullOrEmpty(commonDir)) From c9fe373dda59dfc87fb927aa9bac3ebf538c22ce Mon Sep 17 00:00:00 2001 From: Leonardo Date: Mon, 17 Mar 2025 10:15:17 +0100 Subject: [PATCH 390/865] add missing key and fix untranslated one (#1104) --- src/Resources/Locales/it_IT.axaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Resources/Locales/it_IT.axaml b/src/Resources/Locales/it_IT.axaml index 782d6e78..d002dfef 100644 --- a/src/Resources/Locales/it_IT.axaml +++ b/src/Resources/Locales/it_IT.axaml @@ -454,7 +454,8 @@ Abilita streaming ASPETTO Font Predefinito - Font Size + Larghezza della Tab Editor + Dimensione Font Dimensione Font Predefinita Dimensione Font Editor Font Monospaziato From 2b95ea2ab1cac2cda9b27add6439406f47c163e0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 17 Mar 2025 09:15:30 +0000 Subject: [PATCH 391/865] 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 13887a13..dff78418 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-99.06%25-yellow)](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-91.51%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-99.87%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.24%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.06%25-yellow)](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-91.51%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-%E2%88%9A-brightgreen)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.24%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 b1e1f2c8..0f8ccc2b 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -96,13 +96,13 @@
-### it_IT.axaml: 99.87% +### it_IT.axaml: 100.00%
Missing Keys -- Text.Preferences.Appearance.EditorTabWidth +
From a0cddaea8020b1ca891217df3f918a1a05560e97 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 17 Mar 2025 19:53:47 +0800 Subject: [PATCH 392/865] feature: support `--ff-only` option for `git merge` command Signed-off-by: leo --- src/Models/MergeMode.cs | 1 + src/ViewModels/Histories.cs | 6 +++--- src/ViewModels/Merge.cs | 12 +++++++----- src/ViewModels/Repository.cs | 6 +++--- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/Models/MergeMode.cs b/src/Models/MergeMode.cs index e4389b32..5dc70030 100644 --- a/src/Models/MergeMode.cs +++ b/src/Models/MergeMode.cs @@ -5,6 +5,7 @@ public static readonly MergeMode[] Supported = [ new MergeMode("Default", "Fast-forward if possible", ""), + new MergeMode("Fast-forward", "Refuse to merge when fast-forward is not possible", "--ff-only"), new MergeMode("No Fast-forward", "Always create a merge commit", "--no-ff"), new MergeMode("Squash", "Squash merge", "--squash"), new MergeMode("Don't commit", "Merge without commit", "--no-ff --no-commit"), diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs index 0e67915c..01114dd3 100644 --- a/src/ViewModels/Histories.cs +++ b/src/ViewModels/Histories.cs @@ -871,7 +871,7 @@ namespace SourceGit.ViewModels return; if (_repo.CanCreatePopup()) - _repo.ShowAndStartPopup(new Merge(_repo, b, current.Name)); + _repo.ShowAndStartPopup(new Merge(_repo, b, current.Name, true)); e.Handled = true; }; @@ -972,7 +972,7 @@ namespace SourceGit.ViewModels merge.Click += (_, e) => { if (_repo.CanCreatePopup()) - _repo.ShowPopup(new Merge(_repo, branch, current.Name)); + _repo.ShowPopup(new Merge(_repo, branch, current.Name, false)); e.Handled = true; }; submenu.Items.Add(merge); @@ -1060,7 +1060,7 @@ namespace SourceGit.ViewModels merge.Click += (_, e) => { if (_repo.CanCreatePopup()) - _repo.ShowPopup(new Merge(_repo, branch, current.Name)); + _repo.ShowPopup(new Merge(_repo, branch, current.Name, false)); e.Handled = true; }; diff --git a/src/ViewModels/Merge.cs b/src/ViewModels/Merge.cs index bde9b66d..be938867 100644 --- a/src/ViewModels/Merge.cs +++ b/src/ViewModels/Merge.cs @@ -21,14 +21,14 @@ namespace SourceGit.ViewModels set; } - public Merge(Repository repo, Models.Branch source, string into) + public Merge(Repository repo, Models.Branch source, string into, bool forceFastForward) { _repo = repo; _sourceName = source.FriendlyName; Source = source; Into = into; - Mode = AutoSelectMergeMode(); + Mode = forceFastForward ? Models.MergeMode.Supported[1] : AutoSelectMergeMode(); View = new Views.Merge() { DataContext = this }; } @@ -72,12 +72,14 @@ namespace SourceGit.ViewModels var config = new Commands.Config(_repo.FullPath).Get($"branch.{Into}.mergeoptions"); if (string.IsNullOrEmpty(config)) return Models.MergeMode.Supported[0]; - if (config.Equals("--no-ff", StringComparison.Ordinal)) + if (config.Equals("--ff-only", StringComparison.Ordinal)) return Models.MergeMode.Supported[1]; - if (config.Equals("--squash", StringComparison.Ordinal)) + if (config.Equals("--no-ff", StringComparison.Ordinal)) return Models.MergeMode.Supported[2]; - if (config.Equals("--no-commit", StringComparison.Ordinal) || config.Equals("--no-ff --no-commit", StringComparison.Ordinal)) + if (config.Equals("--squash", StringComparison.Ordinal)) return Models.MergeMode.Supported[3]; + if (config.Equals("--no-commit", StringComparison.Ordinal) || config.Equals("--no-ff --no-commit", StringComparison.Ordinal)) + return Models.MergeMode.Supported[4]; return Models.MergeMode.Supported[0]; } diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index f1c43e7c..bf283532 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -1516,7 +1516,7 @@ namespace SourceGit.ViewModels return; if (CanCreatePopup()) - ShowAndStartPopup(new Merge(this, b, branch.Name)); + ShowAndStartPopup(new Merge(this, b, branch.Name, true)); e.Handled = true; }; @@ -1595,7 +1595,7 @@ namespace SourceGit.ViewModels merge.Click += (_, e) => { if (CanCreatePopup()) - ShowPopup(new Merge(this, branch, _currentBranch.Name)); + ShowPopup(new Merge(this, branch, _currentBranch.Name, false)); e.Handled = true; }; @@ -1876,7 +1876,7 @@ namespace SourceGit.ViewModels merge.Click += (_, e) => { if (CanCreatePopup()) - ShowPopup(new Merge(this, branch, _currentBranch.Name)); + ShowPopup(new Merge(this, branch, _currentBranch.Name, false)); e.Handled = true; }; From b930066b5a2bc0d085a8c628f89b75c268fc6456 Mon Sep 17 00:00:00 2001 From: Gadfly Date: Mon, 17 Mar 2025 19:59:28 +0800 Subject: [PATCH 393/865] fix: improve line splitting to handle both LF and CRLF line endings (#1106) --- src/Commands/CountLocalChangesWithoutUntracked.cs | 2 +- src/Commands/QueryCommitSignInfo.cs | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Commands/CountLocalChangesWithoutUntracked.cs b/src/Commands/CountLocalChangesWithoutUntracked.cs index 7ab9a54a..924f8a89 100644 --- a/src/Commands/CountLocalChangesWithoutUntracked.cs +++ b/src/Commands/CountLocalChangesWithoutUntracked.cs @@ -16,7 +16,7 @@ namespace SourceGit.Commands var rs = ReadToEnd(); if (rs.IsSuccess) { - var lines = rs.StdOut.Split('\n', StringSplitOptions.RemoveEmptyEntries); + var lines = rs.StdOut.Split(['\n', '\r'], StringSplitOptions.RemoveEmptyEntries); return lines.Length; } diff --git a/src/Commands/QueryCommitSignInfo.cs b/src/Commands/QueryCommitSignInfo.cs index 5c81cf57..7b53a1f2 100644 --- a/src/Commands/QueryCommitSignInfo.cs +++ b/src/Commands/QueryCommitSignInfo.cs @@ -1,4 +1,6 @@ -namespace SourceGit.Commands +using System; + +namespace SourceGit.Commands { public class QueryCommitSignInfo : Command { @@ -22,7 +24,7 @@ if (raw.Length <= 1) return null; - var lines = raw.Split('\n'); + var lines = raw.Split(['\n', '\r'], StringSplitOptions.RemoveEmptyEntries); return new Models.CommitSignInfo() { VerifyResult = lines[0][0], From 808302ce84813d59a6a859139dd8f84143cc5f5f Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 17 Mar 2025 20:35:31 +0800 Subject: [PATCH 394/865] code_review: PR #1106 - Use new syntex `[...]` instead of `new char[] {...}` to create char arrays - Use `string.ReplaceLineEndings('\n').Split('\n')` instead of `string.Split(['\n', '\r'], StringSplitOptions.RemoveEmptyEntries)` because that the `Signer` part may be missing Signed-off-by: leo --- src/Commands/Config.cs | 2 +- src/Commands/CountLocalChangesWithoutUntracked.cs | 2 +- src/Commands/LFS.cs | 2 +- src/Commands/QueryBranches.cs | 2 +- src/Commands/QueryCommitSignInfo.cs | 4 ++-- src/Commands/QueryCommits.cs | 6 +++--- src/Commands/QueryRefsContainsCommit.cs | 2 +- src/Commands/QueryStagedChangesWithAmend.cs | 2 +- src/Commands/QuerySubmodules.cs | 4 ++-- src/Commands/QueryTrackStatus.cs | 2 +- src/Commands/Worktree.cs | 2 +- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Commands/Config.cs b/src/Commands/Config.cs index 2fb83325..49e8fcb7 100644 --- a/src/Commands/Config.cs +++ b/src/Commands/Config.cs @@ -29,7 +29,7 @@ namespace SourceGit.Commands var rs = new Dictionary(); if (output.IsSuccess) { - var lines = output.StdOut.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); + var lines = output.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { var idx = line.IndexOf('=', StringComparison.Ordinal); diff --git a/src/Commands/CountLocalChangesWithoutUntracked.cs b/src/Commands/CountLocalChangesWithoutUntracked.cs index 924f8a89..0ba508f8 100644 --- a/src/Commands/CountLocalChangesWithoutUntracked.cs +++ b/src/Commands/CountLocalChangesWithoutUntracked.cs @@ -16,7 +16,7 @@ namespace SourceGit.Commands var rs = ReadToEnd(); if (rs.IsSuccess) { - var lines = rs.StdOut.Split(['\n', '\r'], StringSplitOptions.RemoveEmptyEntries); + var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries); return lines.Length; } diff --git a/src/Commands/LFS.cs b/src/Commands/LFS.cs index 2b7d1de4..f7e56486 100644 --- a/src/Commands/LFS.cs +++ b/src/Commands/LFS.cs @@ -82,7 +82,7 @@ namespace SourceGit.Commands var rs = cmd.ReadToEnd(); if (rs.IsSuccess) { - var lines = rs.StdOut.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); + var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { var match = REG_LOCK().Match(line); diff --git a/src/Commands/QueryBranches.cs b/src/Commands/QueryBranches.cs index 44438cef..8dbc4055 100644 --- a/src/Commands/QueryBranches.cs +++ b/src/Commands/QueryBranches.cs @@ -24,7 +24,7 @@ namespace SourceGit.Commands if (!rs.IsSuccess) return branches; - var lines = rs.StdOut.Split('\n', StringSplitOptions.RemoveEmptyEntries); + var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries); var remoteBranches = new HashSet(); foreach (var line in lines) { diff --git a/src/Commands/QueryCommitSignInfo.cs b/src/Commands/QueryCommitSignInfo.cs index 7b53a1f2..4f729a8d 100644 --- a/src/Commands/QueryCommitSignInfo.cs +++ b/src/Commands/QueryCommitSignInfo.cs @@ -20,11 +20,11 @@ namespace SourceGit.Commands if (!rs.IsSuccess) return null; - var raw = rs.StdOut.Trim(); + var raw = rs.StdOut.Trim().ReplaceLineEndings("\n"); if (raw.Length <= 1) return null; - var lines = raw.Split(['\n', '\r'], StringSplitOptions.RemoveEmptyEntries); + var lines = raw.Split('\n'); return new Models.CommitSignInfo() { VerifyResult = lines[0][0], diff --git a/src/Commands/QueryCommits.cs b/src/Commands/QueryCommits.cs index 312c068f..8d704aee 100644 --- a/src/Commands/QueryCommits.cs +++ b/src/Commands/QueryCommits.cs @@ -10,7 +10,7 @@ namespace SourceGit.Commands { WorkingDirectory = repo; Context = repo; - Args = $"log --no-show-signature --decorate=full --pretty=format:%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s {limits}"; + Args = $"log --no-show-signature --decorate=full --format=%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s {limits}"; _findFirstMerged = needFindHead; } @@ -35,7 +35,7 @@ namespace SourceGit.Commands var argsBuilder = new StringBuilder(); argsBuilder.Append(search); - var words = filter.Split(new[] { ' ', '\t', '\r' }, StringSplitOptions.RemoveEmptyEntries); + var words = filter.Split([' ', '\t', '\r'], StringSplitOptions.RemoveEmptyEntries); foreach (var word in words) { var escaped = word.Trim().Replace("\"", "\\\"", StringComparison.Ordinal); @@ -124,7 +124,7 @@ namespace SourceGit.Commands Args = $"log --since=\"{_commits[^1].CommitterTimeStr}\" --format=\"%H\""; var rs = ReadToEnd(); - var shas = rs.StdOut.Split('\n', StringSplitOptions.RemoveEmptyEntries); + var shas = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries); if (shas.Length == 0) return; diff --git a/src/Commands/QueryRefsContainsCommit.cs b/src/Commands/QueryRefsContainsCommit.cs index 82e9b341..cabe1b50 100644 --- a/src/Commands/QueryRefsContainsCommit.cs +++ b/src/Commands/QueryRefsContainsCommit.cs @@ -20,7 +20,7 @@ namespace SourceGit.Commands if (!output.IsSuccess) return rs; - var lines = output.StdOut.Split('\n'); + var lines = output.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { if (line.EndsWith("/HEAD", StringComparison.Ordinal)) diff --git a/src/Commands/QueryStagedChangesWithAmend.cs b/src/Commands/QueryStagedChangesWithAmend.cs index f5c9659f..cfea5e35 100644 --- a/src/Commands/QueryStagedChangesWithAmend.cs +++ b/src/Commands/QueryStagedChangesWithAmend.cs @@ -24,7 +24,7 @@ namespace SourceGit.Commands if (rs.IsSuccess) { var changes = new List(); - var lines = rs.StdOut.Split('\n', StringSplitOptions.RemoveEmptyEntries); + var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { var match = REG_FORMAT2().Match(line); diff --git a/src/Commands/QuerySubmodules.cs b/src/Commands/QuerySubmodules.cs index 1ceccf78..e2debd06 100644 --- a/src/Commands/QuerySubmodules.cs +++ b/src/Commands/QuerySubmodules.cs @@ -26,7 +26,7 @@ namespace SourceGit.Commands var rs = ReadToEnd(); var builder = new StringBuilder(); - var lines = rs.StdOut.Split('\n', System.StringSplitOptions.RemoveEmptyEntries); + var lines = rs.StdOut.Split(['r', '\n'], System.StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { var match = REG_FORMAT1().Match(line); @@ -55,7 +55,7 @@ namespace SourceGit.Commands return submodules; var dirty = new HashSet(); - lines = rs.StdOut.Split('\n', System.StringSplitOptions.RemoveEmptyEntries); + lines = rs.StdOut.Split(['\r', '\n'], System.StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { var match = REG_FORMAT_STATUS().Match(line); diff --git a/src/Commands/QueryTrackStatus.cs b/src/Commands/QueryTrackStatus.cs index 0bf9746f..e7e1f1c9 100644 --- a/src/Commands/QueryTrackStatus.cs +++ b/src/Commands/QueryTrackStatus.cs @@ -19,7 +19,7 @@ namespace SourceGit.Commands if (!rs.IsSuccess) return status; - var lines = rs.StdOut.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); + var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { if (line[0] == '>') diff --git a/src/Commands/Worktree.cs b/src/Commands/Worktree.cs index b73b8573..960d5501 100644 --- a/src/Commands/Worktree.cs +++ b/src/Commands/Worktree.cs @@ -21,7 +21,7 @@ namespace SourceGit.Commands var last = null as Models.Worktree; if (rs.IsSuccess) { - var lines = rs.StdOut.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); + var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { if (line.StartsWith("worktree ", StringComparison.Ordinal)) From 8d47bd5cd9451360acda528f9dff25fdec431686 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 17 Mar 2025 20:46:01 +0800 Subject: [PATCH 395/865] refactor: use `--format=` instead of `--pretty=format:` Signed-off-by: leo --- src/Commands/QueryCommitFullMessage.cs | 2 +- src/Commands/QueryCommitSignInfo.cs | 6 ++---- src/Commands/QueryCommits.cs | 2 +- src/Commands/QueryCommitsForInteractiveRebase.cs | 2 +- src/Commands/QuerySingleCommit.cs | 2 +- src/Commands/QueryStashes.cs | 2 +- src/Commands/Statistics.cs | 2 +- 7 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/Commands/QueryCommitFullMessage.cs b/src/Commands/QueryCommitFullMessage.cs index c8f1867d..36b6d1c7 100644 --- a/src/Commands/QueryCommitFullMessage.cs +++ b/src/Commands/QueryCommitFullMessage.cs @@ -6,7 +6,7 @@ namespace SourceGit.Commands { WorkingDirectory = repo; Context = repo; - Args = $"show --no-show-signature --pretty=format:%B -s {sha}"; + Args = $"show --no-show-signature --format=%B -s {sha}"; } public string Result() diff --git a/src/Commands/QueryCommitSignInfo.cs b/src/Commands/QueryCommitSignInfo.cs index 4f729a8d..799e142d 100644 --- a/src/Commands/QueryCommitSignInfo.cs +++ b/src/Commands/QueryCommitSignInfo.cs @@ -1,6 +1,4 @@ -using System; - -namespace SourceGit.Commands +namespace SourceGit.Commands { public class QueryCommitSignInfo : Command { @@ -9,7 +7,7 @@ namespace SourceGit.Commands WorkingDirectory = repo; Context = repo; - const string baseArgs = "show --no-show-signature --pretty=format:\"%G?%n%GS%n%GK\" -s"; + const string baseArgs = "show --no-show-signature --format=%G?%n%GS%n%GK -s"; const string fakeSignersFileArg = "-c gpg.ssh.allowedSignersFile=/dev/null"; Args = $"{(useFakeSignersFile ? fakeSignersFileArg : string.Empty)} {baseArgs} {sha}"; } diff --git a/src/Commands/QueryCommits.cs b/src/Commands/QueryCommits.cs index 8d704aee..dd3c39b4 100644 --- a/src/Commands/QueryCommits.cs +++ b/src/Commands/QueryCommits.cs @@ -48,7 +48,7 @@ namespace SourceGit.Commands WorkingDirectory = repo; Context = repo; - Args = $"log -1000 --date-order --no-show-signature --decorate=full --pretty=format:%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s " + search; + Args = $"log -1000 --date-order --no-show-signature --decorate=full --format=%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s " + search; _findFirstMerged = false; } diff --git a/src/Commands/QueryCommitsForInteractiveRebase.cs b/src/Commands/QueryCommitsForInteractiveRebase.cs index 232d86e5..615060a5 100644 --- a/src/Commands/QueryCommitsForInteractiveRebase.cs +++ b/src/Commands/QueryCommitsForInteractiveRebase.cs @@ -11,7 +11,7 @@ namespace SourceGit.Commands WorkingDirectory = repo; Context = repo; - Args = $"log --date-order --no-show-signature --decorate=full --pretty=format:\"%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%B%n{_boundary}\" {on}..HEAD"; + Args = $"log --date-order --no-show-signature --decorate=full --format=\"%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%B%n{_boundary}\" {on}..HEAD"; } public List Result() diff --git a/src/Commands/QuerySingleCommit.cs b/src/Commands/QuerySingleCommit.cs index 1e1c9ea4..35289ec5 100644 --- a/src/Commands/QuerySingleCommit.cs +++ b/src/Commands/QuerySingleCommit.cs @@ -8,7 +8,7 @@ namespace SourceGit.Commands { WorkingDirectory = repo; Context = repo; - Args = $"show --no-show-signature --decorate=full --pretty=format:%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s -s {sha}"; + Args = $"show --no-show-signature --decorate=full --format=%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s -s {sha}"; } public Models.Commit Result() diff --git a/src/Commands/QueryStashes.cs b/src/Commands/QueryStashes.cs index ccf601c5..dd5d10cc 100644 --- a/src/Commands/QueryStashes.cs +++ b/src/Commands/QueryStashes.cs @@ -9,7 +9,7 @@ namespace SourceGit.Commands { WorkingDirectory = repo; Context = repo; - Args = "stash list --pretty=format:%H%n%P%n%ct%n%gd%n%s"; + Args = "stash list --format=%H%n%P%n%ct%n%gd%n%s"; } public List Result() diff --git a/src/Commands/Statistics.cs b/src/Commands/Statistics.cs index 511c43e8..1439cedd 100644 --- a/src/Commands/Statistics.cs +++ b/src/Commands/Statistics.cs @@ -8,7 +8,7 @@ namespace SourceGit.Commands { WorkingDirectory = repo; Context = repo; - Args = $"log --date-order --branches --remotes -{max} --pretty=format:\"%ct$%aN\""; + Args = $"log --date-order --branches --remotes -{max} --format=%ct$%aN"; } public Models.Statistics Result() From 695db2a319918d6ec96ec317432b0b656a154ab3 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 17 Mar 2025 20:57:18 +0800 Subject: [PATCH 396/865] code_style: run `dotnet format` Signed-off-by: leo --- src/Commands/QueryCommitSignInfo.cs | 1 - src/Native/MacOS.cs | 2 +- src/Views/About.axaml | 2 +- src/Views/AddWorktree.axaml | 10 +- src/Views/Askpass.axaml | 4 +- src/Views/AssumeUnchangedManager.axaml | 10 +- src/Views/Blame.axaml | 2 +- src/Views/BranchCompare.axaml | 4 +- src/Views/ChangeCollectionView.axaml | 4 +- src/Views/ChangeViewModeSwitcher.axaml | 2 +- src/Views/CherryPick.axaml | 8 +- src/Views/Clone.axaml | 36 ++-- src/Views/CommitBaseInfo.axaml | 14 +- src/Views/CommitChanges.axaml | 2 +- src/Views/CommitDetail.axaml | 20 +-- src/Views/CommitMessageTextBox.axaml | 4 +- src/Views/CommitRelationTracking.axaml | 2 +- src/Views/ConfigureWorkspace.axaml | 10 +- src/Views/ConfirmCommitWithoutFiles.axaml | 2 +- src/Views/DeleteBranch.axaml | 2 +- src/Views/DeleteRepositoryNode.axaml | 2 +- src/Views/DeleteTag.axaml | 2 +- src/Views/DiffView.axaml | 26 +-- src/Views/Discard.axaml | 16 +- src/Views/EditRepositoryNode.axaml | 2 +- src/Views/FileHistories.axaml | 6 +- src/Views/FilterModeSwitchButton.axaml | 2 +- src/Views/Histories.axaml | 12 +- src/Views/Hotkeys.axaml | 12 +- src/Views/ImageDiffView.axaml | 12 +- src/Views/Init.axaml | 2 +- src/Views/InteractiveRebase.axaml | 22 +-- src/Views/LFSFetch.axaml | 4 +- src/Views/LFSLocks.axaml | 4 +- src/Views/LFSTrackCustomPattern.axaml | 2 +- src/Views/Launcher.axaml | 6 +- src/Views/LauncherPage.axaml | 8 +- src/Views/LauncherTabBar.axaml | 2 +- src/Views/Merge.axaml | 2 +- src/Views/MergeMultiple.axaml | 6 +- src/Views/PopupRunningStatus.axaml | 6 +- src/Views/Preferences.axaml | 12 +- src/Views/Push.axaml | 4 +- src/Views/RepositoryConfigure.axaml | 14 +- src/Views/RepositoryToolbar.axaml | 210 +++++++++++----------- src/Views/RevisionCompare.axaml | 4 +- src/Views/RevisionFileContentViewer.axaml | 4 +- src/Views/RevisionFiles.axaml | 2 +- src/Views/Reword.axaml | 4 +- src/Views/SelfUpdate.axaml | 2 +- src/Views/StashChanges.axaml | 12 +- src/Views/TagsView.axaml | 20 +-- src/Views/TextDiffView.axaml | 10 +- src/Views/WelcomeToolbar.axaml | 4 +- src/Views/WorkingCopy.axaml | 16 +- 55 files changed, 307 insertions(+), 308 deletions(-) diff --git a/src/Commands/QueryCommitSignInfo.cs b/src/Commands/QueryCommitSignInfo.cs index 799e142d..133949af 100644 --- a/src/Commands/QueryCommitSignInfo.cs +++ b/src/Commands/QueryCommitSignInfo.cs @@ -29,7 +29,6 @@ Signer = lines[1], Key = lines[2] }; - } } } diff --git a/src/Native/MacOS.cs b/src/Native/MacOS.cs index 123b160b..d7ef4701 100644 --- a/src/Native/MacOS.cs +++ b/src/Native/MacOS.cs @@ -31,7 +31,7 @@ namespace SourceGit.Native var env = File.ReadAllText(customPathFile).Trim(); if (!string.IsNullOrEmpty(env)) path = env; - } + } Environment.SetEnvironmentVariable("PATH", path); } diff --git a/src/Views/About.axaml b/src/Views/About.axaml index 28529b63..d0dd7b82 100644 --- a/src/Views/About.axaml +++ b/src/Views/About.axaml @@ -28,7 +28,7 @@ Text="{DynamicResource Text.About}" HorizontalAlignment="Center" VerticalAlignment="Center" IsHitTestVisible="False"/> - + diff --git a/src/Views/AddWorktree.axaml b/src/Views/AddWorktree.axaml index d6853aab..1811008c 100644 --- a/src/Views/AddWorktree.axaml +++ b/src/Views/AddWorktree.axaml @@ -27,7 +27,7 @@ - +
- + - - + Text="{DynamicResource Text.AddWorktree.Tracking}"/> + - + - + - + - + @@ -62,7 +62,7 @@ - + @@ -73,7 +73,7 @@ ToolTip.Tip="{DynamicResource Text.Diff.Next}"> - + - - + - + diff --git a/src/Views/Discard.axaml b/src/Views/Discard.axaml index 23162060..1699b051 100644 --- a/src/Views/Discard.axaml +++ b/src/Views/Discard.axaml @@ -11,16 +11,16 @@ - + - - + @@ -31,13 +31,13 @@ Text="{DynamicResource Text.Discard.Changes}"/> - +
- + - + - diff --git a/src/Views/EditRepositoryNode.axaml b/src/Views/EditRepositoryNode.axaml index ac8f50f3..615e3f11 100644 --- a/src/Views/EditRepositoryNode.axaml +++ b/src/Views/EditRepositoryNode.axaml @@ -43,7 +43,7 @@ Fill="{Binding Converter={x:Static c:IntConverters.ToBookmarkBrush}}" HorizontalAlignment="Center" VerticalAlignment="Center" Data="{StaticResource Icons.Bookmark}"/> - + diff --git a/src/Views/FileHistories.axaml b/src/Views/FileHistories.axaml index 124b2e00..e33156fb 100644 --- a/src/Views/FileHistories.axaml +++ b/src/Views/FileHistories.axaml @@ -37,7 +37,7 @@ Text="{DynamicResource Text.FileHistory}" HorizontalAlignment="Center" VerticalAlignment="Center" IsHitTestVisible="False"/> - +
@@ -184,7 +184,7 @@ - + @@ -234,7 +234,7 @@ HorizontalAlignment="Center" VerticalAlignment="Center" IsVisible="{Binding IsLoading}"/> - + diff --git a/src/Views/FilterModeSwitchButton.axaml b/src/Views/FilterModeSwitchButton.axaml index 0fbbbf8e..b202c434 100644 --- a/src/Views/FilterModeSwitchButton.axaml +++ b/src/Views/FilterModeSwitchButton.axaml @@ -5,7 +5,7 @@ xmlns:m="using:SourceGit.Models" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="SourceGit.Views.FilterModeSwitchButton" - x:Name="ThisControl"> + x:Name="ThisControl"> @@ -104,7 +104,7 @@ - + diff --git a/src/Views/LFSTrackCustomPattern.axaml b/src/Views/LFSTrackCustomPattern.axaml index 36eaef65..f60304d5 100644 --- a/src/Views/LFSTrackCustomPattern.axaml +++ b/src/Views/LFSTrackCustomPattern.axaml @@ -11,7 +11,7 @@ - + + WindowStartupLocation="CenterScreen"> @@ -80,7 +80,7 @@ - @@ -93,7 +93,7 @@ - + diff --git a/src/Views/LauncherPage.axaml b/src/Views/LauncherPage.axaml index 81f504c1..7ce450de 100644 --- a/src/Views/LauncherPage.axaml +++ b/src/Views/LauncherPage.axaml @@ -17,14 +17,14 @@ - + - + @@ -32,7 +32,7 @@ - + @@ -138,7 +138,7 @@ + diff --git a/src/Views/LauncherTabBar.axaml b/src/Views/LauncherTabBar.axaml index 9b748e91..73b48f58 100644 --- a/src/Views/LauncherTabBar.axaml +++ b/src/Views/LauncherTabBar.axaml @@ -54,7 +54,7 @@ - + - + diff --git a/src/Views/MergeMultiple.axaml b/src/Views/MergeMultiple.axaml index bb543e16..332d9fef 100644 --- a/src/Views/MergeMultiple.axaml +++ b/src/Views/MergeMultiple.axaml @@ -12,7 +12,7 @@ - + - + @@ -84,7 +84,7 @@ - + diff --git a/src/Views/PopupRunningStatus.axaml b/src/Views/PopupRunningStatus.axaml index c2d86f51..a8467415 100644 --- a/src/Views/PopupRunningStatus.axaml +++ b/src/Views/PopupRunningStatus.axaml @@ -9,19 +9,19 @@ x:Name="ThisControl"> - + - + - + - + - + @@ -635,7 +635,7 @@ - + @@ -646,7 +646,7 @@ - + @@ -725,8 +725,8 @@ - - + + diff --git a/src/Views/RepositoryConfigure.axaml b/src/Views/RepositoryConfigure.axaml index f6a02c49..de777800 100644 --- a/src/Views/RepositoryConfigure.axaml +++ b/src/Views/RepositoryConfigure.axaml @@ -65,7 +65,7 @@ CornerRadius="3" Watermark="{DynamicResource Text.Configure.Email.Placeholder}" Text="{Binding UserEmail, Mode=TwoWay}"/> - + - @@ -256,7 +256,7 @@ - + @@ -315,7 +315,7 @@ - + @@ -442,7 +442,7 @@ - + diff --git a/src/Views/RepositoryToolbar.axaml b/src/Views/RepositoryToolbar.axaml index a409d8d0..9f7f1801 100644 --- a/src/Views/RepositoryToolbar.axaml +++ b/src/Views/RepositoryToolbar.axaml @@ -8,128 +8,128 @@ x:Class="SourceGit.Views.RepositoryToolbar" x:DataType="vm:Repository"> - - + + - - - + - + - - + - - + + - + + + + - + + + - + + + - + + + - + - - + - - + - - - - - - - - + - - - - - - - - + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Views/RevisionCompare.axaml b/src/Views/RevisionCompare.axaml index 73703ff1..f0498fbf 100644 --- a/src/Views/RevisionCompare.axaml +++ b/src/Views/RevisionCompare.axaml @@ -15,7 +15,7 @@ - + @@ -32,7 +32,7 @@ - + diff --git a/src/Views/RevisionFileContentViewer.axaml b/src/Views/RevisionFileContentViewer.axaml index a3a168cf..86393316 100644 --- a/src/Views/RevisionFileContentViewer.axaml +++ b/src/Views/RevisionFileContentViewer.axaml @@ -35,12 +35,12 @@ - + - + diff --git a/src/Views/RevisionFiles.axaml b/src/Views/RevisionFiles.axaml index e0c6577d..6575dc66 100644 --- a/src/Views/RevisionFiles.axaml +++ b/src/Views/RevisionFiles.axaml @@ -50,7 +50,7 @@ - + - + - + - + - + - + + - + diff --git a/src/Views/WorkingCopy.axaml b/src/Views/WorkingCopy.axaml index c9b94d59..4d79135d 100644 --- a/src/Views/WorkingCopy.axaml +++ b/src/Views/WorkingCopy.axaml @@ -23,7 +23,7 @@ - + @@ -106,7 +106,7 @@ - + - + - + @@ -186,7 +186,7 @@ - + @@ -277,7 +277,7 @@ Width="18" Height="18" HorizontalAlignment="Right" IsVisible="{Binding IsCommitting}"/> - + - + From 760e44877ba02104638f0f5fd31c0ee556d6ff7d Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 18 Mar 2025 12:15:00 +0800 Subject: [PATCH 397/865] fix: wrong split char Signed-off-by: leo --- src/Commands/QuerySubmodules.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Commands/QuerySubmodules.cs b/src/Commands/QuerySubmodules.cs index e2debd06..6016b0be 100644 --- a/src/Commands/QuerySubmodules.cs +++ b/src/Commands/QuerySubmodules.cs @@ -26,7 +26,7 @@ namespace SourceGit.Commands var rs = ReadToEnd(); var builder = new StringBuilder(); - var lines = rs.StdOut.Split(['r', '\n'], System.StringSplitOptions.RemoveEmptyEntries); + var lines = rs.StdOut.Split(['\r', '\n'], System.StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { var match = REG_FORMAT1().Match(line); From 822452a20c36054837612cbf43e21795bead6ecc Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 18 Mar 2025 15:55:32 +0800 Subject: [PATCH 398/865] enhance: show inner exception message if possible when check update failed Signed-off-by: leo --- src/App.axaml.cs | 2 +- src/Models/{Version.cs => SelfUpdate.cs} | 24 ++++++++++++-- src/Views/SelfUpdate.axaml | 41 ++++++++++++------------ 3 files changed, 43 insertions(+), 24 deletions(-) rename src/Models/{Version.cs => SelfUpdate.cs} (65%) diff --git a/src/App.axaml.cs b/src/App.axaml.cs index f59d35db..af5e6177 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -532,7 +532,7 @@ namespace SourceGit catch (Exception e) { if (manually) - ShowSelfUpdateResult(e); + ShowSelfUpdateResult(new Models.SelfUpdateFailed(e)); } }); } diff --git a/src/Models/Version.cs b/src/Models/SelfUpdate.cs similarity index 65% rename from src/Models/Version.cs rename to src/Models/SelfUpdate.cs index 35c21778..e02f80d8 100644 --- a/src/Models/Version.cs +++ b/src/Models/SelfUpdate.cs @@ -1,4 +1,5 @@ -using System.Reflection; +using System; +using System.Reflection; using System.Text.Json.Serialization; namespace SourceGit.Models @@ -32,5 +33,24 @@ namespace SourceGit.Models } } - public class AlreadyUpToDate { } + public class AlreadyUpToDate + { + } + + public class SelfUpdateFailed + { + public string Reason + { + get; + private set; + } + + public SelfUpdateFailed(Exception e) + { + if (e.InnerException is { } inner) + Reason = inner.Message; + else + Reason = e.Message; + } + } } diff --git a/src/Views/SelfUpdate.axaml b/src/Views/SelfUpdate.axaml index 0a6fef34..2d5990e7 100644 --- a/src/Views/SelfUpdate.axaml +++ b/src/Views/SelfUpdate.axaml @@ -5,7 +5,6 @@ xmlns:m="using:SourceGit.Models" xmlns:vm="using:SourceGit.ViewModels" xmlns:v="using:SourceGit.Views" - xmlns:sys="clr-namespace:System;assembly=mscorlib" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="SourceGit.Views.SelfUpdate" x:DataType="vm:SelfUpdate" @@ -87,26 +86,6 @@ - - - - - - - - - -
-### ru_RU.axaml: 99.73% +### ru_RU.axaml: 100.00%
Missing Keys -- Text.Repository.HistoriesOptions -- Text.Repository.HistoriesOptions.ShowTagsInGraph +
From a5bdcab3415ac76caee4493e7444dd2bb3c2d2d6 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 20 Mar 2025 09:38:02 +0800 Subject: [PATCH 404/865] code_style: move dynamic context menu creation to view models Signed-off-by: leo --- src/ViewModels/Repository.cs | 168 ++++++++++++++++++++++++++++------ src/Views/Repository.axaml.cs | 116 +---------------------- 2 files changed, 144 insertions(+), 140 deletions(-) diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index bf283532..4f35d215 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -118,20 +118,6 @@ namespace SourceGit.ViewModels } } - public bool EnableTopoOrderInHistories - { - get => _settings.EnableTopoOrderInHistories; - set - { - if (value != _settings.EnableTopoOrderInHistories) - { - _settings.EnableTopoOrderInHistories = value; - OnPropertyChanged(); - Task.Run(RefreshCommits); - } - } - } - public bool OnlyHighlightCurrentBranchInHistories { get => _settings.OnlyHighlighCurrentBranchInHistories; @@ -145,20 +131,6 @@ namespace SourceGit.ViewModels } } - public Models.TagSortMode TagSortMode - { - get => _settings.TagSortMode; - set - { - if (value != _settings.TagSortMode) - { - _settings.TagSortMode = value; - OnPropertyChanged(); - VisibleTags = BuildVisibleTags(); - } - } - } - public string Filter { get => _filter; @@ -1470,6 +1442,97 @@ namespace SourceGit.ViewModels return menu; } + public ContextMenu CreateContextMenuForHistoriesPage() + { + var layout = new MenuItem(); + layout.Header = App.Text("Repository.HistoriesLayout"); + layout.IsEnabled = false; + + var isHorizontal = Preferences.Instance.UseTwoColumnsLayoutInHistories; + var horizontal = new MenuItem(); + horizontal.Header = App.Text("Repository.HistoriesLayout.Horizontal"); + if (isHorizontal) + horizontal.Icon = App.CreateMenuIcon("Icons.Check"); + horizontal.Click += (_, ev) => + { + Preferences.Instance.UseTwoColumnsLayoutInHistories = true; + ev.Handled = true; + }; + + var vertical = new MenuItem(); + vertical.Header = App.Text("Repository.HistoriesLayout.Vertical"); + if (!isHorizontal) + vertical.Icon = App.CreateMenuIcon("Icons.Check"); + vertical.Click += (_, ev) => + { + Preferences.Instance.UseTwoColumnsLayoutInHistories = false; + ev.Handled = true; + }; + + var order = new MenuItem(); + order.Header = App.Text("Repository.HistoriesOrder"); + order.IsEnabled = false; + + var dateOrder = new MenuItem(); + dateOrder.Header = App.Text("Repository.HistoriesOrder.ByDate"); + dateOrder.SetValue(Views.MenuItemExtension.CommandProperty, "--date-order"); + if (!_settings.EnableTopoOrderInHistories) + dateOrder.Icon = App.CreateMenuIcon("Icons.Check"); + dateOrder.Click += (_, ev) => + { + if (_settings.EnableTopoOrderInHistories) + { + _settings.EnableTopoOrderInHistories = false; + Task.Run(RefreshCommits); + } + + ev.Handled = true; + }; + + var topoOrder = new MenuItem(); + topoOrder.Header = App.Text("Repository.HistoriesOrder.Topo"); + topoOrder.SetValue(Views.MenuItemExtension.CommandProperty, "--top-order"); + if (_settings.EnableTopoOrderInHistories) + topoOrder.Icon = App.CreateMenuIcon("Icons.Check"); + topoOrder.Click += (_, ev) => + { + if (!_settings.EnableTopoOrderInHistories) + { + _settings.EnableTopoOrderInHistories = true; + Task.Run(RefreshCommits); + } + + ev.Handled = true; + }; + + var others = new MenuItem(); + others.Header = App.Text("Repository.HistoriesOptions"); + others.IsEnabled = false; + + var showTagsInGraph = new MenuItem(); + showTagsInGraph.Header = App.Text("Repository.HistoriesOptions.ShowTagsInGraph"); + if (Preferences.Instance.ShowTagsInGraph) + showTagsInGraph.Icon = App.CreateMenuIcon("Icons.Check"); + showTagsInGraph.Click += (_, ev) => + { + Preferences.Instance.ShowTagsInGraph = !Preferences.Instance.ShowTagsInGraph; + ev.Handled = true; + }; + + var menu = new ContextMenu(); + menu.Items.Add(layout); + menu.Items.Add(horizontal); + menu.Items.Add(vertical); + menu.Items.Add(new MenuItem() { Header = "-" }); + menu.Items.Add(order); + menu.Items.Add(dateOrder); + menu.Items.Add(topoOrder); + menu.Items.Add(new MenuItem() { Header = "-" }); + menu.Items.Add(others); + menu.Items.Add(showTagsInGraph); + return menu; + } + public ContextMenu CreateContextMenuForLocalBranch(Models.Branch branch) { var menu = new ContextMenu(); @@ -2065,6 +2128,55 @@ namespace SourceGit.ViewModels return menu; } + public ContextMenu CreateContextMenuForTagSortMode() + { + var mode = _settings.TagSortMode; + var changeMode = new Action((m) => + { + if (_settings.TagSortMode != m) + { + _settings.TagSortMode = m; + VisibleTags = BuildVisibleTags(); + } + }); + + var byCreatorDate = new MenuItem(); + byCreatorDate.Header = App.Text("Repository.Tags.OrderByCreatorDate"); + if (mode == Models.TagSortMode.CreatorDate) + byCreatorDate.Icon = App.CreateMenuIcon("Icons.Check"); + byCreatorDate.Click += (_, ev) => + { + changeMode(Models.TagSortMode.CreatorDate); + ev.Handled = true; + }; + + var byNameAsc = new MenuItem(); + byNameAsc.Header = App.Text("Repository.Tags.OrderByNameAsc"); + if (mode == Models.TagSortMode.NameInAscending) + byNameAsc.Icon = App.CreateMenuIcon("Icons.Check"); + byNameAsc.Click += (_, ev) => + { + changeMode(Models.TagSortMode.NameInAscending); + ev.Handled = true; + }; + + var byNameDes = new MenuItem(); + byNameDes.Header = App.Text("Repository.Tags.OrderByNameDes"); + if (mode == Models.TagSortMode.NameInDescending) + byNameDes.Icon = App.CreateMenuIcon("Icons.Check"); + byNameDes.Click += (_, ev) => + { + changeMode(Models.TagSortMode.NameInDescending); + ev.Handled = true; + }; + + var menu = new ContextMenu(); + menu.Items.Add(byCreatorDate); + menu.Items.Add(byNameAsc); + menu.Items.Add(byNameDes); + return menu; + } + public ContextMenu CreateContextMenuForSubmodule(string submodule) { var open = new MenuItem(); diff --git a/src/Views/Repository.axaml.cs b/src/Views/Repository.axaml.cs index e98adf70..d848c000 100644 --- a/src/Views/Repository.axaml.cs +++ b/src/Views/Repository.axaml.cs @@ -396,83 +396,8 @@ namespace SourceGit.Views { if (sender is Button button && DataContext is ViewModels.Repository repo) { - var layout = new MenuItem(); - layout.Header = App.Text("Repository.HistoriesLayout"); - layout.IsEnabled = false; - - var isHorizontal = ViewModels.Preferences.Instance.UseTwoColumnsLayoutInHistories; - var horizontal = new MenuItem(); - horizontal.Header = App.Text("Repository.HistoriesLayout.Horizontal"); - if (isHorizontal) - horizontal.Icon = App.CreateMenuIcon("Icons.Check"); - horizontal.Click += (_, ev) => - { - ViewModels.Preferences.Instance.UseTwoColumnsLayoutInHistories = true; - ev.Handled = true; - }; - - var vertical = new MenuItem(); - vertical.Header = App.Text("Repository.HistoriesLayout.Vertical"); - if (!isHorizontal) - vertical.Icon = App.CreateMenuIcon("Icons.Check"); - vertical.Click += (_, ev) => - { - ViewModels.Preferences.Instance.UseTwoColumnsLayoutInHistories = false; - ev.Handled = true; - }; - - var order = new MenuItem(); - order.Header = App.Text("Repository.HistoriesOrder"); - order.IsEnabled = false; - - var dateOrder = new MenuItem(); - dateOrder.Header = App.Text("Repository.HistoriesOrder.ByDate"); - dateOrder.SetValue(MenuItemExtension.CommandProperty, "--date-order"); - if (!repo.EnableTopoOrderInHistories) - dateOrder.Icon = App.CreateMenuIcon("Icons.Check"); - dateOrder.Click += (_, ev) => - { - repo.EnableTopoOrderInHistories = false; - ev.Handled = true; - }; - - var topoOrder = new MenuItem(); - topoOrder.Header = App.Text("Repository.HistoriesOrder.Topo"); - topoOrder.SetValue(MenuItemExtension.CommandProperty, "--top-order"); - if (repo.EnableTopoOrderInHistories) - topoOrder.Icon = App.CreateMenuIcon("Icons.Check"); - topoOrder.Click += (_, ev) => - { - repo.EnableTopoOrderInHistories = true; - ev.Handled = true; - }; - - var others = new MenuItem(); - others.Header = App.Text("Repository.HistoriesOptions"); - others.IsEnabled = false; - - var showTagsInGraph = new MenuItem(); - showTagsInGraph.Header = App.Text("Repository.HistoriesOptions.ShowTagsInGraph"); - if (ViewModels.Preferences.Instance.ShowTagsInGraph) - showTagsInGraph.Icon = App.CreateMenuIcon("Icons.Check"); - showTagsInGraph.Click += (_, ev) => - { - ViewModels.Preferences.Instance.ShowTagsInGraph = !ViewModels.Preferences.Instance.ShowTagsInGraph; - ev.Handled = true; - }; - - var menu = new ContextMenu(); - menu.Items.Add(layout); - menu.Items.Add(horizontal); - menu.Items.Add(vertical); - menu.Items.Add(new MenuItem() { Header = "-" }); - menu.Items.Add(order); - menu.Items.Add(dateOrder); - menu.Items.Add(topoOrder); - menu.Items.Add(new MenuItem() { Header = "-" }); - menu.Items.Add(others); - menu.Items.Add(showTagsInGraph); - menu.Open(button); + var menu = repo.CreateContextMenuForHistoriesPage(); + menu?.Open(button); } e.Handled = true; @@ -482,41 +407,8 @@ namespace SourceGit.Views { if (sender is Button button && DataContext is ViewModels.Repository repo) { - var byCreatorDate = new MenuItem(); - byCreatorDate.Header = App.Text("Repository.Tags.OrderByCreatorDate"); - if (repo.TagSortMode == Models.TagSortMode.CreatorDate) - byCreatorDate.Icon = App.CreateMenuIcon("Icons.Check"); - byCreatorDate.Click += (_, ev) => - { - repo.TagSortMode = Models.TagSortMode.CreatorDate; - ev.Handled = true; - }; - - var byNameAsc = new MenuItem(); - byNameAsc.Header = App.Text("Repository.Tags.OrderByNameAsc"); - if (repo.TagSortMode == Models.TagSortMode.NameInAscending) - byNameAsc.Icon = App.CreateMenuIcon("Icons.Check"); - byNameAsc.Click += (_, ev) => - { - repo.TagSortMode = Models.TagSortMode.NameInAscending; - ev.Handled = true; - }; - - var byNameDes = new MenuItem(); - byNameDes.Header = App.Text("Repository.Tags.OrderByNameDes"); - if (repo.TagSortMode == Models.TagSortMode.NameInDescending) - byNameDes.Icon = App.CreateMenuIcon("Icons.Check"); - byNameDes.Click += (_, ev) => - { - repo.TagSortMode = Models.TagSortMode.NameInDescending; - ev.Handled = true; - }; - - var menu = new ContextMenu(); - menu.Items.Add(byCreatorDate); - menu.Items.Add(byNameAsc); - menu.Items.Add(byNameDes); - menu.Open(button); + var menu = repo.CreateContextMenuForTagSortMode(); + menu?.Open(button); } e.Handled = true; From 145273b4a71e2c9d91a7c0cca461d5fa6b900e86 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 20 Mar 2025 11:10:48 +0800 Subject: [PATCH 405/865] refactor: move `Show tags in commit graph` to `Preferences` (#1109) Signed-off-by: leo --- src/Resources/Locales/en_US.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 | 17 ----------------- src/Views/Preferences.axaml | 9 +++++++-- 6 files changed, 11 insertions(+), 27 deletions(-) diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 293dd77b..f24d6c65 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -471,6 +471,7 @@ History Commits Show author time instead of commit time in graph Show children in the commit details + Show tags in commit graph Subject Guide Length GIT Enable Auto CRLF @@ -569,8 +570,6 @@ LAYOUT Horizontal Vertical - OPTIONS - Show Tags in Graph COMMITS ORDER Commit Date Topologically diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index 24d296e3..707c9ed9 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -475,6 +475,7 @@ Максимальная длина истории Показывать время автора вместо времени ревизии на графике Показать наследника в деталях комментария + Показывать метки на графике Длина темы ревизии GIT Включить автозавершение CRLF @@ -574,8 +575,6 @@ РАСПОЛОЖЕНИЕ Горизонтально Вертикально - ОПЦИИ - Показывать метки на графике ЗАПРОС РЕВИЗИЙ Дата ревизии Топологически diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index b8dcf417..93d08bd0 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -475,6 +475,7 @@ 最大历史提交数 在提交路线图中显示修改时间而非提交时间 在提交详情页中显示子提交列表 + 在提交路线图中显示标签 SUBJECT字数检测 GIT配置 自动换行转换 @@ -573,8 +574,6 @@ 布局方式 水平排布 竖直排布 - 其它设置 - 在提交路线图中显示标签 提交列表排序规则 按提交时间 按拓扑排序 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 1d2cee7c..d5a7a77c 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -474,6 +474,7 @@ 最大歷史提交數 在提交路線圖中顯示修改時間而非提交時間 在提交詳細資訊中顯示後續提交 + 在路線圖中顯示標籤 提交標題字數偵測 Git 設定 自動換行轉換 @@ -572,8 +573,6 @@ 版面配置 橫向顯示 縱向顯示 - 其它設定 - 在路線圖中顯示標籤 提交顯示順序 依時間排序 依拓撲排序 diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 4f35d215..6ea41e04 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -1505,20 +1505,6 @@ namespace SourceGit.ViewModels ev.Handled = true; }; - var others = new MenuItem(); - others.Header = App.Text("Repository.HistoriesOptions"); - others.IsEnabled = false; - - var showTagsInGraph = new MenuItem(); - showTagsInGraph.Header = App.Text("Repository.HistoriesOptions.ShowTagsInGraph"); - if (Preferences.Instance.ShowTagsInGraph) - showTagsInGraph.Icon = App.CreateMenuIcon("Icons.Check"); - showTagsInGraph.Click += (_, ev) => - { - Preferences.Instance.ShowTagsInGraph = !Preferences.Instance.ShowTagsInGraph; - ev.Handled = true; - }; - var menu = new ContextMenu(); menu.Items.Add(layout); menu.Items.Add(horizontal); @@ -1527,9 +1513,6 @@ namespace SourceGit.ViewModels menu.Items.Add(order); menu.Items.Add(dateOrder); menu.Items.Add(topoOrder); - menu.Items.Add(new MenuItem() { Header = "-" }); - menu.Items.Add(others); - menu.Items.Add(showTagsInGraph); return menu; } diff --git a/src/Views/Preferences.axaml b/src/Views/Preferences.axaml index d2b08467..702ec20f 100644 --- a/src/Views/Preferences.axaml +++ b/src/Views/Preferences.axaml @@ -46,7 +46,7 @@ - + + + - Date: Thu, 20 Mar 2025 03:11:14 +0000 Subject: [PATCH 406/865] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 25 ++++++++++--------------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 1655d03a..5b3dbc20 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-98.79%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-99.73%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-91.26%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-99.73%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-90.99%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-98.92%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-99.87%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-91.39%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-99.87%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.12%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 55262e90..b7f87cdf 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -1,4 +1,4 @@ -### de_DE.axaml: 98.79% +### de_DE.axaml: 98.92%
@@ -10,24 +10,22 @@ - Text.Diff.Last - Text.Preferences.AI.Streaming - Text.Preferences.Appearance.EditorTabWidth -- Text.Repository.HistoriesOptions -- Text.Repository.HistoriesOptions.ShowTagsInGraph +- Text.Preferences.General.ShowTagsInGraph - Text.StashCM.SaveAsPatch
-### es_ES.axaml: 99.73% +### es_ES.axaml: 99.87%
Missing Keys -- Text.Repository.HistoriesOptions -- Text.Repository.HistoriesOptions.ShowTagsInGraph +- Text.Preferences.General.ShowTagsInGraph
-### fr_FR.axaml: 91.26% +### fr_FR.axaml: 91.39%
@@ -66,6 +64,7 @@ - Text.Preferences.Appearance.FontSize.Editor - Text.Preferences.General.DateFormat - Text.Preferences.General.ShowChildren +- Text.Preferences.General.ShowTagsInGraph - Text.Preferences.Git.SSLVerify - Text.Repository.CustomActions - Text.Repository.FilterCommits @@ -75,8 +74,6 @@ - Text.Repository.HistoriesLayout - Text.Repository.HistoriesLayout.Horizontal - Text.Repository.HistoriesLayout.Vertical -- Text.Repository.HistoriesOptions -- Text.Repository.HistoriesOptions.ShowTagsInGraph - Text.Repository.HistoriesOrder - Text.Repository.HistoriesOrder.ByDate - Text.Repository.HistoriesOrder.Topo @@ -101,18 +98,17 @@
-### it_IT.axaml: 99.73% +### it_IT.axaml: 99.87%
Missing Keys -- Text.Repository.HistoriesOptions -- Text.Repository.HistoriesOptions.ShowTagsInGraph +- Text.Preferences.General.ShowTagsInGraph
-### pt_BR.axaml: 90.99% +### pt_BR.axaml: 91.12%
@@ -159,13 +155,12 @@ - Text.Preferences.Appearance.EditorTabWidth - Text.Preferences.General.DateFormat - Text.Preferences.General.ShowChildren +- Text.Preferences.General.ShowTagsInGraph - Text.Preferences.Git.SSLVerify - Text.Repository.FilterCommits - Text.Repository.HistoriesLayout - Text.Repository.HistoriesLayout.Horizontal - Text.Repository.HistoriesLayout.Vertical -- Text.Repository.HistoriesOptions -- Text.Repository.HistoriesOptions.ShowTagsInGraph - Text.Repository.HistoriesOrder - Text.Repository.Notifications.Clear - Text.Repository.OnlyHighlightCurrentBranchInHistories From 891e1b2ec8fc6a00882186e390c06a365ea05d46 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 20 Mar 2025 19:55:50 +0800 Subject: [PATCH 407/865] ux: show name of stash instead of SHA which is useless to user Signed-off-by: leo --- src/Views/StashesPage.axaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Views/StashesPage.axaml b/src/Views/StashesPage.axaml index 028764ca..6b087eb8 100644 --- a/src/Views/StashesPage.axaml +++ b/src/Views/StashesPage.axaml @@ -92,7 +92,7 @@ - + From 65dbfd336d4fe33e05ce6864fdf589e95c96b3c7 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 20 Mar 2025 20:53:30 +0800 Subject: [PATCH 408/865] refactor: it's not necessary to store untracked file list for selected stash Signed-off-by: leo --- src/Models/Stash.cs | 1 - src/ViewModels/StashesPage.cs | 25 ++++++++----------------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/Models/Stash.cs b/src/Models/Stash.cs index 8dca3bdb..257b6d33 100644 --- a/src/Models/Stash.cs +++ b/src/Models/Stash.cs @@ -10,7 +10,6 @@ namespace SourceGit.Models public List Parents { get; set; } = []; public ulong Time { get; set; } = 0; public string Message { get; set; } = ""; - public bool HasUntracked => Parents.Count == 3; public string TimeStr => DateTime.UnixEpoch.AddSeconds(Time).ToLocalTime().ToString(DateTimeFormat.Actived.DateTime); } diff --git a/src/ViewModels/StashesPage.cs b/src/ViewModels/StashesPage.cs index ec7cc84a..d8443c91 100644 --- a/src/ViewModels/StashesPage.cs +++ b/src/ViewModels/StashesPage.cs @@ -59,24 +59,16 @@ namespace SourceGit.ViewModels Task.Run(() => { var changes = new Commands.CompareRevisions(_repo.FullPath, $"{value.SHA}^", value.SHA).Result(); - var untracked = new HashSet(); - if (value.HasUntracked) + if (value.Parents.Count == 3) { - var untrackedChanges = new Commands.CompareRevisions(_repo.FullPath, "4b825dc642cb6eb9a060e54bf8d69288fbee4904", value.Parents[2]).Result(); - foreach (var c in untrackedChanges) - { - untracked.Add(c.Path); + var untracked = new Commands.CompareRevisions(_repo.FullPath, "4b825dc642cb6eb9a060e54bf8d69288fbee4904", value.Parents[2]).Result(); + foreach (var c in untracked) changes.Add(c); - } + + changes.Sort((l, r) => string.Compare(l.Path, r.Path, StringComparison.Ordinal)); } - changes.Sort((l, r) => Models.NumericSort.Compare(l.Path, r.Path)); - - Dispatcher.UIThread.Invoke(() => - { - Changes = changes; - _untrackedChanges = untracked; - }); + Dispatcher.UIThread.Invoke(() => Changes = changes); }); } } @@ -102,7 +94,7 @@ namespace SourceGit.ViewModels { if (value == null) DiffContext = null; - else if (_untrackedChanges.Contains(value.Path)) + else if (value.Index == Models.ChangeState.Added && _selectedStash.Parents.Count == 3) DiffContext = new DiffContext(_repo.FullPath, new Models.DiffOption("4b825dc642cb6eb9a060e54bf8d69288fbee4904", _selectedStash.Parents[2], value), _diffContext); else DiffContext = new DiffContext(_repo.FullPath, new Models.DiffOption(_selectedStash.Parents[0], _selectedStash.SHA, value), _diffContext); @@ -178,7 +170,7 @@ namespace SourceGit.ViewModels var opts = new List(); foreach (var c in _changes) { - if (_untrackedChanges.Contains(c.Path)) + if (c.Index == Models.ChangeState.Added && _selectedStash.Parents.Count == 3) opts.Add(new Models.DiffOption("4b825dc642cb6eb9a060e54bf8d69288fbee4904", _selectedStash.Parents[2], c)); else opts.Add(new Models.DiffOption(_selectedStash.Parents[0], _selectedStash.SHA, c)); @@ -303,7 +295,6 @@ namespace SourceGit.ViewModels private List _visibleStashes = new List(); private string _searchFilter = string.Empty; private Models.Stash _selectedStash = null; - private HashSet _untrackedChanges = new HashSet(); private List _changes = null; private Models.Change _selectedChange = null; private DiffContext _diffContext = null; From 38d87fa1a1b443ede1cab537af489fd46431be21 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 20 Mar 2025 21:12:08 +0800 Subject: [PATCH 409/865] feature: use `git stash show -u --name-status ` command to query changes in selected stash if git >= 2.32.0 Signed-off-by: leo --- src/Commands/QueryStashChanges.cs | 68 +++++++++++++++++++++++++++++++ src/Models/GitVersions.cs | 13 ++++-- src/ViewModels/StashChanges.cs | 4 +- src/ViewModels/StashesPage.cs | 26 ++++++++---- 4 files changed, 98 insertions(+), 13 deletions(-) create mode 100644 src/Commands/QueryStashChanges.cs diff --git a/src/Commands/QueryStashChanges.cs b/src/Commands/QueryStashChanges.cs new file mode 100644 index 00000000..7fc27ea3 --- /dev/null +++ b/src/Commands/QueryStashChanges.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace SourceGit.Commands +{ + /// + /// Query stash changes. Requires git >= 2.32.0 + /// + public partial class QueryStashChanges : Command + { + [GeneratedRegex(@"^([MADRC])\s+(.+)$")] + private static partial Regex REG_FORMAT(); + + public QueryStashChanges(string repo, string stash) + { + WorkingDirectory = repo; + Context = repo; + Args = $"stash show -u --name-status \"{stash}\""; + } + + public List Result() + { + var rs = ReadToEnd(); + if (!rs.IsSuccess) + return []; + + var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries); + var outs = new List(); + foreach (var line in lines) + { + var match = REG_FORMAT().Match(line); + if (!match.Success) + continue; + + var change = new Models.Change() { Path = match.Groups[2].Value }; + var status = match.Groups[1].Value; + + switch (status[0]) + { + case 'M': + change.Set(Models.ChangeState.Modified); + outs.Add(change); + break; + case 'A': + change.Set(Models.ChangeState.Added); + outs.Add(change); + break; + case 'D': + change.Set(Models.ChangeState.Deleted); + outs.Add(change); + break; + case 'R': + change.Set(Models.ChangeState.Renamed); + outs.Add(change); + break; + case 'C': + change.Set(Models.ChangeState.Copied); + outs.Add(change); + break; + } + } + + outs.Sort((l, r) => string.Compare(l.Path, r.Path, StringComparison.Ordinal)); + return outs; + } + } +} diff --git a/src/Models/GitVersions.cs b/src/Models/GitVersions.cs index 394a9518..92fd8c59 100644 --- a/src/Models/GitVersions.cs +++ b/src/Models/GitVersions.cs @@ -13,13 +13,18 @@ public static readonly System.Version ADD_WITH_PATHSPECFILE = new System.Version(2, 25, 0); /// - /// The minimal version of Git that supports the `stash` command with the `--pathspec-from-file` option. + /// The minimal version of Git that supports the `stash push` command with the `--pathspec-from-file` option. /// - public static readonly System.Version STASH_WITH_PATHSPECFILE = new System.Version(2, 26, 0); + public static readonly System.Version STASH_PUSH_WITH_PATHSPECFILE = new System.Version(2, 26, 0); /// - /// The minimal version of Git that supports the `stash` command with the `--staged` option. + /// The minimal version of Git that supports the `stash push` command with the `--staged` option. /// - public static readonly System.Version STASH_ONLY_STAGED = new System.Version(2, 35, 0); + public static readonly System.Version STASH_PUSH_ONLY_STAGED = new System.Version(2, 35, 0); + + /// + /// The minimal version of Git that supports the `stash show` command with the `-u` option. + /// + public static readonly System.Version STASH_SHOW_WITH_UNTRACKED = new System.Version(2, 32, 0); } } diff --git a/src/ViewModels/StashChanges.cs b/src/ViewModels/StashChanges.cs index 33ebb1f3..e35aaad0 100644 --- a/src/ViewModels/StashChanges.cs +++ b/src/ViewModels/StashChanges.cs @@ -64,7 +64,7 @@ namespace SourceGit.ViewModels { if (OnlyStaged) { - if (Native.OS.GitVersion >= Models.GitVersions.STASH_ONLY_STAGED) + if (Native.OS.GitVersion >= Models.GitVersions.STASH_PUSH_ONLY_STAGED) { succ = new Commands.Stash(_repo.FullPath).PushOnlyStaged(Message, KeepIndex); } @@ -109,7 +109,7 @@ namespace SourceGit.ViewModels return true; var succ = false; - if (Native.OS.GitVersion >= Models.GitVersions.STASH_WITH_PATHSPECFILE) + if (Native.OS.GitVersion >= Models.GitVersions.STASH_PUSH_WITH_PATHSPECFILE) { var paths = new List(); foreach (var c in changes) diff --git a/src/ViewModels/StashesPage.cs b/src/ViewModels/StashesPage.cs index d8443c91..77ed5551 100644 --- a/src/ViewModels/StashesPage.cs +++ b/src/ViewModels/StashesPage.cs @@ -58,14 +58,26 @@ namespace SourceGit.ViewModels { Task.Run(() => { - var changes = new Commands.CompareRevisions(_repo.FullPath, $"{value.SHA}^", value.SHA).Result(); - if (value.Parents.Count == 3) - { - var untracked = new Commands.CompareRevisions(_repo.FullPath, "4b825dc642cb6eb9a060e54bf8d69288fbee4904", value.Parents[2]).Result(); - foreach (var c in untracked) - changes.Add(c); + var changes = null as List; - changes.Sort((l, r) => string.Compare(l.Path, r.Path, StringComparison.Ordinal)); + if (Native.OS.GitVersion >= Models.GitVersions.STASH_SHOW_WITH_UNTRACKED) + { + changes = new Commands.QueryStashChanges(_repo.FullPath, value.Name).Result(); + } + else + { + changes = new Commands.CompareRevisions(_repo.FullPath, $"{value.SHA}^", value.SHA).Result(); + if (value.Parents.Count == 3) + { + var untracked = new Commands.CompareRevisions(_repo.FullPath, "4b825dc642cb6eb9a060e54bf8d69288fbee4904", value.Parents[2]).Result(); + var needSort = changes.Count > 0; + + foreach (var c in untracked) + changes.Add(c); + + if (needSort) + changes.Sort((l, r) => string.Compare(l.Path, r.Path, StringComparison.Ordinal)); + } } Dispatcher.UIThread.Invoke(() => Changes = changes); From 7cd5814410b152a1363b9cf173e9e67928dd6fe1 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 20 Mar 2025 21:18:51 +0800 Subject: [PATCH 410/865] enhance: better regex for output of `Commands.CompareRevisions` Signed-off-by: leo --- src/Commands/CompareRevisions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Commands/CompareRevisions.cs b/src/Commands/CompareRevisions.cs index 8a6f2832..e311a88e 100644 --- a/src/Commands/CompareRevisions.cs +++ b/src/Commands/CompareRevisions.cs @@ -6,7 +6,7 @@ namespace SourceGit.Commands { public partial class CompareRevisions : Command { - [GeneratedRegex(@"^(\s?[\w\?]{1,4})\s+(.+)$")] + [GeneratedRegex(@"^([MADRC])\s+(.+)$")] private static partial Regex REG_FORMAT(); public CompareRevisions(string repo, string start, string end) From 5467703a6e085853fbb10762d0d93abc223b004c Mon Sep 17 00:00:00 2001 From: Ilian Delagrange <62717259+ilianoKokoro@users.noreply.github.com> Date: Thu, 20 Mar 2025 21:30:57 -0400 Subject: [PATCH 411/865] localization: add missing french translations (#1113) Co-authored-by: Ilian Delagrange --- src/Resources/Locales/fr_FR.axaml | 64 +++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index f3a71390..19c0859c 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -684,4 +684,68 @@ Verrouiller Supprimer Déverrouiller + RE-GÉNÉRER + APPLIQUER COMME MESSAGE DE COMMIT + Appliquer le Stash + Supprimer après l'application + Rétablir les modifications de l'index + Stash: + Action personnalisée + Branche en amont invalide! + Initialiser et mettre à jour les sous-modules + Branche + Attendre la fin de l'action + Les espaces seront remplacés par des tirets. + Chemin: + Tous les enfants seront retirés de la liste. + Cela le supprimera uniquement de la liste, pas du disque ! + Première différence + Dernière différence + Traitement du commit + Fusionnement + Arrêté à + Annulation du commit + Source: + Fusionner (Plusieurs) + Commit tous les changement + Stratégie: + Cibles: + Activer le streaming + Largeur de tab dans l'éditeur + Taille de police + Défaut + Éditeur + Format de date + Afficher les enfants dans les détails du commit + Afficher les tags dans le graphique des commits + Activer la vérification HTTP SSL + Actions personnalisées + Visibilité dans le graphique + Réinitialiser + Cacher dans le graphique des commits + Filtrer dans le graphique des commits + DISPOSITION + Horizontal + Vertical + ORDRE DES COMMITS + Date du commit + Topologiquement + EFFACER LES NOTIFICATIONS + PASSER + Par date de créateur + Par nom (Croissant) + Par nom (Décroissant) + Trier + Utiliser le temps relatif dans les historiques + Analyser les repositories + Définir la branche suivie + Branche: + Retirer la branche amont + En amont: + Aller sur + Restauration automatique après le stashing + Vos fichiers de travail restent inchangés, mais une sauvegarde est enregistrée. + Sauvegarder en tant que patch... + Commit (Modifier) + SignOff From 56253e95c337210215d85546b1378e9f7b119ce3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 21 Mar 2025 01:31:07 +0000 Subject: [PATCH 412/865] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 67 ++------------------------------------------------ 2 files changed, 3 insertions(+), 66 deletions(-) diff --git a/README.md b/README.md index 5b3dbc20..2f13fce6 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-98.92%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-99.87%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-91.39%25-yellow)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-99.87%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.12%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-98.92%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-99.87%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-%E2%88%9A-brightgreen)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-99.87%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.12%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 b7f87cdf..aa8da630 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -25,76 +25,13 @@
-### fr_FR.axaml: 91.39% +### fr_FR.axaml: 100.00%
Missing Keys -- Text.AIAssistant.Regen -- Text.AIAssistant.Use -- Text.ApplyStash -- Text.ApplyStash.DropAfterApply -- Text.ApplyStash.RestoreIndex -- Text.ApplyStash.Stash -- Text.BranchCM.CustomAction -- Text.BranchUpstreamInvalid -- Text.Clone.RecurseSubmodules -- Text.Configure.CustomAction.Scope.Branch -- Text.Configure.CustomAction.WaitForExit -- Text.CreateBranch.Name.WarnSpace -- Text.DeleteRepositoryNode.Path -- Text.DeleteRepositoryNode.TipForGroup -- Text.DeleteRepositoryNode.TipForRepository -- Text.Diff.First -- Text.Diff.Last -- 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.AI.Streaming -- Text.Preferences.Appearance.EditorTabWidth -- Text.Preferences.Appearance.FontSize -- Text.Preferences.Appearance.FontSize.Default -- Text.Preferences.Appearance.FontSize.Editor -- Text.Preferences.General.DateFormat -- Text.Preferences.General.ShowChildren -- Text.Preferences.General.ShowTagsInGraph -- Text.Preferences.Git.SSLVerify -- Text.Repository.CustomActions -- 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.Notifications.Clear -- Text.Repository.Skip -- Text.Repository.Tags.OrderByCreatorDate -- Text.Repository.Tags.OrderByNameAsc -- Text.Repository.Tags.OrderByNameDes -- Text.Repository.Tags.Sort -- Text.Repository.UseRelativeTimeInHistories -- Text.ScanRepositories -- Text.SetUpstream -- Text.SetUpstream.Local -- Text.SetUpstream.Unset -- Text.SetUpstream.Upstream -- Text.SHALinkCM.NavigateTo -- Text.Stash.AutoRestore -- Text.Stash.AutoRestore.Tip -- Text.StashCM.SaveAsPatch -- Text.WorkingCopy.CommitToEdit -- Text.WorkingCopy.SignOff +
From 8c1e1a3e6a0cb4ea41ed8a6361bc2a894a492617 Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 21 Mar 2025 09:45:42 +0800 Subject: [PATCH 413/865] fix: text diff view scrolling issue introduced by AvaloniaEdit `11.2.0` (commit 7caa03a09b) - `SyncScrollOffset` does not update in `side-by-side` mode while scrolling - Highlighted chunk is not cleared when scroll by drag scrollbar Signed-off-by: leo --- src/Views/TextDiffView.axaml.cs | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index 925c7622..0d20a990 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -565,7 +565,6 @@ namespace SourceGit.Views ScrollToLine(prev.Start); } } - // NOTE: Not implemented (button hidden) for non-block navigation. } public void GotoPrevChange() @@ -678,7 +677,6 @@ namespace SourceGit.Views ScrollToLine(next.Start); } } - // NOTE: Not implemented (button hidden) for non-block navigation. } public override void Render(DrawingContext context) @@ -1229,7 +1227,7 @@ namespace SourceGit.Views if (scroller != null) { scroller.Bind(ScrollViewer.OffsetProperty, new Binding("ScrollOffset", BindingMode.TwoWay)); - scroller.GotFocus += OnTextViewScrollGotFocus; + scroller.ScrollChanged += OnTextViewScrollChanged; } } @@ -1237,7 +1235,7 @@ namespace SourceGit.Views { var scroller = this.FindDescendantOfType(); if (scroller != null) - scroller.GotFocus -= OnTextViewScrollGotFocus; + scroller.ScrollChanged -= OnTextViewScrollChanged; base.OnUnloaded(e); } @@ -1274,9 +1272,9 @@ namespace SourceGit.Views GC.Collect(); } - private void OnTextViewScrollGotFocus(object sender, GotFocusEventArgs e) + private void OnTextViewScrollChanged(object sender, ScrollChangedEventArgs e) { - if (EnableChunkSelection && !TextArea.IsPointerOver) + if (sender is ScrollViewer { IsExpanded: true, IsPointerOver: true } scroller) TrySetChunk(null); } } @@ -1446,12 +1444,9 @@ namespace SourceGit.Views _scrollViewer = this.FindDescendantOfType(); if (_scrollViewer != null) { - _scrollViewer.GotFocus += OnTextViewScrollGotFocus; _scrollViewer.ScrollChanged += OnTextViewScrollChanged; _scrollViewer.Bind(ScrollViewer.OffsetProperty, new Binding("SyncScrollOffset", BindingMode.OneWay)); } - - TextArea.PointerWheelChanged += OnTextAreaPointerWheelChanged; } protected override void OnUnloaded(RoutedEventArgs e) @@ -1459,12 +1454,9 @@ namespace SourceGit.Views if (_scrollViewer != null) { _scrollViewer.ScrollChanged -= OnTextViewScrollChanged; - _scrollViewer.GotFocus -= OnTextViewScrollGotFocus; _scrollViewer = null; } - TextArea.PointerWheelChanged -= OnTextAreaPointerWheelChanged; - base.OnUnloaded(e); GC.Collect(); } @@ -1499,22 +1491,15 @@ namespace SourceGit.Views } } - private void OnTextViewScrollGotFocus(object sender, GotFocusEventArgs e) - { - if (EnableChunkSelection && !TextArea.IsPointerOver) - TrySetChunk(null); - } - private void OnTextViewScrollChanged(object sender, ScrollChangedEventArgs e) { - if (TextArea.IsFocused && DataContext is ViewModels.TwoSideTextDiff diff) + if (IsPointerOver && DataContext is ViewModels.TwoSideTextDiff diff) + { diff.SyncScrollOffset = _scrollViewer?.Offset ?? Vector.Zero; - } - private void OnTextAreaPointerWheelChanged(object sender, PointerWheelEventArgs e) - { - if (!TextArea.IsFocused) - Focus(); + if (sender is ScrollViewer { IsExpanded: true, IsPointerOver: true } scroller ) + TrySetChunk(null); + } } private ScrollViewer _scrollViewer = null; From cdc0fbb753e9e2326765ef193eea0ca4e1812227 Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 21 Mar 2025 10:23:52 +0800 Subject: [PATCH 414/865] doc: update README.md Signed-off-by: leo --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2f13fce6..00779cc7 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ * GIT commands with GUI * Clone/Fetch/Pull/Push... * Merge/Rebase/Reset/Revert/Amend/Cherry-pick... - * Amend/Reword + * Amend/Reword/Squash * Interactive rebase * Branches * Remotes @@ -40,6 +40,7 @@ * Git LFS * Issue Link * Workspace +* Custom Action * Using AI to generate commit message (C# port of [anjerodev/commitollama](https://github.com/anjerodev/commitollama)) > [!WARNING] From 39f4cd173287a3d531e6e3225009b5527f77e193 Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 21 Mar 2025 10:54:47 +0800 Subject: [PATCH 415/865] ci: move all translation status to `TRANSLATION.md` and do not modify `README.md ` while checking localization Signed-off-by: leo --- README.md | 7 +-- TRANSLATION.md | 66 +++++++++-------------------- build/scripts/localization-check.js | 45 ++++++++------------ 3 files changed, 38 insertions(+), 80 deletions(-) diff --git a/README.md b/README.md index 00779cc7..d63886ed 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ * Supports SSH access with each remote * GIT commands with GUI * Clone/Fetch/Pull/Push... - * Merge/Rebase/Reset/Revert/Amend/Cherry-pick... + * Merge/Rebase/Reset/Revert/Cherry-pick... * Amend/Reword/Squash * Interactive rebase * Branches @@ -48,10 +48,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-98.92%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-99.87%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-%E2%88%9A-brightgreen)](TRANSLATION.md) [![it__IT](https://img.shields.io/badge/it__IT-99.87%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-91.12%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) +You can find the current translation status in [TRANSLATION.md](TRANSLATION.md) ## How to Use diff --git a/TRANSLATION.md b/TRANSLATION.md index aa8da630..a96f0fc6 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -1,8 +1,15 @@ -### de_DE.axaml: 98.92% +# Translation Status +This document shows the translation status of each locale file in the repository. + +## Details + +### ![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen) + +### ![de__DE](https://img.shields.io/badge/de__DE-98.92%25-yellow)
-Missing Keys +Missing keys in de_DE.axaml - Text.BranchUpstreamInvalid - Text.Configure.CustomAction.WaitForExit @@ -15,41 +22,30 @@
-### es_ES.axaml: 99.87% - +### ![es__ES](https://img.shields.io/badge/es__ES-99.87%25-yellow)
-Missing Keys +Missing keys in es_ES.axaml - Text.Preferences.General.ShowTagsInGraph
-### fr_FR.axaml: 100.00% +### ![fr__FR](https://img.shields.io/badge/fr__FR-%E2%88%9A-brightgreen) +### ![it__IT](https://img.shields.io/badge/it__IT-99.87%25-yellow)
-Missing Keys - - - -
- -### it_IT.axaml: 99.87% - - -
-Missing Keys +Missing keys in it_IT.axaml - Text.Preferences.General.ShowTagsInGraph
-### pt_BR.axaml: 91.12% - +### ![pt__BR](https://img.shields.io/badge/pt__BR-91.12%25-yellow)
-Missing Keys +Missing keys in pt_BR.axaml - Text.AIAssistant.Regen - Text.AIAssistant.Use @@ -120,32 +116,8 @@
-### ru_RU.axaml: 100.00% +### ![ru__RU](https://img.shields.io/badge/ru__RU-%E2%88%9A-brightgreen) +### ![zh__CN](https://img.shields.io/badge/zh__CN-%E2%88%9A-brightgreen) -
-Missing Keys - - - -
- -### zh_CN.axaml: 100.00% - - -
-Missing Keys - - - -
- -### zh_TW.axaml: 100.00% - - -
-Missing Keys - - - -
+### ![zh__TW](https://img.shields.io/badge/zh__TW-%E2%88%9A-brightgreen) \ No newline at end of file diff --git a/build/scripts/localization-check.js b/build/scripts/localization-check.js index ed89a5e8..1e8f1f0d 100644 --- a/build/scripts/localization-check.js +++ b/build/scripts/localization-check.js @@ -6,7 +6,6 @@ const repoRoot = path.join(__dirname, '../../'); const localesDir = path.join(repoRoot, 'src/Resources/Locales'); const enUSFile = path.join(localesDir, 'en_US.axaml'); const outputFile = path.join(repoRoot, 'TRANSLATION.md'); -const readmeFile = path.join(repoRoot, 'README.md'); const parser = new xml2js.Parser(); @@ -18,46 +17,36 @@ async function parseXml(filePath) { async function calculateTranslationRate() { const enUSData = await parseXml(enUSFile); const enUSKeys = new Set(enUSData.ResourceDictionary['x:String'].map(item => item.$['x:Key'])); - - const translationRates = []; - const badges = []; - 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-%E2%88%9A-brightgreen)](TRANSLATION.md)`); + const lines = []; + + lines.push('# Translation Status'); + lines.push('This document shows the translation status of each locale file in the repository.'); + lines.push(`## Details`); + lines.push(`### ![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen)`); for (const file of files) { + const locale = file.replace('.axaml', '').replace('_', '__'); const filePath = path.join(localesDir, file); const localeData = await parseXml(filePath); const localeKeys = new Set(localeData.ResourceDictionary['x:String'].map(item => item.$['x:Key'])); - const missingKeys = [...enUSKeys].filter(key => !localeKeys.has(key)); - const translationRate = ((enUSKeys.size - missingKeys.length) / enUSKeys.size) * 100; - translationRates.push(`### ${file}: ${translationRate.toFixed(2)}%\n`); - translationRates.push(`
\nMissing Keys\n\n${missingKeys.map(key => `- ${key}`).join('\n')}\n\n
`); + if (missingKeys.length > 0) { + const progress = ((enUSKeys.size - missingKeys.length) / enUSKeys.size) * 100; + const badgeColor = progress >= 75 ? 'yellow' : 'red'; - // Add badges - const locale = file.replace('.axaml', '').replace('_', '__'); - if (translationRate === 100) { - badges.push(`[![${locale}](https://img.shields.io/badge/${locale}-%E2%88%9A-brightgreen)](TRANSLATION.md)`); + lines.push(`### ![${locale}](https://img.shields.io/badge/${locale}-${progress.toFixed(2)}%25-${badgeColor})`); + lines.push(`
\nMissing keys in ${file}\n\n${missingKeys.map(key => `- ${key}`).join('\n')}\n\n
`) } else { - const badgeColor = translationRate >= 75 ? 'yellow' : 'red'; - badges.push(`[![${locale}](https://img.shields.io/badge/${locale}-${translationRate.toFixed(2)}%25-${badgeColor})](TRANSLATION.md)`); - } + lines.push(`### ![${locale}](https://img.shields.io/badge/${locale}-%E2%88%9A-brightgreen)`); + } } - console.log(translationRates.join('\n\n')); - - await fs.writeFile(outputFile, translationRates.join('\n\n') + '\n', 'utf8'); - - // Update README.md - let readmeContent = await fs.readFile(readmeFile, 'utf8'); - const badgeSection = `## Translation Status\n\n${badges.join(' ')}`; - console.log(badgeSection); - readmeContent = readmeContent.replace(/## Translation Status\n\n.*\n\n/, badgeSection + '\n\n'); - await fs.writeFile(readmeFile, readmeContent, 'utf8'); + const content = lines.join('\n\n'); + console.log(content); + await fs.writeFile(outputFile, content, 'utf8'); } calculateTranslationRate().catch(err => console.error(err)); From 03f49ccff01a2c3d4aad95a0bebb49b67faf1cb3 Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 21 Mar 2025 17:35:59 +0800 Subject: [PATCH 416/865] refactor: text diff view block navigation Signed-off-by: leo --- src/Views/DiffView.axaml | 7 +- src/Views/DiffView.axaml.cs | 18 +++-- src/Views/TextDiffView.axaml.cs | 138 +++++++++++++++----------------- 3 files changed, 77 insertions(+), 86 deletions(-) diff --git a/src/Views/DiffView.axaml b/src/Views/DiffView.axaml index 12cfa451..c4da158d 100644 --- a/src/Views/DiffView.axaml +++ b/src/Views/DiffView.axaml @@ -285,10 +285,9 @@ - + diff --git a/src/Views/DiffView.axaml.cs b/src/Views/DiffView.axaml.cs index 889f0df7..f0824307 100644 --- a/src/Views/DiffView.axaml.cs +++ b/src/Views/DiffView.axaml.cs @@ -13,30 +13,32 @@ namespace SourceGit.Views private void OnGotoFirstChange(object _, RoutedEventArgs e) { - var textDiff = this.FindDescendantOfType(); - textDiff?.GotoFirstChange(); + this.FindDescendantOfType()?.GotoFirstChange(); e.Handled = true; } private void OnGotoPrevChange(object _, RoutedEventArgs e) { - var textDiff = this.FindDescendantOfType(); - textDiff?.GotoPrevChange(); + this.FindDescendantOfType()?.GotoPrevChange(); e.Handled = true; } private void OnGotoNextChange(object _, RoutedEventArgs e) { - var textDiff = this.FindDescendantOfType(); - textDiff?.GotoNextChange(); + this.FindDescendantOfType()?.GotoNextChange(); e.Handled = true; } private void OnGotoLastChange(object _, RoutedEventArgs e) { - var textDiff = this.FindDescendantOfType(); - textDiff?.GotoLastChange(); + this.FindDescendantOfType()?.GotoLastChange(); e.Handled = true; } + + private void OnBlockNavigationChanged(object sender, RoutedEventArgs e) + { + if (sender is TextDiffView { UseBlockNavigation: true } textDiff) + BlockNavigationIndicator.Text = textDiff.BlockNavigation?.Indicator ?? string.Empty; + } } } diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index 0d20a990..7b461e57 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -553,7 +553,7 @@ namespace SourceGit.Views { } - public void GotoFirstChange() + public virtual void GotoFirstChange() { var blockNavigation = BlockNavigation; if (blockNavigation != null) @@ -567,7 +567,7 @@ namespace SourceGit.Views } } - public void GotoPrevChange() + public virtual void GotoPrevChange() { var blockNavigation = BlockNavigation; if (blockNavigation != null) @@ -623,7 +623,7 @@ namespace SourceGit.Views } } - public void GotoNextChange() + public virtual void GotoNextChange() { var blockNavigation = BlockNavigation; if (blockNavigation != null) @@ -665,7 +665,7 @@ namespace SourceGit.Views } } - public void GotoLastChange() + public virtual void GotoLastChange() { var blockNavigation = BlockNavigation; if (blockNavigation != null) @@ -766,15 +766,13 @@ namespace SourceGit.Views { var oldValue = change.OldValue as ViewModels.BlockNavigation; if (oldValue != null) - { oldValue.PropertyChanged -= OnBlockNavigationPropertyChanged; - if (oldValue.Current != -1) - TextArea?.TextView?.Redraw(); - } var newValue = change.NewValue as ViewModels.BlockNavigation; if (newValue != null) newValue.PropertyChanged += OnBlockNavigationPropertyChanged; + + TextArea?.TextView?.Redraw(); } } @@ -793,9 +791,10 @@ namespace SourceGit.Views base.OnKeyDown(e); } - private void OnBlockNavigationPropertyChanged(object _1, PropertyChangedEventArgs _2) + private void OnBlockNavigationPropertyChanged(object _1, PropertyChangedEventArgs e) { - TextArea?.TextView?.Redraw(); + if (e.PropertyName == "Current") + TextArea?.TextView?.Redraw(); } private void OnTextViewContextRequested(object sender, ContextRequestedEventArgs e) @@ -1223,19 +1222,18 @@ namespace SourceGit.Views { base.OnLoaded(e); - var scroller = this.FindDescendantOfType(); - if (scroller != null) + _scrollViewer = this.FindDescendantOfType(); + if (_scrollViewer != null) { - scroller.Bind(ScrollViewer.OffsetProperty, new Binding("ScrollOffset", BindingMode.TwoWay)); - scroller.ScrollChanged += OnTextViewScrollChanged; + _scrollViewer.Bind(ScrollViewer.OffsetProperty, new Binding("ScrollOffset", BindingMode.TwoWay)); + _scrollViewer.ScrollChanged += OnTextViewScrollChanged; } } protected override void OnUnloaded(RoutedEventArgs e) { - var scroller = this.FindDescendantOfType(); - if (scroller != null) - scroller.ScrollChanged -= OnTextViewScrollChanged; + if (_scrollViewer != null) + _scrollViewer.ScrollChanged -= OnTextViewScrollChanged; base.OnUnloaded(e); } @@ -1274,9 +1272,11 @@ namespace SourceGit.Views private void OnTextViewScrollChanged(object sender, ScrollChangedEventArgs e) { - if (sender is ScrollViewer { IsExpanded: true, IsPointerOver: true } scroller) + if (_scrollViewer is { IsExpanded: true, IsPointerOver: true }) TrySetChunk(null); } + + private ScrollViewer _scrollViewer = null; } public class SingleSideTextDiffPresenter : ThemedTextDiffPresenter @@ -1288,14 +1288,6 @@ namespace SourceGit.Views TextArea.LeftMargins.Add(new LineModifyTypeMargin()); } - public void ForceSyncScrollOffset() - { - if (_scrollViewer == null) - return; - if (DataContext is ViewModels.TwoSideTextDiff diff) - diff.SyncScrollOffset = _scrollViewer?.Offset ?? Vector.Zero; - } - public override List GetLines() { if (DataContext is ViewModels.TwoSideTextDiff diff) @@ -1310,6 +1302,30 @@ namespace SourceGit.Views return 0; } + public override void GotoFirstChange() + { + base.GotoFirstChange(); + DirectSyncScrollOffset(); + } + + public override void GotoPrevChange() + { + base.GotoPrevChange(); + DirectSyncScrollOffset(); + } + + public override void GotoNextChange() + { + base.GotoNextChange(); + DirectSyncScrollOffset(); + } + + public override void GotoLastChange() + { + base.GotoLastChange(); + DirectSyncScrollOffset(); + } + public override void UpdateSelectedChunk(double y) { var diff = DataContext as ViewModels.TwoSideTextDiff; @@ -1497,11 +1513,17 @@ namespace SourceGit.Views { diff.SyncScrollOffset = _scrollViewer?.Offset ?? Vector.Zero; - if (sender is ScrollViewer { IsExpanded: true, IsPointerOver: true } scroller ) + if (_scrollViewer is { IsExpanded: true, IsPointerOver: true } ) TrySetChunk(null); } } + private void DirectSyncScrollOffset() + { + if (_scrollViewer is { } && DataContext is ViewModels.TwoSideTextDiff diff) + diff.SyncScrollOffset = _scrollViewer?.Offset ?? Vector.Zero; + } + private ScrollViewer _scrollViewer = null; } @@ -1679,13 +1701,13 @@ namespace SourceGit.Views set => SetValue(BlockNavigationProperty, value); } - public static readonly StyledProperty BlockNavigationIndicatorProperty = - AvaloniaProperty.Register(nameof(BlockNavigationIndicator)); + public static readonly RoutedEvent BlockNavigationChangedEvent = + RoutedEvent.Register(nameof(BlockNavigationChanged), RoutingStrategies.Tunnel | RoutingStrategies.Bubble); - public string BlockNavigationIndicator + public event EventHandler BlockNavigationChanged { - get => GetValue(BlockNavigationIndicatorProperty); - set => SetValue(BlockNavigationIndicatorProperty, value); + add { AddHandler(BlockNavigationChangedEvent, value); } + remove { RemoveHandler(BlockNavigationChangedEvent, value); } } static TextDiffView() @@ -1723,54 +1745,26 @@ namespace SourceGit.Views public void GotoFirstChange() { - var presenter = this.FindDescendantOfType(); - if (presenter == null) - return; - - presenter.GotoFirstChange(); - if (presenter is SingleSideTextDiffPresenter singleSide) - singleSide.ForceSyncScrollOffset(); - - BlockNavigationIndicator = BlockNavigation?.Indicator ?? string.Empty; + this.FindDescendantOfType()?.GotoFirstChange(); + RaiseEvent(new RoutedEventArgs(BlockNavigationChangedEvent)); } public void GotoPrevChange() { - var presenter = this.FindDescendantOfType(); - if (presenter == null) - return; - - presenter.GotoPrevChange(); - if (presenter is SingleSideTextDiffPresenter singleSide) - singleSide.ForceSyncScrollOffset(); - - BlockNavigationIndicator = BlockNavigation?.Indicator ?? string.Empty; + this.FindDescendantOfType()?.GotoPrevChange(); + RaiseEvent(new RoutedEventArgs(BlockNavigationChangedEvent)); } public void GotoNextChange() { - var presenter = this.FindDescendantOfType(); - if (presenter == null) - return; - - presenter.GotoNextChange(); - if (presenter is SingleSideTextDiffPresenter singleSide) - singleSide.ForceSyncScrollOffset(); - - BlockNavigationIndicator = BlockNavigation?.Indicator ?? string.Empty; + this.FindDescendantOfType()?.GotoNextChange(); + RaiseEvent(new RoutedEventArgs(BlockNavigationChangedEvent)); } public void GotoLastChange() { - var presenter = this.FindDescendantOfType(); - if (presenter == null) - return; - - presenter.GotoLastChange(); - if (presenter is SingleSideTextDiffPresenter singleSide) - singleSide.ForceSyncScrollOffset(); - - BlockNavigationIndicator = BlockNavigation?.Indicator ?? string.Empty; + this.FindDescendantOfType()?.GotoLastChange(); + RaiseEvent(new RoutedEventArgs(BlockNavigationChangedEvent)); } protected override void OnDataContextChanged(EventArgs e) @@ -1820,15 +1814,11 @@ namespace SourceGit.Views private void RefreshBlockNavigation() { if (UseBlockNavigation) - { BlockNavigation = new ViewModels.BlockNavigation(Editor.Content); - BlockNavigationIndicator = BlockNavigation.Indicator; - } else - { BlockNavigation = null; - BlockNavigationIndicator = "-/-"; - } + + RaiseEvent(new RoutedEventArgs(BlockNavigationChangedEvent)); } private void OnStageChunk(object _1, RoutedEventArgs _2) From 9590f96a449124187b1a6ad4e06cbe42f58e26ca Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 21 Mar 2025 17:46:11 +0800 Subject: [PATCH 417/865] enhance: clear highlight chunk while scrolling out of `TextArea.TextView` Signed-off-by: leo --- src/Views/TextDiffView.axaml.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index 7b461e57..c55719de 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -1272,7 +1272,7 @@ namespace SourceGit.Views private void OnTextViewScrollChanged(object sender, ScrollChangedEventArgs e) { - if (_scrollViewer is { IsExpanded: true, IsPointerOver: true }) + if (!TextArea.TextView.IsPointerOver) TrySetChunk(null); } @@ -1513,7 +1513,7 @@ namespace SourceGit.Views { diff.SyncScrollOffset = _scrollViewer?.Offset ?? Vector.Zero; - if (_scrollViewer is { IsExpanded: true, IsPointerOver: true } ) + if (!TextArea.TextView.IsPointerOver) TrySetChunk(null); } } From d335cac167e817c2581921259ca40569f605d855 Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 21 Mar 2025 18:00:46 +0800 Subject: [PATCH 418/865] enhance: only raise `BlockNavigationChangedEvent` when `UseBlockNavigation` enabled Signed-off-by: leo --- src/Views/DiffView.axaml.cs | 2 +- src/Views/TextDiffView.axaml.cs | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/Views/DiffView.axaml.cs b/src/Views/DiffView.axaml.cs index f0824307..9dd27f24 100644 --- a/src/Views/DiffView.axaml.cs +++ b/src/Views/DiffView.axaml.cs @@ -37,7 +37,7 @@ namespace SourceGit.Views private void OnBlockNavigationChanged(object sender, RoutedEventArgs e) { - if (sender is TextDiffView { UseBlockNavigation: true } textDiff) + if (sender is TextDiffView textDiff) BlockNavigationIndicator.Text = textDiff.BlockNavigation?.Indicator ?? string.Empty; } } diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index c55719de..7ce9f288 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -1746,25 +1746,25 @@ namespace SourceGit.Views public void GotoFirstChange() { this.FindDescendantOfType()?.GotoFirstChange(); - RaiseEvent(new RoutedEventArgs(BlockNavigationChangedEvent)); + TryRaiseBlockNavigationChanged(); } public void GotoPrevChange() { this.FindDescendantOfType()?.GotoPrevChange(); - RaiseEvent(new RoutedEventArgs(BlockNavigationChangedEvent)); + TryRaiseBlockNavigationChanged(); } public void GotoNextChange() { this.FindDescendantOfType()?.GotoNextChange(); - RaiseEvent(new RoutedEventArgs(BlockNavigationChangedEvent)); + TryRaiseBlockNavigationChanged(); } public void GotoLastChange() { this.FindDescendantOfType()?.GotoLastChange(); - RaiseEvent(new RoutedEventArgs(BlockNavigationChangedEvent)); + TryRaiseBlockNavigationChanged(); } protected override void OnDataContextChanged(EventArgs e) @@ -1818,7 +1818,7 @@ namespace SourceGit.Views else BlockNavigation = null; - RaiseEvent(new RoutedEventArgs(BlockNavigationChangedEvent)); + TryRaiseBlockNavigationChanged(); } private void OnStageChunk(object _1, RoutedEventArgs _2) @@ -1990,5 +1990,11 @@ namespace SourceGit.Views repo.MarkWorkingCopyDirtyManually(); repo.SetWatcherEnabled(true); } + + private void TryRaiseBlockNavigationChanged() + { + if (UseBlockNavigation) + RaiseEvent(new RoutedEventArgs(BlockNavigationChangedEvent)); + } } } From 88bb603dc9686ff54a738219678590091db0b929 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 24 Mar 2025 09:44:41 +0800 Subject: [PATCH 419/865] version: Release 2025.10 Signed-off-by: leo --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 23993bfb..e78345d1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2025.09 \ No newline at end of file +2025.10 \ No newline at end of file From 0a877c6730ecc44ca16e32b670dd4bcf348c42d3 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 24 Mar 2025 10:03:27 +0800 Subject: [PATCH 420/865] project: upgrade `OpenAI` and `Azure.AI.OpenAI` to `2.2.0-beta.4` Signed-off-by: leo --- src/SourceGit.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SourceGit.csproj b/src/SourceGit.csproj index 3578d59f..2a4b3c91 100644 --- a/src/SourceGit.csproj +++ b/src/SourceGit.csproj @@ -48,10 +48,10 @@ - + - +
From fc85dd3269bb3c122b36d8b43f7612dd8e242d03 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 24 Mar 2025 19:28:16 +0800 Subject: [PATCH 421/865] enhance: improve `Repository.Open()` performance (#1121) Signed-off-by: leo --- src/ViewModels/Launcher.cs | 47 +++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/src/ViewModels/Launcher.cs b/src/ViewModels/Launcher.cs index 06479394..9ae99b33 100644 --- a/src/ViewModels/Launcher.cs +++ b/src/ViewModels/Launcher.cs @@ -275,22 +275,16 @@ namespace SourceGit.ViewModels if (!Path.Exists(node.Id)) { - var ctx = page == null ? ActivePage.Node.Id : page.Node.Id; - App.RaiseException(ctx, "Repository does NOT exists any more. Please remove it."); + App.RaiseException(node.Id, "Repository does NOT exists any more. Please remove it."); return; } var isBare = new Commands.IsBareRepository(node.Id).Result(); - var gitDir = node.Id; - if (!isBare) + var gitDir = isBare ? node.Id : GetRepositoryGitDir(node.Id); + if (string.IsNullOrEmpty(gitDir)) { - gitDir = new Commands.QueryGitDir(node.Id).Result(); - if (string.IsNullOrEmpty(gitDir)) - { - var ctx = page == null ? ActivePage.Node.Id : page.Node.Id; - App.RaiseException(ctx, "Given path is not a valid git repository!"); - return; - } + App.RaiseException(node.Id, "Given path is not a valid git repository!"); + return; } var repo = new Repository(isBare, node.Id, gitDir); @@ -469,6 +463,37 @@ namespace SourceGit.ViewModels return menu; } + private string GetRepositoryGitDir(string repo) + { + var fullpath = Path.Combine(repo, ".git"); + if (Directory.Exists(fullpath)) + { + if (Directory.Exists(Path.Combine(fullpath, "refs")) && + Directory.Exists(Path.Combine(fullpath, "objects")) && + File.Exists(Path.Combine(fullpath, "HEAD"))) + return fullpath; + + return null; + } + + if (File.Exists(fullpath)) + { + var redirect = File.ReadAllText(fullpath).Trim(); + if (redirect.StartsWith("gitdir: ", StringComparison.Ordinal)) + redirect = redirect.Substring(8); + + if (!Path.IsPathRooted(redirect)) + redirect = Path.GetFullPath(Path.Combine(repo, redirect)); + + if (Directory.Exists(redirect)) + return redirect; + + return null; + } + + return new Commands.QueryGitDir(repo).Result(); + } + private void SwitchWorkspace(Workspace to) { foreach (var one in Pages) From 380e6713b5418ee9f27a7b9bb5dd7e6c4556de82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20J=2E=20Mart=C3=ADnez=20M=2E?= <56406225+jjesus-dev@users.noreply.github.com> Date: Mon, 24 Mar 2025 19:51:22 -0600 Subject: [PATCH 422/865] localization: update spanish translations (#1124) --- src/Resources/Locales/es_ES.axaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index e7e953e5..2f4a7230 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -475,6 +475,7 @@ Commits en el historial Mostrar hora del autor en lugar de la hora del commit en el gráfico Mostrar hijos en los detalles de commit + Mostrar etiquetas en el gráfico de commit Longitud de la guía del asunto GIT Habilitar Auto CRLF @@ -604,7 +605,7 @@ Por Fecha de Creación Por Nombre (Ascendiente) Por Nombre (Descendiente) - Sort + Ordenar Abrir en Terminal Usar tiempo relativo en las historias WORKTREES From 467089aec55005918bd42ba1294234bb06ee8bd0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 25 Mar 2025 01:51:33 +0000 Subject: [PATCH 423/865] doc: Update translation status and missing keys --- TRANSLATION.md | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/TRANSLATION.md b/TRANSLATION.md index a96f0fc6..30a2a679 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -22,14 +22,7 @@ This document shows the translation status of each locale file in the repository -### ![es__ES](https://img.shields.io/badge/es__ES-99.87%25-yellow) - -
-Missing keys in es_ES.axaml - -- Text.Preferences.General.ShowTagsInGraph - -
+### ![es__ES](https://img.shields.io/badge/es__ES-%E2%88%9A-brightgreen) ### ![fr__FR](https://img.shields.io/badge/fr__FR-%E2%88%9A-brightgreen) From f37ac904b9b2babddbba5b970f45de583e30fc33 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 25 Mar 2025 10:33:39 +0800 Subject: [PATCH 424/865] =?UTF-8?q?enhance:=20do=20not=20create=20crash=20?= =?UTF-8?q?log=20for=20unobserved=20task=20exceptions=20(#1121=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: leo --- src/App.axaml.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/App.axaml.cs b/src/App.axaml.cs index af5e6177..86c5200c 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -37,7 +37,6 @@ namespace SourceGit TaskScheduler.UnobservedTaskException += (_, e) => { - LogException(e.Exception); e.SetObserved(); }; From ca0fb7ae1090068de4a7a42de113d0c9c4e203ff Mon Sep 17 00:00:00 2001 From: Iacopo Sbalchiero Date: Wed, 26 Mar 2025 02:27:10 +0100 Subject: [PATCH 425/865] Adding template for Azure DevOps workitems (#1128) * feat: add Azure DevOps issue tracker integration * localization: add Azure DevOps sample rule to issue tracker in multiple languages --- src/Resources/Locales/en_US.axaml | 1 + 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/ViewModels/RepositoryConfigure.cs | 5 +++++ src/Views/RepositoryConfigure.axaml | 1 + 8 files changed, 12 insertions(+) diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index f24d6c65..75d312ea 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -160,6 +160,7 @@ Add Sample GitLab Issue Rule Add Sample GitLab Merge Request Rule Add Sample Jira Rule + Add Sample Azure DevOps Rule New Rule Issue Regex Expression: Rule Name: diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index 2f4a7230..e1eccaa7 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -161,6 +161,7 @@ Añadir Regla de Ejemplo para Pull Requests de Gitee Añadir Regla de Ejemplo para Github Añadir Regla de Ejemplo para Jira + Añadir Regla de Ejemplo para Azure DevOps Añadir Regla de Ejemplo para Incidencias de GitLab Añadir Regla de Ejemplo para Merge Requests de GitLab Nueva Regla diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index 19c0859c..1c3d7d34 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -151,6 +151,7 @@ Ajouter une règle d'exemple pour Pull Request Gitee Ajouter une règle d'exemple Github Ajouter une règle d'exemple Jira + Ajouter une règle d'exemple Azure DevOps Ajouter une règle d'exemple pour Incidents GitLab Ajouter une règle d'exemple pour Merge Request GitLab Nouvelle règle diff --git a/src/Resources/Locales/it_IT.axaml b/src/Resources/Locales/it_IT.axaml index d002dfef..da7d18d1 100644 --- a/src/Resources/Locales/it_IT.axaml +++ b/src/Resources/Locales/it_IT.axaml @@ -161,6 +161,7 @@ Aggiungi una regola di esempio per un Pull Request Gitee Aggiungi una regola di esempio per GitHub Aggiungi una regola di esempio per Jira + Aggiungi una regola di esempio per Azure DevOps Aggiungi una regola di esempio per Issue GitLab Aggiungi una regola di esempio per una Merge Request GitLab Nuova Regola diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml index e811cf3e..e799741c 100644 --- a/src/Resources/Locales/pt_BR.axaml +++ b/src/Resources/Locales/pt_BR.axaml @@ -168,6 +168,7 @@ RASTREADOR DE PROBLEMAS Adicionar Regra de Exemplo do Github Adicionar Regra de Exemplo do Jira + Adicionar Regra de Exemplo do Azure DevOps Adicionar Regra de Exemplo do GitLab Adicionar regra de exemplo de Merge Request do GitLab Nova Regra diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index 707c9ed9..53f04a5b 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -161,6 +161,7 @@ Добавить пример правила запроса скачивания из Gitea Добавить пример правила для Git Добавить пример правила Jira + Добавить пример правила Azure DevOps Добавить пример правила выдачи GitLab Добавить пример правила запроса на слияние в GitLab Новое правило diff --git a/src/ViewModels/RepositoryConfigure.cs b/src/ViewModels/RepositoryConfigure.cs index cf23b6d8..3f590758 100644 --- a/src/ViewModels/RepositoryConfigure.cs +++ b/src/ViewModels/RepositoryConfigure.cs @@ -203,6 +203,11 @@ namespace SourceGit.ViewModels SelectedIssueTrackerRule = _repo.Settings.AddIssueTracker("Jira Tracker", "PROJ-(\\d+)", "https://jira.yourcompany.com/browse/PROJ-$1"); } + public void AddSampleAzureWorkItemTracker() + { + SelectedIssueTrackerRule = _repo.Settings.AddIssueTracker("Azure DevOps Tracker", "#(\\d+)", "https://dev.azure.com/yourcompany/workspace/_workitems/edit/$1"); + } + public void AddSampleGitLabIssueTracker() { var link = "https://gitlab.com/username/repository/-/issues/$1"; diff --git a/src/Views/RepositoryConfigure.axaml b/src/Views/RepositoryConfigure.axaml index de777800..e41375b9 100644 --- a/src/Views/RepositoryConfigure.axaml +++ b/src/Views/RepositoryConfigure.axaml @@ -283,6 +283,7 @@ + From dccf53e51823a8da0eceaa3059d408d6f35c15d3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 26 Mar 2025 01:27:21 +0000 Subject: [PATCH 426/865] doc: Update translation status and missing keys --- TRANSLATION.md | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/TRANSLATION.md b/TRANSLATION.md index 30a2a679..b6ba3ed3 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -6,13 +6,14 @@ This document shows the translation status of each locale file in the repository ### ![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen) -### ![de__DE](https://img.shields.io/badge/de__DE-98.92%25-yellow) +### ![de__DE](https://img.shields.io/badge/de__DE-98.79%25-yellow)
Missing keys in de_DE.axaml - Text.BranchUpstreamInvalid - Text.Configure.CustomAction.WaitForExit +- Text.Configure.IssueTracker.AddSampleAzure - Text.Diff.First - Text.Diff.Last - Text.Preferences.AI.Streaming @@ -35,7 +36,7 @@ This document shows the translation status of each locale file in the repository
-### ![pt__BR](https://img.shields.io/badge/pt__BR-91.12%25-yellow) +### ![pt__BR](https://img.shields.io/badge/pt__BR-91.13%25-yellow)
Missing keys in pt_BR.axaml @@ -111,6 +112,20 @@ This document shows the translation status of each locale file in the repository ### ![ru__RU](https://img.shields.io/badge/ru__RU-%E2%88%9A-brightgreen) -### ![zh__CN](https://img.shields.io/badge/zh__CN-%E2%88%9A-brightgreen) +### ![zh__CN](https://img.shields.io/badge/zh__CN-99.87%25-yellow) -### ![zh__TW](https://img.shields.io/badge/zh__TW-%E2%88%9A-brightgreen) \ No newline at end of file +
+Missing keys in zh_CN.axaml + +- Text.Configure.IssueTracker.AddSampleAzure + +
+ +### ![zh__TW](https://img.shields.io/badge/zh__TW-99.87%25-yellow) + +
+Missing keys in zh_TW.axaml + +- Text.Configure.IssueTracker.AddSampleAzure + +
\ No newline at end of file From 4fb853d1fd91d13e852f64556808705cd345be45 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 26 Mar 2025 09:30:41 +0800 Subject: [PATCH 427/865] localization: add translation `Text.Configure.IssueTracker.AddSampleAzure` for Chinese (#1128) Signed-off-by: leo --- src/Resources/Locales/zh_CN.axaml | 1 + src/Resources/Locales/zh_TW.axaml | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 93d08bd0..ad9b4179 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -157,6 +157,7 @@ 分钟 默认远程 ISSUE追踪 + 新增匹配Azure DevOps规则 新增匹配Gitee议题规则 新增匹配Gitee合并请求规则 新增匹配Github Issue规则 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index d5a7a77c..173ad099 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -157,6 +157,7 @@ 分鐘 預設遠端存放庫 Issue 追蹤 + 新增符合 Azure DevOps 規則 新增符合 Gitee 議題規則 新增符合 Gitee 合併請求規則 新增符合 GitHub Issue 規則 From fc3767754621a0f50b833f7e2259e41b7cd8caad Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 26 Mar 2025 01:30:58 +0000 Subject: [PATCH 428/865] doc: Update translation status and missing keys --- TRANSLATION.md | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/TRANSLATION.md b/TRANSLATION.md index b6ba3ed3..183e77e6 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -112,20 +112,6 @@ This document shows the translation status of each locale file in the repository ### ![ru__RU](https://img.shields.io/badge/ru__RU-%E2%88%9A-brightgreen) -### ![zh__CN](https://img.shields.io/badge/zh__CN-99.87%25-yellow) +### ![zh__CN](https://img.shields.io/badge/zh__CN-%E2%88%9A-brightgreen) -
-Missing keys in zh_CN.axaml - -- Text.Configure.IssueTracker.AddSampleAzure - -
- -### ![zh__TW](https://img.shields.io/badge/zh__TW-99.87%25-yellow) - -
-Missing keys in zh_TW.axaml - -- Text.Configure.IssueTracker.AddSampleAzure - -
\ No newline at end of file +### ![zh__TW](https://img.shields.io/badge/zh__TW-%E2%88%9A-brightgreen) \ No newline at end of file From 4153eec1a8594e67f7b70f81812042886af50dec Mon Sep 17 00:00:00 2001 From: Gadfly Date: Wed, 26 Mar 2025 12:15:15 +0800 Subject: [PATCH 429/865] chore: Update DEB package configuration with installed size (#1130) --- build/resources/deb/DEBIAN/control | 3 ++- build/scripts/package.linux.sh | 11 +++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/build/resources/deb/DEBIAN/control b/build/resources/deb/DEBIAN/control index f553db8b..71786b43 100755 --- a/build/resources/deb/DEBIAN/control +++ b/build/resources/deb/DEBIAN/control @@ -1,7 +1,8 @@ Package: sourcegit -Version: 8.23 +Version: 2025.10 Priority: optional Depends: libx11-6, libice6, libsm6, libicu | libicu76 | libicu74 | libicu72 | libicu71 | libicu70 | libicu69 | libicu68 | libicu67 | libicu66 | libicu65 | libicu63 | libicu60 | libicu57 | libicu55 | libicu52, xdg-utils Architecture: amd64 +Installed-Size: 60440 Maintainer: longshuang@msn.cn Description: Open-source & Free Git GUI Client diff --git a/build/scripts/package.linux.sh b/build/scripts/package.linux.sh index 5abb058b..1b4adbdc 100755 --- a/build/scripts/package.linux.sh +++ b/build/scripts/package.linux.sh @@ -56,8 +56,15 @@ cp -f SourceGit/* resources/deb/opt/sourcegit ln -rsf resources/deb/opt/sourcegit/sourcegit resources/deb/usr/bin cp -r resources/_common/applications resources/deb/usr/share cp -r resources/_common/icons resources/deb/usr/share -sed -i -e "s/^Version:.*/Version: $VERSION/" -e "s/^Architecture:.*/Architecture: $arch/" resources/deb/DEBIAN/control -dpkg-deb --root-owner-group --build resources/deb "sourcegit_$VERSION-1_$arch.deb" +# Calculate installed size in KB +installed_size=$(du -sk resources/deb | cut -f1) +# Update the control file +sed -i -e "s/^Version:.*/Version: $VERSION/" \ + -e "s/^Architecture:.*/Architecture: $arch/" \ + -e "s/^Installed-Size:.*/Installed-Size: $installed_size/" \ + resources/deb/DEBIAN/control +# Build deb package with gzip compression +dpkg-deb -Zgzip --root-owner-group --build resources/deb "sourcegit_$VERSION-1_$arch.deb" rpmbuild -bb --target="$target" resources/rpm/SPECS/build.spec --define "_topdir $(pwd)/resources/rpm" --define "_version $VERSION" mv "resources/rpm/RPMS/$target/sourcegit-$VERSION-1.$target.rpm" ./ From 1575ae977eb1ba1923e2d02e0521a90064aa7b95 Mon Sep 17 00:00:00 2001 From: Gadfly Date: Thu, 27 Mar 2025 20:22:46 +0800 Subject: [PATCH 430/865] fix: improve font family name handling by collapsing multiple spaces (#1131) --- src/App.axaml.cs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/App.axaml.cs b/src/App.axaml.cs index 86c5200c..0448a247 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -559,8 +559,22 @@ namespace SourceGit foreach (var part in parts) { var t = part.Trim(); - if (!string.IsNullOrEmpty(t)) - trimmed.Add(t); + if (string.IsNullOrEmpty(t)) + continue; + + // Collapse multiple spaces into single space + var prevChar = '\0'; + var sb = new StringBuilder(); + + foreach (var c in t) + { + if (c == ' ' && prevChar == ' ') + continue; + sb.Append(c); + prevChar = c; + } + + trimmed.Add(sb.ToString()); } return trimmed.Count > 0 ? string.Join(',', trimmed) : string.Empty; From 56ebc182f2fa244276c2c1014c978ef7cb72c32f Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 28 Mar 2025 12:20:36 +0800 Subject: [PATCH 431/865] enhance: try to reinstate not onl the working tree's change, but also the index's ones (#1135) Signed-off-by: leo --- src/Commands/Stash.cs | 2 +- src/Resources/Locales/de_DE.axaml | 1 - src/Resources/Locales/en_US.axaml | 1 - 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 | 1 - src/Resources/Locales/zh_TW.axaml | 1 - 10 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/Commands/Stash.cs b/src/Commands/Stash.cs index 7acfdf38..7d1a269b 100644 --- a/src/Commands/Stash.cs +++ b/src/Commands/Stash.cs @@ -82,7 +82,7 @@ namespace SourceGit.Commands public bool Pop(string name) { - Args = $"stash pop -q \"{name}\""; + Args = $"stash pop -q --index \"{name}\""; return Exec(); } diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index 7144ef43..ba6592e9 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -650,7 +650,6 @@ Lokale Änderungen stashen Anwenden Entfernen - Anwenden und entfernen Stash entfernen Entfernen: Stashes diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 75d312ea..5c400979 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -655,7 +655,6 @@ Stash Local Changes Apply Drop - Pop Save as Patch... Drop Stash Drop: diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index e1eccaa7..54cb588d 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -659,7 +659,6 @@ Stash Cambios Locales Aplicar Eliminar - Pop Guardar como Parche... Eliminar Stash Eliminar: diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index 1c3d7d34..2dcd52ab 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -600,7 +600,6 @@ Stash les changements locaux Appliquer Effacer - Extraire Effacer le Stash Effacer : Stashes diff --git a/src/Resources/Locales/it_IT.axaml b/src/Resources/Locales/it_IT.axaml index da7d18d1..e973a99c 100644 --- a/src/Resources/Locales/it_IT.axaml +++ b/src/Resources/Locales/it_IT.axaml @@ -659,7 +659,6 @@ Stasha Modifiche Locali Applica Elimina - Estrai Salva come Patch... Elimina Stash Elimina: diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml index e799741c..8ff00158 100644 --- a/src/Resources/Locales/pt_BR.axaml +++ b/src/Resources/Locales/pt_BR.axaml @@ -620,7 +620,6 @@ Guardar Alterações Locais Aplicar Descartar - Pop Descartar Stash Descartar: Stashes diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index 53f04a5b..ede88a10 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -660,7 +660,6 @@ Отложить локальные изменения Принять Отбросить - Применить Сохранить как заплатку... Отбросить тайник Отбросить: diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index ad9b4179..783e5696 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -659,7 +659,6 @@ 贮藏本地变更 应用(apply) 删除(drop) - 应用并删除(pop) 另存为补丁... 丢弃贮藏确认 丢弃贮藏 : diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 173ad099..c10d195f 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -658,7 +658,6 @@ 擱置本機變更 套用 (apply) 刪除 (drop) - 套用並刪除 (pop) 另存為修補檔 (patch)... 捨棄擱置變更確認 捨棄擱置變更: From b26c8a64ad7ebf62e450ca6b121bd0ab3fc14860 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 28 Mar 2025 04:20:55 +0000 Subject: [PATCH 432/865] doc: Update translation status and missing keys --- TRANSLATION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TRANSLATION.md b/TRANSLATION.md index 183e77e6..b51fa09b 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -36,7 +36,7 @@ This document shows the translation status of each locale file in the repository
-### ![pt__BR](https://img.shields.io/badge/pt__BR-91.13%25-yellow) +### ![pt__BR](https://img.shields.io/badge/pt__BR-91.12%25-yellow)
Missing keys in pt_BR.axaml From 276d000bcf66c8e5f686cc3eba0f98d486ee0cf9 Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 28 Mar 2025 18:01:15 +0800 Subject: [PATCH 433/865] refactor: change `Copy File Name` to `Copy Full Path` for selected file or change (#1132) Signed-off-by: leo --- src/Native/OS.cs | 9 +++++++++ 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/BranchCompare.cs | 12 ++++++------ src/ViewModels/CommitDetail.cs | 24 ++++++++++++------------ src/ViewModels/RevisionCompare.cs | 12 ++++++------ src/ViewModels/StashesPage.cs | 12 ++++++------ src/ViewModels/WorkingCopy.cs | 24 ++++++++++++------------ 15 files changed, 54 insertions(+), 51 deletions(-) diff --git a/src/Native/OS.cs b/src/Native/OS.cs index f11d1e7f..320b5208 100644 --- a/src/Native/OS.cs +++ b/src/Native/OS.cs @@ -162,6 +162,15 @@ namespace SourceGit.Native _backend.OpenWithDefaultEditor(file); } + public static string GetAbsPath(string root, string sub) + { + var fullpath = Path.Combine(root, sub); + if (OperatingSystem.IsWindows()) + return fullpath.Replace('/', '\\'); + + return fullpath; + } + private static void UpdateGitVersion() { if (string.IsNullOrEmpty(_gitExecutable) || !File.Exists(_gitExecutable)) diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index ba6592e9..bbfe4545 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -186,7 +186,6 @@ Kopieren Kopiere gesamten Text Pfad kopieren - Dateinamen kopieren Branch erstellen... Basierend auf: Erstellten Branch auschecken diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 5c400979..5ff1e3a4 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -186,7 +186,7 @@ Copy Copy All Text Copy Path - Copy File Name + Copy Full Path Create Branch... Based On: Check out the created branch diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index 54cb588d..d8018097 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -189,7 +189,6 @@ Copiar Copiar Todo el Texto Copiar Ruta - Copiar Nombre del Archivo Crear Rama... Basado En: Checkout de la rama creada diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index 2dcd52ab..70d0af22 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -178,7 +178,6 @@ Type de Changement : Copier Copier tout le texte - Copier le nom de fichier Copier le chemin Créer une branche... Basé sur : diff --git a/src/Resources/Locales/it_IT.axaml b/src/Resources/Locales/it_IT.axaml index e973a99c..85038d9e 100644 --- a/src/Resources/Locales/it_IT.axaml +++ b/src/Resources/Locales/it_IT.axaml @@ -189,7 +189,6 @@ Copia Copia Tutto il Testo Copia Percorso - Copia Nome File Crea Branch... Basato Su: Checkout del Branch Creato diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml index 8ff00158..4ee6cdbc 100644 --- a/src/Resources/Locales/pt_BR.axaml +++ b/src/Resources/Locales/pt_BR.axaml @@ -196,7 +196,6 @@ Copiar Copiar todo o texto Copiar Caminho - Copiar Nome do Arquivo Criar Branch... Baseado Em: Checar o branch criado diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index ede88a10..2d48d127 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -190,7 +190,6 @@ Копировать Копировать весь текст Копировать путь - Копировать имя файла Создать ветку... Основан на: Проверить созданную ветку diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 783e5696..8d2b4f1e 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -189,7 +189,7 @@ 复制 复制全部文本 复制路径 - 复制文件名 + 复制完整路径 新建分支 ... 新分支基于 : 完成后切换到新分支 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index c10d195f..8e823f68 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -189,7 +189,7 @@ 複製 複製全部內容 複製路徑 - 複製檔案名稱 + 複製完整路徑 新增分支... 新分支基於: 完成後切換到新分支 diff --git a/src/ViewModels/BranchCompare.cs b/src/ViewModels/BranchCompare.cs index b3c0009c..4edb978c 100644 --- a/src/ViewModels/BranchCompare.cs +++ b/src/ViewModels/BranchCompare.cs @@ -163,15 +163,15 @@ namespace SourceGit.ViewModels }; menu.Items.Add(copyPath); - var copyFileName = new MenuItem(); - copyFileName.Header = App.Text("CopyFileName"); - copyFileName.Icon = App.CreateMenuIcon("Icons.Copy"); - copyFileName.Click += (_, e) => + var copyFullPath = new MenuItem(); + copyFullPath.Header = App.Text("CopyFullPath"); + copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy"); + copyFullPath.Click += (_, e) => { - App.CopyText(Path.GetFileName(change.Path)); + App.CopyText(Native.OS.GetAbsPath(_repo, change.Path)); e.Handled = true; }; - menu.Items.Add(copyFileName); + menu.Items.Add(copyFullPath); return menu; } diff --git a/src/ViewModels/CommitDetail.cs b/src/ViewModels/CommitDetail.cs index 34ac8308..d04e674b 100644 --- a/src/ViewModels/CommitDetail.cs +++ b/src/ViewModels/CommitDetail.cs @@ -425,17 +425,17 @@ namespace SourceGit.ViewModels ev.Handled = true; }; - var copyFileName = new MenuItem(); - copyFileName.Header = App.Text("CopyFileName"); - copyFileName.Icon = App.CreateMenuIcon("Icons.Copy"); - copyFileName.Click += (_, e) => + var copyFullPath = new MenuItem(); + copyFullPath.Header = App.Text("CopyFullPath"); + copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy"); + copyFullPath.Click += (_, e) => { - App.CopyText(Path.GetFileName(change.Path)); + App.CopyText(Native.OS.GetAbsPath(_repo.FullPath, change.Path)); e.Handled = true; }; menu.Items.Add(copyPath); - menu.Items.Add(copyFileName); + menu.Items.Add(copyFullPath); return menu; } @@ -562,17 +562,17 @@ namespace SourceGit.ViewModels ev.Handled = true; }; - var copyFileName = new MenuItem(); - copyFileName.Header = App.Text("CopyFileName"); - copyFileName.Icon = App.CreateMenuIcon("Icons.Copy"); - copyFileName.Click += (_, e) => + var copyFullPath = new MenuItem(); + copyFullPath.Header = App.Text("CopyFullPath"); + copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy"); + copyFullPath.Click += (_, e) => { - App.CopyText(Path.GetFileName(file.Path)); + App.CopyText(Native.OS.GetAbsPath(_repo.FullPath, file.Path)); e.Handled = true; }; menu.Items.Add(copyPath); - menu.Items.Add(copyFileName); + menu.Items.Add(copyFullPath); return menu; } diff --git a/src/ViewModels/RevisionCompare.cs b/src/ViewModels/RevisionCompare.cs index 77a408e0..3b5717a6 100644 --- a/src/ViewModels/RevisionCompare.cs +++ b/src/ViewModels/RevisionCompare.cs @@ -183,15 +183,15 @@ namespace SourceGit.ViewModels }; menu.Items.Add(copyPath); - var copyFileName = new MenuItem(); - copyFileName.Header = App.Text("CopyFileName"); - copyFileName.Icon = App.CreateMenuIcon("Icons.Copy"); - copyFileName.Click += (_, e) => + var copyFullPath = new MenuItem(); + copyFullPath.Header = App.Text("CopyFullPath"); + copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy"); + copyFullPath.Click += (_, e) => { - App.CopyText(Path.GetFileName(change.Path)); + App.CopyText(Native.OS.GetAbsPath(_repo, change.Path)); e.Handled = true; }; - menu.Items.Add(copyFileName); + menu.Items.Add(copyFullPath); return menu; } diff --git a/src/ViewModels/StashesPage.cs b/src/ViewModels/StashesPage.cs index 77ed5551..e69d9bb5 100644 --- a/src/ViewModels/StashesPage.cs +++ b/src/ViewModels/StashesPage.cs @@ -251,12 +251,12 @@ namespace SourceGit.ViewModels ev.Handled = true; }; - var copyFileName = new MenuItem(); - copyFileName.Header = App.Text("CopyFileName"); - copyFileName.Icon = App.CreateMenuIcon("Icons.Copy"); - copyFileName.Click += (_, e) => + var copyFullPath = new MenuItem(); + copyFullPath.Header = App.Text("CopyFullPath"); + copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy"); + copyFullPath.Click += (_, e) => { - App.CopyText(Path.GetFileName(change.Path)); + App.CopyText(Native.OS.GetAbsPath(_repo.FullPath, change.Path)); e.Handled = true; }; @@ -267,7 +267,7 @@ namespace SourceGit.ViewModels menu.Items.Add(resetToThisRevision); menu.Items.Add(new MenuItem { Header = "-" }); menu.Items.Add(copyPath); - menu.Items.Add(copyFileName); + menu.Items.Add(copyFullPath); return menu; } diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index f9ddb288..40b4c50c 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -903,15 +903,15 @@ namespace SourceGit.ViewModels }; menu.Items.Add(copy); - var copyFileName = new MenuItem(); - copyFileName.Header = App.Text("CopyFileName"); - copyFileName.Icon = App.CreateMenuIcon("Icons.Copy"); - copyFileName.Click += (_, e) => + var copyFullPath = new MenuItem(); + copyFullPath.Header = App.Text("CopyFullPath"); + copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy"); + copyFullPath.Click += (_, e) => { - App.CopyText(Path.GetFileName(change.Path)); + App.CopyText(Native.OS.GetAbsPath(_repo.FullPath, change.Path)); e.Handled = true; }; - menu.Items.Add(copyFileName); + menu.Items.Add(copyFullPath); } else { @@ -1270,17 +1270,17 @@ namespace SourceGit.ViewModels e.Handled = true; }; - var copyFileName = new MenuItem(); - copyFileName.Header = App.Text("CopyFileName"); - copyFileName.Icon = App.CreateMenuIcon("Icons.Copy"); - copyFileName.Click += (_, e) => + var copyFullPath = new MenuItem(); + copyFullPath.Header = App.Text("CopyFullPath"); + copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy"); + copyFullPath.Click += (_, e) => { - App.CopyText(Path.GetFileName(change.Path)); + App.CopyText(Native.OS.GetAbsPath(_repo.FullPath, change.Path)); e.Handled = true; }; menu.Items.Add(copyPath); - menu.Items.Add(copyFileName); + menu.Items.Add(copyFullPath); } else { From ce7196490a5d7143f7502ea8b4aad89a3c719ab8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 28 Mar 2025 10:02:16 +0000 Subject: [PATCH 434/865] doc: Update translation status and missing keys --- TRANSLATION.md | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/TRANSLATION.md b/TRANSLATION.md index b51fa09b..c79847be 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -6,7 +6,7 @@ This document shows the translation status of each locale file in the repository ### ![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen) -### ![de__DE](https://img.shields.io/badge/de__DE-98.79%25-yellow) +### ![de__DE](https://img.shields.io/badge/de__DE-98.65%25-yellow)
Missing keys in de_DE.axaml @@ -14,6 +14,7 @@ This document shows the translation status of each locale file in the repository - Text.BranchUpstreamInvalid - Text.Configure.CustomAction.WaitForExit - Text.Configure.IssueTracker.AddSampleAzure +- Text.CopyFullPath - Text.Diff.First - Text.Diff.Last - Text.Preferences.AI.Streaming @@ -23,20 +24,35 @@ This document shows the translation status of each locale file in the repository
-### ![es__ES](https://img.shields.io/badge/es__ES-%E2%88%9A-brightgreen) +### ![es__ES](https://img.shields.io/badge/es__ES-99.87%25-yellow) -### ![fr__FR](https://img.shields.io/badge/fr__FR-%E2%88%9A-brightgreen) +
+Missing keys in es_ES.axaml -### ![it__IT](https://img.shields.io/badge/it__IT-99.87%25-yellow) +- Text.CopyFullPath + +
+ +### ![fr__FR](https://img.shields.io/badge/fr__FR-99.87%25-yellow) + +
+Missing keys in fr_FR.axaml + +- Text.CopyFullPath + +
+ +### ![it__IT](https://img.shields.io/badge/it__IT-99.73%25-yellow)
Missing keys in it_IT.axaml +- Text.CopyFullPath - Text.Preferences.General.ShowTagsInGraph
-### ![pt__BR](https://img.shields.io/badge/pt__BR-91.12%25-yellow) +### ![pt__BR](https://img.shields.io/badge/pt__BR-90.98%25-yellow)
Missing keys in pt_BR.axaml @@ -59,6 +75,7 @@ This document shows the translation status of each locale file in the repository - Text.Configure.CustomAction.WaitForExit - Text.Configure.IssueTracker.AddSampleGiteeIssue - Text.Configure.IssueTracker.AddSampleGiteePullRequest +- Text.CopyFullPath - Text.CreateBranch.Name.WarnSpace - Text.DeleteRepositoryNode.Path - Text.DeleteRepositoryNode.TipForGroup @@ -110,7 +127,14 @@ This document shows the translation status of each locale file in the repository
-### ![ru__RU](https://img.shields.io/badge/ru__RU-%E2%88%9A-brightgreen) +### ![ru__RU](https://img.shields.io/badge/ru__RU-99.87%25-yellow) + +
+Missing keys in ru_RU.axaml + +- Text.CopyFullPath + +
### ![zh__CN](https://img.shields.io/badge/zh__CN-%E2%88%9A-brightgreen) From 1482a005bb616d5f16926ec77d469e324ce1095a Mon Sep 17 00:00:00 2001 From: AquariusStar <48148723+AquariusStar@users.noreply.github.com> Date: Mon, 31 Mar 2025 04:20:54 +0300 Subject: [PATCH 435/865] localization: update and fix translation russian (#1136) --- src/Resources/Locales/ru_RU.axaml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index 2d48d127..2ea274d1 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -190,6 +190,7 @@ Копировать Копировать весь текст Копировать путь + Копировать полный путь Создать ветку... Основан на: Проверить созданную ветку @@ -212,7 +213,7 @@ Вид: С примечаниями Простой - Удерживайте Ctrl, чтобы начать сразу + Удерживайте Ctrl, чтобы сразу начать Вырезать Удалить ветку Ветка: @@ -330,7 +331,7 @@ Добавить шаблон отслеживания в LFS Git Извлечь Извлечь объекты LFS - Запустить «git lfs fetch», чтобы загрузить объекты LFS Git. При этом рабочая копия не обновляется. + Запустить (git lfs fetch), чтобы загрузить объекты LFS Git. При этом рабочая копия не обновляется. Установить перехват LFS Git Показывать блокировки Нет заблокированных файлов @@ -340,10 +341,10 @@ Разблокировать Принудительно разблокировать Обрезать - Запустить «git lfs prune», чтобы удалить старые файлы LFS из локального хранилища + Запустить (git lfs prune), чтобы удалить старые файлы LFS из локального хранилища Забрать Забрать объекты LFS - Запустить «git lfs pull», чтобы загрузить все файлы LFS Git для текущей ссылки и проверить + Запустить (git lfs pull), чтобы загрузить все файлы LFS Git для текущей ссылки и проверить Выложить Выложить объекты LFS Отправляйте большие файлы, помещенные в очередь, в конечную точку LFS Git @@ -557,7 +558,7 @@ Отказ Автоматическое извлечение изменений с внешних репозиторий... Очистить (Сбор мусора и удаление) - Запустить команду «git gc» для данного репозитория. + Запустить команду (git gc) для данного репозитория. Очистить всё Настройка репозитория ПРОДОЛЖИТЬ From 9ee3a00fbae017de54c33f56ff0d0d3d1b53e29c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 31 Mar 2025 01:21:15 +0000 Subject: [PATCH 436/865] doc: Update translation status and missing keys --- TRANSLATION.md | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/TRANSLATION.md b/TRANSLATION.md index c79847be..341fdce0 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -127,14 +127,7 @@ This document shows the translation status of each locale file in the repository
-### ![ru__RU](https://img.shields.io/badge/ru__RU-99.87%25-yellow) - -
-Missing keys in ru_RU.axaml - -- Text.CopyFullPath - -
+### ![ru__RU](https://img.shields.io/badge/ru__RU-%E2%88%9A-brightgreen) ### ![zh__CN](https://img.shields.io/badge/zh__CN-%E2%88%9A-brightgreen) From 07d99f5fd28cae320cf20b229438ead47ca68e79 Mon Sep 17 00:00:00 2001 From: qiufengshe Date: Mon, 31 Mar 2025 09:21:38 +0800 Subject: [PATCH 437/865] enhance: get email hash code opimization (#1137) (cherry picked from commit 839b92a284d6b103894f6a8a39e5ce1f99bb12fa) --- src/Models/AvatarManager.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Models/AvatarManager.cs b/src/Models/AvatarManager.cs index 9f0bceaf..a506d886 100644 --- a/src/Models/AvatarManager.cs +++ b/src/Models/AvatarManager.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.IO; @@ -196,8 +196,8 @@ namespace SourceGit.Models private string GetEmailHash(string email) { var lowered = email.ToLower(CultureInfo.CurrentCulture).Trim(); - var hash = MD5.Create().ComputeHash(Encoding.Default.GetBytes(lowered)); - var builder = new StringBuilder(); + var hash = MD5.HashData(Encoding.Default.GetBytes(lowered).AsSpan()); + var builder = new StringBuilder(hash.Length * 2); foreach (var c in hash) builder.Append(c.ToString("x2")); return builder.ToString(); From 0045e06d7888ea1463e6f2291bfe8b76d927b563 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 31 Mar 2025 09:29:07 +0800 Subject: [PATCH 438/865] project: upgrade `AvaloniaUI` to `11.2.6` Signed-off-by: leo --- src/SourceGit.csproj | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/SourceGit.csproj b/src/SourceGit.csproj index 2a4b3c91..852c9e34 100644 --- a/src/SourceGit.csproj +++ b/src/SourceGit.csproj @@ -41,11 +41,11 @@ - - - - - + + + + + From ae5fa6a793801fa6171257ef3aa9f94a6f7ba3be Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 31 Mar 2025 09:29:56 +0800 Subject: [PATCH 439/865] version: Release 2025.11 Signed-off-by: leo --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index e78345d1..75c26f38 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2025.10 \ No newline at end of file +2025.11 \ No newline at end of file From 8e55ba1b47168f9fa193d33c1af4dacd04316da4 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 31 Mar 2025 19:06:10 +0800 Subject: [PATCH 440/865] enhance: avoid unhandled exceptions in timer Signed-off-by: leo --- src/ViewModels/Repository.cs | 51 ++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 6ea41e04..6b1e439e 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -2513,30 +2513,37 @@ namespace SourceGit.ViewModels private void AutoFetchImpl(object sender) { - if (!_settings.EnableAutoFetch || _isAutoFetching) - return; - - var lockFile = Path.Combine(_gitDir, "index.lock"); - if (File.Exists(lockFile)) - return; - - var now = DateTime.Now; - var desire = _lastFetchTime.AddMinutes(_settings.AutoFetchInterval); - if (desire > now) - return; - - var remotes = new List(); - lock (_lockRemotes) + try { - foreach (var remote in _remotes) - remotes.Add(remote.Name); - } + if (!_settings.EnableAutoFetch || _isAutoFetching) + return; - Dispatcher.UIThread.Invoke(() => IsAutoFetching = true); - foreach (var remote in remotes) - new Commands.Fetch(_fullpath, remote, false, false, null) { RaiseError = false }.Exec(); - _lastFetchTime = DateTime.Now; - Dispatcher.UIThread.Invoke(() => IsAutoFetching = false); + var lockFile = Path.Combine(_gitDir, "index.lock"); + if (File.Exists(lockFile)) + return; + + var now = DateTime.Now; + var desire = _lastFetchTime.AddMinutes(_settings.AutoFetchInterval); + if (desire > now) + return; + + var remotes = new List(); + lock (_lockRemotes) + { + foreach (var remote in _remotes) + remotes.Add(remote.Name); + } + + Dispatcher.UIThread.Invoke(() => IsAutoFetching = true); + foreach (var remote in remotes) + new Commands.Fetch(_fullpath, remote, false, false, null) { RaiseError = false }.Exec(); + _lastFetchTime = DateTime.Now; + Dispatcher.UIThread.Invoke(() => IsAutoFetching = false); + } + catch + { + // DO nothing, but prevent `System.AggregateException` + } } private string _fullpath = string.Empty; From 2deb79f8cea6580ba89fb24cc7fea537f723ec17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20J=2E=20Mart=C3=ADnez=20M=2E?= <56406225+jjesus-dev@users.noreply.github.com> Date: Wed, 2 Apr 2025 03:20:33 -0600 Subject: [PATCH 441/865] localization: update spanish translations (#1142) add literal translation for 'CopyFullPath' string --- src/Resources/Locales/es_ES.axaml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index d8018097..8b4c350f 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -189,6 +189,7 @@ Copiar Copiar Todo el Texto Copiar Ruta + Copiar Ruta Completa Crear Rama... Basado En: Checkout de la rama creada From 7ef4cca1f548e408984a553bfbbe2e09ed4731ba Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 2 Apr 2025 09:20:43 +0000 Subject: [PATCH 442/865] doc: Update translation status and missing keys --- TRANSLATION.md | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/TRANSLATION.md b/TRANSLATION.md index 341fdce0..011671ea 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -24,14 +24,7 @@ This document shows the translation status of each locale file in the repository -### ![es__ES](https://img.shields.io/badge/es__ES-99.87%25-yellow) - -
-Missing keys in es_ES.axaml - -- Text.CopyFullPath - -
+### ![es__ES](https://img.shields.io/badge/es__ES-%E2%88%9A-brightgreen) ### ![fr__FR](https://img.shields.io/badge/fr__FR-99.87%25-yellow) From 904432a8f1d63472f913071ad1e52f5a8e5fa582 Mon Sep 17 00:00:00 2001 From: UchiTesting <56003633+UchiTesting@users.noreply.github.com> Date: Mon, 7 Apr 2025 03:45:02 +0200 Subject: [PATCH 443/865] style(locale): Add a few translations to the French locale (#1158) --- src/Resources/Locales/fr_FR.axaml | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index 70d0af22..bf238aa2 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -16,13 +16,19 @@ Suivre la branche : Suivi de la branche distante Assistant IA + RE-GÉNERER Utiliser l'IA pour générer un message de commit + APPLIQUER COMME MESSAGE DE COMMIT Appliquer Fichier de patch : Selectionner le fichier .patch à appliquer Ignorer les changements d'espaces blancs Appliquer le patch Espaces blancs : + Appliquer le Stash + Supprimer après application + Rétablir les changements de l'index + Stash: Archiver... Enregistrer l'archive sous : Sélectionnez le chemin du fichier d'archive @@ -39,6 +45,7 @@ Comparer avec HEAD Comparer avec le worktree Copier le nom de la branche + Action personnalisée Supprimer ${0}$... Supprimer {0} branches sélectionnées Rejeter tous les changements @@ -54,6 +61,7 @@ Renommer ${0}$... Définir la branche de suivi... Comparer les branches + Branche amont invalide ! Octets ANNULER Réinitialiser à la révision parente @@ -92,6 +100,7 @@ Récupérer ce commit Cherry-Pick ce commit Cherry-Pick ... + Checkout Commit Comparer avec HEAD Comparer avec le worktree Copier les informations @@ -150,10 +159,10 @@ Ajouter une règle d'exemple Gitee Ajouter une règle d'exemple pour Pull Request Gitee Ajouter une règle d'exemple Github - Ajouter une règle d'exemple Jira - Ajouter une règle d'exemple Azure DevOps Ajouter une règle d'exemple pour Incidents GitLab Ajouter une règle d'exemple pour Merge Request GitLab + Ajouter une règle d'exemple Jira + Ajouter une règle d'exemple Azure DevOps Nouvelle règle Issue Regex Expression: Nom de règle : @@ -179,6 +188,7 @@ Copier Copier tout le texte Copier le chemin + Copier le chemin complet Créer une branche... Basé sur : Récupérer la branche créée @@ -187,6 +197,7 @@ Stash & Réappliquer Nom de la nouvelle branche : Entrez le nom de la branche. + Les espaces seront remplacés par des tirets. Créer une branche locale Créer un tag... Nouveau tag à : @@ -583,13 +594,20 @@ Passer cette version Mise à jour du logiciel Il n'y a pas de mise à jour pour le moment. + Définir la branche de suivi + Branche : + Escamoter la branche amont + Branche amont: Copier le SHA - Squash Commits + Aller à + Squash les commits Dans : Clé privée SSH : Chemin du magasin de clés privées SSH START Stash + Auto-restauration après le stash + Vos fichiers de travail sont inchangés, mais un stash a été sauvegardé. Inclure les fichiers non-suivis Garder les fichiers indexés Message : @@ -599,6 +617,7 @@ Stash les changements locaux Appliquer Effacer + Sauver comme Patch... Effacer le Stash Effacer : Stashes From cbc7079e59f1078e219bd4942ab59fd879a8f484 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 7 Apr 2025 01:45:21 +0000 Subject: [PATCH 444/865] doc: Update translation status and missing keys --- TRANSLATION.md | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/TRANSLATION.md b/TRANSLATION.md index 011671ea..711564ef 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -26,14 +26,7 @@ This document shows the translation status of each locale file in the repository ### ![es__ES](https://img.shields.io/badge/es__ES-%E2%88%9A-brightgreen) -### ![fr__FR](https://img.shields.io/badge/fr__FR-99.87%25-yellow) - -
-Missing keys in fr_FR.axaml - -- Text.CopyFullPath - -
+### ![fr__FR](https://img.shields.io/badge/fr__FR-%E2%88%9A-brightgreen) ### ![it__IT](https://img.shields.io/badge/it__IT-99.73%25-yellow) From ef106e6909e73355ee22cd06ce0d0fef73a3ce02 Mon Sep 17 00:00:00 2001 From: Sousi Omine <110832262+SousiOmine@users.noreply.github.com> Date: Mon, 7 Apr 2025 10:53:20 +0900 Subject: [PATCH 445/865] Add Japanese localization (#1157) * Initial Japanese translation Only a small part was translated * Unspecified words will be in English When new words are added, they will be displayed in English even if Japanese support is delayed. * Expanded translation scope * Expanded translation scope * Proceed with translation with a focus on overall settings * Re-translated the outdated settings screen * Add items that only exist in the latest en_US and remove items that do not exist in en_US * A lot of translation work done * A lot more translation work has been done * ja_JP.axaml has been translated into Japanese * Fixed three incomplete parts of the Japanese translation --- src/App.axaml | 1 + src/Models/Locales.cs | 1 + src/Resources/Locales/ja_JP.axaml | 747 ++++++++++++++++++++++++++++++ 3 files changed, 749 insertions(+) create mode 100644 src/Resources/Locales/ja_JP.axaml diff --git a/src/App.axaml b/src/App.axaml index 76d4baa8..fdfa8e07 100644 --- a/src/App.axaml +++ b/src/App.axaml @@ -20,6 +20,7 @@ + diff --git a/src/Models/Locales.cs b/src/Models/Locales.cs index d5e1534c..802e88ef 100644 --- a/src/Models/Locales.cs +++ b/src/Models/Locales.cs @@ -17,6 +17,7 @@ namespace SourceGit.Models new Locale("Русский", "ru_RU"), new Locale("简体中文", "zh_CN"), new Locale("繁體中文", "zh_TW"), + new Locale("日本語", "ja_JP"), }; public Locale(string name, string key) diff --git a/src/Resources/Locales/ja_JP.axaml b/src/Resources/Locales/ja_JP.axaml new file mode 100644 index 00000000..21255221 --- /dev/null +++ b/src/Resources/Locales/ja_JP.axaml @@ -0,0 +1,747 @@ + + + + + 概要 + SourceGitについて + オープンソース & フリーなGit GUIクライアント + ワークツリーを追加 + チェックアウトする内容: + 既存のブランチ + 新しいブランチを作成 + 場所: + ワークツリーのパスを入力してください。相対パスも使用することができます。 + ブランチの名前: + 任意。デフォルトでは宛先フォルダ名が使用されます。 + 追跡するブランチ: + 追跡中のリモートブランチ + OpenAI アシスタント + 再生成 + OpenAIを使用してコミットメッセージを生成 + コミットメッセージとして適用 + 適用 + パッチファイル: + 適用する .patchファイルを選択 + 空白文字の変更を無視 + パッチを適用 + 空白文字: + スタッシュを適用 + 適用後に削除 + インデックスの変更を復元 + スタッシュ: + アーカイブ... + アーカイブの保存先: + アーカイブファイルのパスを選択 + リビジョン: + アーカイブ + SourceGit Askpass + 変更されていないとみなされるファイル + 変更されていないとみなされるファイルはありません + 削除 + バイナリファイルはサポートされていません!!! + Blame + BLAMEではこのファイルはサポートされていません!!! + ${0}$ をチェックアウトする... + HEADと比較 + ワークツリーと比較 + ブランチ名をコピー + カスタムアクション + ${0}$を削除... + 選択中の{0}個のブランチを削除 + すべての変更を破棄 + ${0}$ へ早送りする + ${0}$ から ${1}$ へフェッチする + Git Flow - Finish ${0}$ + ${0}$ を ${1}$ にマージする... + 選択中の{0}個のブランチを現在のブランチにマージする + ${0}$ をプルする + ${0}$ を ${1}$ にプルする... + ${0}$ をプッシュする + ${0}$ を ${1}$ でリベースする... + ${0}$ をリネームする... + トラッキングブランチを設定... + ブランチの比較 + 無効な上流ブランチ! + バイト + キャンセル + このリビジョンにリセット + 親リビジョンにリセット + コミットメッセージを生成 + 変更表示の切り替え + ファイルとディレクトリのリストを表示 + パスのリストを表示 + ファイルシステムのツリーを表示 + ブランチをチェックアウト + コミットをチェックアウト + 警告: コミットをチェックアウトするとHEADが切断されます + コミット: + ブランチ: + ローカルの変更: + 破棄 + スタッシュして再適用 + チェリーピック + ソースをコミットメッセージに追加 + コミット(複数可): + すべての変更をコミット + メインライン: + 通常、マージをチェリーピックすることはできません。どちらのマージ元をメインラインとして扱うべきかが分からないためです。このオプションを使用すると、指定した親に対して変更を再適用する形でチェリーピックを実行できます。 + スタッシュをクリア + すべてのスタッシュをクリアします。続行しますか? + リモートリポジトリをクローン + 追加の引数: + リポジトリをクローンする際の追加パラメータ(任意)。 + ローカル名: + リポジトリの名前(任意)。 + 親フォルダ: + サブモジュールを初期化して更新 + リポジトリのURL: + 閉じる + エディタ + このコミットをチェリーピック + チェリーピック... + コミットをチェックアウト + HEADと比較 + ワークツリーと比較 + 情報をコピー + SHAをコピー + カスタムアクション + ${0}$ ブランチをここにインタラクティブリベース + ${0}$ にマージ + マージ... + ${0}$ をここにリベース + ${0}$ ブランチをここにリセット + コミットを戻す + 書き直す + パッチとして保存... + 親にスカッシュ + 子コミットをここにスカッシュ + 変更 + 変更を検索... + ファイル + LFSファイル + ファイルを検索... + サブモジュール + コミットの情報 + 著者 + 変更 + + コミッター + このコミットを含む参照を確認 + コミットが含まれるか確認 + 最初の100件の変更のみが表示されています。すべての変更は'変更'タブで確認できます。 + メッセージ + + 参照 + SHA + ブラウザで開く + コミットのタイトルを入力 + 説明 + リポジトリの設定 + コミットテンプレート + テンプレート名: + テンプレート内容: + カスタムアクション + 引数: + ${REPO} - リポジトリのパス; ${BRANCH} - 選択中のブランチ; ${SHA} - 選択中のコミットのSHA + 実行ファイル: + 名前: + スコープ: + ブランチ + コミット + リポジトリ + アクションの終了を待機 + Eメールアドレス + Eメールアドレス + GIT + 自動的にリモートからフェッチ 間隔: + 分(s) + リモートの初期値 + ISSUEトラッカー + サンプルのGitee Issueルールを追加 + サンプルのGiteeプルリクエストルールを追加 + サンプルのGithubルールを追加 + サンプルのGitLab Issueルールを追加 + サンプルのGitLabマージリクエストルールを追加 + サンプルのJiraルールを追加 + サンプルのAzure DevOpsルールを追加 + 新しいルール + Issueの正規表現: + ルール名: + リザルトURL: + 正規表現のグループ値に$1, $2を使用してください。 + AI + 優先するサービス: + 優先するサービスが設定されている場合、SourceGitはこのリポジトリでのみそれを使用します。そうでない場合で複数サービスが利用できる場合は、そのうちの1つを選択するためのコンテキストメニューが表示されます。 + HTTP プロキシ + このリポジトリで使用するHTTPプロキシ + ユーザー名 + このリポジトリにおけるユーザー名 + ワークスペース + + 起動時にタブを復元 + Conventional Commitヘルパー + 破壊的変更: + 閉じたIssue: + 詳細な変更: + スコープ: + 短い説明: + 変更の種類: + コピー + すべてのテキストをコピー + パスをコピー + 絶対パスをコピー + ブランチを作成... + 派生元: + 作成したブランチにチェックアウト + ローカルの変更: + 破棄 + スタッシュして再適用 + 新しいブランチの名前: + ブランチの名前を入力 + スペースはダッシュに置き換えられます。 + ローカルブランチを作成 + タグを作成... + 付与されるコミット: + GPG署名を使用 + タグメッセージ: + 任意。 + タグの名前: + 推奨フォーマット: v1.0.0-alpha + 作成後にすべてのリモートにプッシュ + 新しいタグを作成 + 種類: + 注釈付き + 軽量 + Ctrlキーを押しながらクリックで実行 + 切り取り + ブランチを削除 + ブランチ: + リモートブランチを削除しようとしています!!! + もしリモートブランチを削除する場合、${0}$も削除します。 + 複数のブランチを削除 + 一度に複数のブランチを削除しようとしています! 操作を行う前に再度確認してください! + リモートを削除 + リモート: + パス: + 対象: + すべての子ノードがリストから削除されます。 + グループを削除 + これはリストからのみ削除され、ディスクには保存されません! + リポジトリを削除 + サブモジュールを削除 + サブモジュールのパス: + タグを削除 + タグ: + リモートリポジトリから削除 + バイナリの差分 + NEW + OLD + コピー + ファイルモードが変更されました + 先頭の差分 + 空白の変更を無視 + 最後の差分 + LFSオブジェクトの変更 + 次の差分 + 変更がない、もしくはEOLの変更のみ + 前の差分 + パッチとして保存 + 隠されたシンボルを表示 + 差分の分割表示 + サブモジュール + 新規 + スワップ + シンタックスハイライト + 行の折り返し + ブロックナビゲーションを有効化 + マージツールで開く + すべての行を表示 + 表示する行数を減らす + 表示する行数を増やす + ファイルを選択すると、変更内容が表示されます + マージツールで開く + 変更を破棄 + ワーキングディレクトリのすべての変更を破棄 + 変更: + 無視したファイルを含める + {0}個の変更を破棄します。 + この操作を元に戻すことはできません!!! + ブックマーク: + 新しい名前: + 対象: + 選択中のグループを編集 + 選択中のリポジトリを編集 + カスタムアクションを実行 + アクション名: + (チェックアウトせずに)ブランチを早送りする + フェッチ + すべてのリモートをフェッチ + ローカル参照を強制的に上書き + タグなしでフェッチ + リモート: + リモートの変更をフェッチ + 変更されていないとみなされる + 破棄... + {0}個のファイルを破棄... + 選択された行の変更を破棄 + 外部マージツールで開く + ${0}$ を使用して解決 + パッチとして保存... + ステージ + {0}個のファイルをステージ... + 選択された行の変更をステージ + スタッシュ... + {0}個のファイルをスタッシュ... + アンステージ + {0}個のファイルをアンステージ... + 選択された行の変更をアンステージ + 相手の変更を使用 (checkout --theirs) + 自分の変更を使用 (checkout --ours) + ファイルの履歴 + コンテンツ + 変更 + Git-Flow + 開発ブランチ: + Feature: + Feature プレフィックス: + FLOW - Finish Feature + FLOW - Finish Hotfix + FLOW - Finish Release + 対象: + Hotfix: + Hotfix プレフィックス: + Git-Flowを初期化 + ブランチを保持 + プロダクション ブランチ: + Release: + Release プレフィックス: + Start Feature... + FLOW - Start Feature + Start Hotfix... + FLOW - Start Hotfix + 名前を入力 + Start Release... + FLOW - Start Release + Versionタグ プレフィックス: + Git LFS + トラックパターンを追加... + パターンをファイル名として扱う + カスタム パターン: + Git LFSにトラックパターンを追加 + フェッチ + LFSオブジェクトをフェッチ + `git lfs fetch`を実行して、Git LFSオブジェクトをダウンロードします。ワーキングコピーは更新されません。 + Git LFSフックをインストール + ロックを表示 + ロックされているファイルはありません + ロック + 私のロックのみ表示 + LFSロック + ロック解除 + 強制的にロック解除 + 削除 + `git lfs prune`を実行して、ローカルの保存領域から古いLFSファイルを削除します。 + プル + LFSオブジェクトをプル + `git lfs pull`を実行して、現在の参照とチェックアウトのすべてのGit LFSファイルをダウンロードします。 + プッシュ + LFSオブジェクトをプッシュ + キュー内の大容量ファイルをGit LFSエンドポイントにプッシュします。 + リモート: + {0}という名前のファイルをトラック + すべての*{0}ファイルをトラック + 履歴 + 著者 + 著者時間 + グラフ & コミットのタイトル + SHA + 日時 + {0} コミットを選択しました + 'Ctrl'キーまたは'Shift'キーを押すと、複数のコミットを選択できます。 + ⌘ または ⇧ キーを押して複数のコミットを選択します。 + TIPS: + キーボードショートカットを確認 + 総合 + 現在のポップアップをキャンセル + 新しくリポジトリをクローン + 現在のページを閉じる + 前のページに移動 + 次のページに移動 + 新しいページを作成 + 設定ダイアログを開く + リポジトリ + ステージ済みの変更をコミット + ステージ済みの変更をコミットしてプッシュ + 全ての変更をステージしてコミット + 選択中のコミットから新たなブランチを作成 + 選択した変更を破棄 + 直接フェッチを実行 + ダッシュボードモード (初期値) + 直接プルを実行 + 直接プッシュを実行 + 現在のリポジトリを強制的に再読み込み + 選択中の変更をステージ/アンステージ + コミット検索モード + '変更'に切り替える + '履歴'に切り替える + 'スタッシュ'に切り替える + テキストエディタ + 検索パネルを閉じる + 次のマッチを検索 + 前のマッチを検索 + 検索パネルを開く + ステージ + アンステージ + 破棄 + リポジトリの初期化 + パス: + チェリーピックが進行中です。'中止'を押すと元のHEADが復元されます。 + コミットを処理中 + マージリクエストが進行中です。'中止'を押すと元のHEADが復元されます。 + マージ中 + リベースが進行中です。'中止'を押すと元のHEADが復元されます。 + 停止しました + 元に戻す処理が進行中です。'中止'を押すと元のHEADが復元されます。 + コミットを元に戻しています + インタラクティブ リベース + 対象のブランチ: + On: + ブラウザで開く + リンクをコピー + エラー + 通知 + ブランチのマージ + 宛先: + マージオプション: + ソースブランチ: + マージ (複数) + すべての変更をコミット + マージ戦略: + 対象: + リポジトリノードの移動 + 親ノードを選択: + 名前: + Gitが設定されていません。まず[設定]に移動して設定を行ってください。 + アプリケーションデータのディレクトリを開く + 外部ツールで開く... + 任意。 + 新しいページを開く + ブックマーク + タブを閉じる + 他のタブを閉じる + 右のタブを閉じる + リポジトリパスをコピー + リポジトリ + 貼り付け + たった今 + {0} 分前 + 1 時間前 + {0} 時間前 + 昨日 + {0} 日前 + 先月 + {0} ヶ月前 + 昨年 + {0} 年前 + 設定 + AI + 差分分析プロンプト + APIキー + タイトル生成プロンプト + モデル + 名前 + サーバー + ストリーミングを有効化 + 外観 + デフォルトのフォント + エディタのタブ幅 + フォントサイズ + デフォルト + エディタ + 等幅フォント + テキストエディタでは等幅フォントのみを使用する + テーマ + テーマの上書き + タイトルバーの固定タブ幅を使用 + ネイティブウィンドウフレームを使用 + 差分/マージ ツール + インストール パス + 差分/マージ ツールのパスを入力 + ツール + 総合 + 起動時にアップデートを確認 + 日時のフォーマット + 言語 + コミット履歴 + グラフにコミット時間の代わりに著者の時間を表示する + コミット詳細に子コミットを表示 + コミットグラフにタグを表示 + コミットタイトル枠の大きさ + GIT + 自動CRLFを有効化 + デフォルトのクローンディレクトリ + ユーザー Eメールアドレス + グローバルgitのEメールアドレス + フェッチ時に--pruneを有効化 + インストール パス + HTTP SSL 検証を有効にする + ユーザー名 + グローバルのgitユーザー名 + Gitバージョン + Git (>= 2.23.0) はこのアプリで必要です + GPG 署名 + コミットにGPG署名を行う + タグにGPG署名を行う + GPGフォーマット + プログラムのインストールパス + インストールされたgpgプログラムのパスを入力 + ユーザー署名キー + ユーザーのGPG署名キー + 統合 + シェル/ターミナル + シェル/ターミナル + パス + リモートを削除 + 対象: + 作業ツリーを削除 + `$GIT_DIR/worktrees` の作業ツリー情報を削除 + プル + ブランチ: + すべてのブランチをフェッチ + 宛先: + ローカルの変更: + 破棄 + スタッシュして再適用 + タグなしでフェッチ + リモート: + プル (フェッチ & マージ) + マージの代わりにリベースを使用 + プッシュ + サブモジュールがプッシュされていることを確認 + 強制的にプッシュ + ローカル ブランチ: + リモート: + 変更をリモートにプッシュ + リモート ブランチ: + 追跡ブランチとして設定 + すべてのタグをプッシュ + リモートにタグをプッシュ + すべてのリモートにプッシュ + リモート: + タグ: + 終了 + 現在のブランチをリベース + ローカルの変更をスタッシュして再適用 + On: + リベース: + 更新 + リモートを追加 + リモートを編集 + 名前: + リモートの名前 + リポジトリのURL: + リモートのgitリポジトリのURL + URLをコピー + 削除... + 編集... + フェッチ + ブラウザで開く + 削除 + ワークツリーの削除を確認 + `--force` オプションを有効化 + 対象: + ブランチの名前を編集 + 新しい名前: + このブランチにつける一意な名前 + ブランチ: + 中止 + リモートから変更を自動取得中... + クリーンアップ(GC & Prune) + このリポジトリに対して`git gc`コマンドを実行します。 + すべてのフィルターをクリア + リポジトリの設定 + 続ける + カスタムアクション + カスタムアクションがありません + `--reflog` オプションを有効化 + ファイルブラウザーで開く + ブランチ/タグ/サブモジュールを検索 + 解除 + コミットグラフで非表示 + コミットグラフでフィルター + `--first-parent` オプションを有効化 + レイアウト + 水平 + 垂直 + コミットの並び順 + 日時 + トポロジカルソート + ローカル ブランチ + HEADに移動 + ブランチを作成 + 通知をクリア + グラフで現在のブランチを強調表示 + {0} で開く + 外部ツールで開く + 更新 + リモート + リモートを追加 + コミットを検索 + 著者 + コミッター + ファイル + メッセージ + SHA + 現在のブランチ + タグをツリーとして表示 + スキップ + 統計 + サブモジュール + サブモジュールを追加 + サブモジュールを更新 + タグ + 新しいタグを作成 + 作成者日時 + 名前 (昇順) + 名前 (降順) + ソート + ターミナルで開く + 履歴に相対時間を使用 + ワークツリー + ワークツリーを追加 + 削除 + GitリポジトリのURL + 現在のブランチをリビジョンにリセット + リセットモード: + 移動先: + 現在のブランチ: + ファイルエクスプローラーで表示 + コミットを戻す + コミット: + コミットの変更を戻す + コミットメッセージを書き直す + 改行には'Shift+Enter'キーを使用します。 'Enter"はOKボタンのホットキーとして機能します。 + 実行中です。しばらくお待ちください... + 保存 + 名前を付けて保存... + パッチが正常に保存されました! + リポジトリをスキャン + ルートディレクトリ: + 更新を確認 + 新しいバージョンのソフトウェアが利用可能です: + 更新の確認に失敗しました! + ダウンロード + このバージョンをスキップ + ソフトウェアの更新 + 利用可能なアップデートはありません + トラッキングブランチを設定 + ブランチ: + 上流ブランチを解除 + 上流ブランチ: + SHAをコピー + Go to + スカッシュコミット + 宛先: + SSH プライベートキー: + プライベートSSHキーストアのパス + スタート + スタッシュ + スタッシュ後に自動で復元 + 作業ファイルは変更されず、スタッシュが保存されます。 + 追跡されていないファイルを含める + ステージされたファイルを保持 + メッセージ: + オプション. このスタッシュの名前を入力 + ステージされた変更のみ + 選択したファイルの、ステージされた変更とステージされていない変更の両方がスタッシュされます!!! + ローカルの変更をスタッシュ + 適用 + 破棄 + パッチとして保存 + スタッシュを破棄 + 破棄: + スタッシュ + 変更 + スタッシュ + 統計 + コミット + コミッター + 月間 + 週間 + コミット: + 著者: + 概要 + サブモジュール + サブモジュールを追加 + 相対パスをコピー + ネストされたサブモジュールを取得する + サブモジュールのリポジトリを開く + 相対パス: + このモジュールを保存するフォルダの相対パス + サブモジュールを削除 + OK + タグ名をコピー + タグメッセージをコピー + ${0}$ を削除... + ${0}$ を ${1}$ にマージ... + ${0}$ をプッシュ... + URL: + サブモジュールを更新 + すべてのサブモジュール + 必要に応じて初期化 + 再帰的に更新 + サブモジュール: + --remoteオプションを使用 + 警告 + ようこそ + グループを作成 + サブグループを作成 + リポジトリをクローンする + 削除 + ドラッグ & ドロップでフォルダを追加できます. グループを作成したり、変更したりできます。 + 編集 + 別のグループに移動 + すべてのリポジトリを開く + リポジトリを開く + ターミナルを開く + デフォルトのクローンディレクトリ内のリポジトリを再スキャン + リポジトリを検索... + ソート + 変更 + Git Ignore + すべての*{0}ファイルを無視 + 同じフォルダ内の*{0}ファイルを無視 + 同じフォルダ内のファイルを無視 + このファイルのみを無視 + Amend + このファイルを今すぐステージできます。 + コミット + コミットしてプッシュ + メッセージのテンプレート/履歴 + クリックイベントをトリガー + コミット (Edit) + すべての変更をステージしてコミット + 空のコミットが検出されました。続行しますか? (--allow-empty) + 競合が検出されました + ファイルの競合は解決されました + 追跡されていないファイルを含める + 最近の入力メッセージはありません + コミットテンプレートはありません + サインオフ + ステージしたファイル + ステージを取り消し + すべてステージを取り消し + 未ステージのファイル + ステージへ移動 + すべてステージへ移動 + 変更されていないとみなしたものを表示 + テンプレート: ${0}$ + 選択したファイルを右クリックし、競合を解決する操作を選択してください。 + ワークスペース: + ワークスペースを設定... + ワークツリー + パスをコピー + ロック + 削除 + ロック解除 + From 17d285d9bf410a76b2ea32dcaccabd235b82367b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 7 Apr 2025 01:53:35 +0000 Subject: [PATCH 446/865] doc: Update translation status and missing keys --- TRANSLATION.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/TRANSLATION.md b/TRANSLATION.md index 711564ef..b344e6a3 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -38,6 +38,16 @@ This document shows the translation status of each locale file in the repository +### ![ja__JP](https://img.shields.io/badge/ja__JP-99.73%25-yellow) + +
+Missing keys in ja_JP.axaml + +- Text.Repository.FilterCommits +- Text.Repository.Tags.OrderByNameDes + +
+ ### ![pt__BR](https://img.shields.io/badge/pt__BR-90.98%25-yellow)
From c615d04038cdbc1fda6f3a085070feb750803e15 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 7 Apr 2025 09:54:35 +0800 Subject: [PATCH 447/865] doc: update README.md for Japanese support Signed-off-by: leo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d63886ed..aacf222e 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ * Supports Windows/macOS/Linux * Opensource/Free * Fast -* Deutsch/English/Español/Français/Italiano/Português/Русский/简体中文/繁體中文 +* Deutsch/English/Español/Français/Italiano/Português/Русский/简体中文/繁體中文/日本語 * Built-in light/dark themes * Customize theme * Visual commit graph From 8c9cf05c1d393bcfe1381b1358d3e4f33404cae9 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 7 Apr 2025 10:14:02 +0800 Subject: [PATCH 448/865] fix: renamed files are missing in commit changes and stash changes (#1151) Signed-off-by: leo --- src/Commands/CompareRevisions.cs | 18 +++++++++++++----- src/Commands/QueryStashChanges.cs | 18 +++++++++++++----- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/Commands/CompareRevisions.cs b/src/Commands/CompareRevisions.cs index e311a88e..c3206767 100644 --- a/src/Commands/CompareRevisions.cs +++ b/src/Commands/CompareRevisions.cs @@ -6,8 +6,10 @@ namespace SourceGit.Commands { public partial class CompareRevisions : Command { - [GeneratedRegex(@"^([MADRC])\s+(.+)$")] + [GeneratedRegex(@"^([MADC])\s+(.+)$")] private static partial Regex REG_FORMAT(); + [GeneratedRegex(@"^R[0-9]{0,4}\s+(.+)$")] + private static partial Regex REG_RENAME_FORMAT(); public CompareRevisions(string repo, string start, string end) { @@ -38,7 +40,17 @@ namespace SourceGit.Commands { var match = REG_FORMAT().Match(line); if (!match.Success) + { + match = REG_RENAME_FORMAT().Match(line); + if (match.Success) + { + var renamed = new Models.Change() { Path = match.Groups[1].Value }; + renamed.Set(Models.ChangeState.Renamed); + _changes.Add(renamed); + } + return; + } var change = new Models.Change() { Path = match.Groups[2].Value }; var status = match.Groups[1].Value; @@ -57,10 +69,6 @@ namespace SourceGit.Commands change.Set(Models.ChangeState.Deleted); _changes.Add(change); break; - case 'R': - change.Set(Models.ChangeState.Renamed); - _changes.Add(change); - break; case 'C': change.Set(Models.ChangeState.Copied); _changes.Add(change); diff --git a/src/Commands/QueryStashChanges.cs b/src/Commands/QueryStashChanges.cs index 7fc27ea3..92240569 100644 --- a/src/Commands/QueryStashChanges.cs +++ b/src/Commands/QueryStashChanges.cs @@ -9,8 +9,10 @@ namespace SourceGit.Commands /// public partial class QueryStashChanges : Command { - [GeneratedRegex(@"^([MADRC])\s+(.+)$")] + [GeneratedRegex(@"^([MADC])\s+(.+)$")] private static partial Regex REG_FORMAT(); + [GeneratedRegex(@"^R[0-9]{0,4}\s+(.+)$")] + private static partial Regex REG_RENAME_FORMAT(); public QueryStashChanges(string repo, string stash) { @@ -31,7 +33,17 @@ namespace SourceGit.Commands { var match = REG_FORMAT().Match(line); if (!match.Success) + { + match = REG_RENAME_FORMAT().Match(line); + if (match.Success) + { + var renamed = new Models.Change() { Path = match.Groups[1].Value }; + renamed.Set(Models.ChangeState.Renamed); + outs.Add(renamed); + } + continue; + } var change = new Models.Change() { Path = match.Groups[2].Value }; var status = match.Groups[1].Value; @@ -50,10 +62,6 @@ namespace SourceGit.Commands change.Set(Models.ChangeState.Deleted); outs.Add(change); break; - case 'R': - change.Set(Models.ChangeState.Renamed); - outs.Add(change); - break; case 'C': change.Set(Models.ChangeState.Copied); outs.Add(change); From ac7b02590ba846905b5492900e02a82b5852d01b Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 7 Apr 2025 10:23:37 +0800 Subject: [PATCH 449/865] enhance: add comma between date and time (#1150) Signed-off-by: leo --- src/Models/DateTimeFormat.cs | 22 +++++++++++----------- src/Views/Histories.axaml | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Models/DateTimeFormat.cs b/src/Models/DateTimeFormat.cs index 4e71a74f..4e8aa550 100644 --- a/src/Models/DateTimeFormat.cs +++ b/src/Models/DateTimeFormat.cs @@ -32,17 +32,17 @@ namespace SourceGit.Models public static readonly List Supported = new List { - new DateTimeFormat("yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss"), - new DateTimeFormat("yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss"), - new DateTimeFormat("yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss"), - new DateTimeFormat("MM/dd/yyyy", "MM/dd/yyyy HH:mm:ss"), - new DateTimeFormat("MM.dd.yyyy", "MM.dd.yyyy HH:mm:ss"), - new DateTimeFormat("MM-dd-yyyy", "MM-dd-yyyy HH:mm:ss"), - new DateTimeFormat("dd/MM/yyyy", "dd/MM/yyyy HH:mm:ss"), - new DateTimeFormat("dd.MM.yyyy", "dd.MM.yyyy HH:mm:ss"), - new DateTimeFormat("dd-MM-yyyy", "dd-MM-yyyy HH:mm:ss"), - new DateTimeFormat("MMM d yyyy", "MMM d yyyy HH:mm:ss"), - new DateTimeFormat("d MMM yyyy", "d MMM yyyy HH:mm:ss"), + new DateTimeFormat("yyyy/MM/dd", "yyyy/MM/dd, HH:mm:ss"), + new DateTimeFormat("yyyy.MM.dd", "yyyy.MM.dd, HH:mm:ss"), + new DateTimeFormat("yyyy-MM-dd", "yyyy-MM-dd, HH:mm:ss"), + new DateTimeFormat("MM/dd/yyyy", "MM/dd/yyyy, HH:mm:ss"), + new DateTimeFormat("MM.dd.yyyy", "MM.dd.yyyy, HH:mm:ss"), + new DateTimeFormat("MM-dd-yyyy", "MM-dd-yyyy, HH:mm:ss"), + new DateTimeFormat("dd/MM/yyyy", "dd/MM/yyyy, HH:mm:ss"), + new DateTimeFormat("dd.MM.yyyy", "dd.MM.yyyy, HH:mm:ss"), + new DateTimeFormat("dd-MM-yyyy", "dd-MM-yyyy, HH:mm:ss"), + new DateTimeFormat("MMM d yyyy", "MMM d yyyy, HH:mm:ss"), + new DateTimeFormat("d MMM yyyy", "d MMM yyyy, HH:mm:ss"), }; private static readonly DateTime _example = new DateTime(2025, 1, 31, 8, 0, 0, DateTimeKind.Local); diff --git a/src/Views/Histories.axaml b/src/Views/Histories.axaml index 4fd8909d..96340d1e 100644 --- a/src/Views/Histories.axaml +++ b/src/Views/Histories.axaml @@ -195,7 +195,7 @@ - + Date: Mon, 7 Apr 2025 04:37:58 +0200 Subject: [PATCH 450/865] In Local Changes, added filter-box in Staged area, to match Unstaged area (#1153) Also added minimal handling (RaiseException) if trying to commit with active filter (might commit more changes than visible, so disallow). Minor unification in unstageChanges() to make it more similar to StageChanges(). --- src/ViewModels/WorkingCopy.cs | 70 ++++++++++++++++++++++++++++------- src/Views/WorkingCopy.axaml | 39 +++++++++++++++++-- 2 files changed, 92 insertions(+), 17 deletions(-) diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 40b4c50c..3e6f6fbd 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -109,12 +109,28 @@ namespace SourceGit.ViewModels if (_isLoadingData) return; - VisibleUnstaged = GetVisibleUnstagedChanges(_unstaged); + VisibleUnstaged = GetVisibleChanges(_unstaged, _unstagedFilter); SelectedUnstaged = []; } } } + public string StagedFilter + { + get => _stagedFilter; + set + { + if (SetProperty(ref _stagedFilter, value)) + { + if (_isLoadingData) + return; + + VisibleStaged = GetVisibleChanges(_staged, _stagedFilter); + SelectedStaged = []; + } + } + } + public List Unstaged { get => _unstaged; @@ -133,6 +149,12 @@ namespace SourceGit.ViewModels private set => SetProperty(ref _staged, value); } + public List VisibleStaged + { + get => _visibleStaged; + private set => SetProperty(ref _visibleStaged, value); + } + public List SelectedUnstaged { get => _selectedUnstaged; @@ -216,6 +238,9 @@ namespace SourceGit.ViewModels _visibleUnstaged.Clear(); OnPropertyChanged(nameof(VisibleUnstaged)); + _visibleStaged.Clear(); + OnPropertyChanged(nameof(VisibleStaged)); + _unstaged.Clear(); OnPropertyChanged(nameof(Unstaged)); @@ -269,7 +294,7 @@ namespace SourceGit.ViewModels } } - var visibleUnstaged = GetVisibleUnstagedChanges(unstaged); + var visibleUnstaged = GetVisibleChanges(unstaged, _unstagedFilter); var selectedUnstaged = new List(); foreach (var c in visibleUnstaged) { @@ -278,8 +303,10 @@ namespace SourceGit.ViewModels } var staged = GetStagedChanges(); + + var visibleStaged = GetVisibleChanges(staged, _stagedFilter); var selectedStaged = new List(); - foreach (var c in staged) + foreach (var c in visibleStaged) { if (lastSelectedStaged.Contains(c.Path)) selectedStaged.Add(c); @@ -290,6 +317,7 @@ namespace SourceGit.ViewModels _isLoadingData = true; HasUnsolvedConflicts = hasConflict; VisibleUnstaged = visibleUnstaged; + VisibleStaged = visibleStaged; Unstaged = unstaged; Staged = staged; SelectedUnstaged = selectedUnstaged; @@ -337,7 +365,7 @@ namespace SourceGit.ViewModels public void UnstageAll() { - UnstageChanges(_staged, null); + UnstageChanges(_visibleStaged, null); } public void Discard(List changes) @@ -350,6 +378,11 @@ namespace SourceGit.ViewModels { UnstagedFilter = string.Empty; } + + public void ClearStagedFilter() + { + StagedFilter = string.Empty; + } public async void UseTheirs(List changes) { @@ -1472,16 +1505,16 @@ namespace SourceGit.ViewModels return menu; } - private List GetVisibleUnstagedChanges(List unstaged) + private List GetVisibleChanges(List changes, string filter) { - if (string.IsNullOrEmpty(_unstagedFilter)) - return unstaged; + if (string.IsNullOrEmpty(filter)) + return changes; var visible = new List(); - foreach (var c in unstaged) + foreach (var c in changes) { - if (c.Path.Contains(_unstagedFilter, StringComparison.OrdinalIgnoreCase)) + if (c.Path.Contains(filter, StringComparison.OrdinalIgnoreCase)) visible.Add(c); } @@ -1599,7 +1632,8 @@ namespace SourceGit.ViewModels private async void UnstageChanges(List changes, Models.Change next) { - if (changes.Count == 0) + var count = changes.Count; + if (count == 0) return; // Use `_selectedStaged` instead of `SelectedStaged` to avoid UI refresh. @@ -1611,16 +1645,15 @@ namespace SourceGit.ViewModels { await Task.Run(() => new Commands.UnstageChangesForAmend(_repo.FullPath, changes).Exec()); } - else if (changes.Count == _staged.Count) + else if (count == _staged.Count) { await Task.Run(() => new Commands.Reset(_repo.FullPath).Exec()); } else { - for (int i = 0; i < changes.Count; i += 10) + for (int i = 0; i < count; i += 10) { - var count = Math.Min(10, changes.Count - i); - var step = changes.GetRange(i, count); + var step = changes.GetRange(i, Math.Min(10, count - i)); await Task.Run(() => new Commands.Reset(_repo.FullPath, step).Exec()); } } @@ -1650,6 +1683,13 @@ namespace SourceGit.ViewModels return; } + if (!string.IsNullOrEmpty(_stagedFilter)) + { + // FIXME - make this a proper warning message-box "Staged-area filter will not be applied to commit. Continue?" Yes/No + App.RaiseException(_repo.FullPath, "Committing with staged-area filter applied is NOT allowed!"); + return; + } + if (string.IsNullOrWhiteSpace(_commitMessage)) { App.RaiseException(_repo.FullPath, "Commit without message is NOT allowed!"); @@ -1729,11 +1769,13 @@ namespace SourceGit.ViewModels private List _unstaged = []; private List _visibleUnstaged = []; private List _staged = []; + private List _visibleStaged = []; private List _selectedUnstaged = []; private List _selectedStaged = []; private int _count = 0; private object _detailContext = null; private string _unstagedFilter = string.Empty; + private string _stagedFilter = string.Empty; private string _commitMessage = string.Empty; private bool _hasUnsolvedConflicts = false; diff --git a/src/Views/WorkingCopy.axaml b/src/Views/WorkingCopy.axaml index 4d79135d..6af2b448 100644 --- a/src/Views/WorkingCopy.axaml +++ b/src/Views/WorkingCopy.axaml @@ -129,7 +129,7 @@ Background="{DynamicResource Brush.Border0}"/> - + @@ -156,14 +156,47 @@ + + + + + + + + + + + + + - Date: Mon, 7 Apr 2025 11:45:14 +0800 Subject: [PATCH 451/865] code_review: PR #1153 - use a single filter for both unstage and staged files - show confirm dialog if staged files are displayed partially Signed-off-by: leo --- src/Resources/Locales/en_US.axaml | 1 + src/Resources/Locales/zh_CN.axaml | 1 + src/Resources/Locales/zh_TW.axaml | 1 + src/ViewModels/ConfirmCommit.cs | 26 +++++ src/ViewModels/ConfirmCommitWithoutFiles.cs | 19 ---- src/ViewModels/WorkingCopy.cs | 75 +++++------- ...WithoutFiles.axaml => ConfirmCommit.axaml} | 6 +- ...tFiles.axaml.cs => ConfirmCommit.axaml.cs} | 10 +- src/Views/WorkingCopy.axaml | 107 +++++++----------- 9 files changed, 103 insertions(+), 143 deletions(-) create mode 100644 src/ViewModels/ConfirmCommit.cs delete mode 100644 src/ViewModels/ConfirmCommitWithoutFiles.cs rename src/Views/{ConfirmCommitWithoutFiles.axaml => ConfirmCommit.axaml} (92%) rename src/Views/{ConfirmCommitWithoutFiles.axaml.cs => ConfirmCommit.axaml.cs} (57%) diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 5ff1e3a4..61140173 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -719,6 +719,7 @@ Trigger click event Commit (Edit) Stage all changes and commit + You have staged {0} file(s) but only {1} file(s) displayed ({2} files are filtered out). Do you want to continue? Empty commit detected! Do you want to continue (--allow-empty)? CONFLICTS DETECTED FILE CONFLICTS ARE RESOLVED diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 8d2b4f1e..fec5c780 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -723,6 +723,7 @@ 触发点击事件 提交(修改原始提交) 自动暂存所有变更并提交 + 当前有 {0} 个文件在暂存区中,但仅显示了 {1} 个文件({2} 个文件被过滤掉了),是否继续提交? 提交未包含变更文件!是否继续(--allow-empty)? 检测到冲突 文件冲突已解决 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 8e823f68..66bcc33a 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -722,6 +722,7 @@ 觸發點擊事件 提交 (修改原始提交) 自動暫存全部變更並提交 + 您已暫存 {0} 檔案,但只顯示 {1} 檔案 ({2} 檔案被篩選器隱藏)。您要繼續嗎? 未包含任何檔案變更! 您是否仍要提交 (--allow-empty)? 檢測到衝突 檔案衝突已解決 diff --git a/src/ViewModels/ConfirmCommit.cs b/src/ViewModels/ConfirmCommit.cs new file mode 100644 index 00000000..cea56948 --- /dev/null +++ b/src/ViewModels/ConfirmCommit.cs @@ -0,0 +1,26 @@ +using System; + +namespace SourceGit.ViewModels +{ + public class ConfirmCommit + { + public string Message + { + get; + private set; + } + + public ConfirmCommit(string message, Action onSure) + { + Message = message; + _onSure = onSure; + } + + public void Continue() + { + _onSure?.Invoke(); + } + + private Action _onSure; + } +} diff --git a/src/ViewModels/ConfirmCommitWithoutFiles.cs b/src/ViewModels/ConfirmCommitWithoutFiles.cs deleted file mode 100644 index 3249fba8..00000000 --- a/src/ViewModels/ConfirmCommitWithoutFiles.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace SourceGit.ViewModels -{ - public class ConfirmCommitWithoutFiles - { - public ConfirmCommitWithoutFiles(WorkingCopy wc, bool autoPush) - { - _wc = wc; - _autoPush = autoPush; - } - - public void Continue() - { - _wc.CommitWithoutFiles(_autoPush); - } - - private readonly WorkingCopy _wc; - private bool _autoPush; - } -} diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 3e6f6fbd..a0933ea3 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -99,38 +99,23 @@ namespace SourceGit.ViewModels } } - public string UnstagedFilter + public string Filter { - get => _unstagedFilter; + get => _filter; set { - if (SetProperty(ref _unstagedFilter, value)) + if (SetProperty(ref _filter, value)) { if (_isLoadingData) return; - VisibleUnstaged = GetVisibleChanges(_unstaged, _unstagedFilter); + VisibleUnstaged = GetVisibleChanges(_unstaged); + VisibleStaged = GetVisibleChanges(_staged); SelectedUnstaged = []; } } } - public string StagedFilter - { - get => _stagedFilter; - set - { - if (SetProperty(ref _stagedFilter, value)) - { - if (_isLoadingData) - return; - - VisibleStaged = GetVisibleChanges(_staged, _stagedFilter); - SelectedStaged = []; - } - } - } - public List Unstaged { get => _unstaged; @@ -294,7 +279,7 @@ namespace SourceGit.ViewModels } } - var visibleUnstaged = GetVisibleChanges(unstaged, _unstagedFilter); + var visibleUnstaged = GetVisibleChanges(unstaged); var selectedUnstaged = new List(); foreach (var c in visibleUnstaged) { @@ -304,7 +289,7 @@ namespace SourceGit.ViewModels var staged = GetStagedChanges(); - var visibleStaged = GetVisibleChanges(staged, _stagedFilter); + var visibleStaged = GetVisibleChanges(staged); var selectedStaged = new List(); foreach (var c in visibleStaged) { @@ -374,14 +359,9 @@ namespace SourceGit.ViewModels _repo.ShowPopup(new Discard(_repo, changes)); } - public void ClearUnstagedFilter() + public void ClearFilter() { - UnstagedFilter = string.Empty; - } - - public void ClearStagedFilter() - { - StagedFilter = string.Empty; + Filter = string.Empty; } public async void UseTheirs(List changes) @@ -571,11 +551,6 @@ namespace SourceGit.ViewModels DoCommit(false, true, false); } - public void CommitWithoutFiles(bool autoPush) - { - DoCommit(false, autoPush, true); - } - public ContextMenu CreateContextMenuForUnstagedChanges() { if (_selectedUnstaged == null || _selectedUnstaged.Count == 0) @@ -1505,16 +1480,16 @@ namespace SourceGit.ViewModels return menu; } - private List GetVisibleChanges(List changes, string filter) + private List GetVisibleChanges(List changes) { - if (string.IsNullOrEmpty(filter)) + if (string.IsNullOrEmpty(_filter)) return changes; var visible = new List(); foreach (var c in changes) { - if (c.Path.Contains(filter, StringComparison.OrdinalIgnoreCase)) + if (c.Path.Contains(_filter, StringComparison.OrdinalIgnoreCase)) visible.Add(c); } @@ -1675,7 +1650,7 @@ namespace SourceGit.ViewModels DetailContext = new DiffContext(_repo.FullPath, new Models.DiffOption(change, isUnstaged), _detailContext as DiffContext); } - private void DoCommit(bool autoStage, bool autoPush, bool allowEmpty) + private void DoCommit(bool autoStage, bool autoPush, bool allowEmpty = false, bool confirmWithFilter = false) { if (!_repo.CanCreatePopup()) { @@ -1683,10 +1658,17 @@ namespace SourceGit.ViewModels return; } - if (!string.IsNullOrEmpty(_stagedFilter)) + if (!string.IsNullOrEmpty(_filter) && _staged.Count > _visibleStaged.Count && !confirmWithFilter) { - // FIXME - make this a proper warning message-box "Staged-area filter will not be applied to commit. Continue?" Yes/No - App.RaiseException(_repo.FullPath, "Committing with staged-area filter applied is NOT allowed!"); + var confirmMessage = App.Text("WorkingCopy.ConfirmCommitWithFilter", _staged.Count, _visibleStaged.Count, _staged.Count - _visibleStaged.Count); + App.OpenDialog(new Views.ConfirmCommit() + { + DataContext = new ConfirmCommit(confirmMessage, () => + { + DoCommit(autoStage, autoPush, allowEmpty, true); + }) + }); + return; } @@ -1700,9 +1682,13 @@ namespace SourceGit.ViewModels { if ((autoStage && _count == 0) || (!autoStage && _staged.Count == 0)) { - App.OpenDialog(new Views.ConfirmCommitWithoutFiles() + var confirmMessage = App.Text("WorkingCopy.ConfirmCommitWithoutFiles"); + App.OpenDialog(new Views.ConfirmCommit() { - DataContext = new ConfirmCommitWithoutFiles(this, autoPush) + DataContext = new ConfirmCommit(confirmMessage, () => + { + DoCommit(autoStage, autoPush, true, confirmWithFilter); + }) }); return; @@ -1774,8 +1760,7 @@ namespace SourceGit.ViewModels private List _selectedStaged = []; private int _count = 0; private object _detailContext = null; - private string _unstagedFilter = string.Empty; - private string _stagedFilter = string.Empty; + private string _filter = string.Empty; private string _commitMessage = string.Empty; private bool _hasUnsolvedConflicts = false; diff --git a/src/Views/ConfirmCommitWithoutFiles.axaml b/src/Views/ConfirmCommit.axaml similarity index 92% rename from src/Views/ConfirmCommitWithoutFiles.axaml rename to src/Views/ConfirmCommit.axaml index 4c9fd1c8..77bbdb30 100644 --- a/src/Views/ConfirmCommitWithoutFiles.axaml +++ b/src/Views/ConfirmCommit.axaml @@ -5,8 +5,8 @@ xmlns:v="using:SourceGit.Views" xmlns:vm="using:SourceGit.ViewModels" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" - x:Class="SourceGit.Views.ConfirmCommitWithoutFiles" - x:DataType="vm:ConfirmCommitWithoutFiles" + x:Class="SourceGit.Views.ConfirmCommit" + x:DataType="vm:ConfirmCommit" x:Name="ThisControl" Icon="/App.ico" Title="{DynamicResource Text.Warn}" @@ -38,7 +38,7 @@ - + diff --git a/src/Views/ConfirmCommitWithoutFiles.axaml.cs b/src/Views/ConfirmCommit.axaml.cs similarity index 57% rename from src/Views/ConfirmCommitWithoutFiles.axaml.cs rename to src/Views/ConfirmCommit.axaml.cs index 342600fc..1cf770cb 100644 --- a/src/Views/ConfirmCommitWithoutFiles.axaml.cs +++ b/src/Views/ConfirmCommit.axaml.cs @@ -2,20 +2,16 @@ using Avalonia.Interactivity; namespace SourceGit.Views { - public partial class ConfirmCommitWithoutFiles : ChromelessWindow + public partial class ConfirmCommit : ChromelessWindow { - public ConfirmCommitWithoutFiles() + public ConfirmCommit() { InitializeComponent(); } private void Sure(object _1, RoutedEventArgs _2) { - if (DataContext is ViewModels.ConfirmCommitWithoutFiles vm) - { - vm.Continue(); - } - + (DataContext as ViewModels.ConfirmCommit)?.Continue(); Close(); } diff --git a/src/Views/WorkingCopy.axaml b/src/Views/WorkingCopy.axaml index 6af2b448..94dd0c30 100644 --- a/src/Views/WorkingCopy.axaml +++ b/src/Views/WorkingCopy.axaml @@ -19,13 +19,46 @@ + + + + + + + + + + + + + + - + @@ -75,40 +108,8 @@ - - - - - - - - - - - - - - - - + @@ -155,41 +156,9 @@ ViewMode="{Binding Source={x:Static vm:Preferences.Instance}, Path=StagedChangeViewMode, Mode=TwoWay}"/> - - - - - - - - - - - - - - Date: Mon, 7 Apr 2025 03:48:59 +0000 Subject: [PATCH 452/865] doc: Update translation status and missing keys --- TRANSLATION.md | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/TRANSLATION.md b/TRANSLATION.md index b344e6a3..6ebb72c1 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -6,7 +6,7 @@ This document shows the translation status of each locale file in the repository ### ![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen) -### ![de__DE](https://img.shields.io/badge/de__DE-98.65%25-yellow) +### ![de__DE](https://img.shields.io/badge/de__DE-98.52%25-yellow)
Missing keys in de_DE.axaml @@ -21,34 +21,51 @@ This document shows the translation status of each locale file in the repository - Text.Preferences.Appearance.EditorTabWidth - Text.Preferences.General.ShowTagsInGraph - Text.StashCM.SaveAsPatch +- Text.WorkingCopy.ConfirmCommitWithFilter
-### ![es__ES](https://img.shields.io/badge/es__ES-%E2%88%9A-brightgreen) +### ![es__ES](https://img.shields.io/badge/es__ES-99.87%25-yellow) -### ![fr__FR](https://img.shields.io/badge/fr__FR-%E2%88%9A-brightgreen) +
+Missing keys in es_ES.axaml -### ![it__IT](https://img.shields.io/badge/it__IT-99.73%25-yellow) +- Text.WorkingCopy.ConfirmCommitWithFilter + +
+ +### ![fr__FR](https://img.shields.io/badge/fr__FR-99.87%25-yellow) + +
+Missing keys in fr_FR.axaml + +- Text.WorkingCopy.ConfirmCommitWithFilter + +
+ +### ![it__IT](https://img.shields.io/badge/it__IT-99.60%25-yellow)
Missing keys in it_IT.axaml - Text.CopyFullPath - Text.Preferences.General.ShowTagsInGraph +- Text.WorkingCopy.ConfirmCommitWithFilter
-### ![ja__JP](https://img.shields.io/badge/ja__JP-99.73%25-yellow) +### ![ja__JP](https://img.shields.io/badge/ja__JP-99.60%25-yellow)
Missing keys in ja_JP.axaml - Text.Repository.FilterCommits - Text.Repository.Tags.OrderByNameDes +- Text.WorkingCopy.ConfirmCommitWithFilter
-### ![pt__BR](https://img.shields.io/badge/pt__BR-90.98%25-yellow) +### ![pt__BR](https://img.shields.io/badge/pt__BR-90.86%25-yellow)
Missing keys in pt_BR.axaml @@ -119,11 +136,19 @@ This document shows the translation status of each locale file in the repository - Text.Stash.AutoRestore.Tip - Text.StashCM.SaveAsPatch - Text.WorkingCopy.CommitToEdit +- Text.WorkingCopy.ConfirmCommitWithFilter - Text.WorkingCopy.SignOff
-### ![ru__RU](https://img.shields.io/badge/ru__RU-%E2%88%9A-brightgreen) +### ![ru__RU](https://img.shields.io/badge/ru__RU-99.87%25-yellow) + +
+Missing keys in ru_RU.axaml + +- Text.WorkingCopy.ConfirmCommitWithFilter + +
### ![zh__CN](https://img.shields.io/badge/zh__CN-%E2%88%9A-brightgreen) From b65c697e5b6e9af4c3f82a252fbf97a6f4582c68 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 7 Apr 2025 12:00:45 +0800 Subject: [PATCH 453/865] version: Release 2025.12 Signed-off-by: leo --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 75c26f38..8283ecf3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2025.11 \ No newline at end of file +2025.12 \ No newline at end of file From 39f7f119dd7784f10c9b462d1cc284c22b981423 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 7 Apr 2025 12:06:06 +0800 Subject: [PATCH 454/865] doc: always show current translation status in `develop` branch Signed-off-by: leo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aacf222e..75af9d2c 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ ## Translation Status -You can find the current translation status in [TRANSLATION.md](TRANSLATION.md) +You can find the current translation status in [TRANSLATION.md](https://github.com/sourcegit-scm/sourcegit/blob/develop/TRANSLATION.md) ## How to Use From ad9021e8920815198d655faa76abbcfdc1ca5f6c Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 7 Apr 2025 14:07:58 +0800 Subject: [PATCH 455/865] enhance: allow using `+` character in branch name (#1152) Signed-off-by: leo --- src/ViewModels/CreateBranch.cs | 2 +- src/ViewModels/RenameBranch.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ViewModels/CreateBranch.cs b/src/ViewModels/CreateBranch.cs index 37db0065..6d7fe27a 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 { diff --git a/src/ViewModels/RenameBranch.cs b/src/ViewModels/RenameBranch.cs index 0679a5b5..f78eb46b 100644 --- a/src/ViewModels/RenameBranch.cs +++ b/src/ViewModels/RenameBranch.cs @@ -12,7 +12,7 @@ namespace SourceGit.ViewModels } [Required(ErrorMessage = "Branch name is required!!!")] - [RegularExpression(@"^[\w \-/\.#]+$", ErrorMessage = "Bad branch name format!")] + [RegularExpression(@"^[\w \-/\.#\+]+$", ErrorMessage = "Bad branch name format!")] [CustomValidation(typeof(RenameBranch), nameof(ValidateBranchName))] public string Name { From 3049730dd5c0acee68af771a9d3fa44a874a1ee9 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 7 Apr 2025 14:42:46 +0800 Subject: [PATCH 456/865] feature: add `Preferred Merge Mode` in repository configure (#1156) Signed-off-by: leo --- src/Models/RepositorySettings.cs | 6 ++++ src/Resources/Locales/en_US.axaml | 1 + src/Resources/Locales/zh_CN.axaml | 1 + src/Resources/Locales/zh_TW.axaml | 1 + src/ViewModels/Merge.cs | 9 +++-- src/ViewModels/RepositoryConfigure.cs | 13 +++++++ src/Views/RepositoryConfigure.axaml | 52 ++++++++++++++++++++++----- 7 files changed, 73 insertions(+), 10 deletions(-) diff --git a/src/Models/RepositorySettings.cs b/src/Models/RepositorySettings.cs index 76a7f160..1d326a5e 100644 --- a/src/Models/RepositorySettings.cs +++ b/src/Models/RepositorySettings.cs @@ -224,6 +224,12 @@ namespace SourceGit.Models set; } = []; + public int PreferredMergeMode + { + get; + set; + } = 0; + public Dictionary CollectHistoriesFilters() { var map = new Dictionary(); diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 61140173..d1e32e84 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -153,6 +153,7 @@ Fetch remotes automatically Minute(s) Default Remote + Preferred Merge Mode ISSUE TRACKER Add Sample Gitee Issue Rule Add Sample Gitee Pull Request Rule diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index fec5c780..932f1237 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -156,6 +156,7 @@ 启用定时自动拉取远程更新 分钟 默认远程 + 默认合并方式 ISSUE追踪 新增匹配Azure DevOps规则 新增匹配Gitee议题规则 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 66bcc33a..88b0ab64 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -156,6 +156,7 @@ 啟用定時自動提取 (fetch) 遠端更新 分鐘 預設遠端存放庫 + 首選合併模式 Issue 追蹤 新增符合 Azure DevOps 規則 新增符合 Gitee 議題規則 diff --git a/src/ViewModels/Merge.cs b/src/ViewModels/Merge.cs index be938867..faadaf57 100644 --- a/src/ViewModels/Merge.cs +++ b/src/ViewModels/Merge.cs @@ -69,9 +69,14 @@ namespace SourceGit.ViewModels private Models.MergeMode AutoSelectMergeMode() { + var preferredMergeModeIdx = _repo.Settings.PreferredMergeMode; + if (preferredMergeModeIdx < 0 || preferredMergeModeIdx > Models.MergeMode.Supported.Length) + preferredMergeModeIdx = 0; + + var defaultMergeMode = Models.MergeMode.Supported[preferredMergeModeIdx]; var config = new Commands.Config(_repo.FullPath).Get($"branch.{Into}.mergeoptions"); if (string.IsNullOrEmpty(config)) - return Models.MergeMode.Supported[0]; + return defaultMergeMode; if (config.Equals("--ff-only", StringComparison.Ordinal)) return Models.MergeMode.Supported[1]; if (config.Equals("--no-ff", StringComparison.Ordinal)) @@ -81,7 +86,7 @@ namespace SourceGit.ViewModels if (config.Equals("--no-commit", StringComparison.Ordinal) || config.Equals("--no-ff --no-commit", StringComparison.Ordinal)) return Models.MergeMode.Supported[4]; - return Models.MergeMode.Supported[0]; + return defaultMergeMode; } private readonly Repository _repo = null; diff --git a/src/ViewModels/RepositoryConfigure.cs b/src/ViewModels/RepositoryConfigure.cs index 3f590758..9a3bc9c4 100644 --- a/src/ViewModels/RepositoryConfigure.cs +++ b/src/ViewModels/RepositoryConfigure.cs @@ -36,6 +36,19 @@ namespace SourceGit.ViewModels } } + public int PreferredMergeMode + { + get => _repo.Settings.PreferredMergeMode; + set + { + if (_repo.Settings.PreferredMergeMode != value) + { + _repo.Settings.PreferredMergeMode = value; + OnPropertyChanged(); + } + } + } + public bool GPGCommitSigningEnabled { get; diff --git a/src/Views/RepositoryConfigure.axaml b/src/Views/RepositoryConfigure.axaml index e41375b9..ee1d6fa8 100644 --- a/src/Views/RepositoryConfigure.axaml +++ b/src/Views/RepositoryConfigure.axaml @@ -44,7 +44,7 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + From 67fb0b300f90e6582a5343888fb0a719ab7fd197 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 7 Apr 2025 06:43:08 +0000 Subject: [PATCH 457/865] doc: Update translation status and missing keys --- TRANSLATION.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/TRANSLATION.md b/TRANSLATION.md index 6ebb72c1..0f44cbcf 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -6,13 +6,14 @@ This document shows the translation status of each locale file in the repository ### ![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen) -### ![de__DE](https://img.shields.io/badge/de__DE-98.52%25-yellow) +### ![de__DE](https://img.shields.io/badge/de__DE-98.39%25-yellow)
Missing keys in de_DE.axaml - Text.BranchUpstreamInvalid - Text.Configure.CustomAction.WaitForExit +- Text.Configure.Git.PreferredMergeMode - Text.Configure.IssueTracker.AddSampleAzure - Text.CopyFullPath - Text.Diff.First @@ -25,47 +26,51 @@ This document shows the translation status of each locale file in the repository
-### ![es__ES](https://img.shields.io/badge/es__ES-99.87%25-yellow) +### ![es__ES](https://img.shields.io/badge/es__ES-99.73%25-yellow)
Missing keys in es_ES.axaml +- Text.Configure.Git.PreferredMergeMode - Text.WorkingCopy.ConfirmCommitWithFilter
-### ![fr__FR](https://img.shields.io/badge/fr__FR-99.87%25-yellow) +### ![fr__FR](https://img.shields.io/badge/fr__FR-99.73%25-yellow)
Missing keys in fr_FR.axaml +- Text.Configure.Git.PreferredMergeMode - Text.WorkingCopy.ConfirmCommitWithFilter
-### ![it__IT](https://img.shields.io/badge/it__IT-99.60%25-yellow) +### ![it__IT](https://img.shields.io/badge/it__IT-99.46%25-yellow)
Missing keys in it_IT.axaml +- Text.Configure.Git.PreferredMergeMode - Text.CopyFullPath - Text.Preferences.General.ShowTagsInGraph - Text.WorkingCopy.ConfirmCommitWithFilter
-### ![ja__JP](https://img.shields.io/badge/ja__JP-99.60%25-yellow) +### ![ja__JP](https://img.shields.io/badge/ja__JP-99.46%25-yellow)
Missing keys in ja_JP.axaml +- Text.Configure.Git.PreferredMergeMode - Text.Repository.FilterCommits - Text.Repository.Tags.OrderByNameDes - Text.WorkingCopy.ConfirmCommitWithFilter
-### ![pt__BR](https://img.shields.io/badge/pt__BR-90.86%25-yellow) +### ![pt__BR](https://img.shields.io/badge/pt__BR-90.74%25-yellow)
Missing keys in pt_BR.axaml @@ -86,6 +91,7 @@ This document shows the translation status of each locale file in the repository - Text.CommitDetail.Info.Children - Text.Configure.CustomAction.Scope.Branch - Text.Configure.CustomAction.WaitForExit +- Text.Configure.Git.PreferredMergeMode - Text.Configure.IssueTracker.AddSampleGiteeIssue - Text.Configure.IssueTracker.AddSampleGiteePullRequest - Text.CopyFullPath @@ -141,11 +147,12 @@ This document shows the translation status of each locale file in the repository
-### ![ru__RU](https://img.shields.io/badge/ru__RU-99.87%25-yellow) +### ![ru__RU](https://img.shields.io/badge/ru__RU-99.73%25-yellow)
Missing keys in ru_RU.axaml +- Text.Configure.Git.PreferredMergeMode - Text.WorkingCopy.ConfirmCommitWithFilter
From 3275dd07d226c6c6dc4c6a75b1f83d53108fdcbb Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 7 Apr 2025 16:03:49 +0800 Subject: [PATCH 458/865] enhance: auto stash and re-apply local changes before squashing (#1141) Signed-off-by: leo --- src/ViewModels/Histories.cs | 12 ------------ src/ViewModels/Squash.cs | 21 ++++++++++++++++++++- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs index 01114dd3..b0bbff3c 100644 --- a/src/ViewModels/Histories.cs +++ b/src/ViewModels/Histories.cs @@ -419,12 +419,6 @@ namespace SourceGit.ViewModels squash.Icon = App.CreateMenuIcon("Icons.SquashIntoParent"); squash.Click += (_, e) => { - if (_repo.LocalChangesCount > 0) - { - App.RaiseException(_repo.FullPath, "You have local changes. Please run stash or discard first."); - return; - } - if (_repo.CanCreatePopup()) _repo.ShowPopup(new Squash(_repo, commit, commit.SHA)); @@ -458,12 +452,6 @@ namespace SourceGit.ViewModels squash.IsEnabled = commit.Parents.Count == 1; squash.Click += (_, e) => { - if (_repo.LocalChangesCount > 0) - { - App.RaiseException(_repo.FullPath, "You have local changes. Please run stash or discard first."); - return; - } - if (commit.Parents.Count == 1) { var parent = _commits.Find(x => x.SHA == commit.Parents[0]); diff --git a/src/ViewModels/Squash.cs b/src/ViewModels/Squash.cs index 198dbe9a..eceb8339 100644 --- a/src/ViewModels/Squash.cs +++ b/src/ViewModels/Squash.cs @@ -33,9 +33,28 @@ namespace SourceGit.ViewModels return Task.Run(() => { - var succ = new Commands.Reset(_repo.FullPath, Target.SHA, "--soft").Exec(); + var autoStashed = false; + var succ = false; + + if (_repo.LocalChangesCount > 0) + { + succ = new Commands.Stash(_repo.FullPath).Push("SQUASH_AUTO_STASH"); + if (!succ) + { + CallUIThread(() => _repo.SetWatcherEnabled(true)); + return false; + } + + autoStashed = true; + } + + succ = new Commands.Reset(_repo.FullPath, Target.SHA, "--soft").Exec(); if (succ) succ = new Commands.Commit(_repo.FullPath, _message, true, _repo.Settings.EnableSignOffForCommit).Run(); + + if (succ && autoStashed) + new Commands.Stash(_repo.FullPath).Pop("stash@{0}"); + CallUIThread(() => _repo.SetWatcherEnabled(true)); return succ; }); From f5c213060eb842a302713ba27178c0f0a0c6e37b Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 7 Apr 2025 20:05:24 +0800 Subject: [PATCH 459/865] localization: keep all keys in order and remove duplicated keys in fr_FR (#1161) Signed-off-by: leo --- src/Resources/Locales/de_DE.axaml | 69 +++++------ src/Resources/Locales/en_US.axaml | 2 +- src/Resources/Locales/es_ES.axaml | 71 +++++------ src/Resources/Locales/fr_FR.axaml | 188 ++++++++++++++---------------- src/Resources/Locales/it_IT.axaml | 73 ++++++------ src/Resources/Locales/ja_JP.axaml | 69 +++++------ src/Resources/Locales/pt_BR.axaml | 90 ++++++-------- src/Resources/Locales/ru_RU.axaml | 92 +++++++-------- src/Resources/Locales/zh_CN.axaml | 70 +++++------ src/Resources/Locales/zh_TW.axaml | 70 +++++------ 10 files changed, 377 insertions(+), 417 deletions(-) diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index bbfe4545..276f44e8 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -2,19 +2,20 @@ + Info Über SourceGit Open Source & freier Git GUI Client Worktree hinzufügen - Was auschecken: - Existierender Branch - Neuen Branch erstellen Ordner: Pfad für diesen Worktree. Relativer Pfad wird unterstützt. Branch Name: Optional. Standard ist der Zielordnername. Branch verfolgen: Remote-Branch verfolgen + Was auschecken: + Neuen Branch erstellen + Existierender Branch OpenAI Assistent Neu generieren Verwende OpenAI, um Commit-Nachrichten zu generieren @@ -63,8 +64,8 @@ Branch Vergleich Bytes ABBRECHEN - Auf diese Revision zurücksetzen Auf Vorgänger-Revision zurücksetzen + Auf diese Revision zurücksetzen Generiere Commit-Nachricht ANZEIGE MODUS ÄNDERN Zeige als Datei- und Ordnerliste @@ -72,12 +73,12 @@ Zeige als Dateisystembaum Branch auschecken Commit auschecken - Warnung: Beim Auschecken eines Commits wird dein HEAD losgelöst (detached) sein! Commit: - Branch: + Warnung: Beim Auschecken eines Commits wird dein HEAD losgelöst (detached) sein! Lokale Änderungen: Verwerfen Stashen & wieder anwenden + Branch: Cherry Pick Quelle an Commit-Nachricht anhängen Commit(s): @@ -96,9 +97,9 @@ Repository URL: SCHLIESSEN Editor + Commit auschecken Diesen Commit cherry-picken Mehrere cherry-picken - Commit auschecken Mit HEAD vergleichen Mit Worktree vergleichen Info kopieren @@ -133,12 +134,12 @@ REFS SHA Im Browser öffnen - Commit-Nachricht Details + Commit-Nachricht Repository Einstellungen COMMIT TEMPLATE - Template Name: Template Inhalt: + Template Name: BENUTZERDEFINIERTE AKTION Argumente: ${REPO} - Repository Pfad; ${SHA} - SHA-Wert des selektierten Commits @@ -158,9 +159,9 @@ Beispiel für Gitee Issue Regel einfügen Beispiel für Gitee Pull Request Regel einfügen Beispiel für Github-Regel hinzufügen - Beispiel für Jira-Regel hinzufügen Beispiel für Gitlab Issue Regel einfügen Beispiel für Gitlab Merge Request einfügen + Beispiel für Jira-Regel hinzufügen Neue Regel Ticketnummer Regex-Ausdruck: Name: @@ -220,9 +221,9 @@ Remote: Pfad: Ziel: - Bestätige löschen von Gruppe Alle Nachfolger werden aus der Liste entfernt. Dadurch wird es nur aus der Liste entfernt, nicht von der Festplatte! + Bestätige löschen von Gruppe Bestätige löschen von Repository Lösche Submodul Submodul Pfad: @@ -289,11 +290,11 @@ Unstage {0} Dateien unstagen Änderungen in ausgewählten Zeilen unstagen - "Ihre" verwenden (checkout --theirs) "Meine" verwenden (checkout --ours) + "Ihre" verwenden (checkout --theirs) Datei Historie - INHALT ÄNDERUNGEN + INHALT Git-Flow Development-Branch: Feature: @@ -323,8 +324,8 @@ Eigenes Muster: Verfolgungsmuster zu Git LFS hinzufügen Fetch - LFS Objekte fetchen Führt `git lfs fetch` aus um Git LFS Objekte herunterzuladen. Das aktualisiert nicht die Arbeitskopie. + LFS Objekte fetchen Installiere Git LFS Hooks Sperren anzeigen Keine gesperrten Dateien @@ -336,11 +337,11 @@ Prune Führt `git lfs prune` aus um alte LFS Dateien von lokalem Speicher zu löschen Pull - LFS Objekte pullen Führt `git lfs pull` aus um alle Git LFS Dasteien für aktuellen Ref & Checkout herunterzuladen + LFS Objekte pullen Push - LFS Objekte pushen Pushe große Dateien in der Warteschlange zum Git LFS Endpunkt + LFS Objekte pushen Remote: Verfolge alle '{0}' Dateien Verfolge alle *{0} Dateien @@ -359,8 +360,8 @@ Aktuelles Popup schließen Klone neues Repository Aktuellen Tab schließen - Zum vorherigen Tab wechseln Zum nächsten Tab wechseln + Zum vorherigen Tab wechseln Neuen Tab erstellen Einstellungen öffnen REPOSITORY @@ -371,11 +372,11 @@ Ausgewählte Änderungen verwerfen Fetch, wird direkt ausgeführt Dashboard Modus (Standard) + Commit-Suchmodus Pull, wird direkt ausgeführt Push, wird direkt ausgeführt Erzwinge Neuladen des Repositorys Ausgewählte Änderungen stagen/unstagen - Commit-Suchmodus Wechsle zu 'Änderungen' Wechsle zu 'Verlauf' Wechsle zu 'Stashes' @@ -384,9 +385,9 @@ Suche nächste Übereinstimmung Suche vorherige Übereinstimmung Öffne Suchpanel + Verwerfen Stagen Unstagen - Verwerfen Initialisiere Repository Pfad: Cherry-Pick wird durchgeführt. @@ -398,10 +399,10 @@ Revert wird durchgeführt. Reverte commit Interaktiver Rebase - Ziel Branch: Auf: - In Browser öffnen + Ziel Branch: Link kopieren + In Browser öffnen FEHLER INFO Branch mergen @@ -427,24 +428,24 @@ Kopiere Repository-Pfad Repositories Einfügen - Gerade eben - Vor {0} Minuten + Vor {0} Tagen Vor 1 Stunde Vor {0} Stunden - Gestern - Vor {0} Tagen + Gerade eben Letzter Monat - Vor {0} Monaten Leztes Jahr + Vor {0} Minuten + Vor {0} Monaten Vor {0} Jahren + Gestern Einstellungen OPEN AI Analysierung des Diff Befehl API Schlüssel Generiere Nachricht Befehl + Modell Name Server - Modell DARSTELLUNG Standardschriftart Schriftgröße @@ -474,24 +475,24 @@ Benutzer Email Globale Git Benutzer Email Aktivere --prune beim fetchen + Diese App setzt Git (>= 2.23.0) voraus Installationspfad Aktiviere HTTP SSL Verifizierung Benutzername Globaler Git Benutzername Git Version - Diese App setzt Git (>= 2.23.0) voraus GPG SIGNIERUNG Commit-Signierung - Tag-Signierung GPG Format GPG Installationspfad Installationspfad zum GPG Programm + Tag-Signierung Benutzer Signierungsschlüssel GPG Benutzer Signierungsschlüssel EINBINDUNGEN SHELL/TERMINAL - Shell/Terminal Pfad + Shell/Terminal Remote löschen Ziel: Worktrees löschen @@ -657,11 +658,11 @@ Statistiken COMMITS COMMITTER + ÜBERSICHT MONAT WOCHE - COMMITS: AUTOREN: - ÜBERSICHT + COMMITS: SUBMODULE Submodul hinzufügen Relativen Pfad kopieren @@ -676,13 +677,13 @@ Lösche ${0}$... Merge ${0}$ in ${1}$ hinein... Pushe ${0}$... - URL: Submodule aktualisieren Alle Submodule Initialisiere wenn nötig Rekursiv Submodul: Verwende `--remote` Option + URL: Warnung Willkommensseite Erstelle Gruppe @@ -718,6 +719,7 @@ NICHT-VERFOLGTE DATEIEN INKLUDIEREN KEINE BISHERIGEN COMMIT-NACHRICHTEN KEINE COMMIT TEMPLATES + Rechtsklick auf selektierte Dateien und wähle die Konfliktlösungen aus. SignOff GESTAGED UNSTAGEN @@ -727,7 +729,6 @@ ALLES STAGEN ALS UNVERÄNDERT ANGENOMMENE ANZEIGEN Template: ${0}$ - Rechtsklick auf selektierte Dateien und wähle die Konfliktlösungen aus. ARBEITSPLATZ: Arbeitsplätze konfigurieren... WORKTREE diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index d1e32e84..97b2a832 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -486,7 +486,7 @@ User Name Global git user name Git version - Git (>= 2.23.0) is required by this app + Git (>= 2.23.0) is required by this app GPG SIGNING Commit GPG signing Tag GPG signing diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index 8b4c350f..e6968560 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -2,19 +2,20 @@ + Acerca de Acerca de SourceGit Cliente Git GUI de código abierto y gratuito Agregar Worktree - Qué Checkout: - Rama Existente - Crear Nueva Rama Ubicación: Ruta para este worktree. Se admite ruta relativa. Nombre de la Rama: Opcional. Por defecto es el nombre de la carpeta de destino. Rama de Seguimiento: Seguimiento de rama remota + Qué Checkout: + Crear Nueva Rama + Rama Existente Asistente OpenAI RE-GENERAR Usar OpenAI para generar mensaje de commit @@ -64,8 +65,8 @@ ¡Upstream inválido! Bytes CANCELAR - Resetear a Esta Revisión Resetear a Revisión Padre + Resetear a Esta Revisión Generar mensaje de commit CAMBIAR MODO DE VISUALIZACIÓN Mostrar como Lista de Archivos y Directorios @@ -73,12 +74,12 @@ Mostrar como Árbol de Sistema de Archivos Checkout Rama Checkout Commit - Advertencia: Al hacer un checkout de commit, tu Head se separará Commit: - Rama: + Advertencia: Al hacer un checkout de commit, tu Head se separará Cambios Locales: Descartar Stash & Reaplicar + Rama: Cherry Pick Añadir fuente al mensaje de commit Commit(s): @@ -97,9 +98,9 @@ URL del Repositorio: CERRAR Editor + Checkout Commit Cherry-Pick Este Commit Cherry-Pick ... - Checkout Commit Comparar con HEAD Comparar con Worktree Copiar Información @@ -134,12 +135,12 @@ REFS SHA Abrir en Navegador - Introducir asunto del commit Descripción + Introducir asunto del commit Configurar Repositorio PLANTILLA DE COMMIT - Nombre de la Plantilla: Contenido de la Plantilla: + Nombre de la Plantilla: ACCIÓN PERSONALIZADA Argumentos: ${REPO} - Ruta del repositorio; ${SHA} - SHA del commit seleccionado @@ -157,13 +158,13 @@ Minuto(s) Remoto por Defecto SEGUIMIENTO DE INCIDENCIAS + Añadir Regla de Ejemplo para Azure DevOps Añadir Regla de Ejemplo para Incidencias de Gitee Añadir Regla de Ejemplo para Pull Requests de Gitee Añadir Regla de Ejemplo para Github - Añadir Regla de Ejemplo para Jira - Añadir Regla de Ejemplo para Azure DevOps Añadir Regla de Ejemplo para Incidencias de GitLab Añadir Regla de Ejemplo para Merge Requests de GitLab + Añadir Regla de Ejemplo para Jira Nueva Regla Expresión Regex para Incidencias: Nombre de la Regla: @@ -188,8 +189,8 @@ Tipo de Cambio: Copiar Copiar Todo el Texto - Copiar Ruta Copiar Ruta Completa + Copiar Ruta Crear Rama... Basado En: Checkout de la rama creada @@ -225,8 +226,8 @@ Ruta: Destino: Todos los hijos serán removidos de la lista. - Confirmar Eliminación de Grupo ¡Esto solo lo removera de la lista, no del disco! + Confirmar Eliminación de Grupo Confirmar Eliminación de Repositorio Eliminar Submódulo Ruta del Submódulo: @@ -295,11 +296,11 @@ Unstage Unstage {0} archivos Unstage Cambios en Línea(s) Seleccionada(s) - Usar Suyos (checkout --theirs) Usar Míos (checkout --ours) + Usar Suyos (checkout --theirs) Historial de Archivos - CONTENIDO CAMBIO + CONTENIDO Git-Flow Rama de Desarrollo: Feature: @@ -329,8 +330,8 @@ Patrón Personalizado: Añadir Patrón de Seguimiento a Git LFS Fetch - Fetch Objetos LFS Ejecuta `git lfs fetch` para descargar objetos Git LFS. Esto no actualiza la copia de trabajo. + Fetch Objetos LFS Instalar hooks de Git LFS Mostrar Bloqueos No hay archivos bloqueados @@ -342,11 +343,11 @@ Prune Ejecuta `git lfs prune` para eliminar archivos LFS antiguos del almacenamiento local Pull - Pull Objetos LFS Ejecuta `git lfs pull` para descargar todos los archivos Git LFS para la referencia actual y hacer checkout + Pull Objetos LFS Push - Push Objetos LFS Push archivos grandes en cola al endpoint de Git LFS + Push Objetos LFS Remoto: Seguir archivos llamados '{0}' Seguir todos los archivos *{0} @@ -365,8 +366,8 @@ Cancelar popup actual Clonar repositorio nuevo Cerrar página actual - Ir a la página anterior Ir a la siguiente página + Ir a la página anterior Crear nueva página Abrir diálogo de preferencias REPOSITORIO @@ -377,11 +378,11 @@ Descartar cambios seleccionados Fetch, empieza directamente Modo Dashboard (Por Defecto) + Modo de búsqueda de commits Pull, empieza directamente Push, empieza directamente Forzar a recargar este repositorio Stage/Unstage cambios seleccionados - Modo de búsqueda de commits Cambiar a 'Cambios' Cambiar a 'Historias' Cambiar a 'Stashes' @@ -390,9 +391,9 @@ Buscar siguiente coincidencia Buscar coincidencia anterior Abrir panel de búsqueda + Descartar Stage Unstage - Descartar Inicializar Repositorio Ruta: Cherry-Pick en progreso. @@ -404,10 +405,10 @@ Revert en progreso. Haciendo revert del commit Rebase Interactivo - Rama Objetivo: En: - Abrir en el Navegador + Rama Objetivo: Copiar Enlace + Abrir en el Navegador ERROR AVISO Merge Rama @@ -433,16 +434,16 @@ Copiar Ruta del Repositorio Repositorios Pegar - Justo ahora - Hace {0} minutos + Hace {0} días Hace 1 hora Hace {0} horas - Ayer - Hace {0} días + Justo ahora Último mes - Hace {0} meses Último año + Hace {0} minutos + Hace {0} meses Hace {0} años + Ayer Preferencias Opciones Avanzadas OPEN AI @@ -484,24 +485,24 @@ Email de usuario Email global del usuario git Habilitar --prune para fetch + Se requiere Git (>= 2.23.0) para esta aplicación Ruta de instalación Habilitar verificación HTTP SSL Nombre de usuario Nombre global del usuario git Versión de Git - Se requiere Git (>= 2.23.0) para esta aplicación FIRMA GPG Firma GPG en commit - Firma GPG en etiqueta Formato GPG Ruta de instalación del programa Introducir ruta para el programa gpg instalado + Firma GPG en etiqueta Clave de firma del usuario Clave de firma gpg del usuario INTEGRACIÓN SHELL/TERMINAL - Shell/Terminal Ruta + Shell/Terminal Podar Remoto Destino: Podar Worktrees @@ -668,11 +669,11 @@ Estadísticas COMMITS COMMITTER + GENERAL MES SEMANA - COMMITS: AUTORES: - GENERAL + COMMITS: SUBMÓDULOS Añadir Submódulo Copiar Ruta Relativa @@ -687,13 +688,13 @@ Eliminar ${0}$... Merge ${0}$ en ${1}$... Push ${0}$... - URL: Actualizar Submódulos Todos los submódulos Inicializar según sea necesario Recursivamente Submódulo: Usar opción --remote + URL: Advertencia Página de Bienvenida Crear Grupo @@ -729,6 +730,7 @@ INCLUIR ARCHIVOS NO RASTREADOS NO HAY MENSAJES DE ENTRADA RECIENTES NO HAY PLANTILLAS DE COMMIT + Haz clic derecho en el(los) archivo(s) seleccionado(s) y elige tu opción para resolver conflictos. Firmar STAGED UNSTAGE @@ -738,7 +740,6 @@ STAGE TODO VER ASSUME UNCHANGED Plantilla: ${0}$ - Haz clic derecho en el(los) archivo(s) seleccionado(s) y elige tu opción para resolver conflictos. ESPACIO DE TRABAJO: Configura Espacios de Trabajo... WORKTREE diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index bf238aa2..f3cf80eb 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -2,21 +2,22 @@ + À propos À propos de SourceGit Client Git Open Source et Gratuit Ajouter un Worktree - Que récupérer : - Créer une nouvelle branche - Branche existante Emplacement : Chemin vers ce worktree. Relatif supporté. Nom de branche: Optionnel. Nom du dossier de destination par défaut. Suivre la branche : Suivi de la branche distante + Que récupérer : + Créer une nouvelle branche + Branche existante Assistant IA - RE-GÉNERER + RE-GÉNÉRER Utiliser l'IA pour générer un message de commit APPLIQUER COMME MESSAGE DE COMMIT Appliquer @@ -61,7 +62,7 @@ Renommer ${0}$... Définir la branche de suivi... Comparer les branches - Branche amont invalide ! + Branche en amont invalide! Octets ANNULER Réinitialiser à la révision parente @@ -75,10 +76,10 @@ Récupérer ce commit Commit : Avertissement: une récupération vers un commit aboutiera vers un HEAD détaché - Branche : Changements locaux : Annuler Mettre en stash et réappliquer + Branche : Cherry-Pick de ce commit Ajouter la source au message de commit Commit : @@ -94,13 +95,13 @@ Nom local : Nom de dépôt. Optionnel. Dossier parent : + Initialiser et mettre à jour les sous-modules URL du dépôt : FERMER Éditeur Récupérer ce commit Cherry-Pick ce commit Cherry-Pick ... - Checkout Commit Comparer avec HEAD Comparer avec le worktree Copier les informations @@ -135,20 +136,22 @@ REFS SHA Ouvrir dans le navigateur - Entrez le message du commit Description + Entrez le message du commit Configurer le dépôt MODÈLE DE COMMIT - Nom de modèle: Contenu de modèle: + Nom de modèle: ACTION PERSONNALISÉE Arguments : ${REPO} - Chemin du repository; ${SHA} - SHA du commit sélectionné Fichier exécutable : Nom : Portée : + Branche Commit Repository + Attendre la fin de l'action Adresse e-mail Adresse e-mail GIT @@ -156,13 +159,13 @@ minute(s) Dépôt par défaut SUIVI DES PROBLÈMES + Ajouter une règle d'exemple Azure DevOps Ajouter une règle d'exemple Gitee Ajouter une règle d'exemple pour Pull Request Gitee Ajouter une règle d'exemple Github Ajouter une règle d'exemple pour Incidents GitLab Ajouter une règle d'exemple pour Merge Request GitLab Ajouter une règle d'exemple Jira - Ajouter une règle d'exemple Azure DevOps Nouvelle règle Issue Regex Expression: Nom de règle : @@ -187,8 +190,8 @@ Type de Changement : Copier Copier tout le texte - Copier le chemin Copier le chemin complet + Copier le chemin Créer une branche... Basé sur : Récupérer la branche créée @@ -221,7 +224,10 @@ Vous essayez de supprimer plusieurs branches à la fois. Assurez-vous de revérifier avant de procéder ! Supprimer Remote Remote : + Chemin: Cible : + Tous les enfants seront retirés de la liste. + Cela le supprimera uniquement de la liste, pas du disque ! Confirmer la suppression du groupe Confirmer la suppression du dépôt Supprimer le sous-module @@ -234,7 +240,9 @@ ANCIEN Copier Mode de fichier changé + Première différence Ignorer les changements d'espaces + Dernière différence CHANGEMENT D'OBJET LFS Différence suivante PAS DE CHANGEMENT OU SEULEMENT EN FIN DE LIGNE @@ -247,8 +255,8 @@ Permuter Coloration syntaxique Retour à la ligne - Ouvrir dans l'outil de fusion Activer la navigation par blocs + Ouvrir dans l'outil de fusion Voir toutes les lignes Réduit le nombre de ligne visibles Augmente le nombre de ligne visibles @@ -292,8 +300,8 @@ Utiliser les miennes (checkout --ours) Utiliser les leurs (checkout --theirs) Historique du fichier - CONTENU MODIFICATION + CONTENU Git-Flow Branche de développement : Feature: @@ -323,8 +331,8 @@ Pattern personnalisé : Ajouter un pattern de suivi à Git LFS Fetch - Fetch les objets LFS Lancer `git lfs fetch` pour télécharger les objets Git LFS. Cela ne met pas à jour la copie de travail. + Fetch les objets LFS Installer les hooks Git LFS Afficher les verrous Pas de fichiers verrouillés @@ -336,11 +344,11 @@ Elaguer Lancer `git lfs prune` pour supprimer les anciens fichier LFS du stockage local Pull - Pull les objets LFS Lancer `git lfs pull` pour télécharger tous les fichier Git LFS de la référence actuelle & récupérer + Pull les objets LFS Pousser - Pousser les objets LFS Transférer les fichiers volumineux en file d'attente vers le point de terminaison Git LFS + Pousser les objets LFS Dépôt : Suivre les fichiers appelés '{0}' Suivre tous les fichiers *{0} @@ -359,8 +367,8 @@ Annuler le popup en cours Cloner un nouveau dépôt Fermer la page en cours - Aller à la page précédente Aller à la page suivante + Aller à la page précédente Créer une nouvelle page Ouvrir le dialogue des préférences DÉPÔT @@ -371,11 +379,11 @@ Rejeter les changements sélectionnés Fetch, démarre directement Mode tableau de bord (Défaut) + Recherche de commit Pull, démarre directement Push, démarre directement Forcer le rechargement du dépôt Ajouter/Retirer les changements sélectionnés de l'index - Recherche de commit Basculer vers 'Changements' Basculer vers 'Historique' Basculer vers 'Stashes' @@ -384,25 +392,34 @@ Trouver la prochaine correspondance Trouver la correspondance précédente Ouvrir le panneau de recherche + Rejeter Indexer Retirer de l'index - Rejeter Initialiser le repository Chemin : Cherry-Pick en cours. + Traitement du commit Merge request en cours. + Fusionnement Rebase en cours. + Arrêté à Annulation en cours. + Annulation du commit Rebase interactif - Branche cible : Sur : - Ouvrir dans le navigateur + Branche cible : Copier le lien + Ouvrir dans le navigateur ERREUR NOTICE Merger la branche Dans : Option de merge: + Source: + Fusionner (Plusieurs) + Commit tous les changement + Stratégie: + Cibles: Déplacer le noeud du repository Sélectionnier le noeud parent pour : Nom : @@ -418,16 +435,16 @@ Copier le chemin vers le dépôt Dépôts Coller - A l'instant - il y a {0} minutes + il y a {0} jours il y a 1 heure il y a {0} heures - Hier - il y a {0} jours + A l'instant Le mois dernier - il y a {0} mois L'an dernier + il y a {0} minutes + il y a {0} mois il y a {0} ans + Hier Préférences IA Analyser Diff Prompt @@ -436,10 +453,15 @@ Modèle Nom Serveur + Activer le streaming APPARENCE Police par défaut Taille de police par défaut Taille de police de l'éditeur + Largeur de tab dans l'éditeur + Taille de police + Défaut + Éditeur Police monospace N'utiliser que des polices monospace pour l'éditeur de texte Thème @@ -452,9 +474,12 @@ Outil GÉNÉRAL Vérifier les mises à jour au démarrage + Format de date Language Historique de commits Afficher l'heure de l'auteur au lieu de l'heure de validation dans le graphique + Afficher les enfants dans les détails du commit + Afficher les tags dans le graphique des commits Guide de longueur du sujet GIT Activer auto CRLF @@ -462,24 +487,24 @@ E-mail utilsateur E-mail utilsateur global Activer --prune pour fetch + Cette application requière Git (>= 2.23.0) Chemin d'installation + Activer la vérification HTTP SSL Nom d'utilisateur Nom d'utilisateur global Version de Git - Cette application requière Git (>= 2.23.0) SIGNATURE GPG Signature GPG de commit - Signature GPG de tag Format GPG Chemin d'installation du programme Saisir le chemin d'installation vers le programme GPG + Signature GPG de tag Clé de signature de l'utilisateur Clé de signature GPG de l'utilisateur INTEGRATION SHELL/TERMINAL - Shell/Terminal Chemin - Élaguer une branche distant + Shell/Terminal Cible : Élaguer les Worktrees Élaguer les information de worktree dans `$GIT_COMMON_DIR/worktrees` @@ -539,14 +564,26 @@ Tout effacer Configurer ce repository CONTINUER + Actions personnalisées Pas d'actions personnalisées Activer l'option '--reflog' Ouvrir dans l'explorateur de fichiers Rechercher Branches/Tags/Submodules + Visibilité dans le graphique + Réinitialiser + Cacher dans le graphique des commits + Filtrer dans le graphique des commits Activer l'option '--first-parent' + DISPOSITION + Horizontal + Vertical + ORDRE DES COMMITS + Date du commit + Topologiquement BRANCHES LOCALES Naviguer vers le HEAD Créer une branche + EFFACER LES NOTIFICATIONS Mettre la branche courante en surbrillance dans le graph Ouvrir dans {0} Ouvrir dans un outil externe @@ -561,13 +598,19 @@ SHA Branche actuelle Voir les Tags en tant qu'arbre + PASSER Statistiques SUBMODULES AJOUTER SUBMODULE METTRE A JOUR SUBMODULE TAGS NOUVEAU TAG + Par date de créateur + Par nom (Croissant) + Par nom (Décroissant) + Trier Ouvrir dans un terminal + Utiliser le temps relatif dans les historiques WORKTREES AJOUTER WORKTREE ELAGUER @@ -586,6 +629,7 @@ SAUVEGARDER Sauvegarder en tant que... Le patch a été sauvegardé ! + Analyser les repositories Dossier racine : Rechercher des mises à jour... Une nouvelle version du logiciel est disponible : @@ -594,10 +638,10 @@ Passer cette version Mise à jour du logiciel Il n'y a pas de mise à jour pour le moment. - Définir la branche de suivi - Branche : - Escamoter la branche amont - Branche amont: + Définir la branche suivie + Branche: + Retirer la branche amont + En amont: Copier le SHA Aller à Squash les commits @@ -607,7 +651,7 @@ START Stash Auto-restauration après le stash - Vos fichiers de travail sont inchangés, mais un stash a été sauvegardé. + Vos fichiers de travail restent inchangés, mais une sauvegarde est enregistrée. Inclure les fichiers non-suivis Garder les fichiers indexés Message : @@ -626,11 +670,11 @@ Statistiques COMMITS COMMITTER + APERCU MOIS SEMAINE - COMMITS: AUTEURS : - APERCU + COMMITS: SOUS-MODULES Ajouter un sous-module Copier le chemin relatif @@ -645,13 +689,13 @@ Supprimer ${0}$... Fusionner ${0}$ dans ${1}$... Pousser ${0}$... - URL : Actualiser les sous-modules Tous les sous-modules Initialiser au besoin Récursivement Sous-module : Utiliser l'option --remote + URL : Avertissement Page d'accueil Créer un groupe @@ -679,6 +723,7 @@ COMMIT & POUSSER Modèles/Historiques Trigger click event + Commit (Modifier) Indexer tous les changements et commit Un commit vide a été détecté ! Voulez-vous continuer (--allow-empty) ? CONFLITS DÉTECTÉS @@ -686,6 +731,8 @@ INCLURE LES FICHIERS NON-SUIVIS PAS DE MESSAGE D'ENTRÉE RÉCENT PAS DE MODÈLES DE COMMIT + Faites un clique droit sur les fichiers sélectionnés et faites vos choix pour la résoluion des conflits. + SignOff INDEXÉ RETIRER DE L'INDEX RETIRER TOUT DE L'INDEX @@ -694,7 +741,6 @@ INDEXER TOUT VOIR LES FICHIERS PRÉSUMÉS INCHANGÉS Modèle: ${0}$ - Faites un clique droit sur les fichiers sélectionnés et faites vos choix pour la résoluion des conflits. ESPACE DE TRAVAIL : Configurer les espaces de travail... WORKTREE @@ -702,68 +748,4 @@ Verrouiller Supprimer Déverrouiller - RE-GÉNÉRER - APPLIQUER COMME MESSAGE DE COMMIT - Appliquer le Stash - Supprimer après l'application - Rétablir les modifications de l'index - Stash: - Action personnalisée - Branche en amont invalide! - Initialiser et mettre à jour les sous-modules - Branche - Attendre la fin de l'action - Les espaces seront remplacés par des tirets. - Chemin: - Tous les enfants seront retirés de la liste. - Cela le supprimera uniquement de la liste, pas du disque ! - Première différence - Dernière différence - Traitement du commit - Fusionnement - Arrêté à - Annulation du commit - Source: - Fusionner (Plusieurs) - Commit tous les changement - Stratégie: - Cibles: - Activer le streaming - Largeur de tab dans l'éditeur - Taille de police - Défaut - Éditeur - Format de date - Afficher les enfants dans les détails du commit - Afficher les tags dans le graphique des commits - Activer la vérification HTTP SSL - Actions personnalisées - Visibilité dans le graphique - Réinitialiser - Cacher dans le graphique des commits - Filtrer dans le graphique des commits - DISPOSITION - Horizontal - Vertical - ORDRE DES COMMITS - Date du commit - Topologiquement - EFFACER LES NOTIFICATIONS - PASSER - Par date de créateur - Par nom (Croissant) - Par nom (Décroissant) - Trier - Utiliser le temps relatif dans les historiques - Analyser les repositories - Définir la branche suivie - Branche: - Retirer la branche amont - En amont: - Aller sur - Restauration automatique après le stashing - Vos fichiers de travail restent inchangés, mais une sauvegarde est enregistrée. - Sauvegarder en tant que patch... - Commit (Modifier) - SignOff diff --git a/src/Resources/Locales/it_IT.axaml b/src/Resources/Locales/it_IT.axaml index 85038d9e..95647101 100644 --- a/src/Resources/Locales/it_IT.axaml +++ b/src/Resources/Locales/it_IT.axaml @@ -2,19 +2,20 @@ + Informazioni Informazioni su SourceGit Client GUI Git open source e gratuito Aggiungi Worktree - Di cosa fare il checkout: - Branch esistente - Crea nuovo branch Posizione: Percorso per questo worktree. Supportato il percorso relativo. Nome Branch: Facoltativo. Predefinito è il nome della cartella di destinazione. Traccia Branch: Traccia branch remoto + Di cosa fare il checkout: + Crea nuovo branch + Branch esistente Assistente AI RIGENERA Usa AI per generare il messaggio di commit @@ -64,8 +65,8 @@ Upstream non valido Byte ANNULLA - Ripristina Questa Revisione Ripristina la Revisione Padre + Ripristina Questa Revisione Genera messaggio di commit CAMBIA MODALITÀ DI VISUALIZZAZIONE Mostra come elenco di file e cartelle @@ -73,12 +74,12 @@ Mostra come albero del filesystem Checkout Branch Checkout Commit - Avviso: Effettuando un checkout del commit, la tua HEAD sarà separata Commit: - Branch: + Avviso: Effettuando un checkout del commit, la tua HEAD sarà separata Modifiche Locali: Scarta Stasha e Ripristina + Branch: Cherry Pick Aggiungi sorgente al messaggio di commit Commit(s): @@ -97,9 +98,9 @@ URL del Repository: CHIUDI Editor + Checkout Commit Cherry-Pick Questo Commit Cherry-Pick... - Checkout Commit Confronta con HEAD Confronta con Worktree Copia Info @@ -134,12 +135,12 @@ RIFERIMENTI SHA Apri nel Browser - Inserisci l'oggetto del commit Descrizione + Inserisci l'oggetto del commit Configura Repository TEMPLATE DI COMMIT - Nome Template: Contenuto Template: + Nome Template: AZIONE PERSONALIZZATA Argomenti: ${REPO} - Percorso del repository; ${SHA} - SHA del commit selezionato @@ -157,13 +158,13 @@ Minuto/i Remoto Predefinito TRACCIAMENTO ISSUE + Aggiungi una regola di esempio per Azure DevOps Aggiungi una regola di esempio per un Issue Gitee Aggiungi una regola di esempio per un Pull Request Gitee Aggiungi una regola di esempio per GitHub - Aggiungi una regola di esempio per Jira - Aggiungi una regola di esempio per Azure DevOps Aggiungi una regola di esempio per Issue GitLab Aggiungi una regola di esempio per una Merge Request GitLab + Aggiungi una regola di esempio per Jira Nuova Regola Espressione Regex Issue: Nome Regola: @@ -244,7 +245,6 @@ Differenza Successiva NESSUNA MODIFICA O SOLO CAMBIAMENTI DI FINE LINEA Differenza Precedente - Abilita la navigazione a blocchi Salva come Patch Mostra Simboli Nascosti Diff Affiancato @@ -253,6 +253,7 @@ Scambia Evidenziazione Sintassi Avvolgimento delle Parole + Abilita la navigazione a blocchi Apri nello Strumento di Merge Mostra Tutte le Righe Diminuisci Numero di Righe Visibili @@ -294,11 +295,11 @@ Rimuovi da Stage Rimuovi da Stage {0} file Rimuovi le Righe Selezionate da Stage - Usa Il Loro (checkout --theirs) Usa Il Mio (checkout --ours) + Usa Il Loro (checkout --theirs) Cronologia File - CONTENUTO MODIFICA + CONTENUTO FILTRO Git-Flow Branch di Sviluppo: @@ -329,8 +330,8 @@ Modello Personalizzato: Aggiungi Modello di Tracciamento a Git LFS Recupera - Recupera Oggetti LFS Esegui `git lfs fetch` per scaricare gli oggetti Git LFS. Questo non aggiorna la copia di lavoro. + Recupera Oggetti LFS Installa hook di Git LFS Mostra Blocchi Nessun File Bloccato @@ -342,11 +343,11 @@ Elimina Esegui `git lfs prune` per eliminare vecchi file LFS dallo storage locale Scarica - Scarica Oggetti LFS Esegui `git lfs pull` per scaricare tutti i file LFS per il ref corrente e fare il checkout + Scarica Oggetti LFS Invia - Invia Oggetti LFS Invia grandi file in coda al punto finale di Git LFS + Invia Oggetti LFS Remoto: Traccia file con nome '{0}' Traccia tutti i file *{0} @@ -365,8 +366,8 @@ Annulla il popup corrente Clona una nuova repository Chiudi la pagina corrente - Vai alla pagina precedente Vai alla pagina successiva + Vai alla pagina precedente Crea una nuova pagina Apri la finestra delle preferenze REPOSITORY @@ -377,11 +378,11 @@ Scarta le modifiche selezionate Recupera, avvia direttamente Modalità Dashboard (Predefinita) + Modalità ricerca commit Scarica, avvia direttamente Invia, avvia direttamente Forza l'aggiornamento di questo repository Aggiungi/Rimuovi da stage le modifiche selezionate - Modalità ricerca commit Passa a 'Modifiche' Passa a 'Storico' Passa a 'Stashes' @@ -390,9 +391,9 @@ Trova il prossimo risultato Trova il risultato precedente Apri il pannello di ricerca + Scarta Aggiungi in stage Rimuovi - Scarta Inizializza Repository Percorso: Cherry-Pick in corso. @@ -404,10 +405,10 @@ Ripristino in corso. Ripristinando il commit Riallinea Interattivamente - Branch di destinazione: Su: - Apri nel Browser + Branch di destinazione: Copia il Link + Apri nel Browser ERRORE AVVISO Unisci Branch @@ -433,16 +434,16 @@ Copia Percorso Repository Repository Incolla - Proprio ora - {0} minuti fa + {0} giorni fa 1 ora fa {0} ore fa - Ieri - {0} giorni fa + Proprio ora Il mese scorso - {0} mesi fa L'anno scorso + {0} minuti fa + {0} mesi fa {0} anni fa + Ieri Preferenze AI Analizza il Prompt Differenza @@ -482,24 +483,24 @@ Email Utente Email utente Git globale Abilita --prune durante il fetch + Questa applicazione richiede Git (>= 2.23.0) Percorso Installazione + Abilita la verifica HTTP SSL Nome Utente Nome utente Git globale Versione di Git - Questa applicazione richiede Git (>= 2.23.0) - Abilita la verifica HTTP SSL FIRMA GPG Firma GPG per commit - Firma GPG per tag Formato GPG Percorso Programma Installato Inserisci il percorso per il programma GPG installato + Firma GPG per tag Chiave Firma Utente Chiave GPG dell'utente per la firma INTEGRAZIONE SHELL/TERMINALE - Shell/Terminale Percorso + Shell/Terminale Potatura Remota Destinazione: Potatura Worktrees @@ -667,11 +668,11 @@ Statistiche COMMIT COMMITTER + PANORAMICA MESE SETTIMANA - COMMIT: AUTORI: - PANORAMICA + COMMIT: SOTTOMODULI Aggiungi Sottomodulo Copia Percorso Relativo @@ -686,13 +687,13 @@ Elimina ${0}$... Unisci ${0}$ in ${1}$... Invia ${0}$... - URL: Aggiorna Sottomoduli Tutti i sottomoduli Inizializza se necessario Ricorsivamente Sottomodulo: Usa opzione --remote + URL: Avviso Pagina di Benvenuto Crea Gruppo @@ -728,6 +729,8 @@ INCLUDI FILE NON TRACCIATI NESSUN MESSAGGIO RECENTE INSERITO NESSUN TEMPLATE DI COMMIT + Clicca con il tasto destro sul(i) file selezionato, quindi scegli come risolvere i conflitti. + SignOff IN STAGE RIMUOVI DA STAGE RIMUOVI TUTTO DA STAGE @@ -736,8 +739,6 @@ FAI LO STAGE DI TUTTO VISUALIZZA COME NON MODIFICATO Template: ${0}$ - Clicca con il tasto destro sul(i) file selezionato, quindi scegli come risolvere i conflitti. - SignOff WORKSPACE: Configura Workspaces... WORKTREE diff --git a/src/Resources/Locales/ja_JP.axaml b/src/Resources/Locales/ja_JP.axaml index 21255221..91cefbac 100644 --- a/src/Resources/Locales/ja_JP.axaml +++ b/src/Resources/Locales/ja_JP.axaml @@ -2,19 +2,20 @@ + 概要 SourceGitについて オープンソース & フリーなGit GUIクライアント ワークツリーを追加 - チェックアウトする内容: - 既存のブランチ - 新しいブランチを作成 場所: ワークツリーのパスを入力してください。相対パスも使用することができます。 ブランチの名前: 任意。デフォルトでは宛先フォルダ名が使用されます。 追跡するブランチ: 追跡中のリモートブランチ + チェックアウトする内容: + 新しいブランチを作成 + 既存のブランチ OpenAI アシスタント 再生成 OpenAIを使用してコミットメッセージを生成 @@ -64,8 +65,8 @@ 無効な上流ブランチ! バイト キャンセル - このリビジョンにリセット 親リビジョンにリセット + このリビジョンにリセット コミットメッセージを生成 変更表示の切り替え ファイルとディレクトリのリストを表示 @@ -73,12 +74,12 @@ ファイルシステムのツリーを表示 ブランチをチェックアウト コミットをチェックアウト - 警告: コミットをチェックアウトするとHEADが切断されます コミット: - ブランチ: + 警告: コミットをチェックアウトするとHEADが切断されます ローカルの変更: 破棄 スタッシュして再適用 + ブランチ: チェリーピック ソースをコミットメッセージに追加 コミット(複数可): @@ -97,9 +98,9 @@ リポジトリのURL: 閉じる エディタ + コミットをチェックアウト このコミットをチェリーピック チェリーピック... - コミットをチェックアウト HEADと比較 ワークツリーと比較 情報をコピー @@ -134,12 +135,12 @@ 参照 SHA ブラウザで開く - コミットのタイトルを入力 説明 + コミットのタイトルを入力 リポジトリの設定 コミットテンプレート - テンプレート名: テンプレート内容: + テンプレート名: カスタムアクション 引数: ${REPO} - リポジトリのパス; ${BRANCH} - 選択中のブランチ; ${SHA} - 選択中のコミットのSHA @@ -157,13 +158,13 @@ 分(s) リモートの初期値 ISSUEトラッカー + サンプルのAzure DevOpsルールを追加 サンプルのGitee Issueルールを追加 サンプルのGiteeプルリクエストルールを追加 サンプルのGithubルールを追加 サンプルのGitLab Issueルールを追加 サンプルのGitLabマージリクエストルールを追加 サンプルのJiraルールを追加 - サンプルのAzure DevOpsルールを追加 新しいルール Issueの正規表現: ルール名: @@ -188,8 +189,8 @@ 変更の種類: コピー すべてのテキストをコピー - パスをコピー 絶対パスをコピー + パスをコピー ブランチを作成... 派生元: 作成したブランチにチェックアウト @@ -225,8 +226,8 @@ パス: 対象: すべての子ノードがリストから削除されます。 - グループを削除 これはリストからのみ削除され、ディスクには保存されません! + グループを削除 リポジトリを削除 サブモジュールを削除 サブモジュールのパス: @@ -295,11 +296,11 @@ アンステージ {0}個のファイルをアンステージ... 選択された行の変更をアンステージ - 相手の変更を使用 (checkout --theirs) 自分の変更を使用 (checkout --ours) + 相手の変更を使用 (checkout --theirs) ファイルの履歴 - コンテンツ 変更 + コンテンツ Git-Flow 開発ブランチ: Feature: @@ -329,8 +330,8 @@ カスタム パターン: Git LFSにトラックパターンを追加 フェッチ - LFSオブジェクトをフェッチ `git lfs fetch`を実行して、Git LFSオブジェクトをダウンロードします。ワーキングコピーは更新されません。 + LFSオブジェクトをフェッチ Git LFSフックをインストール ロックを表示 ロックされているファイルはありません @@ -342,11 +343,11 @@ 削除 `git lfs prune`を実行して、ローカルの保存領域から古いLFSファイルを削除します。 プル - LFSオブジェクトをプル `git lfs pull`を実行して、現在の参照とチェックアウトのすべてのGit LFSファイルをダウンロードします。 + LFSオブジェクトをプル プッシュ - LFSオブジェクトをプッシュ キュー内の大容量ファイルをGit LFSエンドポイントにプッシュします。 + LFSオブジェクトをプッシュ リモート: {0}という名前のファイルをトラック すべての*{0}ファイルをトラック @@ -365,8 +366,8 @@ 現在のポップアップをキャンセル 新しくリポジトリをクローン 現在のページを閉じる - 前のページに移動 次のページに移動 + 前のページに移動 新しいページを作成 設定ダイアログを開く リポジトリ @@ -377,11 +378,11 @@ 選択した変更を破棄 直接フェッチを実行 ダッシュボードモード (初期値) + コミット検索モード 直接プルを実行 直接プッシュを実行 現在のリポジトリを強制的に再読み込み 選択中の変更をステージ/アンステージ - コミット検索モード '変更'に切り替える '履歴'に切り替える 'スタッシュ'に切り替える @@ -390,9 +391,9 @@ 次のマッチを検索 前のマッチを検索 検索パネルを開く + 破棄 ステージ アンステージ - 破棄 リポジトリの初期化 パス: チェリーピックが進行中です。'中止'を押すと元のHEADが復元されます。 @@ -404,10 +405,10 @@ 元に戻す処理が進行中です。'中止'を押すと元のHEADが復元されます。 コミットを元に戻しています インタラクティブ リベース - 対象のブランチ: On: - ブラウザで開く + 対象のブランチ: リンクをコピー + ブラウザで開く エラー 通知 ブランチのマージ @@ -433,16 +434,16 @@ リポジトリパスをコピー リポジトリ 貼り付け - たった今 - {0} 分前 + {0} 日前 1 時間前 {0} 時間前 - 昨日 - {0} 日前 + たった今 先月 - {0} ヶ月前 昨年 + {0} 分前 + {0} ヶ月前 {0} 年前 + 昨日 設定 AI 差分分析プロンプト @@ -483,24 +484,24 @@ ユーザー Eメールアドレス グローバルgitのEメールアドレス フェッチ時に--pruneを有効化 + Git (>= 2.23.0) はこのアプリで必要です インストール パス HTTP SSL 検証を有効にする ユーザー名 グローバルのgitユーザー名 Gitバージョン - Git (>= 2.23.0) はこのアプリで必要です GPG 署名 コミットにGPG署名を行う - タグにGPG署名を行う GPGフォーマット プログラムのインストールパス インストールされたgpgプログラムのパスを入力 + タグにGPG署名を行う ユーザー署名キー ユーザーのGPG署名キー 統合 シェル/ターミナル - シェル/ターミナル パス + シェル/ターミナル リモートを削除 対象: 作業ツリーを削除 @@ -666,11 +667,11 @@ 統計 コミット コミッター + 概要 月間 週間 - コミット: 著者: - 概要 + コミット: サブモジュール サブモジュールを追加 相対パスをコピー @@ -685,13 +686,13 @@ ${0}$ を削除... ${0}$ を ${1}$ にマージ... ${0}$ をプッシュ... - URL: サブモジュールを更新 すべてのサブモジュール 必要に応じて初期化 再帰的に更新 サブモジュール: --remoteオプションを使用 + URL: 警告 ようこそ グループを作成 @@ -727,6 +728,7 @@ 追跡されていないファイルを含める 最近の入力メッセージはありません コミットテンプレートはありません + 選択したファイルを右クリックし、競合を解決する操作を選択してください。 サインオフ ステージしたファイル ステージを取り消し @@ -736,7 +738,6 @@ すべてステージへ移動 変更されていないとみなしたものを表示 テンプレート: ${0}$ - 選択したファイルを右クリックし、競合を解決する操作を選択してください。 ワークスペース: ワークスペースを設定... ワークツリー diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml index 4ee6cdbc..09b78c31 100644 --- a/src/Resources/Locales/pt_BR.axaml +++ b/src/Resources/Locales/pt_BR.axaml @@ -3,43 +3,19 @@ - - Sobre Sobre o SourceGit Cliente Git GUI Livre e de Código Aberto Adicionar Worktree - O que Checar: - Branch Existente - Criar Novo Branch Localização: Caminho para este worktree. Caminho relativo é suportado. Nome do Branch: Opcional. O padrão é o nome da pasta de destino. Rastrear Branch: Rastreando branch remoto + O que Checar: + Criar Novo Branch + Branch Existente Assietente IA Utilizar IA para gerar mensagem de commit Patch @@ -80,8 +56,8 @@ Comparação de Branches Bytes CANCELAR - Resetar para Esta Revisão Resetar para Revisão Pai + Resetar para Esta Revisão Gerar mensagem de commit ALTERAR MODO DE EXIBIÇÃO Exibir como Lista de Arquivos e Diretórios @@ -89,12 +65,12 @@ Exibir como Árvore de Sistema de Arquivos Checkout Branch Checkout Commit - Aviso: Ao fazer o checkout de um commit, seu Head ficará desanexado Commit: - Branch: + Aviso: Ao fazer o checkout de um commit, seu Head ficará desanexado Alterações Locais: Descartar Stash & Reaplicar + Branch: Cherry-Pick Adicionar origem à mensagem de commit Commit(s): @@ -112,9 +88,9 @@ URL do Repositório: FECHAR Editor + Checar Commit Cherry-Pick este commit Cherry-Pick ... - Checar Commit Comparar com HEAD Comparar com Worktree Copiar Informações @@ -145,12 +121,12 @@ REFERÊNCIAS SHA Abrir no navegador - Insira o assunto do commit Descrição + Insira o assunto do commit Configurar Repositório TEMPLATE DE COMMIT - Nome do Template: Conteúdo do Template: + Nome do Template: AÇÃO CUSTOMIZADA Argumentos: ${REPO} - Caminho do repositório; ${SHA} - SHA do commit selecionado @@ -166,11 +142,11 @@ Minuto(s) Remoto padrão RASTREADOR DE PROBLEMAS - Adicionar Regra de Exemplo do Github - Adicionar Regra de Exemplo do Jira Adicionar Regra de Exemplo do Azure DevOps + Adicionar Regra de Exemplo do Github Adicionar Regra de Exemplo do GitLab Adicionar regra de exemplo de Merge Request do GitLab + Adicionar Regra de Exemplo do Jira Nova Regra Expressão Regex de Issue: Nome da Regra: @@ -292,11 +268,11 @@ Desfazer Preparação Desfazer Preparação de {0} arquivos Desfazer Preparação nas Linhas Selecionadas - Usar Deles (checkout --theirs) Usar Meu (checkout --ours) + Usar Deles (checkout --theirs) Histórico de Arquivos - CONTEUDO MUDANÇA + CONTEUDO Git-Flow Branch de Desenvolvimento: Feature: @@ -326,8 +302,8 @@ Padrão Personalizado: Adicionar Padrão de Rastreamento ao Git LFS Buscar - Buscar Objetos LFS Execute `git lfs fetch` para baixar objetos Git LFS. Isso não atualiza a cópia de trabalho. + Buscar Objetos LFS Instalar hooks do Git LFS Exibir bloqueios Sem Arquivos Bloqueados @@ -339,11 +315,11 @@ Prune Execute `git lfs prune` para excluir arquivos LFS antigos do armazenamento local Puxar - Puxar Objetos LFS Execute `git lfs pull` para baixar todos os arquivos Git LFS para a referência atual e checkout + Puxar Objetos LFS Enviar - Enviar Objetos LFS Envie arquivos grandes enfileirados para o endpoint Git LFS + Enviar Objetos LFS Remoto: Rastrear arquivos nomeados '{0}' Rastrear todos os arquivos *{0} @@ -361,8 +337,8 @@ GLOBAL Cancelar popup atual Fechar página atual - Ir para a página anterior Ir para a próxima página + Ir para a página anterior Criar nova página Abrir diálogo de preferências REPOSITÓRIO @@ -373,11 +349,11 @@ Descartar mudanças selecionadas Buscar, imediatamente Modo de Dashboard (Padrão) + Modo de busca de commits Puxar, imediatamente Enviar, imediatamente Forçar recarregamento deste repositório Preparar/Despreparar mudanças selecionadas - Modo de busca de commits Alternar para 'Mudanças' Alternar para 'Históricos' Alternar para 'Stashes' @@ -386,9 +362,9 @@ Encontrar próxima correspondência Encontrar correspondência anterior Abrir painel de busca + Descartar Preparar Despreparar - Descartar Inicializar Repositório Caminho: Cherry-Pick em andamento. @@ -396,10 +372,10 @@ Rebase em andamento. Revert em andamento. Rebase Interativo - Ramo Alvo: Em: - Abrir no navegador + Ramo Alvo: Copiar link + Abrir no navegador ERRO AVISO Mesclar Ramo @@ -420,16 +396,16 @@ Copiar Caminho do Repositório Repositórios Colar - Agora mesmo - {0} minutos atrás + {0} dias atrás 1 hora atrás {0} horas atrás - Ontem - {0} dias atrás + Agora mesmo Mês passado - {0} meses atrás Ano passado + {0} minutos atrás + {0} meses atrás {0} anos atrás + Ontem Preferências INTELIGÊNCIA ARTIFICIAL Prompt para Analisar Diff @@ -465,23 +441,23 @@ Email do Usuário Email global do usuário git Habilita --prune ao buscar + Git (>= 2.23.0) é necessário para este aplicativo Caminho de Instalação Nome do Usuário Nome global do usuário git Versão do Git - Git (>= 2.23.0) é necessário para este aplicativo ASSINATURA GPG Assinatura GPG de commit - Assinatura GPG de tag Formato GPG Caminho de Instalação do Programa Insira o caminho para o programa gpg instalado + Assinatura GPG de tag Chave de Assinatura do Usuário Chave de assinatura gpg do usuário INTEGRAÇÃO SHELL/TERMINAL - Shell/Terminal Caminho + Shell/Terminal Prunar Remoto Alvo: Podar Worktrees @@ -627,11 +603,11 @@ Estatísticas COMMITS COMMITTER + VISÃO GERAL MÊS SEMANA - COMMITS: AUTORES: - VISÃO GERAL + COMMITS: SUBMÓDULOS Adicionar Submódulo Copiar Caminho Relativo @@ -646,13 +622,13 @@ Excluir ${0}$... Mesclar ${0}$ em ${1}$... Enviar ${0}$... - URL: Atualizar Submódulos Todos os submódulos Inicializar conforme necessário Recursivamente Submódulo: Usar opção --remote + URL: Aviso Página de Boas-vindas Criar Grupo Raíz @@ -687,6 +663,7 @@ INCLUIR ARQUIVOS NÃO RASTREADOS SEM MENSAGENS DE ENTRADA RECENTES SEM MODELOS DE COMMIT + Clique com o botão direito nos arquivos selecionados e escolha como resolver conflitos. STAGED UNSTAGE UNSTAGE TODOS @@ -695,7 +672,6 @@ STAGE TODOS VER SUPOR NÃO ALTERADO Template: ${0}$ - Clique com o botão direito nos arquivos selecionados e escolha como resolver conflitos. Workspaces: Configurar workspaces... WORKTREE diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index 2ea274d1..7da65b5e 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -2,19 +2,20 @@ + О программе О SourceGit Бесплатный графический клиент Git с исходным кодом Добавить рабочий каталог - Переключиться на: - ветку из списка - создать новую ветку Расположение: Путь к рабочему каталогу (поддерживается относительный путь) Имя ветки: Имя целевого каталога по умолчанию. (необязательно) Отслеживание ветки: Отслеживание внешней ветки + Переключиться на: + создать новую ветку + ветку из списка Помощник OpenAI ПЕРЕСОЗДАТЬ Использовать OpenAI для создания сообщения о ревизии @@ -42,7 +43,6 @@ Расследование РАССЛЕДОВАНИЕ В ЭТОМ ФАЙЛЕ НЕ ПОДДЕРЖИВАЕТСЯ!!! Проверить ${0}$... - Сравнить с ГОЛОВОЙ (HEAD) Сравнить с рабочим каталогом Копировать имя ветки Изменить действие @@ -64,8 +64,8 @@ Недопустимая основная ветка! Байты ОТМЕНА - Сбросить эту ревизию Сбросить родительскую ревизию + Сбросить эту ревизию Произвести сообщение о ревизии ИЗМЕНИТЬ РЕЖИМ ОТОБРАЖЕНИЯ Показывать в виде списка файлов и каталогов @@ -73,12 +73,12 @@ Показывать в виде дерева файловой системы Переключить ветку Переключение ревизии - Предупреждение: После переключения ревизии ваша Голова (HEAD) будет отсоединена Ревизия: - Ветка: + Предупреждение: После переключения ревизии ваша Голова (HEAD) будет отсоединена Локальные изменения: Отклонить Отложить и примненить повторно + Ветка: Частичный выбор Добавить источник для ревизии сообщения Ревизия(и): @@ -97,9 +97,9 @@ Адрес репозитория: ЗАКРЫТЬ Редактор + Переключиться на эту ревизию Применить эту ревизию (cherry-pick) Применить несколько ревизий ... - Переключиться на эту ревизию Сравнить c ГОЛОВОЙ (HEAD) Сравнить с рабочим каталогом Копировать информацию @@ -134,12 +134,12 @@ ССЫЛКИ SHA Открыть в браузере - Введите тему ревизии Описание + Введите тему ревизии Настройка репозитория ШАБЛОН РЕВИЗИИ - Название: Cодержание: + Название: ПОЛЬЗОВАТЕЛЬСКОЕ ДЕЙСТВИЕ Аргументы: ${REPO} - Путь к репозиторию; ${SHA} - SHA ревизий @@ -157,13 +157,13 @@ Минут(а/ы) Внешний репозиторий по умолчанию ОТСЛЕЖИВАНИЕ ПРОБЛЕМ + Добавить пример правила Azure DevOps Добавить пример правила для тем в Gitea Добавить пример правила запроса скачивания из Gitea Добавить пример правила для Git - Добавить пример правила Jira - Добавить пример правила Azure DevOps Добавить пример правила выдачи GitLab Добавить пример правила запроса на слияние в GitLab + Добавить пример правила Jira Новое правило Проблема с регулярным выражением: Имя правила: @@ -177,8 +177,8 @@ Имя пользователя Имя пользователя репозитория Рабочие пространства - Имя Цвет + Имя Восстанавливать вкладки при запуске Общепринятый помощник по ревизии Кардинальные изменения: @@ -189,8 +189,8 @@ Тип изменения: Копировать Копировать весь текст - Копировать путь Копировать полный путь + Копировать путь Создать ветку... Основан на: Проверить созданную ветку @@ -226,8 +226,8 @@ Путь: Цель: Все дочерние элементы будут удалены из списка. - Подтвердите удаление группы Будет удалён из списка. На диске останется. + Подтвердите удаление группы Подтвердите удаление репозитория Удалить подмодуль Путь подмодуля: @@ -242,12 +242,12 @@ Первое различие Игнорировать изменение пробелов Последнее различие - Показывать скрытые символы ИЗМЕНЕНИЕ ОБЪЕКТА LFS Следующее различие НИКАКИХ ИЗМЕНЕНИЙ ИЛИ МЕНЯЕТСЯ ТОЛЬКО EOL Предыдущее различие Сохранить как заплатку + Показывать скрытые символы Различие рядом ПОДМОДУЛЬ НОВЫЙ @@ -296,11 +296,11 @@ Снять подготовленный Неподготовленные {0} файлы Неподготовленные изменения в выбранной(ых) строке(ах) - Использовать их (checkout --theirs) Использовать мой (checkout --ours) + Использовать их (checkout --theirs) История файлов - СОДЕРЖИМОЕ ИЗМЕНИТЬ + СОДЕРЖИМОЕ Git-поток Ветка разработчика: Свойство: @@ -330,8 +330,8 @@ Изменить шаблон: Добавить шаблон отслеживания в LFS Git Извлечь - Извлечь объекты LFS Запустить (git lfs fetch), чтобы загрузить объекты LFS Git. При этом рабочая копия не обновляется. + Извлечь объекты LFS Установить перехват LFS Git Показывать блокировки Нет заблокированных файлов @@ -343,11 +343,11 @@ Обрезать Запустить (git lfs prune), чтобы удалить старые файлы LFS из локального хранилища Забрать - Забрать объекты LFS Запустить (git lfs pull), чтобы загрузить все файлы LFS Git для текущей ссылки и проверить + Забрать объекты LFS Выложить - Выложить объекты LFS Отправляйте большие файлы, помещенные в очередь, в конечную точку LFS Git + Выложить объекты LFS Внешнее хранилище: Отслеживать файлы с именем «{0}» Отслеживать все *{0} файлов @@ -366,8 +366,8 @@ Закрыть окно Клонировать репозиторий Закрыть вкладку - Перейти на предыдущую вкладку Перейти на следующую вкладку + Перейти на предыдущую вкладку Создать новую вкладку Открыть диалоговое окно настроек РЕПОЗИТОРИЙ @@ -378,11 +378,11 @@ Отклонить выбранные изменения Извлечение, запускается сразу Режим доски (по умолчанию) - Принудительно перезагрузить репозиторий + Режим поиска ревизий Забрать, запускается сразу Выложить, запускается сразу + Принудительно перезагрузить репозиторий Подготовленные/Неподготовленные выбранные изменения - Режим поиска ревизий Переключить на «Изменения» Переключить на «Истории» Переключить на «Отложенные» @@ -391,9 +391,9 @@ Найти следующее совпадение Найти предыдущее совпадение Открыть панель поиска + Отклонить Подготовить Снять из подготовленных - Отклонить Создать репозиторий Путь: Выполняется частичный перенос ревизий (cherry-pick). @@ -405,11 +405,10 @@ Выполняется отмена ревизии. Выполняется отмена Интерактивное перемещение - Целевая ветка: На: - Открыть в браузере + Целевая ветка: Копировать ссылку - ОШИБКА + Открыть в браузере УВЕДОМЛЕНИЕ Влить ветку В: @@ -434,20 +433,20 @@ Копировать путь репозитория Репозитории Вставить - Сейчас - {0} минут назад + {0} дней назад 1 час назад {0} часов назад - Вчера - {0} дней назад + Сейчас Последний месяц - {0} месяцев назад В прошлом году + {0} минут назад + {0} месяцев назад {0} лет назад + Вчера Параметры ОТКРЫТЬ ИИ - Ключ API Запрос на анализ различий + Ключ API Произвести запрос на тему Модель Имя: @@ -455,9 +454,9 @@ Разрешить потоковую передачу ВИД Шрифт по умолчанию + Редактировать ширину вкладки Размер шрифта По умолчанию - Редактировать ширину вкладки Редактор Моноширный шрифт В текстовом редакторе используется только моноширный шрифт @@ -484,24 +483,24 @@ Электроная почта пользователя Общая электроная почта пользователя git Разрешить (--prune) при скачивании + Для работы программы требуется версия Git (>= 2.23.0) Путь установки Разрешить верификацию HTTP SSL Имя пользователя Общее имя пользователя git Версия Git - Для работы программы требуется версия Git (>= 2.23.0) GPG ПОДПИСЬ GPG подпись ревизии - GPG подпись метки Формат GPG Путь установки программы Введите путь для установленной программы GPG + GPG подпись метки Ключ подписи пользователя Ключ GPG подписи пользователя ВНЕДРЕНИЕ ОБОЛОЧКА/ТЕРМИНАЛ - Оболочка/Терминал Путь + Оболочка/Терминал Удалить внешний репозиторий Цель: Удалить рабочий каталог @@ -630,8 +629,6 @@ Заплатка успешно сохранена! Сканирование репозиторий Корневой каталог: - Копировать SHA - Перейти Проверка для обновления... Доступна новая версия программного обеспечения: Не удалось проверить наличие обновлений! @@ -643,12 +640,12 @@ Ветка: Снять основную ветку Основная ветка: + Копировать SHA + Перейти Втиснуть ревизии В: Приватный ключ SSH: Путь хранения приватного ключа SSH - Только подготовленные изменения - Подготовленные так и неподготовленные изменения выбранных файлов будут сохранены!!! ЗАПУСК Отложить Автоматически восстанавливать после откладывания @@ -657,6 +654,8 @@ Хранить отложенные файлы Сообщение: Имя тайника (необязательно) + Только подготовленные изменения + Подготовленные так и неподготовленные изменения выбранных файлов будут сохранены!!! Отложить локальные изменения Принять Отбросить @@ -669,11 +668,11 @@ Статистика РЕВИЗИИ РЕВИЗОРЫ (ИСПОЛНИТЕЛИ) + ОБЗОР МЕСЯЦ НЕДЕЛЯ - РЕВИЗИИ: АВТОРЫ: - ОБЗОР + РЕВИЗИИ: ПОДМОДУЛИ Добавить подмодули Копировать относительный путь @@ -688,13 +687,13 @@ Удалить ${0}$... Влить ${0}$ в ${1}$... Выложить ${0}$... - Сетевой адрес: Обновление подмодулей Все подмодули Создавать по необходимости Рекурсивно Подмодуль: Использовать опцию (--remote) + Сетевой адрес: Предупреждение Приветствие Создать группу @@ -707,7 +706,6 @@ Открыть все репозитории Открыть репозиторий Открыть терминал - Повторное сканирование репозиториев в каталоге клонирования по умолчанию Поиск репозиториев... Сортировка Изменения @@ -730,6 +728,7 @@ ВКЛЮЧИТЬ НЕОТСЛЕЖИВАЕМЫЕ ФАЙЛЫ НЕТ ПОСЛЕДНИХ ВХОДНЫХ СООБЩЕНИЙ НЕТ ШАБЛОНОВ РЕВИЗИИ + Щёлкните правой кнопкой мыши выбранный файл(ы) и разрешите конфликты. Завершение работы ПОДГОТОВЛЕННЫЕ СНЯТЬ ПОДГОТОВЛЕННЫЙ @@ -739,7 +738,6 @@ ВСЕ ПОДГОТОВИТЬ ОТКРЫТЬ СПИСОК НЕОТСЛЕЖИВАЕМЫХ ФАЙЛОВ Шаблон: ${0}$ - Щёлкните правой кнопкой мыши выбранный файл(ы) и разрешите конфликты. РАБОЧЕЕ ПРОСТРАНСТВО: Настройка рабочего пространства... РАБОЧИЙ КАТАЛОГ diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 932f1237..281d6a4d 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -2,19 +2,20 @@ + 关于软件 关于本软件 开源免费的Git客户端 新增工作树 - 检出分支方式 : - 已有分支 - 创建新分支 工作树路径 : 填写该工作树的路径。支持相对路径。 分支名 : 选填。默认使用目标文件夹名称。 跟踪分支 设置上游跟踪分支 + 检出分支方式 : + 创建新分支 + 已有分支 AI助手 重新生成 使用AI助手生成提交信息 @@ -64,8 +65,8 @@ 跟踪的上游分支不存在或已删除! 字节 取 消 - 重置文件到该版本 重置文件到上一版本 + 重置文件到该版本 生成提交信息 切换变更显示模式 文件名+路径列表模式 @@ -73,12 +74,12 @@ 文件目录树形结构模式 检出(checkout)分支 检出(checkout)提交 - 注意:执行该操作后,当前HEAD会变为游离(detached)状态! 提交 : - 目标分支 : + 注意:执行该操作后,当前HEAD会变为游离(detached)状态! 未提交更改 : 丢弃更改 贮藏并自动恢复 + 目标分支 : 挑选提交 提交信息中追加来源信息 提交列表 : @@ -97,9 +98,9 @@ 远程仓库 : 关闭 提交信息编辑器 + 检出此提交 挑选(cherry-pick)此提交 挑选(cherry-pick)... - 检出此提交 与当前HEAD比较 与本地工作树比较 复制简要信息 @@ -134,12 +135,12 @@ 相关引用 提交指纹 浏览器中查看 - 填写提交信息主题 详细描述 + 填写提交信息主题 仓库配置 提交信息模板 - 模板名 : 模板内容 : + 模板名 : 自定义操作 命令行参数 : 请使用${REPO}代替仓库路径,${BRANCH}代替选中的分支,${SHA}代替提交哈希 @@ -189,8 +190,8 @@ 类型: 复制 复制全部文本 - 复制路径 复制完整路径 + 复制路径 新建分支 ... 新分支基于 : 完成后切换到新分支 @@ -226,8 +227,8 @@ 路径 : 目标 : 所有子节点将被同时从列表中移除。 - 删除分组确认 仅从列表中移除,不会删除硬盘中的文件! + 删除分组确认 删除仓库确认 删除子模块确认 子模块路径 : @@ -296,11 +297,11 @@ 从暂存中移除 从暂存中移除 {0} 个文件 从暂存中移除选中的更改 - 使用 THEIRS (checkout --theirs) 使用 MINE (checkout --ours) + 使用 THEIRS (checkout --theirs) 文件历史 - 文件内容 文件变更 + 文件内容 GIT工作流 开发分支 : 特性分支 : @@ -330,8 +331,8 @@ 规则 : 添加LFS追踪文件规则 拉取LFS对象 (fetch) - 拉取LFS对象 执行`git lfs prune`命令,下载远程LFS对象,但不会更新工作副本。 + 拉取LFS对象 启用Git LFS支持 显示LFS对象锁 没有锁定的LFS文件 @@ -343,11 +344,11 @@ 精简本地LFS对象存储 运行`git lfs prune`命令,从本地存储中精简当前版本不需要的LFS对象 拉回LFS对象 (pull) - 拉回LFS对象 运行`git lfs pull`命令,下载远程LFS对象并更新工作副本。 + 拉回LFS对象 推送 - 推送LFS对象 将排队的大文件推送到Git LFS远程服务 + 推送LFS对象 远程 : 跟踪名为'{0}'的文件 跟踪所有 *{0} 文件 @@ -366,8 +367,8 @@ 取消弹出面板 克隆远程仓库 关闭当前页面 - 切换到上一个页面 切换到下一个页面 + 切换到上一个页面 新建页面 打开偏好设置面板 仓库页面快捷键 @@ -378,11 +379,11 @@ 丢弃选中的更改 拉取 (fetch) 远程变更 切换左边栏为分支/标签等显示模式(默认) + 切换左边栏为提交搜索模式 拉回 (pull) 远程变更 推送本地变更到远程 重新加载仓库状态 将选中的变更暂存或从暂存列表中移除 - 切换左边栏为提交搜索模式 显示本地更改 显示历史记录 显示贮藏列表 @@ -391,9 +392,9 @@ 定位到下一个匹配搜索的位置 定位到上一个匹配搜索的位置 打开搜索 + 丢弃 暂存 移出暂存区 - 丢弃 初始化新仓库 路径 : 挑选(Cherry-Pick)操作进行中。 @@ -405,10 +406,10 @@ 回滚提交操作进行中。 正在回滚提交 交互式变基 - 目标分支 : 起始提交 : - 在浏览器中访问 + 目标分支 : 复制链接地址 + 在浏览器中访问 出错了 系统提示 合并分支 @@ -434,16 +435,16 @@ 复制仓库路径 新标签页 粘贴 - 刚刚 - {0}分钟前 + {0}天前 1小时前 {0}小时前 - 昨天 - {0}天前 + 刚刚 上个月 - {0}个月前 一年前 + {0}分钟前 + {0}个月前 {0}年前 + 昨天 偏好设置 AI Analyze Diff Prompt @@ -455,11 +456,11 @@ 启用流式输出 外观配置 缺省字体 + 代码字体大小 编辑器制表符宽度 字体大小 默认 代码编辑器 - 代码字体大小 等宽字体 仅在文本编辑器中使用等宽字体 主题 @@ -485,24 +486,24 @@ 邮箱 默认GIT用户邮箱 拉取更新时启用修剪(--prune) + 本软件要求GIT最低版本为2.23.0 安装路径 启用HTTP SSL验证 用户名 默认GIT用户名 Git 版本 - 本软件要求GIT最低版本为2.23.0 GPG签名 启用提交签名 - 启用标签签名 签名格式 签名程序位置 签名程序所在路径 + 启用标签签名 用户签名KEY 输入签名提交所使用的KEY 第三方工具集成 终端/SHELL - 终端/SHELL 安装路径 + 终端/SHELL 清理远程已删除分支 目标 : 清理工作树 @@ -669,11 +670,11 @@ 提交统计 提交次数 提交者 + 总览 本月 本周 - 提交次数: 贡献者人数: - 总览 + 提交次数: 子模块 添加子模块 复制路径 @@ -688,13 +689,13 @@ 删除 ${0}$... 合并 ${0}$ 到 ${1}$... 推送 ${0}$... - 仓库地址 : 更新子模块 更新所有子模块 启用 '--init' 启用 '--recursive' 子模块 : 启用 '--remote' + 仓库地址 : 警告 起始页 新建分组 @@ -724,13 +725,13 @@ 触发点击事件 提交(修改原始提交) 自动暂存所有变更并提交 - 当前有 {0} 个文件在暂存区中,但仅显示了 {1} 个文件({2} 个文件被过滤掉了),是否继续提交? 提交未包含变更文件!是否继续(--allow-empty)? 检测到冲突 文件冲突已解决 显示未跟踪文件 没有提交信息记录 没有可应用的提交信息模板 + 请选中冲突文件,打开右键菜单,选择合适的解决方式 署名 已暂存 从暂存区移除选中 @@ -740,7 +741,6 @@ 暂存所有 查看忽略变更文件 模板:${0}$ - 请选中冲突文件,打开右键菜单,选择合适的解决方式 工作区: 配置工作区... 本地工作树 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 88b0ab64..e090fe2a 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -2,19 +2,20 @@ + 關於 關於 SourceGit 開源免費的 Git 客戶端 新增工作區 - 簽出分支方式: - 已有分支 - 建立新分支 工作區路徑: 填寫該工作區的路徑。支援相對路徑。 分支名稱: 選填。預設使用目標資料夾名稱。 追蹤分支 設定遠端追蹤分支 + 簽出分支方式: + 建立新分支 + 已有分支 AI 助理 重新產生 使用 AI 產生提交訊息 @@ -64,8 +65,8 @@ 追蹤上游分支不存在或已刪除! 位元組 取 消 - 重設檔案為此版本 重設檔案到上一版本 + 重設檔案為此版本 產生提交訊息 切換變更顯示模式 檔案名稱 + 路徑列表模式 @@ -73,12 +74,12 @@ 檔案目錄樹狀結構模式 簽出 (checkout) 分支 簽出 (checkout) 提交 - 注意: 執行該操作後,目前 HEAD 會變為分離 (detached) 狀態! 提交: - 目標分支: + 注意: 執行該操作後,目前 HEAD 會變為分離 (detached) 狀態! 未提交變更: 捨棄變更 擱置變更並自動復原 + 目標分支: 揀選提交 提交資訊中追加來源資訊 提交列表: @@ -97,9 +98,9 @@ 遠端存放庫: 關閉 提交訊息編輯器 + 簽出 (checkout) 此提交 揀選 (cherry-pick) 此提交 揀選 (cherry-pick)... - 簽出 (checkout) 此提交 與目前 HEAD 比較 與本機工作區比較 複製摘要資訊 @@ -134,12 +135,12 @@ 相關參照 提交編號 在瀏覽器中檢視 - 填寫提交訊息標題 詳細描述 + 填寫提交訊息標題 存放庫設定 提交訊息範本 - 範本名稱: 範本內容: + 範本名稱: 自訂動作 指令參數: 使用 ${REPO} 表示存放庫路徑、${BRANCH} 表示所選的分支、${SHA} 表示所選的提交編號 @@ -189,8 +190,8 @@ 類型: 複製 複製全部內容 - 複製路徑 複製完整路徑 + 複製路徑 新增分支... 新分支基於: 完成後切換到新分支 @@ -226,8 +227,8 @@ 路徑: 目標: 所有子節點都會從清單中移除。 - 刪除群組確認 只會從清單中移除,而不會刪除磁碟中的檔案! + 刪除群組確認 刪除存放庫確認 刪除子模組確認 子模組路徑: @@ -296,11 +297,11 @@ 取消暫存 從暫存中移除 {0} 個檔案 取消暫存選取的變更 - 使用對方版本 (checkout --theirs) 使用我方版本 (checkout --ours) + 使用對方版本 (checkout --theirs) 檔案歷史 - 檔案内容 檔案變更 + 檔案内容 Git 工作流 開發分支: 功能分支: @@ -330,8 +331,8 @@ 規則: 加入 LFS 追蹤檔案規則 提取 (fetch) - 提取 LFS 物件 執行 `git lfs fetch` 以下載遠端 LFS 物件,但不會更新工作副本。 + 提取 LFS 物件 啟用 Git LFS 支援 顯示 LFS 物件鎖 沒有鎖定的 LFS 物件 @@ -343,11 +344,11 @@ 清理 (prune) 執行 `git lfs prune` 以從本機中清理目前版本不需要的 LFS 物件 拉取 (pull) - 拉取 LFS 物件 執行 `git lfs pull` 以下載遠端 LFS 物件並更新工作副本。 + 拉取 LFS 物件 推送 (push) - 推送 LFS 物件 將大型檔案推送到 Git LFS 遠端服務 + 推送 LFS 物件 遠端存放庫: 追蹤名稱為「{0}」的檔案 追蹤所有 *{0} 檔案 @@ -366,8 +367,8 @@ 取消彈出面板 複製 (clone) 遠端存放庫 關閉目前頁面 - 切換到上一個頁面 切換到下一個頁面 + 切換到上一個頁面 新增頁面 開啟偏好設定面板 存放庫頁面快速鍵 @@ -378,11 +379,11 @@ 捨棄選取的變更 提取 (fetch) 遠端的變更 切換左邊欄為分支/標籤等顯示模式 (預設) + 切換左邊欄為歷史搜尋模式 拉取 (pull) 遠端的變更 推送 (push) 本機變更到遠端存放庫 強制重新載入存放庫 暫存或取消暫存選取的變更 - 切換左邊欄為歷史搜尋模式 顯示本機變更 顯示歷史記錄 顯示擱置變更列表 @@ -391,9 +392,9 @@ 前往下一個搜尋相符的位置 前往上一個搜尋相符的位置 開啟搜尋面板 + 捨棄 暫存 取消暫存 - 捨棄 初始化存放庫 路徑: 揀選 (cherry-pick) 操作進行中。 @@ -405,10 +406,10 @@ 復原提交操作進行中。 正在復原提交 互動式重定基底 - 目標分支: 起始提交: - 在瀏覽器中開啟連結 + 目標分支: 複製連結 + 在瀏覽器中開啟連結 發生錯誤 系統提示 合併分支 @@ -434,16 +435,16 @@ 複製存放庫路徑 新分頁 貼上 - 剛剛 - {0} 分鐘前 + {0} 天前 1 小時前 {0} 小時前 - 昨天 - {0} 天前 + 剛剛 上個月 - {0} 個月前 一年前 + {0} 分鐘前 + {0} 個月前 {0} 年前 + 昨天 偏好設定 AI 分析變更差異提示詞 @@ -484,24 +485,24 @@ 電子郵件 預設 Git 使用者電子郵件 拉取變更時進行清理 (--prune) + 本軟體要求 Git 最低版本為 2.23.0 安裝路徑 啟用 HTTP SSL 驗證 使用者名稱 預設 Git 使用者名稱 Git 版本 - 本軟體要求 Git 最低版本為 2.23.0 GPG 簽章 啟用提交簽章 - 啟用標籤簽章 GPG 簽章格式 可執行檔案路徑 填寫 gpg.exe 所在路徑 + 啟用標籤簽章 使用者簽章金鑰 填寫簽章提交所使用的金鑰 第三方工具整合 終端機/Shell - 終端機/Shell 安裝路徑 + 終端機/Shell 清理遠端已刪除分支 目標: 清理工作區 @@ -668,11 +669,11 @@ 提交統計 提交次數 提交者 + 總覽 本月 本週 - 提交次數: 貢獻者人數: - 總覽 + 提交次數: 子模組 新增子模組 複製路徑 @@ -687,13 +688,13 @@ 刪除 ${0}$... 合併 ${0}$ 到 ${1}$... 推送 ${0}$... - 存放庫網址: 更新子模組 更新所有子模組 啟用 [--init] 選項 啟用 [--recursive] 選項 子模組: 啟用 [--remote] 選項 + 存放庫網址: 警告 起始頁 新增群組 @@ -706,8 +707,8 @@ 開啟所有包含存放庫 開啟本機存放庫 開啟終端機 - 快速搜尋存放庫... 重新掃描預設複製 (clone) 目錄下的存放庫 + 快速搜尋存放庫... 排序 本機變更 加入至 .gitignore 忽略清單 @@ -723,13 +724,13 @@ 觸發點擊事件 提交 (修改原始提交) 自動暫存全部變更並提交 - 您已暫存 {0} 檔案,但只顯示 {1} 檔案 ({2} 檔案被篩選器隱藏)。您要繼續嗎? 未包含任何檔案變更! 您是否仍要提交 (--allow-empty)? 檢測到衝突 檔案衝突已解決 顯示未追蹤檔案 沒有提交訊息記錄 沒有可套用的提交訊息範本 + 請選擇發生衝突的檔案,開啟右鍵選單,選擇合適的解決方式 署名 已暫存 取消暫存選取的檔案 @@ -739,7 +740,6 @@ 暫存所有檔案 檢視不追蹤變更的檔案 範本: ${0}$ - 請選擇發生衝突的檔案,開啟右鍵選單,選擇合適的解決方式 工作區: 設定工作區... 本機工作區 From f29402ceec9f2c6fcf796c2a5248c656a2c46cb8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 7 Apr 2025 12:05:43 +0000 Subject: [PATCH 460/865] doc: Update translation status and missing keys --- TRANSLATION.md | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/TRANSLATION.md b/TRANSLATION.md index 0f44cbcf..2fd8672b 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -36,12 +36,13 @@ This document shows the translation status of each locale file in the repository
-### ![fr__FR](https://img.shields.io/badge/fr__FR-99.73%25-yellow) +### ![fr__FR](https://img.shields.io/badge/fr__FR-99.60%25-yellow)
Missing keys in fr_FR.axaml - Text.Configure.Git.PreferredMergeMode +- Text.PruneRemote - Text.WorkingCopy.ConfirmCommitWithFilter
@@ -147,16 +148,33 @@ This document shows the translation status of each locale file in the repository -### ![ru__RU](https://img.shields.io/badge/ru__RU-99.73%25-yellow) +### ![ru__RU](https://img.shields.io/badge/ru__RU-99.33%25-yellow)
Missing keys in ru_RU.axaml +- Text.BranchCM.CompareWithHead - Text.Configure.Git.PreferredMergeMode +- Text.Launcher.Error +- Text.Welcome.ScanDefaultCloneDir - Text.WorkingCopy.ConfirmCommitWithFilter
-### ![zh__CN](https://img.shields.io/badge/zh__CN-%E2%88%9A-brightgreen) +### ![zh__CN](https://img.shields.io/badge/zh__CN-99.87%25-yellow) -### ![zh__TW](https://img.shields.io/badge/zh__TW-%E2%88%9A-brightgreen) \ No newline at end of file +
+Missing keys in zh_CN.axaml + +- Text.WorkingCopy.ConfirmCommitWithFilter + +
+ +### ![zh__TW](https://img.shields.io/badge/zh__TW-99.87%25-yellow) + +
+Missing keys in zh_TW.axaml + +- Text.WorkingCopy.ConfirmCommitWithFilter + +
\ No newline at end of file From 2c5ee4fa99b00e25c49e144f8a105a910b5af62b Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 7 Apr 2025 20:19:00 +0800 Subject: [PATCH 461/865] localization: add keys deleted by sorter tools back Signed-off-by: leo --- src/Resources/Locales/fr_FR.axaml | 1 + src/Resources/Locales/ru_RU.axaml | 3 +++ src/Resources/Locales/zh_CN.axaml | 1 + src/Resources/Locales/zh_TW.axaml | 1 + 4 files changed, 6 insertions(+) diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index f3cf80eb..ac2ed8b8 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -505,6 +505,7 @@ SHELL/TERMINAL Chemin Shell/Terminal + Élaguer une branche distant Cible : Élaguer les Worktrees Élaguer les information de worktree dans `$GIT_COMMON_DIR/worktrees` diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index 7da65b5e..e778af86 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -43,6 +43,7 @@ Расследование РАССЛЕДОВАНИЕ В ЭТОМ ФАЙЛЕ НЕ ПОДДЕРЖИВАЕТСЯ!!! Проверить ${0}$... + Сравнить с ГОЛОВОЙ (HEAD) Сравнить с рабочим каталогом Копировать имя ветки Изменить действие @@ -409,6 +410,7 @@ Целевая ветка: Копировать ссылку Открыть в браузере + ОШИБКА УВЕДОМЛЕНИЕ Влить ветку В: @@ -706,6 +708,7 @@ Открыть все репозитории Открыть репозиторий Открыть терминал + Повторное сканирование репозиториев в каталоге клонирования по умолчанию Поиск репозиториев... Сортировка Изменения diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 281d6a4d..c1cbcc77 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -725,6 +725,7 @@ 触发点击事件 提交(修改原始提交) 自动暂存所有变更并提交 + 当前有 {0} 个文件在暂存区中,但仅显示了 {1} 个文件({2} 个文件被过滤掉了),是否继续提交? 提交未包含变更文件!是否继续(--allow-empty)? 检测到冲突 文件冲突已解决 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index e090fe2a..34dac155 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -724,6 +724,7 @@ 觸發點擊事件 提交 (修改原始提交) 自動暫存全部變更並提交 + 您已暫存 {0} 檔案,但只顯示 {1} 檔案 ({2} 檔案被篩選器隱藏)。您要繼續嗎? 未包含任何檔案變更! 您是否仍要提交 (--allow-empty)? 檢測到衝突 檔案衝突已解決 From 7fedef396f2f964a392cf9b422818eaf663d840d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 7 Apr 2025 12:19:19 +0000 Subject: [PATCH 462/865] doc: Update translation status and missing keys --- TRANSLATION.md | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/TRANSLATION.md b/TRANSLATION.md index 2fd8672b..0f44cbcf 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -36,13 +36,12 @@ This document shows the translation status of each locale file in the repository -### ![fr__FR](https://img.shields.io/badge/fr__FR-99.60%25-yellow) +### ![fr__FR](https://img.shields.io/badge/fr__FR-99.73%25-yellow)
Missing keys in fr_FR.axaml - Text.Configure.Git.PreferredMergeMode -- Text.PruneRemote - Text.WorkingCopy.ConfirmCommitWithFilter
@@ -148,33 +147,16 @@ This document shows the translation status of each locale file in the repository -### ![ru__RU](https://img.shields.io/badge/ru__RU-99.33%25-yellow) +### ![ru__RU](https://img.shields.io/badge/ru__RU-99.73%25-yellow)
Missing keys in ru_RU.axaml -- Text.BranchCM.CompareWithHead - Text.Configure.Git.PreferredMergeMode -- Text.Launcher.Error -- Text.Welcome.ScanDefaultCloneDir - Text.WorkingCopy.ConfirmCommitWithFilter
-### ![zh__CN](https://img.shields.io/badge/zh__CN-99.87%25-yellow) +### ![zh__CN](https://img.shields.io/badge/zh__CN-%E2%88%9A-brightgreen) -
-Missing keys in zh_CN.axaml - -- Text.WorkingCopy.ConfirmCommitWithFilter - -
- -### ![zh__TW](https://img.shields.io/badge/zh__TW-99.87%25-yellow) - -
-Missing keys in zh_TW.axaml - -- Text.WorkingCopy.ConfirmCommitWithFilter - -
\ No newline at end of file +### ![zh__TW](https://img.shields.io/badge/zh__TW-%E2%88%9A-brightgreen) \ No newline at end of file From 1555abd027cbf2d9eafdba88edb8ff76995305db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6ran=20W?= <44604769+goran-w@users.noreply.github.com> Date: Mon, 7 Apr 2025 14:22:53 +0200 Subject: [PATCH 463/865] Added new ExternalMerger - Plastic SCM (#1162) Motivation: https://m-pixel.com/how-to-use-plastic-scms-merge-tool-with-p4v/ --- src/Models/ExternalMerger.cs | 1 + .../Images/ExternalToolIcons/plastic_merge.png | Bin 0 -> 6369 bytes 2 files changed, 1 insertion(+) create mode 100644 src/Resources/Images/ExternalToolIcons/plastic_merge.png diff --git a/src/Models/ExternalMerger.cs b/src/Models/ExternalMerger.cs index 49d31df5..d97d3933 100644 --- a/src/Models/ExternalMerger.cs +++ b/src/Models/ExternalMerger.cs @@ -42,6 +42,7 @@ namespace SourceGit.Models new ExternalMerger(7, "win_merge", "WinMerge", "WinMergeU.exe", "\"$MERGED\"", "-u -e -sw \"$LOCAL\" \"$REMOTE\""), new ExternalMerger(8, "codium", "VSCodium", "VSCodium.exe", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""), new ExternalMerger(9, "p4merge", "P4Merge", "p4merge.exe", "-tw 4 \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"", "-tw 4 \"$LOCAL\" \"$REMOTE\""), + new ExternalMerger(10, "plastic_merge", "Plastic SCM", "mergetool.exe", "-s=\"$REMOTE\" -b=\"$BASE\" -d=\"$LOCAL\" -r=\"$MERGED\" --automatic", "-s=\"$LOCAL\" -d=\"$REMOTE\""), }; } else if (OperatingSystem.IsMacOS()) diff --git a/src/Resources/Images/ExternalToolIcons/plastic_merge.png b/src/Resources/Images/ExternalToolIcons/plastic_merge.png new file mode 100644 index 0000000000000000000000000000000000000000..0d82fc86f7f266a9be39ed16757d02f609febcc3 GIT binary patch literal 6369 zcmeH~c{G&m|Ho&{WQ(#!Lemt9W*^KwTFLZy**GEfR)vc_2y>9}S|wIBqx$ z7I%;D6{K+qjcF_ zSm3bk#E$K0K4mQRrI~g1<+F@)674h{_V)Ig)X&lXz^tIvQwCr3m@00Xk9xIf-{BpZ z6D`Hp(U(%6B%W;?uiv1cSV{A_W-I4q-hR1sFRQ2?Eg!0GtG3`OdMUxjb70Qsuzu+H z@W?yt-zU#@e56ih?QMe>PWqv&Z5M=hN01U1KZEb zb?nr8Kcv4llUeb$`oZ~%HAgS_Tp&1gnuMCvS42PRt++j}LhSkJoQrGF-)r-qDta>= z_2#DSzG17nj+u7z*d7+zeadzA=jtaNyWNfbRd?#Y=}J~^8%h2A*K5JG(Z0>OTCQ>l zxVn!7Wn^qh%+0!%41QyR+(bc&S><4NB%D-GY}pt%q^R2^kF9Dvcvd0!70ki2f#b5P z@6RQf?b4~a2|nt&XJ?!%7YOqc^60Sm7i*r&Qz*zwrkPDoM_zdeg`W>Se>;vikSD5p z(N}B<)m#i0sx2mC1&uA_V*!qk1!Cj)(NNLBU{*G9(EvLNl%QB(1Xo~zapR~YjmVU5>3P5Vq;^m zu_UZe6oDg9sZ<=Eh$9j)kOf8@FOUFn7=d`94Dp5G2#VPvZnT6e6rf~GfF)cfu|}hz zanv{e_|Xi;cf3ISRRu^7TpSRMBVh43J|Fkv46(#127-Kb=s(U7`$Ah3=M9R5>qKnO zDFzfs7XFA>?#l4`PLPEZ!R1F!2L*}u(_$RP za}vgq%)(>HR4RaBS+L0%B7s0AQwac`g$I5>xeCM*K)?oNCRj4 zL*}sY7#5L8#aKXj=71D}C51@(0pTg)LRAUye)LL);y@@$I7lLr03wD(0*M$h3!q{E z8I%J84T0g=p@8_KMKF<1^N2l{C&;Ce{%^G z>h~hQr0;LJe#`Ys3jC7s@9O$3*DopXOUA#e>;FwI<$ph>Kmqgy6bpSS1*vGfgg&$6 zS?;DfZ~~RX$@`ZV$nmhEgHKlaA?S!L zy-`wHA;Er#TrGdivvcON&w6sFQV~3P0i&y5J1l*4Sl%3d@9~@-LXQ|cHi4ef1`H_5Lm!;+lLmcNCDJ=wCCAjyo!G+*Wh6Gk;}%`%*deiyyV=+B^2(D_c63Y)5Wi`nT7g+&6*8y; zc}l5vzWoM}U)^!JqGgZQ0J_k_Fg6``+{bW0^`lTNYJZe&$Ber+7hd=haFfJghp>vr zPDyGuLeDT)6QCzF{#SBn+JM*$i6zU3z^#F&T8%3Tov!K zF+No8;hT$SdYIZrZM=WHB-g?|W3F@noDoS(xigD#53sC0jT}xJ3VB%_w2XXlG8(_t zc&<`mG2q&&ur&Lii-KN|KE7Q-iS@a0CVJ9D!uv`1qp&Q%_qUE5z#q9~d~~1rlt_G>_M?X417wZ2Y1;JuxC1EM`$`e zwcmMYiIo1b+I`srEw<_guTws_%w6?6>*|VchDGE|GE^pNS;#@ z8o3Wu-&!cPh-O|=d-SMP>?Ccc&nifVwS-uZxv2%7{)Q*_4qe%v7RQLcDpxwM*FleY z#K3S@SASlaBfV#PU#c+ZkN1Y1;gr0kUWS;Gp>~I~xRvpzU^5*fe1ocNv=2shW}#5G zW_wCXx8_rF4mU<$++O4QVPo#|%jE_Zm%HN->h~AXc@4d-MYana;#&w4Tk95p8u(Y< zg;!(Es>*MYi#OD0wP)%OUBv&ei(-2B8HpZ+mKy9r%qz>1j)h!W%cI&}sZIWjdKH}0 z`z|RUzDEf$v2@tfj*oiSnsW!f+|jto+71z~XS!QZ$?>T67dytkb%wR9UZ%hM>h(Ve zYXq>EHQNyPlx+G;GD6l&<;a&K;pv)7?iFcMn36Hie@fvBCAfa%>2f>UXN9}+YqAeD zGM%4R%IjX#kgr#r8#y!XG;DFV$BhHqZoF$!Io=uGa~}6+KxeI+ZChm{?6Xx)?^QJh zyUBR<&24Fc@DO*u`^iC4ZO60alpAG7%WsfxMQts4=LZj|Md`+0e!WuPCU?`;a)oA7 zyWv3Ll25JoKPw$Qx6C56r1_3K{6H|EV8?%5qS4TVT;V6++zwDR)w$fKtUx+*j=X8j z>k-`>Po!4;M8+9?m4}E9qZtpZOxU)@{?RGvNbp@RTNrYP;ft*TJ_fk$exx6~>@T#& zsFc=SSBL1%Y|SvUyiL3w;H*~MlkJq2r>}+7QeUgj^uYd=PHgvAGPPOhny~}p4~TE;h{1*ne14u0t)ee#MM? zXOlxUN2ZRtF{KIG)e`~I1>JRq@Ay%1D#MRy?MINEfab(QTX&VX#~=KpHaxC*OY45x@g+}_8#CK^{UY+#t5ZEq8ceNA&DiSsWvXLb&&fK! zoHlI>zvQ$UsZTRM0nv5iR%>lSPf=LaN-{67CK_j_`b1L_2E-jZTFY(-tx<} zO|whaEGQ0{A0slZe{mw@%+^6t0Ntd9?Ge0U`y$jnGs#3>_KFNr8hu{)LkD{c z6P=U;kW(`z;NYs@E4;-i3R&$Pny{9AJ$r8%C`l57&hT*DxmWv??<>7}#LLXjE@O=H zqxK1d`iJH<^jT}J=vkLNxGp>2wh{ip>Be2H8T1is$LY#+R=DdJG9qPLO67sz1+VYl zo}ZH8q-1HXL!W)h%(8BBLtBS`+T1@i_fMJjA2f3@;)@gRAM}U@o-b6o(2cG)sa2bZ z+*wkFe0s>JUOBeO?k!GZSz>{fPutYSB#~RuEd;ThJvsPxE%MpYSeI2MZQ%3Qg?CF2 zEx}NO#_U>8SGpHmTzYtZ`b)f=BzrCKN#)j84}%-9ud~Ogj20jFX8uETYSZZ!WLg0Z zvC3%p%|LS2m426`OQAIn4hn-vi|7vmP2uaYbGB1Y3_Xf`HoAS{{md-gSf?Es&H3Ji zbL0loKT%G+HXUBPH-WrPZvuO;vSc#8Q_BJdIPUaCk=Y7~nxE`!J z>~}Jmej6VsQYNL$sY#x-sk|mPE2{ZnK--vb<7C-wJt?sOdR>9JI(ax&*@tcVAGdk& A_y7O^ literal 0 HcmV?d00001 From 7cda7211f1035a63bf444c57051a308cebbe8d48 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 7 Apr 2025 21:20:59 +0800 Subject: [PATCH 464/865] refactor: statistics dialog - use `%aN+%aE` instead of `%aN` to get commit author - show user avatar in statistics dialog Signed-off-by: leo --- src/Commands/Statistics.cs | 2 +- src/Models/Statistics.cs | 16 +++++++++------- src/Views/Statistics.axaml | 16 ++++++++++------ 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/Commands/Statistics.cs b/src/Commands/Statistics.cs index 1439cedd..41b3889e 100644 --- a/src/Commands/Statistics.cs +++ b/src/Commands/Statistics.cs @@ -8,7 +8,7 @@ namespace SourceGit.Commands { WorkingDirectory = repo; Context = repo; - Args = $"log --date-order --branches --remotes -{max} --format=%ct$%aN"; + Args = $"log --date-order --branches --remotes -{max} --format=%ct$%aN±%aE"; } public Models.Statistics Result() diff --git a/src/Models/Statistics.cs b/src/Models/Statistics.cs index 969d3945..87a6eabd 100644 --- a/src/Models/Statistics.cs +++ b/src/Models/Statistics.cs @@ -18,9 +18,9 @@ namespace SourceGit.Models ThisWeek, } - public class StaticsticsAuthor(string name, int count) + public class StaticsticsAuthor(User user, int count) { - public string Name { get; set; } = name; + public User User { get; set; } = user; public int Count { get; set; } = count; } @@ -73,7 +73,7 @@ namespace SourceGit.Models } } - public void AddCommit(DateTime time, string author) + public void AddCommit(DateTime time, User author) { Total++; @@ -126,7 +126,7 @@ namespace SourceGit.Models } private StaticsticsMode _mode = StaticsticsMode.All; - private Dictionary _mapUsers = new Dictionary(); + private Dictionary _mapUsers = new Dictionary(); private Dictionary _mapSamples = new Dictionary(); } @@ -150,14 +150,16 @@ namespace SourceGit.Models public void AddCommit(string author, double timestamp) { + var user = User.FindOrAdd(author); + var time = DateTime.UnixEpoch.AddSeconds(timestamp).ToLocalTime(); if (time >= _thisWeekStart) - Week.AddCommit(time, author); + Week.AddCommit(time, user); if (time >= _thisMonthStart) - Month.AddCommit(time, author); + Month.AddCommit(time, user); - All.AddCommit(time, author); + All.AddCommit(time, user); } public void Complete() diff --git a/src/Views/Statistics.axaml b/src/Views/Statistics.axaml index 0c002407..3bbdafbe 100644 --- a/src/Views/Statistics.axaml +++ b/src/Views/Statistics.axaml @@ -136,7 +136,7 @@ - + - - - + + + + - + @@ -177,7 +181,7 @@ - + From da38b72ee5b3f653bfd197975a73b66ef430b571 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 8 Apr 2025 18:03:40 +0800 Subject: [PATCH 465/865] ux: disable commit button when commit message is empty Signed-off-by: leo --- src/Converters/StringConverters.cs | 3 +++ src/ViewModels/WorkingCopy.cs | 9 +++------ src/Views/WorkingCopy.axaml | 30 +++++++++++++++++++++++++----- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/Converters/StringConverters.cs b/src/Converters/StringConverters.cs index 5e4608c5..bcadfae9 100644 --- a/src/Converters/StringConverters.cs +++ b/src/Converters/StringConverters.cs @@ -81,5 +81,8 @@ namespace SourceGit.Converters public static readonly FuncValueConverter ContainsSpaces = new FuncValueConverter(v => v != null && v.Contains(' ')); + + public static readonly FuncValueConverter IsNotNullOrWhitespace = + new FuncValueConverter(v => v != null && v.Trim().Length > 0); } } diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index a0933ea3..784328cc 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -1652,6 +1652,9 @@ namespace SourceGit.ViewModels private void DoCommit(bool autoStage, bool autoPush, bool allowEmpty = false, bool confirmWithFilter = false) { + if (string.IsNullOrWhiteSpace(_commitMessage)) + return; + if (!_repo.CanCreatePopup()) { App.RaiseException(_repo.FullPath, "Repository has unfinished job! Please wait!"); @@ -1672,12 +1675,6 @@ namespace SourceGit.ViewModels return; } - if (string.IsNullOrWhiteSpace(_commitMessage)) - { - App.RaiseException(_repo.FullPath, "Commit without message is NOT allowed!"); - return; - } - if (!_useAmend && !allowEmpty) { if ((autoStage && _count == 0) || (!autoStage && _staged.Count == 0)) diff --git a/src/Views/WorkingCopy.axaml b/src/Views/WorkingCopy.axaml index 94dd0c30..4ca854fa 100644 --- a/src/Views/WorkingCopy.axaml +++ b/src/Views/WorkingCopy.axaml @@ -295,7 +295,9 @@ - + @@ -309,7 +311,6 @@ Command="{Binding Commit}" HotKey="{OnPlatform Ctrl+Enter, macOS=⌘+Enter}" IsVisible="{Binding InProgressContext, Converter={x:Static ObjectConverters.IsNull}}" - IsEnabled="{Binding !IsCommitting}" ToolTip.Placement="Top" ToolTip.VerticalOffset="0"> @@ -324,6 +325,13 @@ + + + + + + + @@ -331,8 +339,14 @@ Width="0" Height="0" Background="Transparent" Command="{Binding CommitWithAutoStage}" - HotKey="{OnPlatform Ctrl+Shift+Enter, macOS=⌘+Shift+Enter}" - IsEnabled="{Binding !IsCommitting}"/> + HotKey="{OnPlatform Ctrl+Shift+Enter, macOS=⌘+Shift+Enter}"> + + + + + + + + - - - - From a99ab377977776cf0c45c483fd6fa3b44fc09265 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 11 Apr 2025 01:33:18 +0000 Subject: [PATCH 473/865] doc: Update translation status and missing keys --- TRANSLATION.md | 66 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 9 deletions(-) diff --git a/TRANSLATION.md b/TRANSLATION.md index 0a469262..aee13ea5 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -6,7 +6,7 @@ This document shows the translation status of each locale file in the repository ### ![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen) -### ![de__DE](https://img.shields.io/badge/de__DE-97.86%25-yellow) +### ![de__DE](https://img.shields.io/badge/de__DE-97.34%25-yellow)
Missing keys in de_DE.axaml @@ -27,10 +27,14 @@ This document shows the translation status of each locale file in the repository - Text.Preferences.General.ShowTagsInGraph - Text.StashCM.SaveAsPatch - Text.WorkingCopy.ConfirmCommitWithFilter +- Text.WorkingCopy.Conflicts.OpenExternalMergeTool +- Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts +- Text.WorkingCopy.Conflicts.UseMine +- Text.WorkingCopy.Conflicts.UseTheirs
-### ![es__ES](https://img.shields.io/badge/es__ES-99.20%25-yellow) +### ![es__ES](https://img.shields.io/badge/es__ES-98.67%25-yellow)
Missing keys in es_ES.axaml @@ -41,10 +45,14 @@ This document shows the translation status of each locale file in the repository - Text.ConfirmEmptyCommit.Continue - Text.ConfirmEmptyCommit.StageAllThenCommit - Text.WorkingCopy.ConfirmCommitWithFilter +- Text.WorkingCopy.Conflicts.OpenExternalMergeTool +- Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts +- Text.WorkingCopy.Conflicts.UseMine +- Text.WorkingCopy.Conflicts.UseTheirs
-### ![fr__FR](https://img.shields.io/badge/fr__FR-99.20%25-yellow) +### ![fr__FR](https://img.shields.io/badge/fr__FR-98.67%25-yellow)
Missing keys in fr_FR.axaml @@ -55,10 +63,14 @@ This document shows the translation status of each locale file in the repository - Text.ConfirmEmptyCommit.Continue - Text.ConfirmEmptyCommit.StageAllThenCommit - Text.WorkingCopy.ConfirmCommitWithFilter +- Text.WorkingCopy.Conflicts.OpenExternalMergeTool +- Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts +- Text.WorkingCopy.Conflicts.UseMine +- Text.WorkingCopy.Conflicts.UseTheirs
-### ![it__IT](https://img.shields.io/badge/it__IT-98.93%25-yellow) +### ![it__IT](https://img.shields.io/badge/it__IT-98.40%25-yellow)
Missing keys in it_IT.axaml @@ -71,10 +83,14 @@ This document shows the translation status of each locale file in the repository - Text.CopyFullPath - Text.Preferences.General.ShowTagsInGraph - Text.WorkingCopy.ConfirmCommitWithFilter +- Text.WorkingCopy.Conflicts.OpenExternalMergeTool +- Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts +- Text.WorkingCopy.Conflicts.UseMine +- Text.WorkingCopy.Conflicts.UseTheirs
-### ![ja__JP](https://img.shields.io/badge/ja__JP-98.93%25-yellow) +### ![ja__JP](https://img.shields.io/badge/ja__JP-98.40%25-yellow)
Missing keys in ja_JP.axaml @@ -87,10 +103,14 @@ This document shows the translation status of each locale file in the repository - Text.Repository.FilterCommits - Text.Repository.Tags.OrderByNameDes - Text.WorkingCopy.ConfirmCommitWithFilter +- Text.WorkingCopy.Conflicts.OpenExternalMergeTool +- Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts +- Text.WorkingCopy.Conflicts.UseMine +- Text.WorkingCopy.Conflicts.UseTheirs
-### ![pt__BR](https://img.shields.io/badge/pt__BR-90.24%25-yellow) +### ![pt__BR](https://img.shields.io/badge/pt__BR-89.76%25-yellow)
Missing keys in pt_BR.axaml @@ -167,11 +187,15 @@ This document shows the translation status of each locale file in the repository - Text.StashCM.SaveAsPatch - Text.WorkingCopy.CommitToEdit - Text.WorkingCopy.ConfirmCommitWithFilter +- Text.WorkingCopy.Conflicts.OpenExternalMergeTool +- Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts +- Text.WorkingCopy.Conflicts.UseMine +- Text.WorkingCopy.Conflicts.UseTheirs - Text.WorkingCopy.SignOff
-### ![ru__RU](https://img.shields.io/badge/ru__RU-99.20%25-yellow) +### ![ru__RU](https://img.shields.io/badge/ru__RU-98.67%25-yellow)
Missing keys in ru_RU.axaml @@ -182,9 +206,33 @@ This document shows the translation status of each locale file in the repository - Text.ConfirmEmptyCommit.Continue - Text.ConfirmEmptyCommit.StageAllThenCommit - Text.WorkingCopy.ConfirmCommitWithFilter +- Text.WorkingCopy.Conflicts.OpenExternalMergeTool +- Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts +- Text.WorkingCopy.Conflicts.UseMine +- Text.WorkingCopy.Conflicts.UseTheirs
-### ![zh__CN](https://img.shields.io/badge/zh__CN-%E2%88%9A-brightgreen) +### ![zh__CN](https://img.shields.io/badge/zh__CN-99.47%25-yellow) -### ![zh__TW](https://img.shields.io/badge/zh__TW-%E2%88%9A-brightgreen) \ No newline at end of file +
+Missing keys in zh_CN.axaml + +- Text.WorkingCopy.Conflicts.OpenExternalMergeTool +- Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts +- Text.WorkingCopy.Conflicts.UseMine +- Text.WorkingCopy.Conflicts.UseTheirs + +
+ +### ![zh__TW](https://img.shields.io/badge/zh__TW-99.47%25-yellow) + +
+Missing keys in zh_TW.axaml + +- Text.WorkingCopy.Conflicts.OpenExternalMergeTool +- Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts +- Text.WorkingCopy.Conflicts.UseMine +- Text.WorkingCopy.Conflicts.UseTheirs + +
\ No newline at end of file From 1799de4907c9b01290cd9e9700c80717b1238b41 Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 11 Apr 2025 10:02:33 +0800 Subject: [PATCH 474/865] code_review: PR #1173 - rename c-style `file_arg` to `fileArg` - add missing translations for zh_CN and zh_TW - re-design conflict view and add tooltip for `USE THEIRS` and `USE MINE` - re-order unstaged toolbar buttons Signed-off-by: leo --- src/Commands/MergeTool.cs | 6 +- src/Resources/Locales/zh_CN.axaml | 4 + src/Resources/Locales/zh_TW.axaml | 4 + src/Views/Conflict.axaml | 167 ++++++++++++++++-------------- src/Views/WorkingCopy.axaml | 26 ++--- 5 files changed, 115 insertions(+), 92 deletions(-) diff --git a/src/Commands/MergeTool.cs b/src/Commands/MergeTool.cs index 276c078b..f67f5e48 100644 --- a/src/Commands/MergeTool.cs +++ b/src/Commands/MergeTool.cs @@ -14,11 +14,11 @@ namespace SourceGit.Commands cmd.RaiseError = true; // NOTE: If no names are specified, 'git mergetool' will run the merge tool program on every file with merge conflicts. - var file_arg = string.IsNullOrEmpty(file) ? "" : $"\"{file}\""; + var fileArg = string.IsNullOrEmpty(file) ? "" : $"\"{file}\""; if (toolType == 0) { - cmd.Args = $"mergetool {file_arg}"; + cmd.Args = $"mergetool {fileArg}"; return cmd.Exec(); } @@ -35,7 +35,7 @@ namespace SourceGit.Commands return false; } - cmd.Args = $"-c mergetool.sourcegit.cmd=\"\\\"{toolPath}\\\" {supported.Cmd}\" -c mergetool.writeToTemp=true -c mergetool.keepBackup=false -c mergetool.trustExitCode=true mergetool --tool=sourcegit {file_arg}"; + cmd.Args = $"-c mergetool.sourcegit.cmd=\"\\\"{toolPath}\\\" {supported.Cmd}\" -c mergetool.writeToTemp=true -c mergetool.keepBackup=false -c mergetool.trustExitCode=true mergetool --tool=sourcegit {fileArg}"; return cmd.Exec(); } diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index b303374f..1b878b29 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -731,7 +731,11 @@ 自动暂存所有变更并提交 当前有 {0} 个文件在暂存区中,但仅显示了 {1} 个文件({2} 个文件被过滤掉了),是否继续提交? 检测到冲突 + 打开合并工具 + 打开合并工具解决冲突 文件冲突已解决 + 使用 MINE + 使用 THEIRS 显示未跟踪文件 没有提交信息记录 没有可应用的提交信息模板 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 4239667f..e090d32d 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -730,7 +730,11 @@ 自動暫存全部變更並提交 您已暫存 {0} 檔案,但只顯示 {1} 檔案 ({2} 檔案被篩選器隱藏)。您要繼續嗎? 檢測到衝突 + 使用外部合併工具開啟 + 使用外部合併工具開啟 檔案衝突已解決 + 使用 MINE + 使用 THEIRS 顯示未追蹤檔案 沒有提交訊息記錄 沒有可套用的提交訊息範本 diff --git a/src/Views/Conflict.axaml b/src/Views/Conflict.axaml index 7f13f14e..f2d7bdec 100644 --- a/src/Views/Conflict.axaml +++ b/src/Views/Conflict.axaml @@ -12,83 +12,83 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -105,9 +105,24 @@ - + + diff --git a/src/Views/WorkingCopy.axaml b/src/Views/WorkingCopy.axaml index 7d471142..41d80b04 100644 --- a/src/Views/WorkingCopy.axaml +++ b/src/Views/WorkingCopy.axaml @@ -68,6 +68,19 @@ + + - - + + +
diff --git a/src/Views/ConfigureWorkspace.axaml.cs b/src/Views/ConfigureWorkspace.axaml.cs index 9e458f6f..8ef5dec7 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 @@ namespace SourceGit.Views 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 b7aa49403bdb3805460b1c70d7e3b7fa4887c13c Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 14 Apr 2025 17:03:08 +0800 Subject: [PATCH 492/865] code_review: PR #1183 - code style in `Clone` constructor - re-design workspace configuration dialog Signed-off-by: leo --- src/Resources/Locales/de_DE.axaml | 1 + src/Resources/Locales/en_US.axaml | 1 + src/Resources/Locales/es_ES.axaml | 1 + src/Resources/Locales/fr_FR.axaml | 1 + src/Resources/Locales/it_IT.axaml | 1 + src/Resources/Locales/ja_JP.axaml | 1 + src/Resources/Locales/pt_BR.axaml | 1 + src/Resources/Locales/ta_IN.axaml | 1 + src/Resources/Locales/zh_CN.axaml | 1 + src/Resources/Locales/zh_TW.axaml | 1 + src/ViewModels/Clone.cs | 17 +++++------------ src/Views/ConfigureWorkspace.axaml | 29 +++++++++++++++++------------ 12 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index 1ceac07c..3cb70cea 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -176,6 +176,7 @@ Benutzername für dieses Repository Arbeitsplätze Farbe + Name Zuletzt geöffnete Tabs beim Starten wiederherstellen Konventionelle Commit-Hilfe Breaking Change: diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 7ec38670..7e931998 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -176,6 +176,7 @@ User name for this repository Workspaces Color + Name Restore tabs on startup CONTINUE Empty commit detected! Do you want to continue (--allow-empty)? diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index 04fdde4b..24deeabd 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -179,6 +179,7 @@ Nombre de usuario para este repositorio Espacios de Trabajo Color + Nombre Restaurar pestañas al iniciar Asistente de Commit Convencional Cambio Importante: diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index f5679ab8..61098493 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -180,6 +180,7 @@ Nom d'utilisateur pour ce dépôt Espaces de travail Couleur + Nom Restaurer les onglets au démarrage Assistant Commits Conventionnels Changement Radical : diff --git a/src/Resources/Locales/it_IT.axaml b/src/Resources/Locales/it_IT.axaml index 5ed81da2..1d9901a8 100644 --- a/src/Resources/Locales/it_IT.axaml +++ b/src/Resources/Locales/it_IT.axaml @@ -179,6 +179,7 @@ Nome utente per questo repository Spazi di Lavoro Colore + Nome Ripristina schede all'avvio Guida Commit Convenzionali Modifica Sostanziale: diff --git a/src/Resources/Locales/ja_JP.axaml b/src/Resources/Locales/ja_JP.axaml index 1b94ed6f..db671768 100644 --- a/src/Resources/Locales/ja_JP.axaml +++ b/src/Resources/Locales/ja_JP.axaml @@ -179,6 +179,7 @@ このリポジトリにおけるユーザー名 ワークスペース + 名前 起動時にタブを復元 Conventional Commitヘルパー 破壊的変更: diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml index e78c1a36..299ececd 100644 --- a/src/Resources/Locales/pt_BR.axaml +++ b/src/Resources/Locales/pt_BR.axaml @@ -161,6 +161,7 @@ Nome de usuário para este repositório Workspaces Cor + Nome Restaurar abas ao inicializar Assistente de Conventional Commit Breaking Change: diff --git a/src/Resources/Locales/ta_IN.axaml b/src/Resources/Locales/ta_IN.axaml index 30c2244b..d8d6f540 100644 --- a/src/Resources/Locales/ta_IN.axaml +++ b/src/Resources/Locales/ta_IN.axaml @@ -179,6 +179,7 @@ இந்த களஞ்சியத்திற்கான பயனர் பெயர் பணியிடங்கள் நிறம் + பெயர் தாவல்களை மீட்டமை வழக்கமான உறுதிமொழி உதவியாளர் உடைக்கும் மாற்றம்: diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index d8b63422..9040644a 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -180,6 +180,7 @@ 应用于本仓库的用户名 工作区 颜色 + 名称 启动时恢复打开的仓库 确认继续 提交未包含变更文件!是否继续(--allow-empty)? diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 833e6610..8437eefc 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -180,6 +180,7 @@ 用於本存放庫的使用者名稱 工作區 顏色 + 名稱 啟動時還原上次開啟的存放庫 确认继续 未包含任何檔案變更! 您是否仍要提交 (--allow-empty)? diff --git a/src/ViewModels/Clone.cs b/src/ViewModels/Clone.cs index 2b7c2580..97c90523 100644 --- a/src/ViewModels/Clone.cs +++ b/src/ViewModels/Clone.cs @@ -62,18 +62,13 @@ namespace SourceGit.ViewModels 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; - } + _parentFolder = activeWorkspace?.DefaultCloneDir; + if (string.IsNullOrEmpty(ParentFolder)) + _parentFolder = Preferences.Instance.GitDefaultCloneDir; + + View = new Views.Clone() { DataContext = this }; Task.Run(async () => { @@ -81,9 +76,7 @@ namespace SourceGit.ViewModels { var text = await App.GetClipboardTextAsync(); if (Models.Remote.IsValidURL(text)) - { Dispatcher.UIThread.Invoke(() => Remote = text); - } } catch { diff --git a/src/Views/ConfigureWorkspace.axaml b/src/Views/ConfigureWorkspace.axaml index 0bef89b9..169df154 100644 --- a/src/Views/ConfigureWorkspace.axaml +++ b/src/Views/ConfigureWorkspace.axaml @@ -98,20 +98,25 @@ - - - + + + + + + + + + + + + + + - - - - - - - From 558eb7c9ac0ddff802047227e806770e303526cb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 14 Apr 2025 09:03:23 +0000 Subject: [PATCH 493/865] doc: Update translation status and missing keys --- TRANSLATION.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/TRANSLATION.md b/TRANSLATION.md index a2991c6e..7ae5b13f 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -70,7 +70,7 @@ This document shows the translation status of each locale file in the repository -### ![it__IT](https://img.shields.io/badge/it__IT-98.40%25-yellow) +### ![it__IT](https://img.shields.io/badge/it__IT-98.41%25-yellow)
Missing keys in it_IT.axaml @@ -90,7 +90,7 @@ This document shows the translation status of each locale file in the repository
-### ![ja__JP](https://img.shields.io/badge/ja__JP-98.40%25-yellow) +### ![ja__JP](https://img.shields.io/badge/ja__JP-98.41%25-yellow)
Missing keys in ja_JP.axaml @@ -110,7 +110,7 @@ This document shows the translation status of each locale file in the repository
-### ![pt__BR](https://img.shields.io/badge/pt__BR-89.76%25-yellow) +### ![pt__BR](https://img.shields.io/badge/pt__BR-89.77%25-yellow)
Missing keys in pt_BR.axaml From 09c0edef8e97f00e3dc479a2abd02ca416ac9d78 Mon Sep 17 00:00:00 2001 From: Massimo Date: Mon, 14 Apr 2025 13:16:15 +0200 Subject: [PATCH 494/865] feat: implement IPC for opening repositories in new tabs (#1185) * 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. * 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. * revert: Typo in DiffResult comment * revert: update diff arguments to ignore CR at EOL in whitespace handling (like before changes) * revert: update translations to remove EOF references in Text.Apply.IgnoreWS and fixed typo in Text.Diff.IgnoreWhitespace (EOF => EOL) * 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 * 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 --------- Co-authored-by: mpagani --- 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 0448a247..b1be7072 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -2,12 +2,14 @@ using System; 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 @@ namespace SourceGit 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 @@ namespace SourceGit 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 @@ namespace SourceGit 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 @@ namespace SourceGit _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 @@ namespace SourceGit 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 7e931998..123b6381 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 cad6c224..d1e78d6a 100644 --- a/src/ViewModels/Preferences.cs +++ b/src/ViewModels/Preferences.cs @@ -90,6 +90,12 @@ namespace SourceGit.ViewModels } } + public bool OpenReposInNewTab + { + get => _openReposInNewTab; + set => SetProperty(ref _openReposInNewTab, value); + } + public bool UseSystemWindowFrame { get => _useSystemWindowFrame; @@ -632,6 +638,7 @@ namespace SourceGit.ViewModels 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 702ec20f..704757df 100644 --- a/src/Views/Preferences.axaml +++ b/src/Views/Preferences.axaml @@ -46,7 +46,7 @@ - + + + Date: Mon, 14 Apr 2025 22:03:51 +0800 Subject: [PATCH 495/865] code_review: PR #1185 - make `SourceGit` running in singleton mode - `TrySendArgsToExistingInstance` should not be called before `BuildAvaloniaApp().StartWithClassicDesktopLifetime(args)` since we may want to launch `SourceGit` as a core editor. - avoid `preference.json` to be saved by multiple instances. - move IPC code to models. Signed-off-by: leo --- src/App.axaml.cs | 166 +++++------------------------- src/Models/IpcChannel.cs | 97 +++++++++++++++++ src/Resources/Locales/en_US.axaml | 1 - src/ViewModels/Preferences.cs | 15 ++- src/Views/Preferences.axaml | 7 +- 5 files changed, 133 insertions(+), 153 deletions(-) create mode 100644 src/Models/IpcChannel.cs diff --git a/src/App.axaml.cs b/src/App.axaml.cs index b1be7072..6504e85b 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -2,14 +2,12 @@ using System; 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; @@ -48,8 +46,6 @@ namespace SourceGit Environment.Exit(exitTodo); else if (TryLaunchAsRebaseMessageEditor(args, out int exitMessage)) Environment.Exit(exitMessage); - else if (TrySendArgsToExistingInstance(args)) - Environment.Exit(0); else BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); } @@ -81,44 +77,6 @@ namespace SourceGit 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) @@ -370,13 +328,7 @@ namespace SourceGit AvaloniaXamlLoader.Load(this); var pref = ViewModels.Preferences.Instance; - - pref.PropertyChanged += (s, e) => { - pref.Save(); - - if (e.PropertyName.Equals(nameof(ViewModels.Preferences.OpenReposInNewTab))) - HandleOpenReposInNewTabChanged(); - }; + pref.PropertyChanged += (_, _) => pref.Save(); SetLocale(pref.Locale); SetTheme(pref.Theme, pref.ThemeOverrides); @@ -395,7 +347,17 @@ namespace SourceGit if (TryLaunchAsAskpass(desktop)) return; - TryLaunchAsNormal(desktop); + _ipcChannel = new Models.IpcChannel(); + if (!_ipcChannel.IsFirstInstance) + { + _ipcChannel.SendToFirstInstance(desktop.Args is { Length: 1 } ? desktop.Args[0] : string.Empty); + Quit(0); + } + else + { + _ipcChannel.MessageReceived += TryOpenRepository; + TryLaunchAsNormal(desktop); + } } } #endregion @@ -533,12 +495,12 @@ namespace SourceGit if (desktop.Args != null && desktop.Args.Length == 1 && Directory.Exists(desktop.Args[0])) startupRepo = desktop.Args[0]; + var pref = ViewModels.Preferences.Instance; + pref.SetCanModify(); + _launcher = new ViewModels.Launcher(startupRepo); desktop.MainWindow = new Views.Launcher() { DataContext = _launcher }; - - var pref = ViewModels.Preferences.Instance; - - HandleOpenReposInNewTabChanged(); + desktop.Exit += (_, _) => _ipcChannel.Dispose(); #if !DISABLE_UPDATE_DETECTION if (pref.ShouldCheck4UpdateOnStartup()) @@ -546,91 +508,20 @@ namespace SourceGit #endif } - private void HandleOpenReposInNewTabChanged() + private void TryOpenRepository(string repo) { - var pref = ViewModels.Preferences.Instance; - - if (pref.OpenReposInNewTab) + if (string.IsNullOrEmpty(repo) || !Directory.Exists(repo)) + return; + + var test = new Commands.QueryRepositoryRootPath(repo).ReadToEnd(); + if (test.IsSuccess && !string.IsNullOrEmpty(test.StdOut)) { - if (_ipcServerTask == null || _ipcServerTask.IsCompleted) + Dispatcher.UIThread.Invoke(() => { - // 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 + var node = ViewModels.Preferences.Instance.FindOrAddNodeByRepositoryPath(test.StdOut.Trim(), null, false); + ViewModels.Welcome.Instance.Refresh(); + _launcher?.OpenRepositoryInTab(node, null); + }); } } @@ -719,11 +610,10 @@ namespace SourceGit return trimmed.Count > 0 ? string.Join(',', trimmed) : string.Empty; } + private Models.IpcChannel _ipcChannel = null; private ViewModels.Launcher _launcher = null; private ResourceDictionary _activeLocale = null; private ResourceDictionary _themeOverrides = null; private ResourceDictionary _fontsOverrides = null; - private Task _ipcServerTask = null; - private CancellationTokenSource _ipcServerCts = null; } } diff --git a/src/Models/IpcChannel.cs b/src/Models/IpcChannel.cs new file mode 100644 index 00000000..e2a34b29 --- /dev/null +++ b/src/Models/IpcChannel.cs @@ -0,0 +1,97 @@ +using System; +using System.IO; +using System.IO.Pipes; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace SourceGit.Models +{ + public class IpcChannel : IDisposable + { + public bool IsFirstInstance + { + get => _server != null; + } + + public event Action MessageReceived; + + public IpcChannel() + { + try + { + _server = new NamedPipeServerStream("SourceGitIPCChannel", PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous | PipeOptions.CurrentUserOnly); + _cancellationTokenSource = new CancellationTokenSource(); + Task.Run(StartServer); + } + catch + { + // IGNORE + } + } + + public void SendToFirstInstance(string cmd) + { + try + { + using (var client = new NamedPipeClientStream(".", "SourceGitIPCChannel", PipeDirection.Out)) + { + client.Connect(1000); + if (client.IsConnected) + { + using (var writer = new StreamWriter(client)) + { + writer.Write(Encoding.UTF8.GetBytes(cmd)); + writer.Flush(); + } + } + } + } + catch + { + // IGNORE + } + } + + public void Dispose() + { + _server?.Close(); + } + + private async void StartServer() + { + var buffer = new byte[1024]; + + while (true) + { + try + { + await _server.WaitForConnectionAsync(_cancellationTokenSource.Token); + + using (var stream = new MemoryStream()) + { + while (true) + { + var readed = await _server.ReadAsync(buffer.AsMemory(0, 1024), _cancellationTokenSource.Token); + if (readed == 0) + break; + + stream.Write(buffer, 0, readed); + } + + stream.Seek(0, SeekOrigin.Begin); + MessageReceived?.Invoke(Encoding.UTF8.GetString(stream.ToArray()).Trim()); + _server.Disconnect(); + } + } + catch + { + // IGNORE + } + } + } + + private NamedPipeServerStream _server = null; + private CancellationTokenSource _cancellationTokenSource = null; + } +} diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 123b6381..7e931998 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -752,5 +752,4 @@ 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 d1e78d6a..9395e0a7 100644 --- a/src/ViewModels/Preferences.cs +++ b/src/ViewModels/Preferences.cs @@ -90,12 +90,6 @@ namespace SourceGit.ViewModels } } - public bool OpenReposInNewTab - { - get => _openReposInNewTab; - set => SetProperty(ref _openReposInNewTab, value); - } - public bool UseSystemWindowFrame { get => _useSystemWindowFrame; @@ -369,6 +363,11 @@ namespace SourceGit.ViewModels set => SetProperty(ref _lastCheckUpdateTime, value); } + public void SetCanModify() + { + _isReadonly = false; + } + public bool IsGitConfigured() { var path = GitInstallPath; @@ -496,7 +495,7 @@ namespace SourceGit.ViewModels public void Save() { - if (_isLoading) + if (_isLoading || _isReadonly) return; var file = Path.Combine(Native.OS.DataDir, "preference.json"); @@ -632,13 +631,13 @@ namespace SourceGit.ViewModels private static Preferences _instance = null; private static bool _isLoading = false; + private bool _isReadonly = true; private string _locale = "en_US"; private string _theme = "Default"; private string _themeOverrides = string.Empty; 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 704757df..702ec20f 100644 --- a/src/Views/Preferences.axaml +++ b/src/Views/Preferences.axaml @@ -46,7 +46,7 @@ - + - - Date: Mon, 14 Apr 2025 22:05:05 +0800 Subject: [PATCH 496/865] fix: update visible staged changes retrieval in WorkingCopy (#1187) * doc: Update translation status and missing keys * fix: update visible staged changes retrieval in WorkingCopy * fix: prevent unintended amend behavior when changing current branch --------- Co-authored-by: github-actions[bot] --- TRANSLATION.md | 48 +++++++++++++++++++++++++++-------- src/ViewModels/Repository.cs | 10 +++++++- src/ViewModels/WorkingCopy.cs | 1 + 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/TRANSLATION.md b/TRANSLATION.md index 7ae5b13f..b4194fd9 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -6,7 +6,7 @@ This document shows the translation status of each locale file in the repository ### ![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen) -### ![de__DE](https://img.shields.io/badge/de__DE-97.34%25-yellow) +### ![de__DE](https://img.shields.io/badge/de__DE-97.21%25-yellow)
Missing keys in de_DE.axaml @@ -31,10 +31,11 @@ This document shows the translation status of each locale file in the repository - Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts - Text.WorkingCopy.Conflicts.UseMine - Text.WorkingCopy.Conflicts.UseTheirs +- Text.Preferences.General.OpenReposInNewTab
-### ![es__ES](https://img.shields.io/badge/es__ES-98.67%25-yellow) +### ![es__ES](https://img.shields.io/badge/es__ES-98.54%25-yellow)
Missing keys in es_ES.axaml @@ -49,10 +50,11 @@ This document shows the translation status of each locale file in the repository - Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts - Text.WorkingCopy.Conflicts.UseMine - Text.WorkingCopy.Conflicts.UseTheirs +- Text.Preferences.General.OpenReposInNewTab
-### ![fr__FR](https://img.shields.io/badge/fr__FR-98.67%25-yellow) +### ![fr__FR](https://img.shields.io/badge/fr__FR-98.54%25-yellow)
Missing keys in fr_FR.axaml @@ -67,10 +69,11 @@ This document shows the translation status of each locale file in the repository - Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts - Text.WorkingCopy.Conflicts.UseMine - Text.WorkingCopy.Conflicts.UseTheirs +- Text.Preferences.General.OpenReposInNewTab
-### ![it__IT](https://img.shields.io/badge/it__IT-98.41%25-yellow) +### ![it__IT](https://img.shields.io/badge/it__IT-98.28%25-yellow)
Missing keys in it_IT.axaml @@ -87,10 +90,11 @@ This document shows the translation status of each locale file in the repository - Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts - Text.WorkingCopy.Conflicts.UseMine - Text.WorkingCopy.Conflicts.UseTheirs +- Text.Preferences.General.OpenReposInNewTab
-### ![ja__JP](https://img.shields.io/badge/ja__JP-98.41%25-yellow) +### ![ja__JP](https://img.shields.io/badge/ja__JP-98.28%25-yellow)
Missing keys in ja_JP.axaml @@ -107,10 +111,11 @@ This document shows the translation status of each locale file in the repository - Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts - Text.WorkingCopy.Conflicts.UseMine - Text.WorkingCopy.Conflicts.UseTheirs +- Text.Preferences.General.OpenReposInNewTab
-### ![pt__BR](https://img.shields.io/badge/pt__BR-89.77%25-yellow) +### ![pt__BR](https://img.shields.io/badge/pt__BR-89.66%25-yellow)
Missing keys in pt_BR.axaml @@ -192,12 +197,20 @@ This document shows the translation status of each locale file in the repository - Text.WorkingCopy.Conflicts.UseMine - Text.WorkingCopy.Conflicts.UseTheirs - Text.WorkingCopy.SignOff +- Text.Preferences.General.OpenReposInNewTab
-### ![ru__RU](https://img.shields.io/badge/ru__RU-%E2%88%9A-brightgreen) +### ![ru__RU](https://img.shields.io/badge/ru__RU-99.87%25-yellow) -### ![ta__IN](https://img.shields.io/badge/ta__IN-98.67%25-yellow) +
+Missing keys in ru_RU.axaml + +- Text.Preferences.General.OpenReposInNewTab + +
+ +### ![ta__IN](https://img.shields.io/badge/ta__IN-98.54%25-yellow)
Missing keys in ta_IN.axaml @@ -212,9 +225,24 @@ This document shows the translation status of each locale file in the repository - Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts - Text.WorkingCopy.Conflicts.UseMine - Text.WorkingCopy.Conflicts.UseTheirs +- Text.Preferences.General.OpenReposInNewTab
-### ![zh__CN](https://img.shields.io/badge/zh__CN-%E2%88%9A-brightgreen) +### ![zh__CN](https://img.shields.io/badge/zh__CN-99.87%25-yellow) -### ![zh__TW](https://img.shields.io/badge/zh__TW-%E2%88%9A-brightgreen) \ No newline at end of file +
+Missing keys in zh_CN.axaml + +- Text.Preferences.General.OpenReposInNewTab + +
+ +### ![zh__TW](https://img.shields.io/badge/zh__TW-99.87%25-yellow) + +
+Missing keys in zh_TW.axaml + +- Text.Preferences.General.OpenReposInNewTab + +
\ No newline at end of file diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 9b720c7b..97d47a77 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -162,7 +162,15 @@ namespace SourceGit.ViewModels public Models.Branch CurrentBranch { get => _currentBranch; - private set => SetProperty(ref _currentBranch, value); + private set + { + var oldHead = _currentBranch?.Head; + if (SetProperty(ref _currentBranch, value)) + { + if (oldHead != _currentBranch.Head && _workingCopy is { UseAmend: true }) + _workingCopy.UseAmend = false; + } + } } public List LocalBranchTrees diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 802c6c5d..3d7b9a28 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -94,6 +94,7 @@ namespace SourceGit.ViewModels } Staged = GetStagedChanges(); + VisibleStaged = GetVisibleChanges(_staged); SelectedStaged = []; } } From 1e0fd63543607b07664eb5083f6368ab804479e8 Mon Sep 17 00:00:00 2001 From: Gadfly Date: Mon, 14 Apr 2025 22:07:24 +0800 Subject: [PATCH 497/865] localization: add translation sorting and formatting (#1186) * doc: Update translation status and missing keys * localization: add translation sorting and formatting --------- Co-authored-by: github-actions[bot] --- .github/workflows/localization-check.yml | 5 ++-- build/scripts/localization-check.js | 34 +++++++++++++++++++++++- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/.github/workflows/localization-check.yml b/.github/workflows/localization-check.yml index cc5201ab..8dcd61c8 100644 --- a/.github/workflows/localization-check.yml +++ b/.github/workflows/localization-check.yml @@ -4,7 +4,6 @@ on: branches: [ develop ] paths: - 'src/Resources/Locales/**' - - 'README.md' workflow_dispatch: workflow_call: @@ -32,8 +31,8 @@ jobs: git config --global user.name 'github-actions[bot]' git config --global user.email 'github-actions[bot]@users.noreply.github.com' if [ -n "$(git status --porcelain)" ]; then - git add README.md TRANSLATION.md - git commit -m 'doc: Update translation status and missing keys' + git add TRANSLATION.md src/Resources/Locales/*.axaml + git commit -m 'doc: Update translation status and sort locale files' git push else echo "No changes to commit" diff --git a/build/scripts/localization-check.js b/build/scripts/localization-check.js index 1e8f1f0d..fc27fd1b 100644 --- a/build/scripts/localization-check.js +++ b/build/scripts/localization-check.js @@ -14,6 +14,22 @@ async function parseXml(filePath) { return parser.parseStringPromise(data); } +async function filterAndSortTranslations(localeData, enUSKeys, enUSData) { + const strings = localeData.ResourceDictionary['x:String']; + // Remove keys that don't exist in English file + const filtered = strings.filter(item => enUSKeys.has(item.$['x:Key'])); + + // Sort based on the key order in English file + const enUSKeysArray = enUSData.ResourceDictionary['x:String'].map(item => item.$['x:Key']); + filtered.sort((a, b) => { + const aIndex = enUSKeysArray.indexOf(a.$['x:Key']); + const bIndex = enUSKeysArray.indexOf(b.$['x:Key']); + return aIndex - bIndex; + }); + + return filtered; +} + async function calculateTranslationRate() { const enUSData = await parseXml(enUSFile); const enUSKeys = new Set(enUSData.ResourceDictionary['x:String'].map(item => item.$['x:Key'])); @@ -33,6 +49,22 @@ async function calculateTranslationRate() { const localeKeys = new Set(localeData.ResourceDictionary['x:String'].map(item => item.$['x:Key'])); const missingKeys = [...enUSKeys].filter(key => !localeKeys.has(key)); + // Sort and clean up extra translations + const sortedAndCleaned = await filterAndSortTranslations(localeData, enUSKeys, enUSData); + localeData.ResourceDictionary['x:String'] = sortedAndCleaned; + + // Save the updated file + const builder = new xml2js.Builder({ + headless: true, + renderOpts: { pretty: true, indent: ' ' } + }); + let xmlStr = builder.buildObject(localeData); + + // Add an empty line before the first x:String + xmlStr = xmlStr.replace(' 0) { const progress = ((enUSKeys.size - missingKeys.length) / enUSKeys.size) * 100; const badgeColor = progress >= 75 ? 'yellow' : 'red'; @@ -41,7 +73,7 @@ async function calculateTranslationRate() { lines.push(`
\nMissing keys in ${file}\n\n${missingKeys.map(key => `- ${key}`).join('\n')}\n\n
`) } else { lines.push(`### ![${locale}](https://img.shields.io/badge/${locale}-%E2%88%9A-brightgreen)`); - } + } } const content = lines.join('\n\n'); From e5dc211c35cb2a0d72a0d8910dee1c2dd06e9df6 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 14 Apr 2025 22:24:48 +0800 Subject: [PATCH 498/865] refactor: simpfy IPC code Signed-off-by: leo --- src/Models/IpcChannel.cs | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/src/Models/IpcChannel.cs b/src/Models/IpcChannel.cs index e2a34b29..9a9e0315 100644 --- a/src/Models/IpcChannel.cs +++ b/src/Models/IpcChannel.cs @@ -1,7 +1,6 @@ using System; using System.IO; using System.IO.Pipes; -using System.Text; using System.Threading; using System.Threading.Tasks; @@ -41,7 +40,7 @@ namespace SourceGit.Models { using (var writer = new StreamWriter(client)) { - writer.Write(Encoding.UTF8.GetBytes(cmd)); + writer.WriteLine(cmd); writer.Flush(); } } @@ -55,34 +54,22 @@ namespace SourceGit.Models public void Dispose() { - _server?.Close(); + _cancellationTokenSource?.Cancel(); } private async void StartServer() { - var buffer = new byte[1024]; + using var reader = new StreamReader(_server); - while (true) + while (!_cancellationTokenSource.IsCancellationRequested) { try { await _server.WaitForConnectionAsync(_cancellationTokenSource.Token); - - using (var stream = new MemoryStream()) - { - while (true) - { - var readed = await _server.ReadAsync(buffer.AsMemory(0, 1024), _cancellationTokenSource.Token); - if (readed == 0) - break; - - stream.Write(buffer, 0, readed); - } - - stream.Seek(0, SeekOrigin.Begin); - MessageReceived?.Invoke(Encoding.UTF8.GetString(stream.ToArray()).Trim()); - _server.Disconnect(); - } + + var line = (await reader.ReadLineAsync(_cancellationTokenSource.Token))?.Trim(); + MessageReceived?.Invoke(line); + _server.Disconnect(); } catch { From 05982e6dc0df4784c8c3863b6b08c45eb1f87fc2 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 14 Apr 2025 23:23:40 +0800 Subject: [PATCH 499/865] style: re-design style for disabled primary button Signed-off-by: leo --- src/Resources/Styles.axaml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Resources/Styles.axaml b/src/Resources/Styles.axaml index 38321356..391b9523 100644 --- a/src/Resources/Styles.axaml +++ b/src/Resources/Styles.axaml @@ -499,6 +499,12 @@ + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ diff --git a/src/Views/ViewLogs.axaml.cs b/src/Views/ViewLogs.axaml.cs new file mode 100644 index 00000000..624ff21e --- /dev/null +++ b/src/Views/ViewLogs.axaml.cs @@ -0,0 +1,108 @@ +using System; +using System.ComponentModel; + +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.Primitives; +using Avalonia.Interactivity; + +using AvaloniaEdit; +using AvaloniaEdit.Document; +using AvaloniaEdit.Editing; +using AvaloniaEdit.TextMate; + +namespace SourceGit.Views +{ + public class LogContentPresenter : TextEditor + { + public static readonly StyledProperty LogProperty = + AvaloniaProperty.Register(nameof(Log)); + + public ViewModels.CommandLog Log + { + get => GetValue(LogProperty); + set => SetValue(LogProperty, value); + } + + protected override Type StyleKeyOverride => typeof(TextEditor); + + public LogContentPresenter() : base(new TextArea(), new TextDocument()) + { + IsReadOnly = true; + ShowLineNumbers = false; + WordWrap = false; + HorizontalScrollBarVisibility = ScrollBarVisibility.Auto; + VerticalScrollBarVisibility = ScrollBarVisibility.Auto; + + TextArea.TextView.Margin = new Thickness(4, 0); + TextArea.TextView.Options.EnableHyperlinks = true; + TextArea.TextView.Options.EnableEmailHyperlinks = true; + } + + protected override void OnLoaded(RoutedEventArgs e) + { + base.OnLoaded(e); + + if (_textMate == null) + { + _textMate = Models.TextMateHelper.CreateForEditor(this); + Models.TextMateHelper.SetGrammarByFileName(_textMate, "Log.log"); + } + } + + protected override void OnUnloaded(RoutedEventArgs e) + { + base.OnUnloaded(e); + + if (_textMate != null) + { + _textMate.Dispose(); + _textMate = null; + } + + GC.Collect(); + } + + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); + + if (change.Property == LogProperty) + { + if (change.NewValue is ViewModels.CommandLog log) + { + Text = log.Content; + log.Register(OnLogLineReceived); + } + else + { + Text = string.Empty; + } + } + } + + private void OnLogLineReceived(string newline) + { + AppendText("\n"); + AppendText(newline); + } + + private TextMate.Installation _textMate = null; + } + + public partial class ViewLogs : ChromelessWindow + { + public ViewLogs() + { + InitializeComponent(); + } + + private void OnRemoveLog(object sender, RoutedEventArgs e) + { + if (sender is Button { DataContext: ViewModels.CommandLog log } && DataContext is ViewModels.ViewLogs vm) + vm.Logs.Remove(log); + + e.Handled = true; + } + } +} From c23177229836cf9329bb40f9048e2b7a0c8e922d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 17 Apr 2025 05:24:26 +0000 Subject: [PATCH 525/865] doc: Update translation status and sort locale files --- TRANSLATION.md | 36 +++++++++++++++++++++++-------- src/Resources/Locales/zh_CN.axaml | 2 +- src/Resources/Locales/zh_TW.axaml | 2 +- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/TRANSLATION.md b/TRANSLATION.md index d942a328..e2535903 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -6,7 +6,7 @@ This document shows the translation status of each locale file in the repository ### ![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen) -### ![de__DE](https://img.shields.io/badge/de__DE-97.21%25-yellow) +### ![de__DE](https://img.shields.io/badge/de__DE-96.96%25-yellow)
Missing keys in de_DE.axaml @@ -26,7 +26,9 @@ This document shows the translation status of each locale file in the repository - Text.Preferences.AI.Streaming - Text.Preferences.Appearance.EditorTabWidth - Text.Preferences.General.ShowTagsInGraph +- Text.Repository.ViewLogs - Text.StashCM.SaveAsPatch +- Text.ViewLogs - Text.WorkingCopy.ConfirmCommitWithFilter - Text.WorkingCopy.Conflicts.OpenExternalMergeTool - Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts @@ -35,7 +37,7 @@ This document shows the translation status of each locale file in the repository
-### ![es__ES](https://img.shields.io/badge/es__ES-98.54%25-yellow) +### ![es__ES](https://img.shields.io/badge/es__ES-98.28%25-yellow)
Missing keys in es_ES.axaml @@ -46,6 +48,8 @@ This document shows the translation status of each locale file in the repository - Text.ConfirmEmptyCommit.NoLocalChanges - Text.ConfirmEmptyCommit.StageAllThenCommit - Text.ConfirmEmptyCommit.WithLocalChanges +- Text.Repository.ViewLogs +- Text.ViewLogs - Text.WorkingCopy.ConfirmCommitWithFilter - Text.WorkingCopy.Conflicts.OpenExternalMergeTool - Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts @@ -54,7 +58,7 @@ This document shows the translation status of each locale file in the repository
-### ![fr__FR](https://img.shields.io/badge/fr__FR-98.54%25-yellow) +### ![fr__FR](https://img.shields.io/badge/fr__FR-98.28%25-yellow)
Missing keys in fr_FR.axaml @@ -65,6 +69,8 @@ This document shows the translation status of each locale file in the repository - Text.ConfirmEmptyCommit.NoLocalChanges - Text.ConfirmEmptyCommit.StageAllThenCommit - Text.ConfirmEmptyCommit.WithLocalChanges +- Text.Repository.ViewLogs +- Text.ViewLogs - Text.WorkingCopy.ConfirmCommitWithFilter - Text.WorkingCopy.Conflicts.OpenExternalMergeTool - Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts @@ -73,7 +79,7 @@ This document shows the translation status of each locale file in the repository
-### ![it__IT](https://img.shields.io/badge/it__IT-98.28%25-yellow) +### ![it__IT](https://img.shields.io/badge/it__IT-98.02%25-yellow)
Missing keys in it_IT.axaml @@ -86,6 +92,8 @@ This document shows the translation status of each locale file in the repository - Text.ConfirmEmptyCommit.WithLocalChanges - Text.CopyFullPath - Text.Preferences.General.ShowTagsInGraph +- Text.Repository.ViewLogs +- Text.ViewLogs - Text.WorkingCopy.ConfirmCommitWithFilter - Text.WorkingCopy.Conflicts.OpenExternalMergeTool - Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts @@ -94,7 +102,7 @@ This document shows the translation status of each locale file in the repository
-### ![ja__JP](https://img.shields.io/badge/ja__JP-98.28%25-yellow) +### ![ja__JP](https://img.shields.io/badge/ja__JP-98.02%25-yellow)
Missing keys in ja_JP.axaml @@ -107,6 +115,8 @@ This document shows the translation status of each locale file in the repository - Text.ConfirmEmptyCommit.WithLocalChanges - Text.Repository.FilterCommits - Text.Repository.Tags.OrderByNameDes +- Text.Repository.ViewLogs +- Text.ViewLogs - Text.WorkingCopy.ConfirmCommitWithFilter - Text.WorkingCopy.Conflicts.OpenExternalMergeTool - Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts @@ -115,7 +125,7 @@ This document shows the translation status of each locale file in the repository
-### ![pt__BR](https://img.shields.io/badge/pt__BR-89.66%25-yellow) +### ![pt__BR](https://img.shields.io/badge/pt__BR-89.42%25-yellow)
Missing keys in pt_BR.axaml @@ -183,6 +193,7 @@ This document shows the translation status of each locale file in the repository - Text.Repository.Tags.OrderByNameDes - Text.Repository.Tags.Sort - Text.Repository.UseRelativeTimeInHistories +- Text.Repository.ViewLogs - Text.SetUpstream - Text.SetUpstream.Local - Text.SetUpstream.Unset @@ -191,6 +202,7 @@ This document shows the translation status of each locale file in the repository - Text.Stash.AutoRestore - Text.Stash.AutoRestore.Tip - Text.StashCM.SaveAsPatch +- Text.ViewLogs - Text.WorkingCopy.CommitToEdit - Text.WorkingCopy.ConfirmCommitWithFilter - Text.WorkingCopy.Conflicts.OpenExternalMergeTool @@ -201,16 +213,18 @@ This document shows the translation status of each locale file in the repository
-### ![ru__RU](https://img.shields.io/badge/ru__RU-99.87%25-yellow) +### ![ru__RU](https://img.shields.io/badge/ru__RU-99.60%25-yellow)
Missing keys in ru_RU.axaml - Text.CommitMessageTextBox.SubjectCount +- Text.Repository.ViewLogs +- Text.ViewLogs
-### ![ta__IN](https://img.shields.io/badge/ta__IN-98.54%25-yellow) +### ![ta__IN](https://img.shields.io/badge/ta__IN-98.28%25-yellow)
Missing keys in ta_IN.axaml @@ -221,7 +235,9 @@ This document shows the translation status of each locale file in the repository - Text.ConfirmEmptyCommit.NoLocalChanges - Text.ConfirmEmptyCommit.StageAllThenCommit - Text.ConfirmEmptyCommit.WithLocalChanges +- Text.Repository.ViewLogs - Text.UpdateSubmodules.Target +- Text.ViewLogs - Text.WorkingCopy.Conflicts.OpenExternalMergeTool - Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts - Text.WorkingCopy.Conflicts.UseMine @@ -229,13 +245,15 @@ This document shows the translation status of each locale file in the repository
-### ![uk__UA](https://img.shields.io/badge/uk__UA-99.73%25-yellow) +### ![uk__UA](https://img.shields.io/badge/uk__UA-99.47%25-yellow)
Missing keys in uk_UA.axaml - Text.CommitMessageTextBox.SubjectCount - Text.ConfigureWorkspace.Name +- Text.Repository.ViewLogs +- Text.ViewLogs
diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index a4d33601..cb99d6f0 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -759,4 +759,4 @@ 锁定工作树 移除工作树 解除工作树锁定 - + \ No newline at end of file diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 581f25f2..2fa67983 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -759,4 +759,4 @@ 鎖定工作區 移除工作區 解除鎖定工作區 - + \ No newline at end of file From 0e967ffc8e28a361d3bc4a48a1f72e38a58897c7 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 17 Apr 2025 13:30:25 +0800 Subject: [PATCH 526/865] fix: pressing `Alt+Enter` to commit and push in a repository that has no remotes will crash (#1205) Signed-off-by: leo --- src/ViewModels/WorkingCopy.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 60b8fd11..10544970 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -1735,7 +1735,7 @@ namespace SourceGit.ViewModels CommitMessage = string.Empty; UseAmend = false; - if (autoPush) + if (autoPush && _repo.Remotes.Count > 0) _repo.ShowAndStartPopup(new Push(_repo, null)); } From 33ae6a998959bc63aa8796f10bdd4c705e7c021b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20J=2E=20Mart=C3=ADnez=20M=2E?= <56406225+jjesus-dev@users.noreply.github.com> Date: Wed, 16 Apr 2025 23:34:27 -0600 Subject: [PATCH 527/865] localization: update spanish translations (#1206) add missing translations modify instances of `stagear` with `hacer stage` --- src/Resources/Locales/es_ES.axaml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index d4d442b0..ff6d02f7 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -136,6 +136,7 @@ SHA Abrir en Navegador Descripción + ASUNTO Introducir asunto del commit Configurar Repositorio PLANTILLA DE COMMIT @@ -157,6 +158,7 @@ Fetch remotos automáticamente Minuto(s) Remoto por Defecto + Modo preferido de Merge SEGUIMIENTO DE INCIDENCIAS Añadir Regla de Ejemplo para Azure DevOps Añadir Regla de Ejemplo para Incidencias de Gitee @@ -181,6 +183,10 @@ Color Nombre Restaurar pestañas al iniciar + CONTINUAR + ¡Commit vacío detectado! ¿Quieres continuar (--allow-empty)? + HACER STAGE A TODO & COMMIT + ¡Commit vacío detectado! ¿Quieres continuar (--allow-empty) o hacer stage a todo y después commit? Asistente de Commit Convencional Cambio Importante: Incidencia Cerrada: @@ -717,15 +723,20 @@ Ignorar archivos en la misma carpeta Ignorar solo este archivo Enmendar - Puedes stagear este archivo ahora. + Puedes hacer stage a este archivo ahora. COMMIT COMMIT & PUSH Plantilla/Historias Activar evento de clic Commit (Editar) - Stagear todos los cambios y commit + Hacer stage a todos los cambios y commit + Tienes {0} archivo(s) en stage, pero solo {1} archivo(s) mostrado(s) ({2} archivo(s) están filtrados). ¿Quieres continuar? CONFLICTOS DETECTADOS + ABRIR HERRAMIENTA DE MERGE EXTERNA + ABRIR TODOS LOS CONFLICTOS EN HERRAMIENTA DE MERGE EXTERNA LOS CONFLICTOS DE ARCHIVOS ESTÁN RESUELTOS + USAR MÍOS + USAR SUYOS INCLUIR ARCHIVOS NO RASTREADOS NO HAY MENSAJES DE ENTRADA RECIENTES NO HAY PLANTILLAS DE COMMIT From 2a43efde07864bdfac359757cfcf1d17fe3f3e9d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 17 Apr 2025 05:34:40 +0000 Subject: [PATCH 528/865] doc: Update translation status and sort locale files --- TRANSLATION.md | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/TRANSLATION.md b/TRANSLATION.md index e2535903..62fe960f 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -37,24 +37,13 @@ This document shows the translation status of each locale file in the repository
-### ![es__ES](https://img.shields.io/badge/es__ES-98.28%25-yellow) +### ![es__ES](https://img.shields.io/badge/es__ES-99.74%25-yellow)
Missing keys in es_ES.axaml -- Text.CommitMessageTextBox.SubjectCount -- Text.Configure.Git.PreferredMergeMode -- Text.ConfirmEmptyCommit.Continue -- Text.ConfirmEmptyCommit.NoLocalChanges -- Text.ConfirmEmptyCommit.StageAllThenCommit -- Text.ConfirmEmptyCommit.WithLocalChanges - Text.Repository.ViewLogs - Text.ViewLogs -- Text.WorkingCopy.ConfirmCommitWithFilter -- Text.WorkingCopy.Conflicts.OpenExternalMergeTool -- Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts -- Text.WorkingCopy.Conflicts.UseMine -- Text.WorkingCopy.Conflicts.UseTheirs
From c1e31ac4e3a1a7ca062761c50533de65d455e692 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 17 Apr 2025 15:48:02 +0800 Subject: [PATCH 529/865] ci: try to remove zlib1g-dev:arm64 Signed-off-by: leo --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bcb32580..12792cf6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -58,7 +58,7 @@ jobs: if: ${{ matrix.runtime == 'linux-arm64' }} run: | sudo apt-get update - sudo apt-get install -y llvm gcc-aarch64-linux-gnu zlib1g-dev:arm64 + sudo apt-get install -y llvm gcc-aarch64-linux-gnu - name: Build run: dotnet build -c Release - name: Publish From 021aab84087fd348a56283fda640caa9c89ec054 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 17 Apr 2025 16:07:40 +0800 Subject: [PATCH 530/865] enhance: add a button to clear all git command logs Signed-off-by: leo --- build/scripts/localization-check.js | 3 +-- src/Resources/Locales/en_US.axaml | 1 + src/Resources/Locales/zh_CN.axaml | 3 ++- src/Resources/Locales/zh_TW.axaml | 3 ++- src/ViewModels/ViewLogs.cs | 6 ++++++ src/Views/ViewLogs.axaml | 11 ++++++++++- 6 files changed, 22 insertions(+), 5 deletions(-) diff --git a/build/scripts/localization-check.js b/build/scripts/localization-check.js index fc27fd1b..8d636b5b 100644 --- a/build/scripts/localization-check.js +++ b/build/scripts/localization-check.js @@ -62,8 +62,7 @@ async function calculateTranslationRate() { // Add an empty line before the first x:String xmlStr = xmlStr.replace(' 0) { const progress = ((enUSKeys.size - missingKeys.length) / enUSKeys.size) * 100; diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 5d1bb7e1..1e92ae38 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -699,6 +699,7 @@ Use --remote option URL: Logs + CLEAR ALL Warning Welcome Page Create Group diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index cb99d6f0..0471285f 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -703,6 +703,7 @@ 启用 '--remote' 仓库地址 : 日志列表 + 清空日志 警告 起始页 新建分组 @@ -759,4 +760,4 @@ 锁定工作树 移除工作树 解除工作树锁定 - \ No newline at end of file + diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 2fa67983..edd8cf8c 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -703,6 +703,7 @@ 啟用 [--remote] 選項 存放庫網址: 日誌清單 + 清除所有日誌 警告 起始頁 新增群組 @@ -759,4 +760,4 @@ 鎖定工作區 移除工作區 解除鎖定工作區 - \ No newline at end of file + diff --git a/src/ViewModels/ViewLogs.cs b/src/ViewModels/ViewLogs.cs index 44c819ce..21ab81ab 100644 --- a/src/ViewModels/ViewLogs.cs +++ b/src/ViewModels/ViewLogs.cs @@ -21,6 +21,12 @@ namespace SourceGit.ViewModels _repo = repo; } + public void ClearAll() + { + SelectedLog = null; + Logs.Clear(); + } + private Repository _repo = null; private CommandLog _selectedLog = null; } diff --git a/src/Views/ViewLogs.axaml b/src/Views/ViewLogs.axaml index 8272078d..125caa22 100644 --- a/src/Views/ViewLogs.axaml +++ b/src/Views/ViewLogs.axaml @@ -4,6 +4,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vm="using:SourceGit.ViewModels" xmlns:v="using:SourceGit.Views" + xmlns:c="using:SourceGit.Converters" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="SourceGit.Views.ViewLogs" x:DataType="vm:ViewLogs" @@ -13,7 +14,7 @@ Width="800" Height="500" CanResize="False" WindowStartupLocation="CenterOwner"> - + + + +
diff --git a/src/Views/ViewLogs.axaml.cs b/src/Views/ViewLogs.axaml.cs index 624ff21e..62bf288d 100644 --- a/src/Views/ViewLogs.axaml.cs +++ b/src/Views/ViewLogs.axaml.cs @@ -97,10 +97,33 @@ namespace SourceGit.Views InitializeComponent(); } - private void OnRemoveLog(object sender, RoutedEventArgs e) + private void OnLogContextRequested(object sender, ContextRequestedEventArgs e) { - if (sender is Button { DataContext: ViewModels.CommandLog log } && DataContext is ViewModels.ViewLogs vm) + if (sender is not Grid { DataContext: ViewModels.CommandLog log } grid || DataContext is not ViewModels.ViewLogs vm) + return; + + var copy = new MenuItem(); + copy.Header = App.Text("ViewLogs.CopyLog"); + copy.Icon = App.CreateMenuIcon("Icons.Copy"); + copy.Click += (_, ev) => + { + App.CopyText(log.Content); + ev.Handled = true; + }; + + var rm = new MenuItem(); + rm.Header = App.Text("ViewLogs.Delete"); + rm.Icon = App.CreateMenuIcon("Icons.Clear"); + rm.Click += (_, ev) => + { vm.Logs.Remove(log); + ev.Handled = true; + }; + + var menu = new ContextMenu(); + menu.Items.Add(copy); + menu.Items.Add(rm); + menu.Open(grid); e.Handled = true; } From a06d1183d76049bd7df1e6136025895dddbe1655 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 17 Apr 2025 08:32:08 +0000 Subject: [PATCH 533/865] doc: Update translation status and sort locale files --- TRANSLATION.md | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/TRANSLATION.md b/TRANSLATION.md index 5e316750..4f13d26a 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -6,7 +6,7 @@ This document shows the translation status of each locale file in the repository ### ![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen) -### ![de__DE](https://img.shields.io/badge/de__DE-96.83%25-yellow) +### ![de__DE](https://img.shields.io/badge/de__DE-96.57%25-yellow)
Missing keys in de_DE.axaml @@ -30,6 +30,8 @@ This document shows the translation status of each locale file in the repository - Text.StashCM.SaveAsPatch - Text.ViewLogs - Text.ViewLogs.Clear +- Text.ViewLogs.CopyLog +- Text.ViewLogs.Delete - Text.WorkingCopy.ConfirmCommitWithFilter - Text.WorkingCopy.Conflicts.OpenExternalMergeTool - Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts @@ -38,7 +40,7 @@ This document shows the translation status of each locale file in the repository
-### ![es__ES](https://img.shields.io/badge/es__ES-99.60%25-yellow) +### ![es__ES](https://img.shields.io/badge/es__ES-99.34%25-yellow)
Missing keys in es_ES.axaml @@ -46,10 +48,12 @@ This document shows the translation status of each locale file in the repository - Text.Repository.ViewLogs - Text.ViewLogs - Text.ViewLogs.Clear +- Text.ViewLogs.CopyLog +- Text.ViewLogs.Delete
-### ![fr__FR](https://img.shields.io/badge/fr__FR-98.15%25-yellow) +### ![fr__FR](https://img.shields.io/badge/fr__FR-97.89%25-yellow)
Missing keys in fr_FR.axaml @@ -63,6 +67,8 @@ This document shows the translation status of each locale file in the repository - Text.Repository.ViewLogs - Text.ViewLogs - Text.ViewLogs.Clear +- Text.ViewLogs.CopyLog +- Text.ViewLogs.Delete - Text.WorkingCopy.ConfirmCommitWithFilter - Text.WorkingCopy.Conflicts.OpenExternalMergeTool - Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts @@ -71,7 +77,7 @@ This document shows the translation status of each locale file in the repository
-### ![it__IT](https://img.shields.io/badge/it__IT-97.89%25-yellow) +### ![it__IT](https://img.shields.io/badge/it__IT-97.63%25-yellow)
Missing keys in it_IT.axaml @@ -87,6 +93,8 @@ This document shows the translation status of each locale file in the repository - Text.Repository.ViewLogs - Text.ViewLogs - Text.ViewLogs.Clear +- Text.ViewLogs.CopyLog +- Text.ViewLogs.Delete - Text.WorkingCopy.ConfirmCommitWithFilter - Text.WorkingCopy.Conflicts.OpenExternalMergeTool - Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts @@ -95,7 +103,7 @@ This document shows the translation status of each locale file in the repository
-### ![ja__JP](https://img.shields.io/badge/ja__JP-97.89%25-yellow) +### ![ja__JP](https://img.shields.io/badge/ja__JP-97.63%25-yellow)
Missing keys in ja_JP.axaml @@ -111,6 +119,8 @@ This document shows the translation status of each locale file in the repository - Text.Repository.ViewLogs - Text.ViewLogs - Text.ViewLogs.Clear +- Text.ViewLogs.CopyLog +- Text.ViewLogs.Delete - Text.WorkingCopy.ConfirmCommitWithFilter - Text.WorkingCopy.Conflicts.OpenExternalMergeTool - Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts @@ -119,7 +129,7 @@ This document shows the translation status of each locale file in the repository
-### ![pt__BR](https://img.shields.io/badge/pt__BR-89.30%25-yellow) +### ![pt__BR](https://img.shields.io/badge/pt__BR-89.06%25-yellow)
Missing keys in pt_BR.axaml @@ -198,6 +208,8 @@ This document shows the translation status of each locale file in the repository - Text.StashCM.SaveAsPatch - Text.ViewLogs - Text.ViewLogs.Clear +- Text.ViewLogs.CopyLog +- Text.ViewLogs.Delete - Text.WorkingCopy.CommitToEdit - Text.WorkingCopy.ConfirmCommitWithFilter - Text.WorkingCopy.Conflicts.OpenExternalMergeTool @@ -208,7 +220,7 @@ This document shows the translation status of each locale file in the repository
-### ![ru__RU](https://img.shields.io/badge/ru__RU-99.47%25-yellow) +### ![ru__RU](https://img.shields.io/badge/ru__RU-99.21%25-yellow)
Missing keys in ru_RU.axaml @@ -217,10 +229,12 @@ This document shows the translation status of each locale file in the repository - Text.Repository.ViewLogs - Text.ViewLogs - Text.ViewLogs.Clear +- Text.ViewLogs.CopyLog +- Text.ViewLogs.Delete
-### ![ta__IN](https://img.shields.io/badge/ta__IN-98.15%25-yellow) +### ![ta__IN](https://img.shields.io/badge/ta__IN-97.89%25-yellow)
Missing keys in ta_IN.axaml @@ -235,6 +249,8 @@ This document shows the translation status of each locale file in the repository - Text.UpdateSubmodules.Target - Text.ViewLogs - Text.ViewLogs.Clear +- Text.ViewLogs.CopyLog +- Text.ViewLogs.Delete - Text.WorkingCopy.Conflicts.OpenExternalMergeTool - Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts - Text.WorkingCopy.Conflicts.UseMine @@ -242,7 +258,7 @@ This document shows the translation status of each locale file in the repository
-### ![uk__UA](https://img.shields.io/badge/uk__UA-99.34%25-yellow) +### ![uk__UA](https://img.shields.io/badge/uk__UA-99.08%25-yellow)
Missing keys in uk_UA.axaml @@ -252,6 +268,8 @@ This document shows the translation status of each locale file in the repository - Text.Repository.ViewLogs - Text.ViewLogs - Text.ViewLogs.Clear +- Text.ViewLogs.CopyLog +- Text.ViewLogs.Delete
From 104a3f0bbf762063cadb7d97119f0e50139243db Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 17 Apr 2025 16:35:18 +0800 Subject: [PATCH 534/865] code_style: run `dotnet format` Signed-off-by: leo --- src/Commands/QueryLocalChanges.cs | 226 +++++++++++++++--------------- src/ViewModels/CommandLog.cs | 2 +- src/Views/TextDiffView.axaml.cs | 2 +- src/Views/ViewLogs.axaml.cs | 1 - 4 files changed, 115 insertions(+), 116 deletions(-) diff --git a/src/Commands/QueryLocalChanges.cs b/src/Commands/QueryLocalChanges.cs index e85e79c9..4e626a79 100644 --- a/src/Commands/QueryLocalChanges.cs +++ b/src/Commands/QueryLocalChanges.cs @@ -36,119 +36,119 @@ namespace SourceGit.Commands switch (status) { - case " M": - change.Set(Models.ChangeState.None, Models.ChangeState.Modified); - break; - case " T": - change.Set(Models.ChangeState.None, Models.ChangeState.TypeChanged); - break; - case " A": - change.Set(Models.ChangeState.None, Models.ChangeState.Added); - break; - case " D": - change.Set(Models.ChangeState.None, Models.ChangeState.Deleted); - break; - case " R": - change.Set(Models.ChangeState.None, Models.ChangeState.Renamed); - break; - case " C": - change.Set(Models.ChangeState.None, Models.ChangeState.Copied); - break; - case "M": - change.Set(Models.ChangeState.Modified); - break; - case "MM": - change.Set(Models.ChangeState.Modified, Models.ChangeState.Modified); - break; - case "MT": - change.Set(Models.ChangeState.Modified, Models.ChangeState.TypeChanged); - break; - case "MD": - change.Set(Models.ChangeState.Modified, Models.ChangeState.Deleted); - break; - case "T": - change.Set(Models.ChangeState.TypeChanged); - break; - case "TM": - change.Set(Models.ChangeState.TypeChanged, Models.ChangeState.Modified); - break; - case "TT": - change.Set(Models.ChangeState.TypeChanged, Models.ChangeState.TypeChanged); - break; - case "TD": - change.Set(Models.ChangeState.TypeChanged, Models.ChangeState.Deleted); - break; - case "A": - change.Set(Models.ChangeState.Added); - break; - case "AM": - change.Set(Models.ChangeState.Added, Models.ChangeState.Modified); - break; - case "AT": - change.Set(Models.ChangeState.Added, Models.ChangeState.TypeChanged); - break; - case "AD": - change.Set(Models.ChangeState.Added, Models.ChangeState.Deleted); - break; - case "D": - change.Set(Models.ChangeState.Deleted); - break; - case "R": - change.Set(Models.ChangeState.Renamed); - break; - case "RM": - change.Set(Models.ChangeState.Renamed, Models.ChangeState.Modified); - break; - case "RT": - change.Set(Models.ChangeState.Renamed, Models.ChangeState.TypeChanged); - break; - case "RD": - change.Set(Models.ChangeState.Renamed, Models.ChangeState.Deleted); - break; - case "C": - change.Set(Models.ChangeState.Copied); - break; - case "CM": - change.Set(Models.ChangeState.Copied, Models.ChangeState.Modified); - break; - case "CT": - change.Set(Models.ChangeState.Copied, Models.ChangeState.TypeChanged); - break; - case "CD": - change.Set(Models.ChangeState.Copied, Models.ChangeState.Deleted); - break; - case "DR": - change.Set(Models.ChangeState.Deleted, Models.ChangeState.Renamed); - break; - case "DC": - change.Set(Models.ChangeState.Deleted, Models.ChangeState.Copied); - break; - case "DD": - change.Set(Models.ChangeState.Deleted, Models.ChangeState.Deleted); - break; - case "AU": - change.Set(Models.ChangeState.Added, Models.ChangeState.Unmerged); - break; - case "UD": - change.Set(Models.ChangeState.Unmerged, Models.ChangeState.Deleted); - break; - case "UA": - change.Set(Models.ChangeState.Unmerged, Models.ChangeState.Added); - break; - case "DU": - change.Set(Models.ChangeState.Deleted, Models.ChangeState.Unmerged); - break; - case "AA": - change.Set(Models.ChangeState.Added, Models.ChangeState.Added); - break; - case "UU": - change.Set(Models.ChangeState.Unmerged, Models.ChangeState.Unmerged); - break; - case "??": - change.Set(Models.ChangeState.Untracked, Models.ChangeState.Untracked); - break; - default: - break; + case " M": + change.Set(Models.ChangeState.None, Models.ChangeState.Modified); + break; + case " T": + change.Set(Models.ChangeState.None, Models.ChangeState.TypeChanged); + break; + case " A": + change.Set(Models.ChangeState.None, Models.ChangeState.Added); + break; + case " D": + change.Set(Models.ChangeState.None, Models.ChangeState.Deleted); + break; + case " R": + change.Set(Models.ChangeState.None, Models.ChangeState.Renamed); + break; + case " C": + change.Set(Models.ChangeState.None, Models.ChangeState.Copied); + break; + case "M": + change.Set(Models.ChangeState.Modified); + break; + case "MM": + change.Set(Models.ChangeState.Modified, Models.ChangeState.Modified); + break; + case "MT": + change.Set(Models.ChangeState.Modified, Models.ChangeState.TypeChanged); + break; + case "MD": + change.Set(Models.ChangeState.Modified, Models.ChangeState.Deleted); + break; + case "T": + change.Set(Models.ChangeState.TypeChanged); + break; + case "TM": + change.Set(Models.ChangeState.TypeChanged, Models.ChangeState.Modified); + break; + case "TT": + change.Set(Models.ChangeState.TypeChanged, Models.ChangeState.TypeChanged); + break; + case "TD": + change.Set(Models.ChangeState.TypeChanged, Models.ChangeState.Deleted); + break; + case "A": + change.Set(Models.ChangeState.Added); + break; + case "AM": + change.Set(Models.ChangeState.Added, Models.ChangeState.Modified); + break; + case "AT": + change.Set(Models.ChangeState.Added, Models.ChangeState.TypeChanged); + break; + case "AD": + change.Set(Models.ChangeState.Added, Models.ChangeState.Deleted); + break; + case "D": + change.Set(Models.ChangeState.Deleted); + break; + case "R": + change.Set(Models.ChangeState.Renamed); + break; + case "RM": + change.Set(Models.ChangeState.Renamed, Models.ChangeState.Modified); + break; + case "RT": + change.Set(Models.ChangeState.Renamed, Models.ChangeState.TypeChanged); + break; + case "RD": + change.Set(Models.ChangeState.Renamed, Models.ChangeState.Deleted); + break; + case "C": + change.Set(Models.ChangeState.Copied); + break; + case "CM": + change.Set(Models.ChangeState.Copied, Models.ChangeState.Modified); + break; + case "CT": + change.Set(Models.ChangeState.Copied, Models.ChangeState.TypeChanged); + break; + case "CD": + change.Set(Models.ChangeState.Copied, Models.ChangeState.Deleted); + break; + case "DR": + change.Set(Models.ChangeState.Deleted, Models.ChangeState.Renamed); + break; + case "DC": + change.Set(Models.ChangeState.Deleted, Models.ChangeState.Copied); + break; + case "DD": + change.Set(Models.ChangeState.Deleted, Models.ChangeState.Deleted); + break; + case "AU": + change.Set(Models.ChangeState.Added, Models.ChangeState.Unmerged); + break; + case "UD": + change.Set(Models.ChangeState.Unmerged, Models.ChangeState.Deleted); + break; + case "UA": + change.Set(Models.ChangeState.Unmerged, Models.ChangeState.Added); + break; + case "DU": + change.Set(Models.ChangeState.Deleted, Models.ChangeState.Unmerged); + break; + case "AA": + change.Set(Models.ChangeState.Added, Models.ChangeState.Added); + break; + case "UU": + change.Set(Models.ChangeState.Unmerged, Models.ChangeState.Unmerged); + break; + case "??": + change.Set(Models.ChangeState.Untracked, Models.ChangeState.Untracked); + break; + default: + break; } if (change.Index != Models.ChangeState.None || change.WorkTree != Models.ChangeState.None) diff --git a/src/ViewModels/CommandLog.cs b/src/ViewModels/CommandLog.cs index e10aa724..a677d0be 100644 --- a/src/ViewModels/CommandLog.cs +++ b/src/ViewModels/CommandLog.cs @@ -82,6 +82,6 @@ namespace SourceGit.ViewModels private string _content = string.Empty; private StringBuilder _builder = new StringBuilder(); - private event Action _onNewLineReceived; + private event Action _onNewLineReceived; } } diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index 722d6912..ad2f8cea 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -1261,7 +1261,7 @@ namespace SourceGit.Views if (line.NoNewLineEndOfFile) builder.Append("\u26D4"); - + builder.Append('\n'); } diff --git a/src/Views/ViewLogs.axaml.cs b/src/Views/ViewLogs.axaml.cs index 62bf288d..107341ab 100644 --- a/src/Views/ViewLogs.axaml.cs +++ b/src/Views/ViewLogs.axaml.cs @@ -1,5 +1,4 @@ using System; -using System.ComponentModel; using Avalonia; using Avalonia.Controls; From 3358ff9aee18918c67cdbf3fb7055ccb43b9fd35 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 17 Apr 2025 17:24:56 +0800 Subject: [PATCH 535/865] enhance: disable hyper link and email link in git command logs Signed-off-by: leo --- src/Views/ViewLogs.axaml.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Views/ViewLogs.axaml.cs b/src/Views/ViewLogs.axaml.cs index 107341ab..dcfc3dc9 100644 --- a/src/Views/ViewLogs.axaml.cs +++ b/src/Views/ViewLogs.axaml.cs @@ -34,8 +34,8 @@ namespace SourceGit.Views VerticalScrollBarVisibility = ScrollBarVisibility.Auto; TextArea.TextView.Margin = new Thickness(4, 0); - TextArea.TextView.Options.EnableHyperlinks = true; - TextArea.TextView.Options.EnableEmailHyperlinks = true; + TextArea.TextView.Options.EnableHyperlinks = false; + TextArea.TextView.Options.EnableEmailHyperlinks = false; } protected override void OnLoaded(RoutedEventArgs e) From 231010abc666c1d3e0bb2cc36e0da4cf207b633d Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 17 Apr 2025 17:45:49 +0800 Subject: [PATCH 536/865] ux: custom style for command line in git command log Signed-off-by: leo --- src/Views/ViewLogs.axaml.cs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/Views/ViewLogs.axaml.cs b/src/Views/ViewLogs.axaml.cs index dcfc3dc9..8a3426d2 100644 --- a/src/Views/ViewLogs.axaml.cs +++ b/src/Views/ViewLogs.axaml.cs @@ -4,16 +4,39 @@ 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.Rendering; using AvaloniaEdit.TextMate; namespace SourceGit.Views { public class LogContentPresenter : TextEditor { + public class LineStyleTransformer : DocumentColorizingTransformer + { + protected override void ColorizeLine(DocumentLine line) + { + var content = CurrentContext.Document.GetText(line); + if (content.StartsWith("$ git ", StringComparison.Ordinal)) + { + ChangeLinePart(line.Offset, line.Offset + 1, v => + { + v.TextRunProperties.SetForegroundBrush(Brushes.Orange); + }); + + ChangeLinePart(line.Offset + 2, line.EndOffset, v => + { + var old = v.TextRunProperties.Typeface; + v.TextRunProperties.SetTypeface(new Typeface(old.FontFamily, old.Style, FontWeight.Bold)); + }); + } + } + } + public static readonly StyledProperty LogProperty = AvaloniaProperty.Register(nameof(Log)); @@ -46,6 +69,7 @@ namespace SourceGit.Views { _textMate = Models.TextMateHelper.CreateForEditor(this); Models.TextMateHelper.SetGrammarByFileName(_textMate, "Log.log"); + TextArea.TextView.LineTransformers.Add(new LineStyleTransformer()); } } From 090b64d68dcfdc19d1b05366f9b9b96e6027dc1e Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 17 Apr 2025 18:21:55 +0800 Subject: [PATCH 537/865] refactor: notification popup uses the same text presenter with git command log viewer (#1149) Signed-off-by: leo --- src/Views/CommandLogContentPresenter.cs | 152 ++++++++++++++++++++++++ src/Views/LauncherPage.axaml | 8 +- src/Views/ViewLogs.axaml | 4 +- src/Views/ViewLogs.axaml.cs | 111 ----------------- 4 files changed, 159 insertions(+), 116 deletions(-) create mode 100644 src/Views/CommandLogContentPresenter.cs diff --git a/src/Views/CommandLogContentPresenter.cs b/src/Views/CommandLogContentPresenter.cs new file mode 100644 index 00000000..a2499f8d --- /dev/null +++ b/src/Views/CommandLogContentPresenter.cs @@ -0,0 +1,152 @@ +using System; +using System.Collections.Generic; + +using Avalonia; +using Avalonia.Controls.Primitives; +using Avalonia.Interactivity; +using Avalonia.Media; + +using AvaloniaEdit; +using AvaloniaEdit.Document; +using AvaloniaEdit.Editing; +using AvaloniaEdit.Rendering; +using AvaloniaEdit.TextMate; + +namespace SourceGit.Views +{ + public class CommandLogContentPresenter : TextEditor + { + public class LineStyleTransformer : DocumentColorizingTransformer + { + protected override void ColorizeLine(DocumentLine line) + { + var content = CurrentContext.Document.GetText(line); + if (content.StartsWith("$ git ", StringComparison.Ordinal)) + { + ChangeLinePart(line.Offset, line.Offset + 1, v => + { + v.TextRunProperties.SetForegroundBrush(Brushes.Orange); + }); + + ChangeLinePart(line.Offset + 2, line.EndOffset, v => + { + var old = v.TextRunProperties.Typeface; + v.TextRunProperties.SetTypeface(new Typeface(old.FontFamily, old.Style, FontWeight.Bold)); + }); + } + else if (content.StartsWith("remote: ", StringComparison.Ordinal)) + { + ChangeLinePart(line.Offset, line.Offset + 7, v => + { + v.TextRunProperties.SetForegroundBrush(Brushes.SeaGreen); + }); + } + else + { + foreach (var err in _errors) + { + var idx = content.IndexOf(err, StringComparison.Ordinal); + if (idx >= 0) + { + ChangeLinePart(line.Offset + idx, line.Offset + err.Length + 1, v => + { + v.TextRunProperties.SetForegroundBrush(Brushes.Red); + }); + } + } + } + } + + private readonly List _errors = ["! [rejected]", "! [remote rejected]"]; + } + + public static readonly StyledProperty LogProperty = + AvaloniaProperty.Register(nameof(Log)); + + public ViewModels.CommandLog Log + { + get => GetValue(LogProperty); + set => SetValue(LogProperty, value); + } + + public static readonly StyledProperty PureTextProperty = + AvaloniaProperty.Register(nameof(PureText)); + + public string PureText + { + get => GetValue(PureTextProperty); + set => SetValue(PureTextProperty, value); + } + + protected override Type StyleKeyOverride => typeof(TextEditor); + + public CommandLogContentPresenter() : base(new TextArea(), new TextDocument()) + { + IsReadOnly = true; + ShowLineNumbers = false; + WordWrap = false; + HorizontalScrollBarVisibility = ScrollBarVisibility.Auto; + VerticalScrollBarVisibility = ScrollBarVisibility.Auto; + + 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); + + if (_textMate == null) + { + _textMate = Models.TextMateHelper.CreateForEditor(this); + Models.TextMateHelper.SetGrammarByFileName(_textMate, "Log.log"); + TextArea.TextView.LineTransformers.Add(new LineStyleTransformer()); + } + } + + protected override void OnUnloaded(RoutedEventArgs e) + { + base.OnUnloaded(e); + + if (_textMate != null) + { + _textMate.Dispose(); + _textMate = null; + } + + GC.Collect(); + } + + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); + + if (change.Property == LogProperty) + { + if (change.NewValue is ViewModels.CommandLog log) + { + Text = log.Content; + log.Register(OnLogLineReceived); + } + else + { + Text = string.Empty; + } + } + else if (change.Property == PureTextProperty) + { + if (!string.IsNullOrEmpty(PureText)) + Text = PureText; + } + } + + private void OnLogLineReceived(string newline) + { + AppendText("\n"); + AppendText(newline); + } + + private TextMate.Installation _textMate = null; + } +} diff --git a/src/Views/LauncherPage.axaml b/src/Views/LauncherPage.axaml index 7ce450de..46fb97f6 100644 --- a/src/Views/LauncherPage.axaml +++ b/src/Views/LauncherPage.axaml @@ -141,9 +141,11 @@ - - - + diff --git a/src/Views/ViewLogs.axaml b/src/Views/ViewLogs.axaml index 9c1ae435..c4aa46f7 100644 --- a/src/Views/ViewLogs.axaml +++ b/src/Views/ViewLogs.axaml @@ -100,8 +100,8 @@ BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="1" Background="{DynamicResource Brush.Contents}"> - + diff --git a/src/Views/ViewLogs.axaml.cs b/src/Views/ViewLogs.axaml.cs index 8a3426d2..f0a27884 100644 --- a/src/Views/ViewLogs.axaml.cs +++ b/src/Views/ViewLogs.axaml.cs @@ -1,118 +1,7 @@ -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.Rendering; -using AvaloniaEdit.TextMate; namespace SourceGit.Views { - public class LogContentPresenter : TextEditor - { - public class LineStyleTransformer : DocumentColorizingTransformer - { - protected override void ColorizeLine(DocumentLine line) - { - var content = CurrentContext.Document.GetText(line); - if (content.StartsWith("$ git ", StringComparison.Ordinal)) - { - ChangeLinePart(line.Offset, line.Offset + 1, v => - { - v.TextRunProperties.SetForegroundBrush(Brushes.Orange); - }); - - ChangeLinePart(line.Offset + 2, line.EndOffset, v => - { - var old = v.TextRunProperties.Typeface; - v.TextRunProperties.SetTypeface(new Typeface(old.FontFamily, old.Style, FontWeight.Bold)); - }); - } - } - } - - public static readonly StyledProperty LogProperty = - AvaloniaProperty.Register(nameof(Log)); - - public ViewModels.CommandLog Log - { - get => GetValue(LogProperty); - set => SetValue(LogProperty, value); - } - - protected override Type StyleKeyOverride => typeof(TextEditor); - - public LogContentPresenter() : base(new TextArea(), new TextDocument()) - { - IsReadOnly = true; - ShowLineNumbers = false; - WordWrap = false; - HorizontalScrollBarVisibility = ScrollBarVisibility.Auto; - VerticalScrollBarVisibility = ScrollBarVisibility.Auto; - - 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); - - if (_textMate == null) - { - _textMate = Models.TextMateHelper.CreateForEditor(this); - Models.TextMateHelper.SetGrammarByFileName(_textMate, "Log.log"); - TextArea.TextView.LineTransformers.Add(new LineStyleTransformer()); - } - } - - protected override void OnUnloaded(RoutedEventArgs e) - { - base.OnUnloaded(e); - - if (_textMate != null) - { - _textMate.Dispose(); - _textMate = null; - } - - GC.Collect(); - } - - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) - { - base.OnPropertyChanged(change); - - if (change.Property == LogProperty) - { - if (change.NewValue is ViewModels.CommandLog log) - { - Text = log.Content; - log.Register(OnLogLineReceived); - } - else - { - Text = string.Empty; - } - } - } - - private void OnLogLineReceived(string newline) - { - AppendText("\n"); - AppendText(newline); - } - - private TextMate.Installation _textMate = null; - } - public partial class ViewLogs : ChromelessWindow { public ViewLogs() From 4c1a04477e69c2dfa146cc0fd32db822632c6461 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 17 Apr 2025 20:03:46 +0800 Subject: [PATCH 538/865] refactor: enhanced copy commit information context menu (#1209) Signed-off-by: leo --- src/Resources/Icons.axaml | 3 ++ src/Resources/Locales/de_DE.axaml | 4 +-- src/Resources/Locales/en_US.axaml | 7 ++-- 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/uk_UA.axaml | 4 +-- src/Resources/Locales/zh_CN.axaml | 7 ++-- src/Resources/Locales/zh_TW.axaml | 7 ++-- src/ViewModels/Histories.cs | 56 ++++++++++++++++++++++++++----- 14 files changed, 84 insertions(+), 32 deletions(-) diff --git a/src/Resources/Icons.axaml b/src/Resources/Icons.axaml index a966d47d..51e3d8bf 100644 --- a/src/Resources/Icons.axaml +++ b/src/Resources/Icons.axaml @@ -46,6 +46,7 @@ M416 832H128V128h384v192C512 355 541 384 576 384L768 384v32c0 19 13 32 32 32S832 435 832 416v-64c0-6 0-19-6-25l-256-256c-6-6-19-6-25-6H128A64 64 0 0064 128v704C64 867 93 896 129 896h288c19 0 32-13 32-32S435 832 416 832zM576 172 722 320H576V172zM736 512C614 512 512 614 512 736S614 960 736 960s224-102 224-224S858 512 736 512zM576 736C576 646 646 576 736 576c32 0 58 6 83 26l-218 218c-19-26-26-51-26-83zm160 160c-32 0-64-13-96-32l224-224c19 26 32 58 32 96 0 90-70 160-160 160z M896 320c0-19-6-32-19-45l-192-192c-13-13-26-19-45-19H192c-38 0-64 26-64 64v768c0 38 26 64 64 64h640c38 0 64-26 64-64V320zm-256 384H384c-19 0-32-13-32-32s13-32 32-32h256c19 0 32 13 32 32s-13 32-32 32zm166-384H640V128l192 192h-26z M599 425 599 657 425 832 425 425 192 192 832 192Z + M505 74c-145 3-239 68-239 68-12 8-15 25-7 37 9 13 25 15 38 6 0 0 184-136 448 2 12 7 29 3 36-10 8-13 3-29-12-37-71-38-139-56-199-63-23-3-44-3-65-3m17 111c-254-3-376 201-376 201-8 12-5 29 7 37 12 8 29 4 39-10 0 0 103-178 329-175 226 3 325 173 325 173 8 12 24 17 37 9 14-8 17-24 9-37 0 0-117-195-370-199m-31 106c-72 5-140 31-192 74C197 449 132 603 204 811c5 14 20 21 34 17 14-5 21-20 16-34-66-191-7-316 79-388 84-69 233-85 343-17 54 34 96 93 118 151 22 58 20 114 3 141-18 28-54 38-86 30-32-8-58-31-59-80-1-73-58-118-118-125-57-7-123 24-140 92-32 125 49 302 238 361 14 4 29-3 34-17 4-14-3-29-18-34-163-51-225-206-202-297 10-41 46-55 84-52 37 4 69 26 69 73 2 70 48 117 100 131 52 13 112-3 144-52 33-50 28-120 3-188-26-68-73-136-140-178a356 356 0 00-213-52m15 104v0c-76 3-152 42-195 125-56 106-31 215 7 293 38 79 90 131 90 131 10 11 27 11 38 0s11-26 0-38c0 0-46-47-79-116s-54-157-8-244c48-90 133-111 208-90 76 22 140 88 138 186-2 15 9 28 24 29 15 1 27-10 29-27 3-122-79-210-176-239a246 246 0 00-75-9m9 213c-15 0-26 13-26 27 0 0 1 63 36 124 36 61 112 119 244 107 15-1 26-13 25-28-1-15-14-26-30-25-116 11-165-33-193-81-28-47-29-98-29-98a27 27 0 00-27-27z m211 611a142 142 0 00-90-4v-190a142 142 0 0090-4v198zm0 262v150h-90v-146a142 142 0 0090-4zm0-723a142 142 0 00-90-4v-146h90zm-51 246a115 115 0 11115-115 115 115 0 01-115 115zm0 461a115 115 0 11115-115 115 115 0 01-115 115zm256-691h563v90h-563zm0 461h563v90h-563zm0-282h422v90h-422zm0 474h422v90h-422z M853 267H514c-4 0-6-2-9-4l-38-66c-13-21-38-36-64-36H171c-41 0-75 34-75 75v555c0 41 34 75 75 75h683c41 0 75-34 75-75V341c0-41-34-75-75-75zm-683-43h233c4 0 6 2 9 4l38 66c13 21 38 36 64 36H853c6 0 11 4 11 11v75h-704V235c0-6 4-11 11-11zm683 576H171c-6 0-11-4-11-11V480h704V789c0 6-4 11-11 11z M1088 227H609L453 78a11 11 0 00-7-3H107a43 43 0 00-43 43v789a43 43 0 0043 43h981a43 43 0 0043-43V270a43 43 0 00-43-43zM757 599c0 5-5 9-10 9h-113v113c0 5-4 9-9 9h-56c-5 0-9-4-9-9V608h-113c-5 0-10-4-10-9V543c0-5 5-9 10-9h113V420c0-5 4-9 9-9h56c5 0 9 4 9 9V533h113c5 0 10 4 10 9v56z @@ -116,6 +117,7 @@ M558 545 790 403c24-15 31-47 16-71-15-24-46-31-70-17L507 457 277 315c-24-15-56-7-71 17-15 24-7 56 17 71l232 143V819c0 28 23 51 51 51 28 0 51-23 51-51V545h0zM507 0l443 256v512L507 1024 63 768v-512L507 0z M770 320a41 41 0 00-56-14l-252 153L207 306a41 41 0 10-43 70l255 153 2 296a41 41 0 0082 0l-2-295 255-155a41 41 0 0014-56zM481 935a42 42 0 01-42 0L105 741a42 42 0 01-21-36v-386a42 42 0 0121-36L439 89a42 42 0 0142 0l335 193a42 42 0 0121 36v87h84v-87a126 126 0 00-63-109L523 17a126 126 0 00-126 0L63 210a126 126 0 00-63 109v386a126 126 0 0063 109l335 193a126 126 0 00126 0l94-54-42-72zM1029 700h-126v-125a42 42 0 00-84 0v126h-126a42 42 0 000 84h126v126a42 42 0 1084 0v-126h126a42 42 0 000-84z M416 587c21 0 37 17 37 37v299A37 37 0 01416 960h-299a37 37 0 01-37-37v-299c0-21 17-37 37-37h299zm448 0c21 0 37 17 37 37v299A37 37 0 01864 960h-299a37 37 0 01-37-37v-299c0-21 17-37 37-37h299zM758 91l183 189a37 37 0 010 52l-182 188a37 37 0 01-53 1l-183-189a37 37 0 010-52l182-188a37 37 0 0153-1zM416 139c21 0 37 17 37 37v299A37 37 0 01416 512h-299a37 37 0 01-37-37v-299c0-21 17-37 37-37h299z + M653 435l-26 119H725c9 0 13 4 13 13v47c0 9-4 13-13 13h-107l-21 115c0 9-4 13-13 13h-47c-9 0-13-4-13-13l21-111H427l-21 115c0 9-4 13-13 13H346c-9 0-13-4-13-13l21-107h-85c-4-9-9-21-13-34v-38c0-9 4-13 13-13h98l26-119H294c-9 0-13-4-13-13V375c0-9 4-13 13-13h115l13-81c0-9 4-13 13-13h43c9 0 13 4 13 13L469 363h119l13-81c0-9 4-13 13-13h47c9 0 13 4 13 13l-13 77h85c9 0 13 4 13 13v47c0 9-4 13-13 13h-98v4zM512 0C230 0 0 230 0 512c0 145 60 282 166 375L90 1024H512c282 0 512-230 512-512S794 0 512 0zm-73 559h124l26-119h-128l-21 119z M875 128h-725A107 107 0 0043 235v555A107 107 0 00149 896h725a107 107 0 00107-107v-555A107 107 0 00875 128zm-115 640h-183v-58l25-3c15 0 19-8 14-24l-22-61H419l-28 82 39 2V768h-166v-58l18-3c18-2 22-11 26-24l125-363-40-4V256h168l160 448 39 3zM506 340l-72 218h145l-71-218h-2z M177 156c-22 5-33 17-36 37c-10 57-33 258-13 278l445 445c23 23 61 23 84 0l246-246c23-23 23-61 0-84l-445-445C437 120 231 145 177 156zM331 344c-26 26-69 26-95 0c-26-26-26-69 0-95s69-26 95 0C357 276 357 318 331 344z M683 537h-144v-142h-142V283H239a44 44 0 00-41 41v171a56 56 0 0014 34l321 321a41 41 0 0058 0l174-174a41 41 0 000-58zm-341-109a41 41 0 110-58a41 41 0 010 58zM649 284V142h-69v142h-142v68h142v142h69v-142h142v-68h-142z @@ -130,6 +132,7 @@ M762 1024C876 818 895 504 448 514V768L64 384l384-384v248c535-14 595 472 314 776z M832 464H332V240c0-31 25-56 56-56h248c31 0 56 25 56 56v68c0 4 4 8 8 8h56c4 0 8-4 8-8v-68c0-71-57-128-128-128H388c-71 0-128 57-128 128v224h-68c-18 0-32 14-32 32v384c0 18 14 32 32 32h640c18 0 32-14 32-32V496c0-18-14-32-32-32zM540 701v53c0 4-4 8-8 8h-40c-4 0-8-4-8-8v-53c-12-9-20-23-20-39 0-27 22-48 48-48s48 22 48 48c0 16-8 30-20 39z M170 831l343-342L855 831l105-105-448-448L64 726 170 831z + M667 607c-3-2-7-14-0-38 73-77 118-187 118-290C784 115 668 0 508 0 348 0 236 114 236 278c0 104 45 215 119 292 7 24-2 33-8 35C274 631 0 725 0 854L0 1024l1024 0 0-192C989 714 730 627 667 607L667 607z M880 128A722 722 0 01555 13a77 77 0 00-85 0 719 719 0 01-325 115c-40 4-71 38-71 80v369c0 246 329 446 439 446 110 0 439-200 439-446V207c0-41-31-76-71-80zM465 692a36 36 0 01-53 0L305 579a42 42 0 010-57 36 36 0 0153 0l80 85L678 353a36 36 0 0153 0 42 42 0 01-0 57L465 692z M812 864h-29V654c0-21-11-40-28-52l-133-88 134-89c18-12 28-31 28-52V164h28c18 0 32-14 32-32s-14-32-32-32H212c-18 0-32 14-32 32s14 32 32 32h30v210c0 21 11 40 28 52l133 88-134 89c-18 12-28 31-28 52V864H212c-18 0-32 14-32 32s14 32 32 32h600c18 0 32-14 32-32s-14-32-32-32zM441 566c18-12 28-31 28-52s-11-40-28-52L306 373V164h414v209l-136 90c-18 12-28 31-28 52 0 21 11 40 28 52l135 89V695c-9-7-20-13-32-19-30-15-93-41-176-41-63 0-125 14-175 38-12 6-22 12-31 18v-36l136-90z M0 512M1024 512M512 0M512 1024M762 412v100h-500v-100h-150v200h800v-200h-150z diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml index 3cb70cea..7a3da294 100644 --- a/src/Resources/Locales/de_DE.axaml +++ b/src/Resources/Locales/de_DE.axaml @@ -102,8 +102,8 @@ Mehrere cherry-picken Mit HEAD vergleichen Mit Worktree vergleichen - Info kopieren - SHA kopieren + Information + SHA Benutzerdefinierte Aktion Interactives Rebase von ${0}$ auf diesen Commit Merge in ${0}$ hinein diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index bd4cfc56..20a70f22 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -99,8 +99,11 @@ Cherry-Pick ... Compare with HEAD Compare with Worktree - Copy Info - Copy SHA + Author + Committer + Information + SHA + Subject Custom Action Interactively Rebase ${0}$ on Here Merge to ${0}$ diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index e316a470..204cfc1a 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -103,8 +103,8 @@ Cherry-Pick ... Comparar con HEAD Comparar con Worktree - Copiar Información - Copiar SHA + Información + SHA Acción personalizada Rebase Interactivo ${0}$ hasta Aquí Merge a ${0}$ diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index fd41b4f0..f45a83d9 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -103,8 +103,8 @@ Cherry-Pick ... Comparer avec HEAD Comparer avec le worktree - Copier les informations - Copier le SHA + Informations + SHA Action personnalisée Rebase interactif de ${0}$ ici Fusionner dans ${0}$ diff --git a/src/Resources/Locales/it_IT.axaml b/src/Resources/Locales/it_IT.axaml index 4498348d..b7d2568a 100644 --- a/src/Resources/Locales/it_IT.axaml +++ b/src/Resources/Locales/it_IT.axaml @@ -103,8 +103,8 @@ Cherry-Pick... Confronta con HEAD Confronta con Worktree - Copia Info - Copia SHA + Informazioni + SHA Azione Personalizzata Riallinea Interattivamente ${0}$ fino a Qui Unisci a ${0}$ diff --git a/src/Resources/Locales/ja_JP.axaml b/src/Resources/Locales/ja_JP.axaml index 4b785c3d..c50504e1 100644 --- a/src/Resources/Locales/ja_JP.axaml +++ b/src/Resources/Locales/ja_JP.axaml @@ -103,8 +103,8 @@ チェリーピック... HEADと比較 ワークツリーと比較 - 情報をコピー - SHAをコピー + 情報 + SHA カスタムアクション ${0}$ ブランチをここにインタラクティブリベース ${0}$ にマージ diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml index 299ececd..a4e9d883 100644 --- a/src/Resources/Locales/pt_BR.axaml +++ b/src/Resources/Locales/pt_BR.axaml @@ -93,8 +93,8 @@ Cherry-Pick ... Comparar com HEAD Comparar com Worktree - Copiar Informações - Copiar SHA + Informações + SHA Ação customizada Rebase Interativo ${0}$ até Aqui Rebase ${0}$ até Aqui diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index c3e8b87a..b8c86415 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -103,8 +103,8 @@ Применить несколько ревизий ... Сравнить c ГОЛОВОЙ (HEAD) Сравнить с рабочим каталогом - Копировать информацию - Копировать SHA + Информацию + SHA Пользовательское действие Интерактивное перемещение (rebase -i) ${0}$ сюда Влить в ${0}$ diff --git a/src/Resources/Locales/ta_IN.axaml b/src/Resources/Locales/ta_IN.axaml index c62dd2b5..b4e4d939 100644 --- a/src/Resources/Locales/ta_IN.axaml +++ b/src/Resources/Locales/ta_IN.axaml @@ -103,8 +103,8 @@ கனி-பறி ... தலையுடன் ஒப்பிடுக பணிமரத்துடன் ஒப்பிடுக - தகவலை நகலெடு - பாகொவ-வை நகலெடு + தகவலை + பாகொவ-வை தனிப்பயன் செயல் இங்கே ${0}$ ஐ ஊடாடும் வகையில் மறுதளம் ${0}$ இதற்கு ஒன்றிணை diff --git a/src/Resources/Locales/uk_UA.axaml b/src/Resources/Locales/uk_UA.axaml index 828c36f8..a3b63bde 100644 --- a/src/Resources/Locales/uk_UA.axaml +++ b/src/Resources/Locales/uk_UA.axaml @@ -103,8 +103,8 @@ Cherry-pick ... Порівняти з HEAD Порівняти з робочим деревом - Копіювати інформацію - Копіювати SHA + Iнформацію + SHA Спеціальна дія Інтерактивно перебазувати ${0}$ сюди Злиття в ${0}$ diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 7546b3c4..3d41bccd 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -103,8 +103,11 @@ 挑选(cherry-pick)... 与当前HEAD比较 与本地工作树比较 - 复制简要信息 - 复制提交指纹 + 作者 + 提交者 + 简要信息 + 提交指纹 + 主题 自定义操作 交互式变基(rebase -i) ${0}$ 到此处 合并(merge)此提交至 ${0}$ diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 61921ea4..3a10f6ca 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -103,8 +103,11 @@ 揀選 (cherry-pick)... 與目前 HEAD 比較 與本機工作區比較 - 複製摘要資訊 - 複製提交編號 + 作者 + 提交者 + 摘要資訊 + 提交編號 + 標題 自訂動作 互動式重定基底 (rebase -i) ${0}$ 到此處 合併 (merge) 此提交到 ${0}$ diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs index b3216a91..ee5e5891 100644 --- a/src/ViewModels/Histories.cs +++ b/src/ViewModels/Histories.cs @@ -330,7 +330,7 @@ namespace SourceGit.ViewModels var copyMultipleSHAs = new MenuItem(); copyMultipleSHAs.Header = App.Text("CommitCM.CopySHA"); - copyMultipleSHAs.Icon = App.CreateMenuIcon("Icons.Copy"); + copyMultipleSHAs.Icon = App.CreateMenuIcon("Icons.Fingerprint"); copyMultipleSHAs.Click += (_, e) => { var builder = new StringBuilder(); @@ -340,11 +340,10 @@ namespace SourceGit.ViewModels App.CopyText(builder.ToString()); e.Handled = true; }; - multipleMenu.Items.Add(copyMultipleSHAs); var copyMultipleInfo = new MenuItem(); copyMultipleInfo.Header = App.Text("CommitCM.CopyInfo"); - copyMultipleInfo.Icon = App.CreateMenuIcon("Icons.Copy"); + copyMultipleInfo.Icon = App.CreateMenuIcon("Icons.Info"); copyMultipleInfo.Click += (_, e) => { var builder = new StringBuilder(); @@ -354,7 +353,13 @@ namespace SourceGit.ViewModels App.CopyText(builder.ToString()); e.Handled = true; }; - multipleMenu.Items.Add(copyMultipleInfo); + + var copyMultiple = new MenuItem(); + copyMultiple.Header = App.Text("Copy"); + copyMultiple.Icon = App.CreateMenuIcon("Icons.Copy"); + copyMultiple.Items.Add(copyMultipleSHAs); + copyMultiple.Items.Add(copyMultipleInfo); + multipleMenu.Items.Add(copyMultiple); return multipleMenu; } @@ -715,23 +720,58 @@ namespace SourceGit.ViewModels var copySHA = new MenuItem(); copySHA.Header = App.Text("CommitCM.CopySHA"); - copySHA.Icon = App.CreateMenuIcon("Icons.Copy"); + copySHA.Icon = App.CreateMenuIcon("Icons.Fingerprint"); copySHA.Click += (_, e) => { App.CopyText(commit.SHA); e.Handled = true; }; - menu.Items.Add(copySHA); + + var copySubject = new MenuItem(); + copySubject.Header = App.Text("CommitCM.CopySubject"); + copySubject.Icon = App.CreateMenuIcon("Icons.Subject"); + copySubject.Click += (_, e) => + { + App.CopyText(commit.Subject); + e.Handled = true; + }; var copyInfo = new MenuItem(); copyInfo.Header = App.Text("CommitCM.CopyInfo"); - copyInfo.Icon = App.CreateMenuIcon("Icons.Copy"); + copyInfo.Icon = App.CreateMenuIcon("Icons.Info"); copyInfo.Click += (_, e) => { App.CopyText($"{commit.SHA.Substring(0, 10)} - {commit.Subject}"); e.Handled = true; }; - menu.Items.Add(copyInfo); + + var copyAuthor = new MenuItem(); + copyAuthor.Header = App.Text("CommitCM.CopyAuthor"); + copyAuthor.Icon = App.CreateMenuIcon("Icons.User"); + copyAuthor.Click += (_, e) => + { + App.CopyText(commit.Author.ToString()); + e.Handled = true; + }; + + var copyCommitter = new MenuItem(); + copyCommitter.Header = App.Text("CommitCM.CopyCommitter"); + copyCommitter.Icon = App.CreateMenuIcon("Icons.User"); + copyCommitter.Click += (_, e) => + { + App.CopyText(commit.Committer.ToString()); + e.Handled = true; + }; + + var copy = new MenuItem(); + copy.Header = App.Text("Copy"); + copy.Icon = App.CreateMenuIcon("Icons.Copy"); + copy.Items.Add(copySHA); + copy.Items.Add(copySubject); + copy.Items.Add(copyInfo); + copy.Items.Add(copyAuthor); + copy.Items.Add(copyCommitter); + menu.Items.Add(copy); return menu; } From 5bd7dd428dc0df2616f8a7a8cf21af8c9d65981a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 17 Apr 2025 12:04:02 +0000 Subject: [PATCH 539/865] doc: Update translation status and sort locale files --- TRANSLATION.md | 45 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/TRANSLATION.md b/TRANSLATION.md index 4f13d26a..866aac65 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -6,12 +6,15 @@ This document shows the translation status of each locale file in the repository ### ![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen) -### ![de__DE](https://img.shields.io/badge/de__DE-96.57%25-yellow) +### ![de__DE](https://img.shields.io/badge/de__DE-96.19%25-yellow)
Missing keys in de_DE.axaml - Text.BranchUpstreamInvalid +- Text.CommitCM.CopyAuthor +- Text.CommitCM.CopyCommitter +- Text.CommitCM.CopySubject - Text.CommitMessageTextBox.SubjectCount - Text.Configure.CustomAction.WaitForExit - Text.Configure.Git.PreferredMergeMode @@ -40,11 +43,14 @@ This document shows the translation status of each locale file in the repository
-### ![es__ES](https://img.shields.io/badge/es__ES-99.34%25-yellow) +### ![es__ES](https://img.shields.io/badge/es__ES-98.95%25-yellow)
Missing keys in es_ES.axaml +- Text.CommitCM.CopyAuthor +- Text.CommitCM.CopyCommitter +- Text.CommitCM.CopySubject - Text.Repository.ViewLogs - Text.ViewLogs - Text.ViewLogs.Clear @@ -53,11 +59,14 @@ This document shows the translation status of each locale file in the repository
-### ![fr__FR](https://img.shields.io/badge/fr__FR-97.89%25-yellow) +### ![fr__FR](https://img.shields.io/badge/fr__FR-97.51%25-yellow)
Missing keys in fr_FR.axaml +- Text.CommitCM.CopyAuthor +- Text.CommitCM.CopyCommitter +- Text.CommitCM.CopySubject - Text.CommitMessageTextBox.SubjectCount - Text.Configure.Git.PreferredMergeMode - Text.ConfirmEmptyCommit.Continue @@ -77,11 +86,14 @@ This document shows the translation status of each locale file in the repository
-### ![it__IT](https://img.shields.io/badge/it__IT-97.63%25-yellow) +### ![it__IT](https://img.shields.io/badge/it__IT-97.24%25-yellow)
Missing keys in it_IT.axaml +- Text.CommitCM.CopyAuthor +- Text.CommitCM.CopyCommitter +- Text.CommitCM.CopySubject - Text.CommitMessageTextBox.SubjectCount - Text.Configure.Git.PreferredMergeMode - Text.ConfirmEmptyCommit.Continue @@ -103,11 +115,14 @@ This document shows the translation status of each locale file in the repository
-### ![ja__JP](https://img.shields.io/badge/ja__JP-97.63%25-yellow) +### ![ja__JP](https://img.shields.io/badge/ja__JP-97.24%25-yellow)
Missing keys in ja_JP.axaml +- Text.CommitCM.CopyAuthor +- Text.CommitCM.CopyCommitter +- Text.CommitCM.CopySubject - Text.CommitMessageTextBox.SubjectCount - Text.Configure.Git.PreferredMergeMode - Text.ConfirmEmptyCommit.Continue @@ -129,7 +144,7 @@ This document shows the translation status of each locale file in the repository
-### ![pt__BR](https://img.shields.io/badge/pt__BR-89.06%25-yellow) +### ![pt__BR](https://img.shields.io/badge/pt__BR-88.71%25-yellow)
Missing keys in pt_BR.axaml @@ -144,6 +159,9 @@ This document shows the translation status of each locale file in the repository - Text.BranchCM.MergeMultiBranches - Text.BranchUpstreamInvalid - Text.Clone.RecurseSubmodules +- Text.CommitCM.CopyAuthor +- Text.CommitCM.CopyCommitter +- Text.CommitCM.CopySubject - Text.CommitCM.Merge - Text.CommitCM.MergeMultiple - Text.CommitDetail.Files.Search @@ -220,11 +238,14 @@ This document shows the translation status of each locale file in the repository
-### ![ru__RU](https://img.shields.io/badge/ru__RU-99.21%25-yellow) +### ![ru__RU](https://img.shields.io/badge/ru__RU-98.82%25-yellow)
Missing keys in ru_RU.axaml +- Text.CommitCM.CopyAuthor +- Text.CommitCM.CopyCommitter +- Text.CommitCM.CopySubject - Text.CommitMessageTextBox.SubjectCount - Text.Repository.ViewLogs - Text.ViewLogs @@ -234,11 +255,14 @@ This document shows the translation status of each locale file in the repository
-### ![ta__IN](https://img.shields.io/badge/ta__IN-97.89%25-yellow) +### ![ta__IN](https://img.shields.io/badge/ta__IN-97.51%25-yellow)
Missing keys in ta_IN.axaml +- Text.CommitCM.CopyAuthor +- Text.CommitCM.CopyCommitter +- Text.CommitCM.CopySubject - Text.CommitMessageTextBox.SubjectCount - Text.Configure.Git.PreferredMergeMode - Text.ConfirmEmptyCommit.Continue @@ -258,11 +282,14 @@ This document shows the translation status of each locale file in the repository
-### ![uk__UA](https://img.shields.io/badge/uk__UA-99.08%25-yellow) +### ![uk__UA](https://img.shields.io/badge/uk__UA-98.69%25-yellow)
Missing keys in uk_UA.axaml +- Text.CommitCM.CopyAuthor +- Text.CommitCM.CopyCommitter +- Text.CommitCM.CopySubject - Text.CommitMessageTextBox.SubjectCount - Text.ConfigureWorkspace.Name - Text.Repository.ViewLogs From de31d4bad417e50ddea85496fe00da284f04e28f Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 17 Apr 2025 21:17:54 +0800 Subject: [PATCH 540/865] ux: layout of git command log item Signed-off-by: leo --- src/Views/ViewLogs.axaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Views/ViewLogs.axaml b/src/Views/ViewLogs.axaml index c4aa46f7..e29a5afd 100644 --- a/src/Views/ViewLogs.axaml +++ b/src/Views/ViewLogs.axaml @@ -75,7 +75,7 @@ Date: Thu, 17 Apr 2025 17:14:52 +0100 Subject: [PATCH 541/865] Fixed tooltip Tooltip for chosing mine was wrong. Was --theirs when should be --ours. (cherry picked from commit 26a471933c21a135e946273d49b9135b401bbd7f) --- src/Views/Conflict.axaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Views/Conflict.axaml b/src/Views/Conflict.axaml index f2d7bdec..cf2e25a0 100644 --- a/src/Views/Conflict.axaml +++ b/src/Views/Conflict.axaml @@ -111,7 +111,7 @@ -