From 828028736225c18d9eaecb98babc6746a5c96d02 Mon Sep 17 00:00:00 2001 From: GadflyFang Date: Mon, 28 Oct 2024 09:45:16 +0800 Subject: [PATCH 01/68] doc: add link on badges (#607) Signed-off-by: Gadfly --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8ebbbb98..89a44a10 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ # SourceGit - Opensource Git GUI client. -![stars](https://img.shields.io/github/stars/sourcegit-scm/sourcegit.svg) ![forks](https://img.shields.io/github/forks/sourcegit-scm/sourcegit.svg) ![license](https://img.shields.io/github/license/sourcegit-scm/sourcegit.svg) ![latest](https://img.shields.io/github/v/release/sourcegit-scm/sourcegit.svg) ![downloads](https://img.shields.io/github/downloads/sourcegit-scm/sourcegit/total) +[![stars](https://img.shields.io/github/stars/sourcegit-scm/sourcegit.svg)](https://github.com/sourcegit-scm/sourcegit/stargazers) +[![forks](https://img.shields.io/github/forks/sourcegit-scm/sourcegit.svg)](https://github.com/sourcegit-scm/sourcegit/forks) +[![license](https://img.shields.io/github/license/sourcegit-scm/sourcegit.svg)](LICENSE) +[![latest](https://img.shields.io/github/v/release/sourcegit-scm/sourcegit.svg)](https://github.com/sourcegit-scm/sourcegit/releases/latest) +[![downloads](https://img.shields.io/github/downloads/sourcegit-scm/sourcegit/total)](https://github.com/sourcegit-scm/sourcegit/releases) ## Highlights From 1044915be100ea75e2a7b475cd67ddabd14d0174 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 28 Oct 2024 11:00:11 +0800 Subject: [PATCH 02/68] refactor: OpenAI integration * supports configure multiple services * supports select service when generate commit message by OpenAI Signed-off-by: leo --- src/Commands/GenerateCommitMessage.cs | 8 +- src/Models/OpenAI.cs | 81 ++++++++--- src/Resources/Locales/en_US.axaml | 2 +- src/Resources/Locales/ru_RU.axaml | 1 - src/Resources/Locales/zh_CN.axaml | 8 +- src/Resources/Locales/zh_TW.axaml | 2 +- src/ViewModels/Preference.cs | 113 +--------------- src/ViewModels/WorkingCopy.cs | 64 ++++++--- src/Views/AIAssistant.axaml.cs | 7 +- src/Views/Preference.axaml | 185 +++++++++++++++----------- src/Views/Preference.axaml.cs | 28 ++++ src/Views/WorkingCopy.axaml | 2 +- src/Views/WorkingCopy.axaml.cs | 11 ++ 13 files changed, 283 insertions(+), 229 deletions(-) diff --git a/src/Commands/GenerateCommitMessage.cs b/src/Commands/GenerateCommitMessage.cs index 3bcf7010..e4f25f38 100644 --- a/src/Commands/GenerateCommitMessage.cs +++ b/src/Commands/GenerateCommitMessage.cs @@ -20,8 +20,9 @@ namespace SourceGit.Commands } } - public GenerateCommitMessage(string repo, List changes, CancellationToken cancelToken, Action onProgress) + public GenerateCommitMessage(Models.OpenAIService service, string repo, List changes, CancellationToken cancelToken, Action onProgress) { + _service = service; _repo = repo; _changes = changes; _cancelToken = cancelToken; @@ -75,7 +76,7 @@ namespace SourceGit.Commands var rs = new GetDiffContent(_repo, new Models.DiffOption(change, false)).ReadToEnd(); var diff = rs.IsSuccess ? rs.StdOut : "unknown change"; - var rsp = Models.OpenAI.Chat(Models.OpenAI.AnalyzeDiffPrompt, $"Here is the `git diff` output: {diff}", _cancelToken); + var rsp = _service.Chat(_service.AnalyzeDiffPrompt, $"Here is the `git diff` output: {diff}", _cancelToken); if (rsp != null && rsp.Choices.Count > 0) return rsp.Choices[0].Message.Content; @@ -84,13 +85,14 @@ namespace SourceGit.Commands private string GenerateSubject(string summary) { - var rsp = Models.OpenAI.Chat(Models.OpenAI.GenerateSubjectPrompt, $"Here are the summaries changes:\n{summary}", _cancelToken); + var rsp = _service.Chat(_service.GenerateSubjectPrompt, $"Here are the summaries changes:\n{summary}", _cancelToken); if (rsp != null && rsp.Choices.Count > 0) return rsp.Choices[0].Message.Content; return string.Empty; } + private Models.OpenAIService _service; private string _repo; private List _changes; private CancellationToken _cancelToken; diff --git a/src/Models/OpenAI.cs b/src/Models/OpenAI.cs index b1bb9465..e9c7b5ed 100644 --- a/src/Models/OpenAI.cs +++ b/src/Models/OpenAI.cs @@ -6,6 +6,8 @@ using System.Text.Json; using System.Text.Json.Serialization; using System.Threading; +using CommunityToolkit.Mvvm.ComponentModel; + namespace SourceGit.Models { public class OpenAIChatMessage @@ -74,44 +76,78 @@ namespace SourceGit.Models } } - public static class OpenAI + public class OpenAIService : ObservableObject { - public static string Server + public string Name { - get; - set; + get => _name; + set => SetProperty(ref _name, value); } - public static string ApiKey + public string Server { - get; - set; + get => _server; + set => SetProperty(ref _server, value); } - public static string Model + public string ApiKey { - get; - set; + get => _apiKey; + set => SetProperty(ref _apiKey, value); } - public static string AnalyzeDiffPrompt + public string Model { - get; - set; + get => _model; + set => SetProperty(ref _model, value); } - public static string GenerateSubjectPrompt + public string AnalyzeDiffPrompt { - get; - set; + get => _analyzeDiffPrompt; + set => SetProperty(ref _analyzeDiffPrompt, value); } - public static bool IsValid + public string GenerateSubjectPrompt { - get => !string.IsNullOrEmpty(Server) && !string.IsNullOrEmpty(Model); + get => _generateSubjectPrompt; + set => SetProperty(ref _generateSubjectPrompt, value); } - public static OpenAIChatResponse Chat(string prompt, string question, CancellationToken cancellation) + public OpenAIService() + { + AnalyzeDiffPrompt = """ + You are an expert developer specialist in creating commits. + Provide a super concise one sentence overall changes summary of the user `git diff` output following strictly the next rules: + - Do not use any code snippets, imports, file routes or bullets points. + - Do not mention the route of file that has been change. + - Write clear, concise, and descriptive messages that explain the MAIN GOAL made of the changes. + - Use the present tense and active voice in the message, for example, "Fix bug" instead of "Fixed bug.". + - Use the imperative mood, which gives the message a sense of command, e.g. "Add feature" instead of "Added feature". + - Avoid using general terms like "update" or "change", be specific about what was updated or changed. + - Avoid using terms like "The main goal of", just output directly the summary in plain text + """; + + GenerateSubjectPrompt = """ + You are an expert developer specialist in creating commits messages. + Your only goal is to retrieve a single commit message. + Based on the provided user changes, combine them in ONE SINGLE commit message retrieving the global idea, following strictly the next rules: + - Assign the commit {type} according to the next conditions: + feat: Only when adding a new feature. + fix: When fixing a bug. + docs: When updating documentation. + style: When changing elements styles or design and/or making changes to the code style (formatting, missing semicolons, etc.) without changing the code logic. + test: When adding or updating tests. + chore: When making changes to the build process or auxiliary tools and libraries. + revert: When undoing a previous commit. + refactor: When restructuring code without changing its external behavior, or is any of the other refactor types. + - Do not add any issues numeration, explain your output nor introduce your answer. + - Output directly only one commit message in plain text with the next format: {type}: {commit_message}. + - Be as concise as possible, keep the message under 50 characters. + """; + } + + public OpenAIChatResponse Chat(string prompt, string question, CancellationToken cancellation) { var chat = new OpenAIChatRequest() { Model = Model }; chat.AddMessage("system", prompt); @@ -144,5 +180,12 @@ namespace SourceGit.Models throw; } } + + private string _name; + private string _server; + private string _apiKey; + private string _model; + private string _analyzeDiffPrompt; + private string _generateSubjectPrompt; } } diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index ff846035..ae386385 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -401,12 +401,12 @@ Last year {0} years ago Preference - Advanced Options OPEN AI Analyze Diff Prompt API Key Generate Subject Prompt Model + Name Server APPEARANCE Default Font diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index 0d7c55fb..f9271a95 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -405,7 +405,6 @@ В пролому году {0} лет назад Параметры - Расширенные опции ОТКРЫТЬ ИИ Ключ API Запрос на анализ различий diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index f4027111..eea6d169 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -404,7 +404,13 @@ 一年前 {0}年前 偏好设置 - 高级设置 + OPEN AI + Analyze Diff Prompt + API密钥 + Generate Subject Prompt + 模型 + 配置名称 + 服务地址 外观配置 缺省字体 默认字体大小 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index a72914f7..5ae1f860 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -403,12 +403,12 @@ {0} 個月前 一年前 {0} 年前 - 偏好設定 進階設定 OpenAI 伺服器 API 金鑰 模型 + 名稱 分析變更差異提示詞 產生提交訊息提示詞 外觀設定 diff --git a/src/ViewModels/Preference.cs b/src/ViewModels/Preference.cs index 72667f54..2741650c 100644 --- a/src/ViewModels/Preference.cs +++ b/src/ViewModels/Preference.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Text.Json; using System.Text.Json.Serialization; - +using Avalonia.Collections; using CommunityToolkit.Mvvm.ComponentModel; namespace SourceGit.ViewModels @@ -25,7 +25,6 @@ namespace SourceGit.ViewModels _instance.PrepareGit(); _instance.PrepareShellOrTerminal(); _instance.PrepareWorkspaces(); - _instance.PrepareOpenAIPrompt(); return _instance; } @@ -277,71 +276,6 @@ namespace SourceGit.ViewModels set => SetProperty(ref _externalMergeToolPath, value); } - public string OpenAIServer - { - get => Models.OpenAI.Server; - set - { - if (value != Models.OpenAI.Server) - { - Models.OpenAI.Server = value; - OnPropertyChanged(); - } - } - } - - public string OpenAIApiKey - { - get => Models.OpenAI.ApiKey; - set - { - if (value != Models.OpenAI.ApiKey) - { - Models.OpenAI.ApiKey = value; - OnPropertyChanged(); - } - } - } - - public string OpenAIModel - { - get => Models.OpenAI.Model; - set - { - if (value != Models.OpenAI.Model) - { - Models.OpenAI.Model = value; - OnPropertyChanged(); - } - } - } - - public string OpenAIAnalyzeDiffPrompt - { - get => Models.OpenAI.AnalyzeDiffPrompt; - set - { - if (value != Models.OpenAI.AnalyzeDiffPrompt) - { - Models.OpenAI.AnalyzeDiffPrompt = value; - OnPropertyChanged(); - } - } - } - - public string OpenAIGenerateSubjectPrompt - { - get => Models.OpenAI.GenerateSubjectPrompt; - set - { - if (value != Models.OpenAI.GenerateSubjectPrompt) - { - Models.OpenAI.GenerateSubjectPrompt = value; - OnPropertyChanged(); - } - } - } - public uint StatisticsSampleColor { get => _statisticsSampleColor; @@ -360,6 +294,12 @@ namespace SourceGit.ViewModels set; } = []; + public AvaloniaList OpenAIServices + { + get; + set; + } = []; + public double LastCheckUpdateTime { get => _lastCheckUpdateTime; @@ -554,45 +494,6 @@ namespace SourceGit.ViewModels } } - private void PrepareOpenAIPrompt() - { - if (string.IsNullOrEmpty(Models.OpenAI.AnalyzeDiffPrompt)) - { - Models.OpenAI.AnalyzeDiffPrompt = """ - You are an expert developer specialist in creating commits. - Provide a super concise one sentence overall changes summary of the user `git diff` output following strictly the next rules: - - Do not use any code snippets, imports, file routes or bullets points. - - Do not mention the route of file that has been change. - - Write clear, concise, and descriptive messages that explain the MAIN GOAL made of the changes. - - Use the present tense and active voice in the message, for example, "Fix bug" instead of "Fixed bug.". - - Use the imperative mood, which gives the message a sense of command, e.g. "Add feature" instead of "Added feature". - - Avoid using general terms like "update" or "change", be specific about what was updated or changed. - - Avoid using terms like "The main goal of", just output directly the summary in plain text - """; - } - - if (string.IsNullOrEmpty(Models.OpenAI.GenerateSubjectPrompt)) - { - Models.OpenAI.GenerateSubjectPrompt = """ - You are an expert developer specialist in creating commits messages. - Your only goal is to retrieve a single commit message. - Based on the provided user changes, combine them in ONE SINGLE commit message retrieving the global idea, following strictly the next rules: - - Assign the commit {type} according to the next conditions: - feat: Only when adding a new feature. - fix: When fixing a bug. - docs: When updating documentation. - style: When changing elements styles or design and/or making changes to the code style (formatting, missing semicolons, etc.) without changing the code logic. - test: When adding or updating tests. - chore: When making changes to the build process or auxiliary tools and libraries. - revert: When undoing a previous commit. - refactor: When restructuring code without changing its external behavior, or is any of the other refactor types. - - Do not add any issues numeration, explain your output nor introduce your answer. - - Output directly only one commit message in plain text with the next format: {type}: {commit_message}. - - Be as concise as possible, keep the message under 50 characters. - """; - } - } - private RepositoryNode FindNodeRecursive(string id, List collection) { foreach (var node in collection) diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 6fcbedd9..6393c6ad 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -403,25 +403,6 @@ namespace SourceGit.ViewModels } } - public void GenerateCommitMessageByAI() - { - if (!Models.OpenAI.IsValid) - { - App.RaiseException(_repo.FullPath, "Bad configuration for OpenAI"); - return; - } - - if (_staged is { Count: > 0 }) - { - var dialog = new Views.AIAssistant(_repo.FullPath, _staged, generated => CommitMessage = generated); - App.OpenDialog(dialog); - } - else - { - App.RaiseException(_repo.FullPath, "No files added to commit!"); - } - } - public void Commit() { DoCommit(false, false, false); @@ -1211,6 +1192,51 @@ namespace SourceGit.ViewModels return menu; } + public ContextMenu CreateContextForOpenAI() + { + if (_staged == null || _staged.Count == 0) + { + App.RaiseException(_repo.FullPath, "No files added to commit!"); + return null; + } + + var services = Preference.Instance.OpenAIServices; + if (services.Count == 0) + { + App.RaiseException(_repo.FullPath, "Bad configuration for OpenAI"); + return null; + } + + if (services.Count == 1) + { + var dialog = new Views.AIAssistant(services[0], _repo.FullPath, _staged, generated => CommitMessage = generated); + App.OpenDialog(dialog); + return null; + } + else + { + 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 dialog = new Views.AIAssistant(dup, _repo.FullPath, _staged, generated => CommitMessage = generated); + App.OpenDialog(dialog); + e.Handled = true; + }; + + menu.Items.Add(item); + } + + return menu; + } + } + private List GetStagedChanges() { if (_useAmend) diff --git a/src/Views/AIAssistant.axaml.cs b/src/Views/AIAssistant.axaml.cs index 6ceb5610..331d380d 100644 --- a/src/Views/AIAssistant.axaml.cs +++ b/src/Views/AIAssistant.axaml.cs @@ -17,12 +17,14 @@ namespace SourceGit.Views InitializeComponent(); } - public AIAssistant(string repo, List changes, Action onDone) + public AIAssistant(Models.OpenAIService service, string repo, List changes, Action onDone) { + _service = service; _repo = repo; _changes = changes; _onDone = onDone; _cancel = new CancellationTokenSource(); + InitializeComponent(); } @@ -35,7 +37,7 @@ namespace SourceGit.Views Task.Run(() => { - var message = new Commands.GenerateCommitMessage(_repo, _changes, _cancel.Token, SetDescription).Result(); + var message = new Commands.GenerateCommitMessage(_service, _repo, _changes, _cancel.Token, SetDescription).Result(); if (_cancel.IsCancellationRequested) return; @@ -63,6 +65,7 @@ namespace SourceGit.Views Dispatcher.UIThread.Invoke(() => ProgressMessage.Text = message); } + private Models.OpenAIService _service; private string _repo; private List _changes; private Action _onDone; diff --git a/src/Views/Preference.axaml b/src/Views/Preference.axaml index b95dbe66..63d5ff68 100644 --- a/src/Views/Preference.axaml +++ b/src/Views/Preference.axaml @@ -412,7 +412,7 @@ - + @@ -459,82 +459,117 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Views/Preference.axaml.cs b/src/Views/Preference.axaml.cs index 2f08e0db..f7cabec1 100644 --- a/src/Views/Preference.axaml.cs +++ b/src/Views/Preference.axaml.cs @@ -74,6 +74,15 @@ namespace SourceGit.Views set; } + public static readonly StyledProperty SelectedOpenAIServiceProperty = + AvaloniaProperty.Register(nameof(SelectedOpenAIService)); + + public Models.OpenAIService SelectedOpenAIService + { + get => GetValue(SelectedOpenAIServiceProperty); + set => SetValue(SelectedOpenAIServiceProperty, value); + } + public Preference() { var pref = ViewModels.Preference.Instance; @@ -312,5 +321,24 @@ namespace SourceGit.Views e.Handled = true; } + + private void OnAddOpenAIService(object sender, RoutedEventArgs e) + { + var service = new Models.OpenAIService() { Name = "Unnamed Service" }; + ViewModels.Preference.Instance.OpenAIServices.Add(service); + SelectedOpenAIService = service; + + e.Handled = true; + } + + private void OnRemoveSelectedOpenAIService(object sender, RoutedEventArgs e) + { + if (SelectedOpenAIService == null) + return; + + ViewModels.Preference.Instance.OpenAIServices.Remove(SelectedOpenAIService); + SelectedOpenAIService = null; + e.Handled = true; + } } } diff --git a/src/Views/WorkingCopy.axaml b/src/Views/WorkingCopy.axaml index 3d080fc6..9fab9927 100644 --- a/src/Views/WorkingCopy.axaml +++ b/src/Views/WorkingCopy.axaml @@ -199,7 +199,7 @@ @@ -105,7 +121,7 @@ VerticalAlignment="Center" UseGraphColor="False"/> - + SetValue(MessageProperty, value); } + public static readonly StyledProperty SignInfoProperty = + AvaloniaProperty.Register(nameof(SignInfo)); + + public Models.CommitSignInfo SignInfo + { + get => GetValue(SignInfoProperty); + set => SetValue(SignInfoProperty, value); + } + public static readonly StyledProperty SupportsContainsInProperty = AvaloniaProperty.Register(nameof(SupportsContainsIn)); diff --git a/src/Views/CommitDetail.axaml b/src/Views/CommitDetail.axaml index 8307d650..cb99b3d9 100644 --- a/src/Views/CommitDetail.axaml +++ b/src/Views/CommitDetail.axaml @@ -21,6 +21,7 @@ From 8f68e966070253adf3ad79d93bd99a265180b99c Mon Sep 17 00:00:00 2001 From: AquariusStar <48148723+AquariusStar@users.noreply.github.com> Date: Wed, 30 Oct 2024 04:33:10 +0300 Subject: [PATCH 26/68] loacaliztion: update translate (#624) --- src/Resources/Locales/ru_RU.axaml | 58 +++++++++++++++++-------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index 1a63ae61..33237603 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -16,7 +16,7 @@ Существующую ветку Создать новую ветку Расположение: - Путь к этому рабочему дереву. Поддерживается относительный путью + Путь к этому рабочему дереву. Поддерживается относительный путь. Имя ветки: Необязательно. По умолчанию используется имя целевой папки. Отслеживание ветки: @@ -27,7 +27,7 @@ Ошибка Выдает ошибки и отказывается применять исправление Все ошибки - Аналогично "ошибке", но показывает больше + Аналогично «ошибке», но показывает больше Файл исправлений: Выберите файл .patch для применения Игнорировать изменения пробелов @@ -58,6 +58,7 @@ Удалить выбранные {0} ветки Отклонить все изменения. Перемотать вперёд к ${0}$ + Извлечь ${0}$ в ${1}$... Поток Git - Завершение ${0}$ Слить ${0}$ в ${1}$... Забрать ${0}$ @@ -72,6 +73,7 @@ ОТМЕНА Сбросить эту ревизию Сбросить родительскую ревизию + Произвести сообщение о фиксации ИЗМЕНИТЬ РЕЖИМ ОТОБРАЖЕНИЯ Показывать в виде списка файлов и каталогов Показывать в виде списка путей @@ -115,8 +117,8 @@ Вернуть фиксацию Переформулировать Сохранить как исправление... - Уплотнить в родительскую - Уплотнить дочерную фиксацию сюда + Втиснуть в родительскую + Втиснуть дочерную фиксацию сюда ИЗМЕНЕНИЯ Найти изменения.... ФАЙЛЫ @@ -157,6 +159,9 @@ Имя правила: Адрес результата: Пожалуйста, используйте $1, $2 для доступа к значениям групп регулярных выражений. + ОТКРЫТЬ ИИ + Предпочитаемый сервис: + Если «Предпочитаемый сервис» установлен, SourceGit будет использовать только этот хранилище. В противном случае, если доступно более одной услуги, будет отображено контекстное меню для выбора одной из них. HTTP-прокси HTTP-прокси, используемый этим хранилищем Имя пользовтаеля @@ -306,7 +311,7 @@ Добавить шаблон отслеживания в ХБФ Git Извлечь Извлечь объекты ХБФ - Запустить `git lfs fetch", чтобы загрузить объекты ХБФ Git. При этом рабочая копия не обновляется. + Запустить «git lfs fetch», чтобы загрузить объекты ХБФ Git. При этом рабочая копия не обновляется. Установить перехват ХБФ Git Показывать блокировки Нет заблокированных файлов @@ -316,15 +321,15 @@ Разблокировать Принудительно разблокировать Обрезать - Запустите `git lfs prune", чтобы удалить старые файлы ХБФ из локального хранилища + Запустить «git lfs prune», чтобы удалить старые файлы ХБФ из локального хранилища Забрать Забрать объекты ХБФ - Запустите `git lfs pull", чтобы загрузить все файлы ХБФ Git для текущей ссылки и проверить + Запустить «git lfs pull», чтобы загрузить все файлы ХБФ Git для текущей ссылки и проверить Выложить Выложить объекты ХБФ Отправляйте большие файлы, помещенные в очередь, в конечную точку ХБФ Git Внешнее хранилище: - Отслеживать файлы с именем '{0}' + Отслеживать файлы с именем «{0}» Отслеживать все *{0} файлов Истории Переключение горизонтального/вертикального расположения @@ -334,7 +339,7 @@ SHA ВРЕМЯ ФИКСАЦИИ ВЫБРАННЫЕ {0} ФИКСАЦИИ - Удерживайте 'Ctrl' или 'Shift', чтобы выбрать несколько фиксаций. + Удерживайте Ctrl или Shift, чтобы выбрать несколько фиксаций. Удерживайте ⌘ или ⇧, чтобы выбрать несколько фиксаций. ПОДСКАЗКИ: Ссылка на сочетания клавиш @@ -354,9 +359,9 @@ Принудительно перезагрузить этот хранилище Подготовленные/Неподготовленные выбранные изменения Режим поиска фиксаций - Переключить на 'Изменения' - Переключить на 'Истории' - Переключить на 'Отложенные' + Переключить на «Изменения» + Переключить на «Истории» + Переключить на «Отложенные» ТЕКСТОВЫЙ РЕДАКТОР Закрыть панель поиска Найти следующее совпадение @@ -367,10 +372,10 @@ Отклонить Инициализировать хранилище Путь: - Выполняется частичный забор. Нажмите 'Отказ' для восстановления заголовка. - Выполняет запрос слияния. Нажмите 'Отказ' для восстановления заголовка. - Выполняется перенос. Нажмите 'Отказ' для восстановления заголовка. - Выполняется возврат. Нажмите 'Отказ' для восстановления заголовка. + Выполняется частичный забор. Нажмите «Отказ» для восстановления заголовка. + Выполняет запрос слияния. Нажмите «Отказ» для восстановления заголовка. + Выполняется перенос. Нажмите «Отказ» для восстановления заголовка. + Выполняется возврат. Нажмите «Отказ» для восстановления заголовка. Интерактивное перемещение Целевая ветка: На: @@ -408,7 +413,7 @@ ОТКРЫТЬ ИИ Ключ API Запрос на анализ различий - Сгенерировать запрос на тему + Произвести запрос на тему Модель Имя: Сервер @@ -456,7 +461,7 @@ Удалить внешнее хранилище Цель: Удалить рабочее дерево - Информация об обрезке рабочего дерева в `$GIT_DIR/worktrees` + Информация об обрезке рабочего дерева в «$GIT_DIR/worktrees» Забрать Ветка: Извлечь все ветки @@ -501,7 +506,7 @@ Открыть в браузере Удалить Подтвердить удаление рабочего дерева - Включить опцию `--force` + Включить опцию --force Цель: Переименовать ветку Новое имя: @@ -510,17 +515,17 @@ Отказ Автоматическое извлечение изменений с внешних хранилищ... Очистить (Сбор мусора и удаление) - Запустить команду `git gc` для данного хранилища. + Запустить команду «git gc» для данного хранилища. Очистить всё Настройка этого хранилища ПРОДОЛЖИТЬ - Разрешить опцию '--reflog' + Разрешить опцию --reflog Открыть в файловом менеджере Поиск веток, меток и подмодулей - ОТФИЛЬТРОВАНО ОТ: + ОТФИЛЬТРОВАНО: ЛОКАЛЬНЫЕ ВЕТКИ Навигация по заголовку - Включить опцию '--first-parent' + Включить опцию --first-parent Создать ветку Открыть в {0} Открыть в расширенном инструменте @@ -550,12 +555,12 @@ Режим сброса: Переместить в: Текущая ветка: - Раскрыть в файловом менеджере + Открыть в файловом менеджере Отменить фиксацию Фиксация: Отмена изменений фиксации Переформулировать сообщение фиксации - Использовать "Shift+Enter" для ввода новой строки. "Enter" - это горячая клавиша кнопки OK + Использовать «Shift+Enter» для ввода новой строки. «Enter» - это горячая клавиша кнопки OK Запуск. Подождите пожалуйста... СОХРАНИТЬ Сохранить как... @@ -569,7 +574,7 @@ Пропустить эту версию Обновление ПО В настоящее время обновления недоступны. - Уплотнить фиксации + Втиснуть фиксации В: Частный ключ SSH: Путь хранения частного ключа SSH @@ -578,6 +583,7 @@ ЗАПУСК Отложить Включить неотслеживаемые файлы + Хранить отложенные файлы Сообщение: Необязательно. Имя этого тайника Отложить локальные изменения From 30e0e84b63951d9d86f4e333a78dd3805a41bd77 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 30 Oct 2024 01:33:23 +0000 Subject: [PATCH 27/68] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index a87f4732..3caa8dac 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-98.06%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-89.55%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.69%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.10%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-98.06%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-89.55%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.69%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-100.00%25-brightgreen)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-100.00%25-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-100.00%25-brightgreen)](TRANSLATION.md) ## How to Use diff --git a/TRANSLATION.md b/TRANSLATION.md index ff5c8801..e5c43b3e 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -157,18 +157,13 @@ -### ru_RU.axaml: 99.10% +### ru_RU.axaml: 100.00%
Missing Keys -- Text.BranchCM.FetchInto -- Text.ChangeCM.GenerateCommitMessage -- Text.Configure.OpenAI -- Text.Configure.OpenAI.Prefered -- Text.Configure.OpenAI.Prefered.Tip -- Text.Stash.KeepIndex +
From ca5f2f92ba2b0cf4f0f5aa1864d3664b6d91856f Mon Sep 17 00:00:00 2001 From: jmmanzano Date: Wed, 30 Oct 2024 02:43:10 +0100 Subject: [PATCH 28/68] localization: added es_ES.axaml (#623) localization: added es_ES.axaml --- src/App.axaml | 1 + src/Models/Locales.cs | 1 + src/Resources/Locales/es_ES.axaml | 667 ++++++++++++++++++++++++++++++ 3 files changed, 669 insertions(+) create mode 100644 src/Resources/Locales/es_ES.axaml diff --git a/src/App.axaml b/src/App.axaml index b1fe303b..fc55776e 100644 --- a/src/App.axaml +++ b/src/App.axaml @@ -18,6 +18,7 @@ + diff --git a/src/Models/Locales.cs b/src/Models/Locales.cs index 0d9e5f69..3fa9ab7c 100644 --- a/src/Models/Locales.cs +++ b/src/Models/Locales.cs @@ -15,6 +15,7 @@ namespace SourceGit.Models new Locale("Русский", "ru_RU"), new Locale("简体中文", "zh_CN"), new Locale("繁體中文", "zh_TW"), + new Locale("Español", "es_ES"), }; public Locale(string name, string key) diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml new file mode 100644 index 00000000..e9c7733d --- /dev/null +++ b/src/Resources/Locales/es_ES.axaml @@ -0,0 +1,667 @@ + + Acerca de + Acerca de SourceGit + • Construido con + • El gráfico es renderizado por + © 2024 sourcegit-scm + • 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: + 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 + Asistente OpenAI + Usar OpenAI para generar mensaje de commit + Aplicar Patch + Error + Genera errores y se niega a aplicar el patch + Error Todo + Similar a 'error', pero muestra más + Archivo Patch: + Seleccionar archivo .patch para aplicar + Ignorar cambios de espacios en blanco + Sin Advertencia + Desactiva la advertencia de espacios en blanco al final + Aplicar Patch + Advertencia + Genera advertencias para algunos de estos errores, pero aplica + Espacios en Blanco: + Archivar... + Guardar Archivo en: + Seleccionar ruta del archivo + Revisión: + Archivar + SourceGit Askpass + ARCHIVOS ASUMIDOS COMO SIN CAMBIOS + NO HAY ARCHIVOS ASUMIDOS COMO SIN CAMBIOS + REMOVER + ¡ARCHIVO BINARIO NO SOPORTADO! + Blame + ¡BLAME EN ESTE ARCHIVO NO SOPORTADO! + Checkout ${0}$... + Comparar con Rama + Comparar con HEAD + Comparar con Worktree + Copiar Nombre de Rama + Eliminar ${0}$... + Eliminar {0} ramas seleccionadas + Descartar todos los cambios + Fast-Forward a ${0}$ + Fetch ${0}$ en ${1}$... + Git Flow - Finalizar ${0}$ + Merge ${0}$ en ${1}$... + Pull ${0}$ + Pull ${0}$ en ${1}$... + Push ${0}$ + Rebase ${0}$ en ${1}$... + Renombrar ${0}$... + Establecer Rama de Seguimiento + Desestablecer Upstream + Comparar Ramas + Bytes + CANCELAR + Resetear a Esta Revisión + Resetear a Revisión Padre + CAMBIAR MODO DE VISUALIZACIÓN + Mostrar como Lista de Archivos y Directorios + Mostrar como Lista de Rutas + Mostrar como Árbol de Sistema de Archivos + Checkout Rama + Checkout Commit + Advertencia: Al hacer un checkout de commit, tu Head se separará + Commit: + Rama: + Cambios Locales: + Descartar + No Hacer Nada + Stash & Reaplicar + Cherry Pick + Añadir fuente al mensaje de commit + Commit(s): + Commit todos los cambios + Mainline: + Normalmente no puedes cherry-pick un merge porque no sabes qué lado del merge debe considerarse la línea principal. Esta opción permite que cherry-pick reproduzca el cambio en relación con el padre especificado. + Limpiar Stashes + Estás intentando limpiar todos los stashes. ¿Estás seguro de continuar? + Clonar Repositorio Remoto + Parámetros Adicionales: + Argumentos adicionales para clonar el repositorio. Opcional. + Nombre Local: + Nombre del repositorio. Opcional. + Carpeta Padre: + URL del Repositorio: + CERRAR + Editor + Cherry-Pick Este Commit + Cherry-Pick ... + Checkout Commit + Comparar con HEAD + Comparar con Worktree + Copiar Información + Copiar SHA + Rebase Interactivo ${0}$ hasta Aquí + Rebase ${0}$ hasta Aquí + Reset ${0}$ hasta Aquí + Revertir Commit + Reescribir + Guardar como Patch... + Squash en Parent + Squash Commits Hijos hasta Aquí + CAMBIOS + Buscar Cambios... + ARCHIVOS + Archivo LFS + Submódulo + INFORMACIÓN + AUTOR + CAMBIADO + COMMITTER + Ver refs que contienen este commit + COMMIT ESTÁ CONTENIDO EN + Muestra solo los primeros 100 cambios. Ver todos los cambios en la pestaña CAMBIOS. + MENSAJE + PADRES + REFS + SHA + Abrir en Navegador + Introducir asunto del commit + Descripción + Configurar Repositorio + PLANTILLA DE COMMIT + Nombre de la Plantilla: + Contenido de la Plantilla: + Dirección de Email + Dirección de email + GIT + Fetch remotos automáticamente + Minuto(s) + Remoto por Defecto + Habilitar --signoff para commit + SEGUIMIENTO DE INCIDENCIAS + Añadir Regla de Ejemplo para Github + Añadir Regla de Ejemplo para Jira + Añadir Regla de Ejemplo para Incidencias de GitLab + Añadir Regla de Ejemplo para Merge Requests de GitLab + Nueva Regla + Expresión Regex para Incidencias: + Nombre de la Regla: + URL Resultante: + Por favor, use $1, $2 para acceder a los valores de los grupos regex. + Proxy HTTP + Proxy HTTP utilizado por este repositorio + Nombre de Usuario + Nombre de usuario para este repositorio + Espacios de Trabajo + Color + Restaurar pestañas al iniciar + Asistente de Commit Convencional + Cambio Importante: + Incidencia Cerrada: + Detalles del Cambio: + Alcance: + Descripción Corta: + Tipo de Cambio: + Copiar + Copiar Todo el Texto + COPIAR MENSAJE + Copiar Ruta + Copiar Nombre del Archivo + Crear Rama... + Basado En: + Checkout de la rama creada + Cambios Locales: + Descartar + No Hacer Nada + Stash & Reaplicar + Nombre de la Nueva Rama: + Introduzca el nombre de la rama. + Crear Rama Local + Crear Etiqueta... + Nueva Etiqueta En: + Firma GPG + Mensaje de la Etiqueta: + Opcional. + Nombre de la Etiqueta: + Formato recomendado: v1.0.0-alpha + Push a todos los remotos después de crear + Crear Nueva Etiqueta + Tipo: + anotada + ligera + Mantenga Ctrl para iniciar directamente + Cortar + Eliminar Rama + Rama: + ¡Estás a punto de eliminar una rama remota! + También eliminar la rama remota ${0}$ + Eliminar Múltiples Ramas + Estás intentando eliminar múltiples ramas a la vez. ¡Asegúrate de revisar antes de tomar acción! + Eliminar Remoto + Remoto: + Destino: + Confirmar Eliminación de Grupo + Confirmar Eliminación de Repositorio + Eliminar Submódulo + Ruta del Submódulo: + Eliminar Etiqueta + Etiqueta: + Eliminar de los repositorios remotos + DIFERENCIA BINARIA + NUEVO + ANTIGUO + Copiar + Modo de Archivo Cambiado + Ignorar Cambio de Espacios en Blanco + CAMBIO DE OBJETO LFS + Siguiente Diferencia + SIN CAMBIOS O SOLO CAMBIOS DE EOL + Diferencia Anterior + Mostrar símbolos ocultos + Diferencia Lado a Lado + SUBMÓDULO + NUEVO + Intercambiar + Resaltado de Sintaxis + Ajuste de Línea + Abrir en Herramienta de Merge + Disminuir Número de Líneas Visibles + Aumentar Número de Líneas Visibles + SELECCIONA ARCHIVO PARA VER CAMBIOS + Abrir en Herramienta de Merge + Descartar Cambios + Todos los cambios locales en la copia de trabajo. + Cambios: + Incluir archivos ignorados + Total {0} cambios serán descartados + ¡No puedes deshacer esta acción! + Marcador: + Nuevo Nombre: + Destino: + Editar Grupo Seleccionado + Editar Repositorio Seleccionado + Fast-Forward (sin checkout) + Fetch + Fetch todos los remotos + Fetch sin etiquetas + Remoto: + Fetch Cambios Remotos + Asumir sin cambios + Descartar... + Descartar {0} archivos... + Descartar Cambios en Línea(s) Seleccionada(s) + Abrir Herramienta de Merge Externa + Guardar Como Patch... + Stage + Stage {0} archivos + Stage Cambios en Línea(s) Seleccionada(s) + Stash... + Stash {0} archivos... + Unstage + Unstage {0} archivos + Unstage Cambios en Línea(s) Seleccionada(s) + Usar Suyos (checkout --theirs) + Usar Míos (checkout --ours) + Historial de Archivos + CONTENIDO + CAMBIO + FILTRO + Git-Flow + Rama de Desarrollo: + Feature: + Prefijo de Feature: + FLOW - Finalizar Feature + FLOW - Finalizar Hotfix + FLOW - Finalizar Release + Destino: + Hotfix: + Prefijo de Hotfix: + Inicializar Git-Flow + Mantener rama + Rama de Producción: + Release: + Prefijo de Release: + Iniciar Feature... + FLOW - Iniciar Feature + Iniciar Hotfix... + FLOW - Iniciar Hotfix + Introducir nombre + Iniciar Release... + FLOW - Iniciar Release + Prefijo de Etiqueta de Versión: + Git LFS + Añadir Patrón de Seguimiento... + El patrón es el nombre del archivo + 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. + Instalar hooks de Git LFS + Mostrar Bloqueos + No hay archivos bloqueados + Bloquear + Mostrar solo mis bloqueos + Bloqueos LFS + Desbloquear + Forzar Desbloqueo + 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 + Push + Push Objetos LFS + Push archivos grandes en cola al endpoint de Git LFS + Remoto: + Seguir archivos llamados '{0}' + Seguir todos los archivos *{0} + Historias + Cambiar a Disposición Horizontal/Vertical + AUTOR + HORA DEL AUTOR + GRÁFICO & ASUNTO + SHA + FECHA DE COMMIT + {0} COMMITS SELECCIONADOS + Mantén 'Ctrl' o 'Shift' para seleccionar múltiples commits. + Mantén ⌘ o ⇧ para seleccionar múltiples commits. + CONSEJOS: + Referencia de Atajos de Teclado + GLOBAL + Cancelar popup actual + Cerrar página actual + Ir a la página anterior + Ir a la siguiente página + Crear nueva página + Abrir diálogo de preferencias + REPOSITORIO + Commit cambios staged + Commit y push cambios staged + Stage todos los cambios y commit + Descartar cambios seleccionados + Modo Dashboard (Por Defecto) + Forzar a recargar este repositorio + Stage/Unstage cambios seleccionados + Modo de búsqueda de commits + Cambiar a 'Cambios' + Cambiar a 'Historias' + Cambiar a 'Stashes' + EDITOR DE TEXTO + Cerrar panel de búsqueda + Buscar siguiente coincidencia + Buscar coincidencia anterior + Abrir panel de búsqueda + Stage + Unstage + Descartar + Inicializar Repositorio + Ruta: + Cherry-Pick en progreso. Presiona 'Abort' para restaurar el HEAD original. + Merge en progreso. Presiona 'Abort' para restaurar el HEAD original. + Rebase en progreso. Presiona 'Abort' para restaurar el HEAD original. + Revert en progreso. Presiona 'Abort' para restaurar el HEAD original. + Rebase Interactivo + Rama Objetivo: + En: + ERROR + AVISO + Merge Rama + En: + Opción de Merge: + Rama Fuente: + Mover Nodo del Repositorio + Seleccionar nodo padre para: + Nombre: + Git NO ha sido configurado. Por favor, ve a [Preferencias] y configúralo primero. + Abrir Directorio de Datos de la App + Abrir Con... + Opcional. + Crear Nueva Página + Marcador + Cerrar Pestaña + Cerrar Otras Pestañas + Cerrar Pestañas a la Derecha + Copiar Ruta del Repositorio + Repositorios + Pegar + Justo ahora + Hace {0} minutos + Hace {0} horas + Ayer + Hace {0} días + Último mes + Hace {0} meses + Último año + Hace {0} años + Preferencias + Opciones Avanzadas + OPEN AI + Analizar Diff Prompt + Clave API + Generar Subject Prompt + Modelo + Servidor + APARIENCIA + Fuente por defecto + Tamaño de fuente por defecto + Fuente Monospace + Usar solo fuente monospace en el editor de texto + Tema + Sobreescritura de temas + Usar ancho de pestaña fijo en la barra de título + Usar marco de ventana nativo + HERRAMIENTA DIFF/MERGE + Ruta de instalación + Introducir ruta para la herramienta diff/merge + Herramienta + GENERAL + Buscar actualizaciones al iniciar + Idioma + Commits en el historial + Mostrar hora del autor en lugar de la hora del commit en el gráfico + Longitud de la guía del asunto + GIT + Habilitar Auto CRLF + Directorio de clonado por defecto + Email de usuario + Email global del usuario git + Ruta de instalación + 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 + Clave de firma del usuario + Clave de firma gpg del usuario + INTEGRACIÓN + SHELL/TERMINAL + Shell/Terminal + Ruta + Podar Remoto + Destino: + Podar Worktrees + Podar información de worktree en `$GIT_DIR/worktrees` + Pull + Rama: + Fetch todas las ramas + En: + Cambios Locales: + Descartar + No Hacer Nada + Stash & Reaplicar + Fetch sin etiquetas + Remoto: + Pull (Fetch & Merge) + Usar rebase en lugar de merge + Push + Asegurarse de que los submódulos se hayan hecho push + Forzar push + Rama Local: + Remoto: + Push Cambios al Remoto + Rama Remota: + Establecer como rama de seguimiento + Push todas las etiquetas + Push Etiqueta al Remoto + Push a todos los remotos + Remoto: + Etiqueta: + Salir + Rebase Rama Actual + Stash & reaplicar cambios locales + En: + Rebase: + Refrescar + Añadir Remoto + Editar Remoto + Nombre: + Nombre remoto + URL del Repositorio: + URL del repositorio git remoto + Copiar URL + Borrar... + Editar... + Fetch + Abrir En Navegador + Podar (Prune) + Confirmar para Eliminar Worktree + Utilizar Opción `--force` + Destino: + Renombrar Rama + Nuevo Nombre: + Nombre único para esta rama + Rama: + ABORTAR + Auto fetching cambios desde remotos... + Limpiar (GC & Prune) + Ejecutar comando `git gc` para este repositorio. + Limpiar todo + Configurar este repositorio + CONTINUAR + Habilitar Opción '--reflog' + Abrir en el Explorador + Buscar Ramas/Etiquetas/Submódulos + FILTRAR POR: + RAMAS LOCALES + Navegar a HEAD + Habilitar Opción '--first-parent' + Crear Rama + Abrir en {0} + Abrir en Herramientas Externas + Refrescar + REMOTOS + AÑADIR REMOTO + RESOLVER + Buscar Commit + Archivo + Mensaje + SHA + Autor & Committer + Rama Actual + Mostrar Etiquetas como Árbol + Estadísticas + SUBMÓDULOS + AÑADIR SUBMÓDULO + ACTUALIZAR SUBMÓDULO + ETIQUETAS + NUEVA ETIQUETA + Abrir en Terminal + WORKTREES + AÑADIR WORKTREE + PRUNE + URL del Repositorio Git + Resetear Rama Actual a Revisión + Modo de Reset: + Mover a: + Rama Actual: + Revelar en el Explorador de Archivos + Revertir Commit + Commit: + Commit revertir cambios + Reescribir Mensaje de Commit + Usa 'Shift+Enter' para introducir una nueva línea. 'Enter' es el atajo del botón OK + Ejecutando. Por favor espera... + GUARDAR + Guardar Como... + ¡El patch se ha guardado exitosamente! + Escanear Repositorios + Directorio Raíz: + Buscar Actualizaciones... + Nueva versión de este software disponible: + ¡Error al buscar actualizaciones! + Descargar + Omitir Esta Versión + Actualización de Software + Actualmente no hay actualizaciones disponibles. + Squash Commits + En: + Clave Privada SSH: + Ruta de almacenamiento de la clave privada SSH + INICIAR + Stash + Incluir archivos no rastreados + Mensaje: + Opcional. Nombre de este stash + Solo cambios staged + ¡Tanto los cambios staged como los no staged de los archivos seleccionados serán stashed! + Stash Cambios Locales + Aplicar + Eliminar + Pop + Eliminar Stash + Eliminar: + Stashes + CAMBIOS + STASHES + Estadísticas + COMMITS + COMMITTER + MES + SEMANA + COMMITS: + AUTORES: + GENERAL + SUBMÓDULOS + Añadir Submódulo + Copiar Ruta Relativa + Fetch submódulos anidados + Abrir Repositorio del Submódulo + Ruta Relativa: + Carpeta relativa para almacenar este módulo. + Eliminar Submódulo + OK + Copiar Nombre de la Etiqueta + Copiar Mensaje de la Etiqueta + Eliminar ${0}$... + Push ${0}$... + URL: + Actualizar Submódulos + Todos los submódulos + Inicializar según sea necesario + Recursivamente + Submódulo: + Usar opción --remote + Advertencia + Página de Bienvenida + Crear Grupo + Crear Sub-Grupo + Clonar Repositorio + Eliminar + SOPORTA ARRASTRAR Y SOLTAR CARPETAS. SOPORTA AGRUPACIÓN PERSONALIZADA. + Editar + Mover a Otro Grupo + Abrir Todos Los Repositorios + Abrir Repositorio + Abrir Terminal + Reescanear Repositorios en el Directorio de Clonado por Defecto + Buscar Repositorios... + Ordenar + Cambios + Git Ignore + Ignorar todos los archivos *{0} + Ignorar archivos *{0} en la misma carpeta + Ignorar archivos en la misma carpeta + Ignorar solo este archivo + Enmendar (Amend) + Puedes stagear este archivo ahora. + COMMIT + COMMIT & PUSH + Plantilla/Historias + Activar evento de clic + Stagear todos los cambios y commit + ¡Commit vacío detectado! ¿Quieres continuar (--allow-empty)? + CONFLICTOS DETECTADOS + LOS CONFLICTOS DE ARCHIVOS ESTÁN RESUELTOS + INCLUIR ARCHIVOS NO RASTREADOS + NO HAY MENSAJES DE ENTRADA RECIENTES + NO HAY PLANTILLAS DE COMMIT + STAGED + UNSTAGE + UNSTAGE TODO + UNSTAGED + STAGE + 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 + Copiar Ruta + Bloquear + Eliminar + Desbloquear + From 047444124052a3704231930695fbcec4c6a92f3f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 30 Oct 2024 01:43:21 +0000 Subject: [PATCH 29/68] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3caa8dac..d2832347 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-98.06%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-89.55%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.69%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-100.00%25-brightgreen)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-100.00%25-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-100.00%25-brightgreen)](TRANSLATION.md) +[![en_US](https://img.shields.io/badge/en__US-100%25-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-98.06%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-99.10%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-89.55%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.69%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-100.00%25-brightgreen)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-100.00%25-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-100.00%25-brightgreen)](TRANSLATION.md) ## How to Use diff --git a/TRANSLATION.md b/TRANSLATION.md index e5c43b3e..9aa14567 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -20,6 +20,21 @@ +### es_ES.axaml: 99.10% + + +
+Missing Keys + +- Text.ChangeCM.GenerateCommitMessage +- Text.Configure.OpenAI +- Text.Configure.OpenAI.Prefered +- Text.Configure.OpenAI.Prefered.Tip +- Text.Preference.AI.Name +- Text.Stash.KeepIndex + +
+ ### fr_FR.axaml: 89.55% From 28fad000ab9ba4088a2486f5fbf0dde66a5db251 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 30 Oct 2024 09:44:05 +0800 Subject: [PATCH 30/68] project: add missing scripts to solution file Signed-off-by: leo --- SourceGit.sln | 1 + 1 file changed, 1 insertion(+) diff --git a/SourceGit.sln b/SourceGit.sln index abd42aee..9799a09e 100644 --- a/SourceGit.sln +++ b/SourceGit.sln @@ -76,6 +76,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "appimage", "appimage", "{5D EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{C54D4001-9940-477C-A0B6-E795ED0A3209}" ProjectSection(SolutionItems) = preProject + build\scripts\localization-check.js = build\scripts\localization-check.js build\scripts\package.linux.sh = build\scripts\package.linux.sh build\scripts\package.osx-app.sh = build\scripts\package.osx-app.sh build\scripts\package.windows-portable.sh = build\scripts\package.windows-portable.sh From 81f76f0771504d9f244ebdc11fb12a3941a8c78c Mon Sep 17 00:00:00 2001 From: Masgalor Date: Wed, 30 Oct 2024 02:45:41 +0100 Subject: [PATCH 31/68] fix: Make RPM builds compatible with OpenSUSE (#622) --- build/resources/rpm/SPECS/build.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/resources/rpm/SPECS/build.spec b/build/resources/rpm/SPECS/build.spec index 289cbe39..0f80aac3 100644 --- a/build/resources/rpm/SPECS/build.spec +++ b/build/resources/rpm/SPECS/build.spec @@ -6,7 +6,7 @@ License: MIT URL: https://sourcegit-scm.github.io/ Source: https://github.com/sourcegit-scm/sourcegit/archive/refs/tags/v%_version.tar.gz Requires: libX11 -Requires: libSM +Requires: (libSM or libSM6) %define _build_id_links none From b175ab3a3e57a1de73335d90d5e102c25650c9b2 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 30 Oct 2024 09:47:33 +0800 Subject: [PATCH 32/68] code_review: PR #623 * keep locales in order * update README.md Signed-off-by: leo --- README.md | 2 +- src/Models/Locales.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d2832347..af799116 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ * Supports Windows/macOS/Linux * Opensource/Free * Fast -* English/Français/Deutsch/Português/Русский/简体中文/繁體中文 +* English/Español/Français/Deutsch/Português/Русский/简体中文/繁體中文 * Built-in light/dark themes * Customize theme * Visual commit graph diff --git a/src/Models/Locales.cs b/src/Models/Locales.cs index 3fa9ab7c..28d55459 100644 --- a/src/Models/Locales.cs +++ b/src/Models/Locales.cs @@ -9,13 +9,13 @@ namespace SourceGit.Models public static readonly List Supported = new List() { new Locale("English", "en_US"), + new Locale("Español", "es_ES"), new Locale("Deutsch", "de_DE"), new Locale("Français", "fr_FR"), new Locale("Português (Brasil)", "pt_BR"), new Locale("Русский", "ru_RU"), new Locale("简体中文", "zh_CN"), new Locale("繁體中文", "zh_TW"), - new Locale("Español", "es_ES"), }; public Locale(string name, string key) From 4a6cbddeac9dfcd3ed673d2d7aabd28f6b8182ef Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 30 Oct 2024 09:53:58 +0800 Subject: [PATCH 33/68] refactor: select the previous tab while closing the actived one (#621) Signed-off-by: leo --- src/ViewModels/Launcher.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/ViewModels/Launcher.cs b/src/ViewModels/Launcher.cs index dd618e41..8e4f7775 100644 --- a/src/ViewModels/Launcher.cs +++ b/src/ViewModels/Launcher.cs @@ -204,12 +204,7 @@ namespace SourceGit.ViewModels var activeIdx = Pages.IndexOf(_activePage); if (removeIdx == activeIdx) { - ActivePage = Pages[removeIdx == Pages.Count - 1 ? removeIdx - 1 : removeIdx + 1]; - CloseRepositoryInTab(page); - Pages.RemoveAt(removeIdx); - } - else if (removeIdx + 1 == activeIdx) - { + ActivePage = Pages[removeIdx > 0 ? removeIdx - 1 : removeIdx + 1]; CloseRepositoryInTab(page); Pages.RemoveAt(removeIdx); } From c2e83778cc94046727284c909e3453c13d6d7f40 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 30 Oct 2024 09:56:57 +0800 Subject: [PATCH 34/68] readme: keep the same order for locales Signed-off-by: leo --- README.md | 2 +- src/Models/Locales.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index af799116..4242056b 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ * Supports Windows/macOS/Linux * Opensource/Free * Fast -* English/Español/Français/Deutsch/Português/Русский/简体中文/繁體中文 +* English/Deutsch/Español/Français/Português/Русский/简体中文/繁體中文 * Built-in light/dark themes * Customize theme * Visual commit graph diff --git a/src/Models/Locales.cs b/src/Models/Locales.cs index 28d55459..203eb2dd 100644 --- a/src/Models/Locales.cs +++ b/src/Models/Locales.cs @@ -9,8 +9,8 @@ namespace SourceGit.Models public static readonly List Supported = new List() { new Locale("English", "en_US"), - new Locale("Español", "es_ES"), new Locale("Deutsch", "de_DE"), + new Locale("Español", "es_ES"), new Locale("Français", "fr_FR"), new Locale("Português (Brasil)", "pt_BR"), new Locale("Русский", "ru_RU"), From 1adcf4dd80c4342701978614e4b4280ab43c46ff Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 30 Oct 2024 10:10:17 +0800 Subject: [PATCH 35/68] enhance: do NOT query `gpg.ssh.allowedSignersFile` every time while getting commit's signing status Signed-off-by: leo --- src/Commands/QueryCommitSignInfo.cs | 5 ++--- src/ViewModels/CommitDetail.cs | 2 +- src/ViewModels/Repository.cs | 12 ++++++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/Commands/QueryCommitSignInfo.cs b/src/Commands/QueryCommitSignInfo.cs index 5ce18319..95f6d4d6 100644 --- a/src/Commands/QueryCommitSignInfo.cs +++ b/src/Commands/QueryCommitSignInfo.cs @@ -2,13 +2,12 @@ { public class QueryCommitSignInfo : Command { - public QueryCommitSignInfo(string repo, string sha) + public QueryCommitSignInfo(string repo, string sha, bool useFakeSignersFile) { WorkingDirectory = repo; Context = repo; - var allowedSignersFile = new Config(repo).Get("gpg.ssh.allowedSignersFile"); - if (string.IsNullOrEmpty(allowedSignersFile)) + if (useFakeSignersFile) Args = $"-c gpg.ssh.allowedSignersFile=/dev/null show --no-show-signature --pretty=format:\"%G? %GK\" -s {sha}"; else Args = $"show --no-show-signature --pretty=format:\"%G? %GK\" -s {sha}"; diff --git a/src/ViewModels/CommitDetail.cs b/src/ViewModels/CommitDetail.cs index b533b24a..1600c4cd 100644 --- a/src/ViewModels/CommitDetail.cs +++ b/src/ViewModels/CommitDetail.cs @@ -498,7 +498,7 @@ namespace SourceGit.ViewModels Task.Run(() => { - var signInfo = new Commands.QueryCommitSignInfo(_repo.FullPath, _commit.SHA).Result(); + var signInfo = new Commands.QueryCommitSignInfo(_repo.FullPath, _commit.SHA, !_repo.HasAllowedSignersFile).Result(); Dispatcher.UIThread.Invoke(() => SignInfo = signInfo); }); diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 9708f1e2..917833db 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -45,6 +45,11 @@ namespace SourceGit.ViewModels get => _settings; } + public bool HasAllowedSignersFile + { + get => _hasAllowedSignersFile; + } + public int SelectedViewIndex { get => _selectedViewIndex; @@ -444,6 +449,12 @@ namespace SourceGit.ViewModels public void RefreshAll() { + Task.Run(() => + { + var allowedSignersFile = new Commands.Config(_fullpath).Get("gpg.ssh.allowedSignersFile"); + _hasAllowedSignersFile = !string.IsNullOrEmpty(allowedSignersFile); + }); + Task.Run(() => { RefreshBranches(); @@ -2135,6 +2146,7 @@ namespace SourceGit.ViewModels private string _fullpath = string.Empty; private string _gitDir = string.Empty; private Models.RepositorySettings _settings = null; + private bool _hasAllowedSignersFile = false; private Models.Watcher _watcher = null; private Histories _histories = null; From df3b4e424adca8623ba0979dc81c8b4e224a2404 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 30 Oct 2024 10:13:33 +0800 Subject: [PATCH 36/68] localization: add fallback locale for `es_ES` (#623) Signed-off-by: leo --- src/Resources/Locales/es_ES.axaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index e9c7733d..f8a2fa68 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -1,4 +1,7 @@ + + + Acerca de Acerca de SourceGit • Construido con From 81fc859a37319621349319382f0e8113ce4026ad Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 30 Oct 2024 10:17:44 +0800 Subject: [PATCH 37/68] readme: keep the same order for locales Signed-off-by: leo --- README.md | 2 +- src/Models/Locales.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4242056b..f0ce7b41 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ * Supports Windows/macOS/Linux * Opensource/Free * Fast -* English/Deutsch/Español/Français/Português/Русский/简体中文/繁體中文 +* Deutsch/English/Español/Français/Português/Русский/简体中文/繁體中文 * Built-in light/dark themes * Customize theme * Visual commit graph diff --git a/src/Models/Locales.cs b/src/Models/Locales.cs index 203eb2dd..9d24f491 100644 --- a/src/Models/Locales.cs +++ b/src/Models/Locales.cs @@ -8,8 +8,8 @@ namespace SourceGit.Models public string Key { get; set; } public static readonly List Supported = new List() { - new Locale("English", "en_US"), new Locale("Deutsch", "de_DE"), + new Locale("English", "en_US"), new Locale("Español", "es_ES"), new Locale("Français", "fr_FR"), new Locale("Português (Brasil)", "pt_BR"), From 9abda2c6abd2673a6df9f9b18f93f528d51d7911 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 30 Oct 2024 10:27:14 +0800 Subject: [PATCH 38/68] ux: move the commit signing status icon to the last Signed-off-by: leo --- src/Views/CommitBaseInfo.axaml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Views/CommitBaseInfo.axaml b/src/Views/CommitBaseInfo.axaml index d45b5a86..806abe65 100644 --- a/src/Views/CommitBaseInfo.axaml +++ b/src/Views/CommitBaseInfo.axaml @@ -60,22 +60,6 @@ Margin="12,0,4,0" VerticalAlignment="Center"/> - - - - - - - - - - - - - - @@ -87,6 +71,22 @@ + + + + + + + + + + + + + + From f8f169d23a76db0eef20fd99eea988582bfe7fc2 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 30 Oct 2024 12:58:46 +0800 Subject: [PATCH 39/68] fix: typo in commit signing status info Signed-off-by: leo --- src/Models/CommitSignInfo.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Models/CommitSignInfo.cs b/src/Models/CommitSignInfo.cs index 143cb347..2428b2af 100644 --- a/src/Models/CommitSignInfo.cs +++ b/src/Models/CommitSignInfo.cs @@ -36,15 +36,15 @@ namespace SourceGit.Models switch (VerifyResult) { case 'G': - return $"Good Signature.\n\nKey: {Key}"; + return $"Good signature.\n\nKey: {Key}"; case 'B': - return $"Bad Signature.\n\nKey: {Key}"; + return $"Bad signature.\n\nKey: {Key}"; case 'U': - return $"Good Signature with unknown validity.\n\nKey: {Key}"; + return $"Good signature with unknown validity.\n\nKey: {Key}"; case 'X': - return $"Good Signature but has expired.\n\nKey: {Key}"; + return $"Good signature but has expired.\n\nKey: {Key}"; case 'Y': - return $"Good Signature made by expired key.\n\nKey: {Key}"; + return $"Good signature made by expired key.\n\nKey: {Key}"; case 'R': return $"Good signature made by a revoked key.\n\nKey: {Key}"; case 'E': From e680f8477e1204873ac5de8c6208ccaf2ed933f1 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 30 Oct 2024 13:07:30 +0800 Subject: [PATCH 40/68] readme: contributor image Signed-off-by: leo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f0ce7b41..7e675368 100644 --- a/README.md +++ b/README.md @@ -162,4 +162,4 @@ Everyone is welcome to submit a PR. Please make sure your PR is based on the lat Thanks to all the people who contribute. -[![Contributors](https://contrib.rocks/image?repo=sourcegit-scm/sourcegit&columns=10)](https://github.com/sourcegit-scm/sourcegit/graphs/contributors) +[![Contributors](https://contrib.rocks/image?repo=sourcegit-scm/sourcegit&columns=20)](https://github.com/sourcegit-scm/sourcegit/graphs/contributors) From 4e87b25765801e001f7f0016dccec15802de9d1d Mon Sep 17 00:00:00 2001 From: GadflyFang Date: Wed, 30 Oct 2024 14:48:37 +0800 Subject: [PATCH 41/68] enhance: show commit signer (#626) Signed-off-by: Gadfly --- src/Commands/QueryCommitSignInfo.cs | 20 +++++++++++++------- src/Models/CommitSignInfo.cs | 19 ++++++++++--------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/Commands/QueryCommitSignInfo.cs b/src/Commands/QueryCommitSignInfo.cs index 95f6d4d6..18517d8d 100644 --- a/src/Commands/QueryCommitSignInfo.cs +++ b/src/Commands/QueryCommitSignInfo.cs @@ -7,10 +7,9 @@ WorkingDirectory = repo; Context = repo; - if (useFakeSignersFile) - Args = $"-c gpg.ssh.allowedSignersFile=/dev/null show --no-show-signature --pretty=format:\"%G? %GK\" -s {sha}"; - else - Args = $"show --no-show-signature --pretty=format:\"%G? %GK\" -s {sha}"; + const string baseArgs = "show --no-show-signature --pretty=format:\"%G?%n%GS%n%GK\" -s"; + const string fakeSignersFileArg = "-c gpg.ssh.allowedSignersFile=/dev/null"; + Args = $"{(useFakeSignersFile ? fakeSignersFileArg : string.Empty)} {baseArgs} {sha}"; } public Models.CommitSignInfo Result() @@ -20,10 +19,17 @@ return null; var raw = rs.StdOut.Trim(); - if (raw.Length > 1) - return new Models.CommitSignInfo() { VerifyResult = raw[0], Key = raw.Substring(2) }; + if (raw.Length <= 1) + return null; + + var lines = raw.Split('\n'); + return new Models.CommitSignInfo() + { + VerifyResult = lines[0][0], + Signer = string.IsNullOrEmpty(lines[1]) ? "" : lines[1], + Key = lines[2] + }; - return null; } } } diff --git a/src/Models/CommitSignInfo.cs b/src/Models/CommitSignInfo.cs index 2428b2af..ab2bfbf4 100644 --- a/src/Models/CommitSignInfo.cs +++ b/src/Models/CommitSignInfo.cs @@ -4,8 +4,9 @@ namespace SourceGit.Models { public class CommitSignInfo { - public string Key { get; set; } = string.Empty; - public char VerifyResult { get; set; } = 'N'; + public char VerifyResult { get; init; } = 'N'; + public string Signer { get; init; } = string.Empty; + public string Key { get; init; } = string.Empty; public IBrush Brush { @@ -36,19 +37,19 @@ namespace SourceGit.Models switch (VerifyResult) { case 'G': - return $"Good signature.\n\nKey: {Key}"; + return $"Good signature.\n\nSigner: {Signer}\n\nKey: {Key}"; case 'B': - return $"Bad signature.\n\nKey: {Key}"; + return $"Bad signature.\n\nSigner: {Signer}\n\nKey: {Key}"; case 'U': - return $"Good signature with unknown validity.\n\nKey: {Key}"; + return $"Good signature with unknown validity.\n\nSigner: {Signer}\n\nKey: {Key}"; case 'X': - return $"Good signature but has expired.\n\nKey: {Key}"; + return $"Good signature but has expired.\n\nSigner: {Signer}\n\nKey: {Key}"; case 'Y': - return $"Good signature made by expired key.\n\nKey: {Key}"; + return $"Good signature made by expired key.\n\nSigner: {Signer}\n\nKey: {Key}"; case 'R': - return $"Good signature made by a revoked key.\n\nKey: {Key}"; + return $"Good signature made by a revoked key.\n\nSigner: {Signer}\n\nKey: {Key}"; case 'E': - return $"Signature cannot be checked.\n\nKey: {Key}"; + return $"Signature cannot be checked.\n\nSigner: {Signer}\n\nKey: {Key}"; default: return "No signature."; } From 195325187ded55e9b7116ebe5daa0eaaf6207919 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 30 Oct 2024 15:01:08 +0800 Subject: [PATCH 42/68] ux: tooltip of commit signing status icon * do NOT show signer if it is not available * new tooltip style Signed-off-by: leo --- src/Commands/QueryCommitSignInfo.cs | 2 +- src/Models/CommitSignInfo.cs | 16 ++++++++-------- src/Views/CommitBaseInfo.axaml | 15 ++++++++++++++- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/Commands/QueryCommitSignInfo.cs b/src/Commands/QueryCommitSignInfo.cs index 18517d8d..5c81cf57 100644 --- a/src/Commands/QueryCommitSignInfo.cs +++ b/src/Commands/QueryCommitSignInfo.cs @@ -26,7 +26,7 @@ return new Models.CommitSignInfo() { VerifyResult = lines[0][0], - Signer = string.IsNullOrEmpty(lines[1]) ? "" : lines[1], + Signer = lines[1], Key = lines[2] }; diff --git a/src/Models/CommitSignInfo.cs b/src/Models/CommitSignInfo.cs index ab2bfbf4..c6c30797 100644 --- a/src/Models/CommitSignInfo.cs +++ b/src/Models/CommitSignInfo.cs @@ -37,19 +37,19 @@ namespace SourceGit.Models switch (VerifyResult) { case 'G': - return $"Good signature.\n\nSigner: {Signer}\n\nKey: {Key}"; - case 'B': - return $"Bad signature.\n\nSigner: {Signer}\n\nKey: {Key}"; + return "Good signature."; case 'U': - return $"Good signature with unknown validity.\n\nSigner: {Signer}\n\nKey: {Key}"; + return "Good signature with unknown validity."; case 'X': - return $"Good signature but has expired.\n\nSigner: {Signer}\n\nKey: {Key}"; + return "Good signature but has expired."; case 'Y': - return $"Good signature made by expired key.\n\nSigner: {Signer}\n\nKey: {Key}"; + return "Good signature made by expired key."; case 'R': - return $"Good signature made by a revoked key.\n\nSigner: {Signer}\n\nKey: {Key}"; + return "Good signature made by a revoked key."; + case 'B': + return "Bad signature."; case 'E': - return $"Signature cannot be checked.\n\nSigner: {Signer}\n\nKey: {Key}"; + return "Signature cannot be checked."; default: return "No signature."; } diff --git a/src/Views/CommitBaseInfo.axaml b/src/Views/CommitBaseInfo.axaml index 806abe65..fd9969ac 100644 --- a/src/Views/CommitBaseInfo.axaml +++ b/src/Views/CommitBaseInfo.axaml @@ -81,7 +81,20 @@ - + + + + + + + + + + + + + + From fe03512c5c8510fe3e44253be8ec4a709ffb54c4 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 30 Oct 2024 15:10:26 +0800 Subject: [PATCH 43/68] ux: tooltip of commit signing status icon Signed-off-by: leo --- src/Models/CommitSignInfo.cs | 1 + src/Views/CommitBaseInfo.axaml | 14 ++++++-------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/Models/CommitSignInfo.cs b/src/Models/CommitSignInfo.cs index c6c30797..44b95e61 100644 --- a/src/Models/CommitSignInfo.cs +++ b/src/Models/CommitSignInfo.cs @@ -7,6 +7,7 @@ namespace SourceGit.Models public char VerifyResult { get; init; } = 'N'; public string Signer { get; init; } = string.Empty; public string Key { get; init; } = string.Empty; + public bool HasSigner => !string.IsNullOrEmpty(Signer); public IBrush Brush { diff --git a/src/Views/CommitBaseInfo.axaml b/src/Views/CommitBaseInfo.axaml index fd9969ac..62117480 100644 --- a/src/Views/CommitBaseInfo.axaml +++ b/src/Views/CommitBaseInfo.axaml @@ -85,14 +85,12 @@ - - - - - - - - + + + + + + From 2d7ea561e2662efa0928cf338f7316d880c946da Mon Sep 17 00:00:00 2001 From: yindf <112849074+yindf@users.noreply.github.com> Date: Wed, 30 Oct 2024 17:59:14 +0800 Subject: [PATCH 44/68] fix bug that stuck auto fetch when pull failed & make stage area resizeable (#627) * fix watcher stuck by pull * make stage area resizeable --------- Co-authored-by: yindf (cherry picked from commit a842aca042a73cb5fa3995794aae2a2e3540b37f) --- src/ViewModels/Pull.cs | 3 +++ src/Views/WorkingCopy.axaml | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/src/ViewModels/Pull.cs b/src/ViewModels/Pull.cs index fdaad920..b5c038ae 100644 --- a/src/ViewModels/Pull.cs +++ b/src/ViewModels/Pull.cs @@ -149,7 +149,10 @@ namespace SourceGit.ViewModels SetProgressDescription($"Fetching remote: {_selectedRemote.Name}..."); rs = new Commands.Fetch(_repo.FullPath, _selectedRemote.Name, NoTags, SetProgressDescription).Exec(); if (!rs) + { + CallUIThread(() => _repo.SetWatcherEnabled(true)); return false; + } _repo.MarkFetched(); diff --git a/src/Views/WorkingCopy.axaml b/src/Views/WorkingCopy.axaml index dae1f886..2e07d970 100644 --- a/src/Views/WorkingCopy.axaml +++ b/src/Views/WorkingCopy.axaml @@ -80,6 +80,15 @@ ChangeDoubleTapped="OnUnstagedChangeDoubleTapped" KeyDown="OnUnstagedKeyDown"/> + + + + From a4befd010ad8635d4ad027f0c5c11bafa4c928c9 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 30 Oct 2024 18:10:53 +0800 Subject: [PATCH 45/68] code_review: PR #627 * add minimal height for both unstaged and staged changes view Signed-off-by: leo --- src/Views/WorkingCopy.axaml | 219 +++++++++++++++++++----------------- 1 file changed, 114 insertions(+), 105 deletions(-) diff --git a/src/Views/WorkingCopy.axaml b/src/Views/WorkingCopy.axaml index 2e07d970..4550e46a 100644 --- a/src/Views/WorkingCopy.axaml +++ b/src/Views/WorkingCopy.axaml @@ -16,117 +16,126 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - + Background="{DynamicResource Brush.Border0}"/> - - - - - - - - - - - - + + + + + + + + + + + + + + - - + + + Date: Wed, 30 Oct 2024 18:39:38 +0800 Subject: [PATCH 46/68] feature: add an option in repository configuration to enable `--prune` on fetch (#590) Signed-off-by: leo --- src/Commands/Fetch.cs | 5 ++++- src/Commands/Pull.cs | 4 +++- 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/AddRemote.cs | 2 +- src/ViewModels/Fetch.cs | 6 ++++-- src/ViewModels/Pull.cs | 17 +++++++++++++++-- src/ViewModels/Repository.cs | 2 +- src/ViewModels/RepositoryConfigure.cs | 8 +++++++- src/Views/RepositoryConfigure.axaml | 8 ++++++-- 12 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/Commands/Fetch.cs b/src/Commands/Fetch.cs index 25c499fd..08d2d1c6 100644 --- a/src/Commands/Fetch.cs +++ b/src/Commands/Fetch.cs @@ -4,7 +4,7 @@ namespace SourceGit.Commands { public class Fetch : Command { - public Fetch(string repo, string remote, bool noTags, Action outputHandler) + public Fetch(string repo, string remote, bool noTags, bool prune, Action outputHandler) { _outputHandler = outputHandler; WorkingDirectory = repo; @@ -18,6 +18,9 @@ namespace SourceGit.Commands else Args += "--force "; + if (prune) + Args += "--prune "; + Args += remote; } diff --git a/src/Commands/Pull.cs b/src/Commands/Pull.cs index a4efa4b6..732530f5 100644 --- a/src/Commands/Pull.cs +++ b/src/Commands/Pull.cs @@ -4,7 +4,7 @@ namespace SourceGit.Commands { public class Pull : Command { - public Pull(string repo, string remote, string branch, bool useRebase, bool noTags, Action outputHandler) + public Pull(string repo, string remote, string branch, bool useRebase, bool noTags, bool prune, Action outputHandler) { _outputHandler = outputHandler; WorkingDirectory = repo; @@ -17,6 +17,8 @@ namespace SourceGit.Commands Args += "--rebase "; if (noTags) Args += "--no-tags "; + if (prune) + Args += "--prune "; Args += $"{remote} {branch}"; } diff --git a/src/Models/RepositorySettings.cs b/src/Models/RepositorySettings.cs index ce4119f5..a8cc5770 100644 --- a/src/Models/RepositorySettings.cs +++ b/src/Models/RepositorySettings.cs @@ -16,6 +16,12 @@ namespace SourceGit.Models set; } = DealWithLocalChanges.DoNothing; + public bool EnablePruneOnFetch + { + get; + set; + } = false; + public bool FetchWithoutTags { get; diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index b2e0ef8d..c6f88ed1 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -145,6 +145,7 @@ Fetch remotes automatically Minute(s) Default Remote + Enable --prune on fetch Enable --signoff for commit ISSUE TRACKER Add Sample Github Rule diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 333dbd06..a274c06c 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -149,6 +149,7 @@ 分钟 默认远程 提交信息追加署名 (--signoff) + 拉取更新时启用修剪(--prune) ISSUE追踪 新增匹配Github Issue规则 新增匹配Jira规则 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 06f9bba4..ce62c299 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -149,6 +149,7 @@ 分鐘 預設遠端存放庫 提交訊息追加署名 (--signoff) + 提取變更时啟用修剪(--prune) Issue 追蹤 新增符合 GitHub Issue 規則 新增符合 Jira 規則 diff --git a/src/ViewModels/AddRemote.cs b/src/ViewModels/AddRemote.cs index d2a7729a..d6424572 100644 --- a/src/ViewModels/AddRemote.cs +++ b/src/ViewModels/AddRemote.cs @@ -100,7 +100,7 @@ namespace SourceGit.ViewModels { SetProgressDescription("Fetching from added remote ..."); new Commands.Config(_repo.FullPath).Set($"remote.{_name}.sshkey", _useSSH ? SSHKey : null); - new Commands.Fetch(_repo.FullPath, _name, false, SetProgressDescription).Exec(); + new Commands.Fetch(_repo.FullPath, _name, false, false, SetProgressDescription).Exec(); } CallUIThread(() => { diff --git a/src/ViewModels/Fetch.cs b/src/ViewModels/Fetch.cs index 3fe92a5f..7f54680d 100644 --- a/src/ViewModels/Fetch.cs +++ b/src/ViewModels/Fetch.cs @@ -40,6 +40,8 @@ namespace SourceGit.ViewModels { _repo.SetWatcherEnabled(false); + var notags = _repo.Settings.FetchWithoutTags; + var prune = _repo.Settings.EnablePruneOnFetch; return Task.Run(() => { if (FetchAllRemotes) @@ -47,13 +49,13 @@ namespace SourceGit.ViewModels foreach (var remote in _repo.Remotes) { SetProgressDescription($"Fetching remote: {remote.Name}"); - new Commands.Fetch(_repo.FullPath, remote.Name, NoTags, SetProgressDescription).Exec(); + new Commands.Fetch(_repo.FullPath, remote.Name, notags, prune, SetProgressDescription).Exec(); } } else { SetProgressDescription($"Fetching remote: {SelectedRemote.Name}"); - new Commands.Fetch(_repo.FullPath, SelectedRemote.Name, NoTags, SetProgressDescription).Exec(); + new Commands.Fetch(_repo.FullPath, SelectedRemote.Name, notags, prune, SetProgressDescription).Exec(); } CallUIThread(() => diff --git a/src/ViewModels/Pull.cs b/src/ViewModels/Pull.cs index b5c038ae..6c493449 100644 --- a/src/ViewModels/Pull.cs +++ b/src/ViewModels/Pull.cs @@ -147,7 +147,13 @@ namespace SourceGit.ViewModels if (FetchAllBranches) { SetProgressDescription($"Fetching remote: {_selectedRemote.Name}..."); - rs = new Commands.Fetch(_repo.FullPath, _selectedRemote.Name, NoTags, SetProgressDescription).Exec(); + rs = new Commands.Fetch( + _repo.FullPath, + _selectedRemote.Name, + NoTags, + _repo.Settings.EnablePruneOnFetch, + SetProgressDescription).Exec(); + if (!rs) { CallUIThread(() => _repo.SetWatcherEnabled(true)); @@ -171,7 +177,14 @@ namespace SourceGit.ViewModels else { SetProgressDescription($"Pull {_selectedRemote.Name}/{_selectedBranch.Name}..."); - rs = new Commands.Pull(_repo.FullPath, _selectedRemote.Name, _selectedBranch.Name, UseRebase, NoTags, SetProgressDescription).Exec(); + rs = new Commands.Pull( + _repo.FullPath, + _selectedRemote.Name, + _selectedBranch.Name, + UseRebase, + NoTags, + _repo.Settings.EnablePruneOnFetch, + SetProgressDescription).Exec(); } if (rs && needPopStash) diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 917833db..c64967d1 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -2137,7 +2137,7 @@ namespace SourceGit.ViewModels IsAutoFetching = true; Dispatcher.UIThread.Invoke(() => OnPropertyChanged(nameof(IsAutoFetching))); - new Commands.Fetch(_fullpath, "--all", false, null) { RaiseError = false }.Exec(); + new Commands.Fetch(_fullpath, "--all", false, _settings.EnablePruneOnFetch, null) { RaiseError = false }.Exec(); _lastFetchTime = DateTime.Now; IsAutoFetching = false; Dispatcher.UIThread.Invoke(() => OnPropertyChanged(nameof(IsAutoFetching))); diff --git a/src/ViewModels/RepositoryConfigure.cs b/src/ViewModels/RepositoryConfigure.cs index d7eaa1cb..94efc09d 100644 --- a/src/ViewModels/RepositoryConfigure.cs +++ b/src/ViewModels/RepositoryConfigure.cs @@ -67,6 +67,12 @@ namespace SourceGit.ViewModels set => _repo.Settings.EnableSignOffForCommit = value; } + public bool EnablePruneOnFetch + { + get => _repo.Settings.EnablePruneOnFetch; + set => _repo.Settings.EnablePruneOnFetch = value; + } + public bool EnableAutoFetch { get => _repo.Settings.EnableAutoFetch; @@ -134,7 +140,7 @@ namespace SourceGit.ViewModels AvailableOpenAIServices.Add(service.Name); if (AvailableOpenAIServices.IndexOf(PreferedOpenAIService) == -1) - PreferedOpenAIService = "---"; + PreferedOpenAIService = "---"; _cached = new Commands.Config(repo.FullPath).ListAll(); if (_cached.TryGetValue("user.name", out var name)) diff --git a/src/Views/RepositoryConfigure.axaml b/src/Views/RepositoryConfigure.axaml index ced0dab6..535a016c 100644 --- a/src/Views/RepositoryConfigure.axaml +++ b/src/Views/RepositoryConfigure.axaml @@ -51,7 +51,7 @@ - + - + + + From 0228bef1dbc28b461a19ed70bf41355ee49f0cf3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 30 Oct 2024 10:40:00 +0000 Subject: [PATCH 47/68] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 7e675368..2c7310c8 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-98.06%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-99.10%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-89.55%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.69%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-100.00%25-brightgreen)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-100.00%25-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-100.00%25-brightgreen)](TRANSLATION.md) +[![en_US](https://img.shields.io/badge/en__US-100%25-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-97.91%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-98.96%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-89.42%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.55%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.85%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 9aa14567..5cf27b14 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -1,4 +1,4 @@ -### de_DE.axaml: 98.06% +### de_DE.axaml: 97.91%
@@ -6,6 +6,7 @@ - Text.BranchCM.FetchInto - Text.ChangeCM.GenerateCommitMessage +- Text.Configure.Git.EnablePruneOnFetch - Text.Configure.Git.EnableSignOff - Text.Configure.IssueTracker.AddSampleGitLabIssue - Text.Configure.IssueTracker.AddSampleGitLabMergeRequest @@ -20,13 +21,14 @@
-### es_ES.axaml: 99.10% +### es_ES.axaml: 98.96%
Missing Keys - Text.ChangeCM.GenerateCommitMessage +- Text.Configure.Git.EnablePruneOnFetch - Text.Configure.OpenAI - Text.Configure.OpenAI.Prefered - Text.Configure.OpenAI.Prefered.Tip @@ -35,7 +37,7 @@
-### fr_FR.axaml: 89.55% +### fr_FR.axaml: 89.42%
@@ -53,6 +55,7 @@ - Text.CommitCM.SquashCommitsSinceThis - Text.CommitDetail.Info.WebLinks - Text.Configure.Git.DefaultRemote +- Text.Configure.Git.EnablePruneOnFetch - Text.Configure.Git.EnableSignOff - Text.Configure.IssueTracker.AddSampleGitLabIssue - Text.Configure.IssueTracker.AddSampleGitLabMergeRequest @@ -114,7 +117,7 @@
-### pt_BR.axaml: 92.69% +### pt_BR.axaml: 92.55%
@@ -134,6 +137,7 @@ - Text.CommitDetail.Info.ContainsIn.Title - Text.CommitDetail.Info.WebLinks - Text.Configure.Git.DefaultRemote +- Text.Configure.Git.EnablePruneOnFetch - Text.Configure.Git.EnableSignOff - Text.Configure.IssueTracker.AddSampleGitLabIssue - Text.Configure.IssueTracker.AddSampleGitLabMergeRequest @@ -172,13 +176,13 @@
-### ru_RU.axaml: 100.00% +### ru_RU.axaml: 99.85%
Missing Keys - +- Text.Configure.Git.EnablePruneOnFetch
From 9816a5e8ba58e6fc7794dcb260ffeb613cca086f Mon Sep 17 00:00:00 2001 From: Masgalor Date: Wed, 30 Oct 2024 11:45:25 +0100 Subject: [PATCH 48/68] fix: Make RPM builds compatible with OpenSUSE (libX11) (#628) --- build/resources/rpm/SPECS/build.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/resources/rpm/SPECS/build.spec b/build/resources/rpm/SPECS/build.spec index 0f80aac3..9dda5f96 100644 --- a/build/resources/rpm/SPECS/build.spec +++ b/build/resources/rpm/SPECS/build.spec @@ -5,7 +5,7 @@ Summary: Open-source & Free Git Gui Client License: MIT URL: https://sourcegit-scm.github.io/ Source: https://github.com/sourcegit-scm/sourcegit/archive/refs/tags/v%_version.tar.gz -Requires: libX11 +Requires: (libX11 or libX11-6) Requires: (libSM or libSM6) %define _build_id_links none From cffcf3448e854d5a3ee1dbfbe810d83ed9d30af6 Mon Sep 17 00:00:00 2001 From: GadflyFang Date: Wed, 30 Oct 2024 18:48:41 +0800 Subject: [PATCH 49/68] fix: query file size quote filename (#629) Signed-off-by: Gadfly --- src/Commands/QueryFileSize.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Commands/QueryFileSize.cs b/src/Commands/QueryFileSize.cs index c36984dd..9016d826 100644 --- a/src/Commands/QueryFileSize.cs +++ b/src/Commands/QueryFileSize.cs @@ -11,7 +11,7 @@ namespace SourceGit.Commands { WorkingDirectory = repo; Context = repo; - Args = $"ls-tree {revision} -l -- {file}"; + Args = $"ls-tree {revision} -l -- \"{file}\""; } public long Result() From 9b2e0bc5cfeeaf50e77a1e92872ca701851acfec Mon Sep 17 00:00:00 2001 From: AquariusStar <48148723+AquariusStar@users.noreply.github.com> Date: Thu, 31 Oct 2024 00:56:06 +0300 Subject: [PATCH 50/68] localization: update (#632) --- src/Resources/Locales/ru_RU.axaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index 33237603..da689e1b 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -147,8 +147,9 @@ GIT Автоматическое извлечение внешних хранилищ Минут(а/ы) - Удалённое хранилище по-умолчанию Разрешить --signoff для фиксации + Удалённое хранилище по-умолчанию + Разрешить --prune при извлечении ОТСЛЕЖИВАНИЕ ПРОБЛЕМ Добавить пример правила для Git Добавить пример правила Jira From 39250466d59fd29f2994ca4220e697e5c02f762b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 30 Oct 2024 21:56:22 +0000 Subject: [PATCH 51/68] 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 2c7310c8..51008ea3 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.91%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-98.96%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-89.42%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.55%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.85%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-97.91%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-98.96%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-89.42%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.55%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-100.00%25-brightgreen)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-100.00%25-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-100.00%25-brightgreen)](TRANSLATION.md) ## How to Use diff --git a/TRANSLATION.md b/TRANSLATION.md index 5cf27b14..8cd78b5c 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -176,13 +176,13 @@ -### ru_RU.axaml: 99.85% +### ru_RU.axaml: 100.00%
Missing Keys -- Text.Configure.Git.EnablePruneOnFetch +
From 1999e4bf477b815bc3c8b8acbcfc0aeef2ebf8f8 Mon Sep 17 00:00:00 2001 From: leo Date: Thu, 31 Oct 2024 20:02:31 +0800 Subject: [PATCH 52/68] ux: remove button padding and use content alignment to center text Signed-off-by: leo --- src/Views/LauncherPage.axaml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Views/LauncherPage.axaml b/src/Views/LauncherPage.axaml index 3ef4286a..1b256e7b 100644 --- a/src/Views/LauncherPage.axaml +++ b/src/Views/LauncherPage.axaml @@ -60,13 +60,19 @@ HorizontalAlignment="Right" IsVisible="{Binding InProgress, Converter={x:Static BoolConverters.Not}}"> - - -
-
- diff --git a/src/Views/CaptionButtonsMacOS.axaml.cs b/src/Views/CaptionButtonsMacOS.axaml.cs deleted file mode 100644 index 98bbb88f..00000000 --- a/src/Views/CaptionButtonsMacOS.axaml.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Avalonia; -using Avalonia.Controls; -using Avalonia.Interactivity; -using Avalonia.VisualTree; - -namespace SourceGit.Views -{ - public partial class CaptionButtonsMacOS : UserControl - { - public static readonly StyledProperty IsCloseButtonOnlyProperty = - AvaloniaProperty.Register(nameof(IsCloseButtonOnly)); - - public bool IsCloseButtonOnly - { - get => GetValue(IsCloseButtonOnlyProperty); - set => SetValue(IsCloseButtonOnlyProperty, value); - } - - public CaptionButtonsMacOS() - { - InitializeComponent(); - } - - private void MinimizeWindow(object _, RoutedEventArgs e) - { - var window = this.FindAncestorOfType(); - if (window != null) - window.WindowState = WindowState.Minimized; - - e.Handled = true; - } - - private void MaximizeOrRestoreWindow(object _, RoutedEventArgs e) - { - var window = this.FindAncestorOfType(); - if (window != null) - window.WindowState = window.WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized; - - e.Handled = true; - } - - private void CloseWindow(object _, RoutedEventArgs e) - { - var window = this.FindAncestorOfType(); - window?.Close(); - e.Handled = true; - } - } -} diff --git a/src/Views/ChromelessWindow.cs b/src/Views/ChromelessWindow.cs index a9b9f259..107a7ba3 100644 --- a/src/Views/ChromelessWindow.cs +++ b/src/Views/ChromelessWindow.cs @@ -32,14 +32,35 @@ namespace SourceGit.Views Classes.Add("custom_window_frame"); } } - else + else if (OperatingSystem.IsWindows()) { ExtendClientAreaChromeHints = ExtendClientAreaChromeHints.NoChrome; ExtendClientAreaToDecorationsHint = true; - - if (OperatingSystem.IsWindows()) - Classes.Add("fix_maximized_padding"); + Classes.Add("fix_maximized_padding"); } + else + { + ExtendClientAreaChromeHints = ExtendClientAreaChromeHints.SystemChrome; + ExtendClientAreaToDecorationsHint = true; + } + } + + public void BeginMoveWindow(object _, PointerPressedEventArgs e) + { + if (e.ClickCount == 1) + BeginMoveDrag(e); + + e.Handled = true; + } + + public void MaximizeOrRestoreWindow(object _, TappedEventArgs e) + { + if (WindowState == WindowState.Maximized) + WindowState = WindowState.Normal; + else + WindowState = WindowState.Maximized; + + e.Handled = true; } protected override void OnApplyTemplate(TemplateAppliedEventArgs e) diff --git a/src/Views/ConfigureWorkspace.axaml b/src/Views/ConfigureWorkspace.axaml index c7ed900b..9c18ad04 100644 --- a/src/Views/ConfigureWorkspace.axaml +++ b/src/Views/ConfigureWorkspace.axaml @@ -2,10 +2,8 @@ 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" - xmlns:c="using:SourceGit.Converters" mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450" x:Class="SourceGit.Views.ConfigureWorkspace" x:DataType="vm:ConfigureWorkspace" @@ -17,30 +15,23 @@ WindowStartupLocation="CenterOwner"> - - + - - - - - diff --git a/src/Views/ConfigureWorkspace.axaml.cs b/src/Views/ConfigureWorkspace.axaml.cs index 82d8cd30..e2cc1cb2 100644 --- a/src/Views/ConfigureWorkspace.axaml.cs +++ b/src/Views/ConfigureWorkspace.axaml.cs @@ -1,5 +1,4 @@ using Avalonia.Controls; -using Avalonia.Input; namespace SourceGit.Views { @@ -15,10 +14,5 @@ namespace SourceGit.Views ViewModels.Preference.Instance.Save(); base.OnClosing(e); } - - private void BeginMoveWindow(object _, PointerPressedEventArgs e) - { - BeginMoveDrag(e); - } } } diff --git a/src/Views/ConfirmCommitWithoutFiles.axaml b/src/Views/ConfirmCommitWithoutFiles.axaml index 0b457531..a056f016 100644 --- a/src/Views/ConfirmCommitWithoutFiles.axaml +++ b/src/Views/ConfirmCommitWithoutFiles.axaml @@ -15,30 +15,23 @@ WindowStartupLocation="CenterOwner"> - - + - - - - - diff --git a/src/Views/ConfirmCommitWithoutFiles.axaml.cs b/src/Views/ConfirmCommitWithoutFiles.axaml.cs index 0be18902..342600fc 100644 --- a/src/Views/ConfirmCommitWithoutFiles.axaml.cs +++ b/src/Views/ConfirmCommitWithoutFiles.axaml.cs @@ -1,4 +1,3 @@ -using Avalonia.Input; using Avalonia.Interactivity; namespace SourceGit.Views @@ -10,11 +9,6 @@ namespace SourceGit.Views InitializeComponent(); } - private void BeginMoveWindow(object _, PointerPressedEventArgs e) - { - BeginMoveDrag(e); - } - private void Sure(object _1, RoutedEventArgs _2) { if (DataContext is ViewModels.ConfirmCommitWithoutFiles vm) diff --git a/src/Views/ConfirmRestart.axaml b/src/Views/ConfirmRestart.axaml index 9aafda7e..de2ddd4f 100644 --- a/src/Views/ConfirmRestart.axaml +++ b/src/Views/ConfirmRestart.axaml @@ -13,30 +13,23 @@ WindowStartupLocation="CenterOwner"> - - + - - - - - diff --git a/src/Views/ConfirmRestart.axaml.cs b/src/Views/ConfirmRestart.axaml.cs index d0647731..ea49bea1 100644 --- a/src/Views/ConfirmRestart.axaml.cs +++ b/src/Views/ConfirmRestart.axaml.cs @@ -1,8 +1,6 @@ using System; using System.Diagnostics; -using Avalonia.Controls; -using Avalonia.Input; using Avalonia.Interactivity; namespace SourceGit.Views @@ -14,11 +12,6 @@ namespace SourceGit.Views InitializeComponent(); } - private void BeginMoveWindow(object _, PointerPressedEventArgs e) - { - BeginMoveDrag(e); - } - private void CloseWindow(object _1, RoutedEventArgs _2) { Console.Out.WriteLine("No passphrase entered."); diff --git a/src/Views/ConventionalCommitMessageBuilder.axaml b/src/Views/ConventionalCommitMessageBuilder.axaml index ab2ae37f..4fe8b8f9 100644 --- a/src/Views/ConventionalCommitMessageBuilder.axaml +++ b/src/Views/ConventionalCommitMessageBuilder.axaml @@ -5,7 +5,6 @@ xmlns:m="using:SourceGit.Models" 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.ConventionalCommitMessageBuilder" x:DataType="vm:ConventionalCommitMessageBuilder" @@ -18,30 +17,23 @@ WindowStartupLocation="CenterOwner"> - - + - - - - - diff --git a/src/Views/ConventionalCommitMessageBuilder.axaml.cs b/src/Views/ConventionalCommitMessageBuilder.axaml.cs index dfe56f0d..955450ed 100644 --- a/src/Views/ConventionalCommitMessageBuilder.axaml.cs +++ b/src/Views/ConventionalCommitMessageBuilder.axaml.cs @@ -1,4 +1,3 @@ -using Avalonia.Input; using Avalonia.Interactivity; namespace SourceGit.Views @@ -10,11 +9,6 @@ namespace SourceGit.Views InitializeComponent(); } - private void BeginMoveWindow(object _, PointerPressedEventArgs e) - { - BeginMoveDrag(e); - } - private void OnApplyClicked(object _, RoutedEventArgs e) { if (DataContext is ViewModels.ConventionalCommitMessageBuilder builder) diff --git a/src/Views/FileHistories.axaml b/src/Views/FileHistories.axaml index bc048706..703957b8 100644 --- a/src/Views/FileHistories.axaml +++ b/src/Views/FileHistories.axaml @@ -20,29 +20,26 @@ - + - - - - - - - - - - - + + + - - - + diff --git a/src/Views/FileHistories.axaml.cs b/src/Views/FileHistories.axaml.cs index 6a2ee7c9..c7a01e2f 100644 --- a/src/Views/FileHistories.axaml.cs +++ b/src/Views/FileHistories.axaml.cs @@ -1,3 +1,6 @@ +using System; + +using Avalonia; using Avalonia.Controls; using Avalonia.Input; using Avalonia.Interactivity; @@ -6,27 +9,29 @@ namespace SourceGit.Views { public partial class FileHistories : ChromelessWindow { + public static readonly StyledProperty HasLeftCaptionButtonProperty = + AvaloniaProperty.Register(nameof(HasLeftCaptionButton)); + + public bool HasLeftCaptionButton + { + get => GetValue(HasLeftCaptionButtonProperty); + set => SetValue(HasLeftCaptionButtonProperty, value); + } + public FileHistories() { + if (OperatingSystem.IsMacOS()) + HasLeftCaptionButton = true; + InitializeComponent(); } - - private void MaximizeOrRestoreWindow(object _, TappedEventArgs e) + + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) { - if (WindowState == WindowState.Maximized) - WindowState = WindowState.Normal; - else - WindowState = WindowState.Maximized; - - e.Handled = true; - } - - private void BeginMoveWindow(object _, PointerPressedEventArgs e) - { - if (e.ClickCount == 1) - BeginMoveDrag(e); - - e.Handled = true; + base.OnPropertyChanged(change); + + if (change.Property == WindowStateProperty) + HasLeftCaptionButton = WindowState != WindowState.FullScreen; } private void OnPressCommitSHA(object sender, PointerPressedEventArgs e) diff --git a/src/Views/Hotkeys.axaml b/src/Views/Hotkeys.axaml index 5d98238d..a28bc566 100644 --- a/src/Views/Hotkeys.axaml +++ b/src/Views/Hotkeys.axaml @@ -15,30 +15,23 @@ WindowStartupLocation="CenterOwner"> - - + - - - - - diff --git a/src/Views/Hotkeys.axaml.cs b/src/Views/Hotkeys.axaml.cs index 2a21fef9..d8b5e1a8 100644 --- a/src/Views/Hotkeys.axaml.cs +++ b/src/Views/Hotkeys.axaml.cs @@ -1,5 +1,3 @@ -using Avalonia.Input; - namespace SourceGit.Views { public partial class Hotkeys : ChromelessWindow @@ -8,10 +6,5 @@ namespace SourceGit.Views { InitializeComponent(); } - - private void BeginMoveWindow(object _, PointerPressedEventArgs e) - { - BeginMoveDrag(e); - } } } diff --git a/src/Views/InteractiveRebase.axaml b/src/Views/InteractiveRebase.axaml index e1161a2b..c008193b 100644 --- a/src/Views/InteractiveRebase.axaml +++ b/src/Views/InteractiveRebase.axaml @@ -16,30 +16,23 @@ WindowStartupLocation="CenterOwner"> - - + - - - - - diff --git a/src/Views/InteractiveRebase.axaml.cs b/src/Views/InteractiveRebase.axaml.cs index 8f75cc26..a31b8a23 100644 --- a/src/Views/InteractiveRebase.axaml.cs +++ b/src/Views/InteractiveRebase.axaml.cs @@ -81,11 +81,6 @@ namespace SourceGit.Views InitializeComponent(); } - private void BeginMoveWindow(object _, PointerPressedEventArgs e) - { - BeginMoveDrag(e); - } - private void CloseWindow(object _1, RoutedEventArgs _2) { Close(); diff --git a/src/Views/LFSLocks.axaml b/src/Views/LFSLocks.axaml index ccbe9fe2..ac495bf1 100644 --- a/src/Views/LFSLocks.axaml +++ b/src/Views/LFSLocks.axaml @@ -16,30 +16,23 @@ WindowStartupLocation="CenterOwner"> - - + - - - - - diff --git a/src/Views/LFSLocks.axaml.cs b/src/Views/LFSLocks.axaml.cs index ee4b6ff1..695341f4 100644 --- a/src/Views/LFSLocks.axaml.cs +++ b/src/Views/LFSLocks.axaml.cs @@ -1,5 +1,4 @@ using Avalonia.Controls; -using Avalonia.Input; using Avalonia.Interactivity; namespace SourceGit.Views @@ -11,11 +10,6 @@ namespace SourceGit.Views InitializeComponent(); } - private void BeginMoveWindow(object _, PointerPressedEventArgs e) - { - BeginMoveDrag(e); - } - private void OnUnlockButtonClicked(object sender, RoutedEventArgs e) { if (DataContext is ViewModels.LFSLocks vm && sender is Button button) diff --git a/src/Views/Launcher.axaml b/src/Views/Launcher.axaml index 285ea72c..ad5a7f34 100644 --- a/src/Views/Launcher.axaml +++ b/src/Views/Launcher.axaml @@ -25,13 +25,11 @@ - - - + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Views/RepositoryConfigure.axaml.cs b/src/Views/RepositoryConfigure.axaml.cs index 21f6ad23..3faba5ee 100644 --- a/src/Views/RepositoryConfigure.axaml.cs +++ b/src/Views/RepositoryConfigure.axaml.cs @@ -1,4 +1,6 @@ using Avalonia.Controls; +using Avalonia.Interactivity; +using Avalonia.Platform.Storage; namespace SourceGit.Views { @@ -14,5 +16,20 @@ namespace SourceGit.Views (DataContext as ViewModels.RepositoryConfigure)?.Save(); base.OnClosing(e); } + + 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; + } } } diff --git a/src/Views/RepositoryToolbar.axaml b/src/Views/RepositoryToolbar.axaml index b76cfd63..c1eec786 100644 --- a/src/Views/RepositoryToolbar.axaml +++ b/src/Views/RepositoryToolbar.axaml @@ -96,6 +96,10 @@ + + diff --git a/src/Views/RepositoryToolbar.axaml.cs b/src/Views/RepositoryToolbar.axaml.cs index 27ac43cd..55132620 100644 --- a/src/Views/RepositoryToolbar.axaml.cs +++ b/src/Views/RepositoryToolbar.axaml.cs @@ -91,6 +91,17 @@ namespace SourceGit.Views e.Handled = true; } + + private void OpenCustomActionMenu(object sender, RoutedEventArgs e) + { + if (DataContext is ViewModels.Repository repo) + { + var menu = repo.CreateContextMenuForCustomAction(); + (sender as Control)?.OpenContextMenu(menu); + } + + e.Handled = true; + } } } From 26fe56e0652b44dc54162bfd30f1a1fa908ba5e1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 1 Nov 2024 09:25:17 +0000 Subject: [PATCH 57/68] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 76 ++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 71 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 51008ea3..9f0d8cae 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.91%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-98.96%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-89.42%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-92.55%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-100.00%25-brightgreen)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-100.00%25-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-100.00%25-brightgreen)](TRANSLATION.md) +[![en_US](https://img.shields.io/badge/en__US-100%25-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-96.05%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.08%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-87.72%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-90.79%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-98.10%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 8cd78b5c..4b22ac57 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -1,4 +1,4 @@ -### de_DE.axaml: 97.91% +### de_DE.axaml: 96.05%
@@ -6,6 +6,15 @@ - Text.BranchCM.FetchInto - Text.ChangeCM.GenerateCommitMessage +- Text.CommitCM.CustomAction +- Text.Configure.CustomAction +- Text.Configure.CustomAction.Arguments +- Text.Configure.CustomAction.Arguments.Tip +- Text.Configure.CustomAction.Executable +- Text.Configure.CustomAction.Name +- Text.Configure.CustomAction.Scope +- Text.Configure.CustomAction.Scope.Commit +- Text.Configure.CustomAction.Scope.Repository - Text.Configure.Git.EnablePruneOnFetch - Text.Configure.Git.EnableSignOff - Text.Configure.IssueTracker.AddSampleGitLabIssue @@ -13,31 +22,48 @@ - Text.Configure.OpenAI - Text.Configure.OpenAI.Prefered - Text.Configure.OpenAI.Prefered.Tip +- Text.ExecuteCustomAction +- Text.ExecuteCustomAction.Name - Text.Preference.AI.AnalyzeDiffPrompt - Text.Preference.AI.GenerateSubjectPrompt - Text.Preference.AI.Name +- Text.Repository.CustomActions +- Text.Repository.CustomActions.Empty - Text.Stash.KeepIndex - Text.WorkingCopy.ConfirmCommitWithoutFiles
-### es_ES.axaml: 98.96% +### es_ES.axaml: 97.08%
Missing Keys - Text.ChangeCM.GenerateCommitMessage +- Text.CommitCM.CustomAction +- Text.Configure.CustomAction +- Text.Configure.CustomAction.Arguments +- Text.Configure.CustomAction.Arguments.Tip +- Text.Configure.CustomAction.Executable +- Text.Configure.CustomAction.Name +- Text.Configure.CustomAction.Scope +- Text.Configure.CustomAction.Scope.Commit +- Text.Configure.CustomAction.Scope.Repository - Text.Configure.Git.EnablePruneOnFetch - Text.Configure.OpenAI - Text.Configure.OpenAI.Prefered - Text.Configure.OpenAI.Prefered.Tip +- Text.ExecuteCustomAction +- Text.ExecuteCustomAction.Name - Text.Preference.AI.Name +- Text.Repository.CustomActions +- Text.Repository.CustomActions.Empty - Text.Stash.KeepIndex
-### fr_FR.axaml: 89.42% +### fr_FR.axaml: 87.72%
@@ -52,8 +78,17 @@ - Text.CherryPick.Mainline - Text.CherryPick.Mainline.Tips - Text.CommitCM.CherryPickMultiple +- Text.CommitCM.CustomAction - Text.CommitCM.SquashCommitsSinceThis - Text.CommitDetail.Info.WebLinks +- Text.Configure.CustomAction +- Text.Configure.CustomAction.Arguments +- Text.Configure.CustomAction.Arguments.Tip +- Text.Configure.CustomAction.Executable +- Text.Configure.CustomAction.Name +- Text.Configure.CustomAction.Scope +- Text.Configure.CustomAction.Scope.Commit +- Text.Configure.CustomAction.Scope.Repository - Text.Configure.Git.DefaultRemote - Text.Configure.Git.EnablePruneOnFetch - Text.Configure.Git.EnableSignOff @@ -74,6 +109,8 @@ - Text.ConventionalCommit.Type - Text.Diff.IgnoreWhitespace - Text.Discard.IncludeIgnored +- Text.ExecuteCustomAction +- Text.ExecuteCustomAction.Name - Text.FileHistory.FileChange - Text.GitLFS.Locks.OnlyMine - Text.Histories.Header.AuthorTime @@ -97,6 +134,8 @@ - Text.Preference.Shell.Type - Text.Preference.Shell.Path - Text.Repository.AutoFetching +- Text.Repository.CustomActions +- Text.Repository.CustomActions.Empty - Text.Repository.EnableReflog - Text.Repository.Search.InCurrentBranch - Text.ScanRepositories @@ -117,7 +156,7 @@
-### pt_BR.axaml: 92.55% +### pt_BR.axaml: 90.79%
@@ -132,10 +171,19 @@ - Text.CherryPick.Mainline - Text.CherryPick.Mainline.Tips - Text.CommitCM.CherryPickMultiple +- Text.CommitCM.CustomAction - Text.CommitCM.SquashCommitsSinceThis - Text.CommitDetail.Info.ContainsIn - Text.CommitDetail.Info.ContainsIn.Title - Text.CommitDetail.Info.WebLinks +- Text.Configure.CustomAction +- Text.Configure.CustomAction.Arguments +- Text.Configure.CustomAction.Arguments.Tip +- Text.Configure.CustomAction.Executable +- Text.Configure.CustomAction.Name +- Text.Configure.CustomAction.Scope +- Text.Configure.CustomAction.Scope.Commit +- Text.Configure.CustomAction.Scope.Repository - Text.Configure.Git.DefaultRemote - Text.Configure.Git.EnablePruneOnFetch - Text.Configure.Git.EnableSignOff @@ -156,6 +204,8 @@ - Text.ConventionalCommit.Type - Text.CopyAllText - Text.Discard.IncludeIgnored +- Text.ExecuteCustomAction +- Text.ExecuteCustomAction.Name - Text.FileHistory.FileContent - Text.FileHistory.FileChange - Text.GitLFS.Locks.OnlyMine @@ -163,6 +213,8 @@ - Text.MoveRepositoryNode.Target - Text.Preference.AI.Name - Text.Push.CheckSubmodules +- Text.Repository.CustomActions +- Text.Repository.CustomActions.Empty - Text.Squash.Into - Text.Stash.KeepIndex - Text.Stash.OnlyStagedChanges @@ -176,13 +228,25 @@
-### ru_RU.axaml: 100.00% +### ru_RU.axaml: 98.10%
Missing Keys - +- Text.CommitCM.CustomAction +- Text.Configure.CustomAction +- Text.Configure.CustomAction.Arguments +- Text.Configure.CustomAction.Arguments.Tip +- Text.Configure.CustomAction.Executable +- Text.Configure.CustomAction.Name +- Text.Configure.CustomAction.Scope +- Text.Configure.CustomAction.Scope.Commit +- Text.Configure.CustomAction.Scope.Repository +- Text.ExecuteCustomAction +- Text.ExecuteCustomAction.Name +- Text.Repository.CustomActions +- Text.Repository.CustomActions.Empty
From ba3c72585d352d1d2f3858ff22a7eeeade831347 Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 1 Nov 2024 17:54:05 +0800 Subject: [PATCH 58/68] enhance: use Inter as default font for all platforms (#639) Signed-off-by: leo --- src/App.axaml.cs | 6 +++++- src/Resources/Themes.axaml | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/App.axaml.cs b/src/App.axaml.cs index 682ec5fc..dfec763b 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -59,6 +59,10 @@ namespace SourceGit builder.UsePlatformDetect(); builder.LogToTrace(); builder.WithInterFont(); + builder.With(new FontManagerOptions() + { + DefaultFamilyName = "fonts:Inter#Inter" + }); builder.ConfigureFonts(manager => { var monospace = new EmbeddedFontCollection( @@ -223,7 +227,7 @@ namespace SourceGit if (onlyUseMonospaceFontInEditor) { if (string.IsNullOrEmpty(defaultFont)) - resDic.Add("Fonts.Primary", new FontFamily("fonts:Inter#Inter, $Default")); + resDic.Add("Fonts.Primary", new FontFamily("fonts:Inter#Inter")); else resDic.Add("Fonts.Primary", new FontFamily(defaultFont)); } diff --git a/src/Resources/Themes.axaml b/src/Resources/Themes.axaml index aa0cbbb8..6326023a 100644 --- a/src/Resources/Themes.axaml +++ b/src/Resources/Themes.axaml @@ -83,7 +83,7 @@ - fonts:Inter#Inter, $Default + fonts:Inter#Inter fonts:SourceGit#JetBrains Mono fonts:SourceGit#JetBrains Mono
From 2f9e825b63274eba3330069f4015243aabf0a9c1 Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 1 Nov 2024 18:10:22 +0800 Subject: [PATCH 59/68] refactor: pass Models.Commit instead of just sha of it Signed-off-by: leo --- src/ViewModels/ExecuteCustomAction.cs | 6 +++--- src/ViewModels/Histories.cs | 2 +- src/ViewModels/Repository.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ViewModels/ExecuteCustomAction.cs b/src/ViewModels/ExecuteCustomAction.cs index e8893f5a..920b9f43 100644 --- a/src/ViewModels/ExecuteCustomAction.cs +++ b/src/ViewModels/ExecuteCustomAction.cs @@ -10,12 +10,12 @@ namespace SourceGit.ViewModels private set; } - public ExecuteCustomAction(Repository repo, Models.CustomAction action, string sha) + public ExecuteCustomAction(Repository repo, Models.CustomAction action, Models.Commit commit) { _repo = repo; _args = action.Arguments.Replace("${REPO}", _repo.FullPath); - if (!string.IsNullOrEmpty(sha)) - _args = _args.Replace("${SHA}", sha); + if (commit != null) + _args = _args.Replace("${SHA}", commit.SHA); CustomAction = action; View = new Views.ExecuteCustomAction() { DataContext = this }; diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs index fc973948..713e1635 100644 --- a/src/ViewModels/Histories.cs +++ b/src/ViewModels/Histories.cs @@ -626,7 +626,7 @@ namespace SourceGit.ViewModels item.Click += (_, e) => { if (PopupHost.CanCreatePopup()) - PopupHost.ShowAndStartPopup(new ExecuteCustomAction(_repo, action, commit.SHA)); + PopupHost.ShowAndStartPopup(new ExecuteCustomAction(_repo, dup, commit)); e.Handled = true; }; diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index ae24d5ef..9dd5ab9d 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -1310,7 +1310,7 @@ namespace SourceGit.ViewModels item.Click += (_, e) => { if (PopupHost.CanCreatePopup()) - PopupHost.ShowAndStartPopup(new ExecuteCustomAction(this, action, null)); + PopupHost.ShowAndStartPopup(new ExecuteCustomAction(this, dup, null)); e.Handled = true; }; From 174430338c7cc1b7829ffefca835a9711cd01673 Mon Sep 17 00:00:00 2001 From: AquariusStar <48148723+AquariusStar@users.noreply.github.com> Date: Sat, 2 Nov 2024 06:11:48 +0300 Subject: [PATCH 60/68] localiztion: update (#641) --- src/Resources/Locales/ru_RU.axaml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml index da689e1b..d2076099 100644 --- a/src/Resources/Locales/ru_RU.axaml +++ b/src/Resources/Locales/ru_RU.axaml @@ -111,6 +111,7 @@ Сравнить с рабочим деревом Копировать информацию Копировать SHA + Пользовательское действие Интерактивное перемещение ${0}$ сюда Переместить ${0}$ сюда Сбросить ${0}$ сюда @@ -142,6 +143,14 @@ ШАБЛОН ФИКСАЦИИ Имя шаблона: Шаблон содержания: + ПОЛЬЗОВАТЕЛЬСКОЕ ДЕЙСТВИЕ + Аргументы: + ${REPO} - Путь хранилища; ${SHA} - Выбранные фиксации SHA + Исполняемый фалй: + Имя: + Диапазон: + Фиксация + Хранилище Адрес электронной почты Адрес электронной почты GIT @@ -165,7 +174,7 @@ Если «Предпочитаемый сервис» установлен, SourceGit будет использовать только этот хранилище. В противном случае, если доступно более одной услуги, будет отображено контекстное меню для выбора одной из них. HTTP-прокси HTTP-прокси, используемый этим хранилищем - Имя пользовтаеля + Имя пользователя Имя пользователя для этого хранилища Рабочие пространства Имя @@ -256,6 +265,8 @@ Цель: Редактировать выбранную группу Редактировать выбранное хранилище + Выполнить пользовательское действие + Имя действия: Быстрая перемотка вперёд (без проверки) Извлечь Извлечь все внешние хранилища @@ -520,6 +531,8 @@ Очистить всё Настройка этого хранилища ПРОДОЛЖИТЬ + Изменить действия + Не изменять действия Разрешить опцию --reflog Открыть в файловом менеджере Поиск веток, меток и подмодулей From 1fecbbb37f493ebde61b154112f756a8e8cb69b2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 2 Nov 2024 03:12:01 +0000 Subject: [PATCH 61/68] doc: Update translation status and missing keys --- README.md | 2 +- TRANSLATION.md | 16 ++-------------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 9f0d8cae..52383670 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-96.05%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.08%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-87.72%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-90.79%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-98.10%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-96.05%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-97.08%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-87.72%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-90.79%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-100.00%25-brightgreen)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-100.00%25-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-100.00%25-brightgreen)](TRANSLATION.md) ## How to Use diff --git a/TRANSLATION.md b/TRANSLATION.md index 4b22ac57..b6c255a1 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -228,25 +228,13 @@ -### ru_RU.axaml: 98.10% +### ru_RU.axaml: 100.00%
Missing Keys -- Text.CommitCM.CustomAction -- Text.Configure.CustomAction -- Text.Configure.CustomAction.Arguments -- Text.Configure.CustomAction.Arguments.Tip -- Text.Configure.CustomAction.Executable -- Text.Configure.CustomAction.Name -- Text.Configure.CustomAction.Scope -- Text.Configure.CustomAction.Scope.Commit -- Text.Configure.CustomAction.Scope.Repository -- Text.ExecuteCustomAction -- Text.ExecuteCustomAction.Name -- Text.Repository.CustomActions -- Text.Repository.CustomActions.Empty +
From 794163fe1cb80a39e2b62f1abab2385199c4f180 Mon Sep 17 00:00:00 2001 From: Aliaksandr Liakhavets Date: Sun, 3 Nov 2024 04:25:32 +0300 Subject: [PATCH 62/68] Set default focus on password text box (#644) Co-authored-by: AleksandrLiakhavetsEPAM <97155822+AleksandrLiakhavetsEPAM@users.noreply.github.com> --- src/Views/Askpass.axaml | 4 +++- src/Views/Askpass.axaml.cs | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Views/Askpass.axaml b/src/Views/Askpass.axaml index 9a38c58f..e1d257ec 100644 --- a/src/Views/Askpass.axaml +++ b/src/Views/Askpass.axaml @@ -39,9 +39,11 @@ - Date: Sun, 3 Nov 2024 10:58:50 +0800 Subject: [PATCH 63/68] code_review: PR #644 - use `AutoFocusBehaviour.IsEnable` instead of toggle focus by code in `OnOpened ` Signed-off-by: leo --- src/Views/Askpass.axaml | 6 +++--- src/Views/Askpass.axaml.cs | 6 ------ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/Views/Askpass.axaml b/src/Views/Askpass.axaml index e1d257ec..f2308805 100644 --- a/src/Views/Askpass.axaml +++ b/src/Views/Askpass.axaml @@ -39,15 +39,15 @@ - + HorizontalAlignment="Stretch" + v:AutoFocusBehaviour.IsEnabled="True"> Date: Sun, 3 Nov 2024 14:45:19 +0800 Subject: [PATCH 64/68] localization: update zh_TW.axaml (#645) --- src/Resources/Locales/zh_TW.axaml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 4526cce5..77a832ff 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -58,7 +58,7 @@ 刪除所選的 {0} 個分支 捨棄所有變更 快轉 (fast-forward) 到 ${0}$ - 提取(fetch) ${0}$ 至 ${1}$... + 提取 (fetch) ${0}$ 到 ${1}$... Git 工作流 - 完成 ${0}$ 合併 ${0}$ 到 ${1}$... 拉取 (pull) ${0}$ @@ -144,10 +144,10 @@ 範本名稱: 範本內容: 自訂動作 - 指令行參數: - 使用${REPO}代表儲存庫的路徑,${SHA}代表所選的提交編號 + 指令參數: + 使用 ${REPO} 表示存放庫路徑、${SHA} 表示所選的提交編號 可執行檔案路徑: - 名稱 : + 名稱: 執行範圍: 選取的提交 存放庫 @@ -158,20 +158,20 @@ 分鐘 預設遠端存放庫 提交訊息追加署名 (--signoff) - 提取變更时啟用修剪(--prune) + 拉取變更時進行清理 (--prune) Issue 追蹤 新增符合 GitHub Issue 規則 新增符合 Jira 規則 新增符合 GitLab 議題規則 新增符合 GitLab 合併請求規則 新增自訂規則 - 符合 Issue 的正則表達式: + 符合 Issue 的正規表達式: 規則名稱: 為 Issue 產生的網址連結: - 可在網址中使用 $1、$2 等變數填入正則表示式相符的內容 - OPEN AI - 启用特定服务 : - 当【启用特定服务】被设置时,SourceGit将在本仓库中仅使用该服务。否则将弹出可用的OpenAI服务列表供用户选择。 + 可在網址中使用 $1、$2 等變數填入正規表達式相符的內容 + OpenAI + 偏好服務: + 設定 [偏好服務] 後,SourceGit 將於此存放庫中使用該服務,否則會顯示 OpenAI 服務列表供使用者選擇。 HTTP 代理 HTTP 網路代理 使用者名稱 From fba84c82978efcacee91cffbbc455aba331e8e9b Mon Sep 17 00:00:00 2001 From: Chiahong <36815907+ChiahongHong@users.noreply.github.com> Date: Sun, 3 Nov 2024 17:00:17 +0800 Subject: [PATCH 65/68] fix: prevent crash in Custom Action when executable path is missing (#646) --- src/Commands/ExecuteCustomAction.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Commands/ExecuteCustomAction.cs b/src/Commands/ExecuteCustomAction.cs index 0573aed9..253c6b43 100644 --- a/src/Commands/ExecuteCustomAction.cs +++ b/src/Commands/ExecuteCustomAction.cs @@ -45,6 +45,9 @@ namespace SourceGit.Commands try { proc.Start(); + proc.BeginOutputReadLine(); + proc.BeginErrorReadLine(); + proc.WaitForExit(); } catch (Exception e) { @@ -54,9 +57,6 @@ namespace SourceGit.Commands }); } - proc.BeginOutputReadLine(); - proc.BeginErrorReadLine(); - proc.WaitForExit(); proc.Close(); } } From 1d0098703e771d4368821c80bc6179561efc201b Mon Sep 17 00:00:00 2001 From: "Dmitrij D. Czarkoff" Date: Mon, 4 Nov 2024 01:22:16 +0000 Subject: [PATCH 66/68] feature: add support for Visual Studio as external tool (#648) * feature: support Visual Studio external tool on Windows * feature: when opening in Visual Studio, try to locate solution file --- README.md | 1 + src/Models/ExternalTool.cs | 40 ++++++++++++++++++++++++++++++++------ src/Native/Windows.cs | 20 +++++++++++++++++++ 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 52383670..44ed5917 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,7 @@ This app supports open repository in external tools listed in the table below. | JetBrains Fleet | YES | YES | YES | FLEET | | Sublime Text | YES | YES | YES | SUBLIME_TEXT | | Zed | NO | YES | YES | ZED | +| Visual Studio | YES | YES | YES | VISUALSTUDIO | > [!NOTE] > This app will try to find those tools based on some pre-defined or expected locations automatically. If you are using one portable version of these tools, it will not be detected by this app. diff --git a/src/Models/ExternalTool.cs b/src/Models/ExternalTool.cs index b26a9a90..960ebde6 100644 --- a/src/Models/ExternalTool.cs +++ b/src/Models/ExternalTool.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Linq; using System.Text.Json; using System.Text.Json.Serialization; @@ -16,12 +17,14 @@ namespace SourceGit.Models public string Executable { get; private set; } public string OpenCmdArgs { get; private set; } public Bitmap IconImage { get; private set; } = null; + public Func ArgTransform { get; private set; } - public ExternalTool(string name, string icon, string executable, string openCmdArgs) + public ExternalTool(string name, string icon, string executable, string openCmdArgs, Func argsTransform) { Name = name; Executable = executable; OpenCmdArgs = openCmdArgs; + ArgTransform = argsTransform ?? ((s) => s); try { @@ -37,11 +40,16 @@ namespace SourceGit.Models public void Open(string repo) { + string arguments = string.Format(OpenCmdArgs, repo); + + if (ArgTransform != null) + arguments = ArgTransform.Invoke(arguments); + Process.Start(new ProcessStartInfo() { WorkingDirectory = repo, FileName = Executable, - Arguments = string.Format(OpenCmdArgs, repo), + Arguments = arguments, UseShellExecute = false, }); } @@ -110,17 +118,17 @@ namespace SourceGit.Models _customPaths = new ExternalToolPaths(); } - public void TryAdd(string name, string icon, string args, string key, Func finder) + public void TryAdd(string name, string icon, string args, string key, Func finder, Func argsTransform = null) { if (_customPaths.Tools.TryGetValue(key, out var customPath) && File.Exists(customPath)) { - Founded.Add(new ExternalTool(name, icon, customPath, args)); + Founded.Add(new ExternalTool(name, icon, customPath, args, argsTransform)); } else { var path = finder(); if (!string.IsNullOrEmpty(path) && File.Exists(path)) - Founded.Add(new ExternalTool(name, icon, path, args)); + Founded.Add(new ExternalTool(name, icon, path, args, argsTransform)); } } @@ -154,6 +162,25 @@ namespace SourceGit.Models TryAdd("Zed", "zed", "\"{0}\"", "ZED", platformFinder); } + public void VisualStudio(Func platformFinder) + { + TryAdd("Visual Studio", "vs", "\"{0}\"", "VISUALSTUDIO", platformFinder, VisualStudioTryFindSolution); + } + + private static string VisualStudioTryFindSolution(string path) + { + try + { + if (Directory.GetFiles(path.Trim('\"'), "*.sln", SearchOption.AllDirectories).FirstOrDefault() is string solutionPath) + return Path.GetFullPath(solutionPath); + } + catch + { + // do nothing + } + return path; + } + public void FindJetBrainsFromToolbox(Func platformFinder) { var exclude = new List { "fleet", "dotmemory", "dottrace", "resharper-u", "androidstudio" }; @@ -171,7 +198,8 @@ namespace SourceGit.Models $"{tool.DisplayName} {tool.DisplayVersion}", supported_icons.Contains(tool.ProductCode) ? $"JetBrains/{tool.ProductCode}" : "JetBrains/JB", Path.Combine(tool.InstallLocation, tool.LaunchCommand), - "\"{0}\"")); + "\"{0}\"", + null)); } } } diff --git a/src/Native/Windows.cs b/src/Native/Windows.cs index 6ca0bbb0..0563644c 100644 --- a/src/Native/Windows.cs +++ b/src/Native/Windows.cs @@ -134,6 +134,7 @@ namespace SourceGit.Native finder.Fleet(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\Programs\\Fleet\\Fleet.exe"); finder.FindJetBrainsFromToolbox(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\JetBrains\\Toolbox"); finder.SublimeText(FindSublimeText); + finder.VisualStudio(FindVisualStudio); return finder.Founded; } @@ -313,6 +314,25 @@ namespace SourceGit.Native return string.Empty; } + + private string FindVisualStudio() + { + var localMachine = Microsoft.Win32.RegistryKey.OpenBaseKey( + Microsoft.Win32.RegistryHive.LocalMachine, + Microsoft.Win32.RegistryView.Registry64); + + // Get default class for VisualStudio.Launcher.sln - the handler for *.sln files + if (localMachine.OpenSubKey(@"SOFTWARE\Classes\VisualStudio.Launcher.sln\CLSID") is Microsoft.Win32.RegistryKey launcher) + { + // Get actual path to the executable + if (launcher.GetValue(string.Empty) is string CLSID && localMachine.OpenSubKey(@$"SOFTWARE\Classes\CLSID\{CLSID}\LocalServer32") is Microsoft.Win32.RegistryKey devenv && devenv.GetValue(string.Empty) is string localServer32) + { + return localServer32!.Trim('\"'); + } + } + + return string.Empty; + } #endregion private void OpenFolderAndSelectFile(string folderPath) From 6b348fbd1a9ecc9f42fc0247ef508de96cadf346 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 4 Nov 2024 10:02:20 +0800 Subject: [PATCH 67/68] code_review!: PR #648 * rewrite `Models.ExternalTool` to use `_execArgsGenerator` instead of `OpenCmdArgs` and `ArgTransform` * remove dependency of `System.Linq` due to AOT limitations * since the `Visual Studio` is only available on Windows, use `TryAdd` directly. * update `README.md` BREAKING CHANGE: now the key in `external_editors.json` uses the same name with external tool. Signed-off-by: leo --- README.md | 20 ++++++------ src/Models/ExternalTool.cs | 66 +++++++++++--------------------------- src/Native/Windows.cs | 32 ++++++++++++++++-- 3 files changed, 59 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 44ed5917..6a688d99 100644 --- a/README.md +++ b/README.md @@ -119,15 +119,15 @@ For other AI service: This app supports open repository in external tools listed in the table below. -| Tool | Windows | macOS | Linux | KEY IN `external_editors.json` | -|-------------------------------|---------|-------|-------|--------------------------------| -| Visual Studio Code | YES | YES | YES | VSCODE | -| Visual Studio Code - Insiders | YES | YES | YES | VSCODE_INSIDERS | -| VSCodium | YES | YES | YES | VSCODIUM | -| JetBrains Fleet | YES | YES | YES | FLEET | -| Sublime Text | YES | YES | YES | SUBLIME_TEXT | -| Zed | NO | YES | YES | ZED | -| Visual Studio | YES | YES | YES | VISUALSTUDIO | +| Tool | Windows | macOS | Linux | +|-------------------------------|---------|-------|-------| +| Visual Studio Code | YES | YES | YES | +| Visual Studio Code - Insiders | YES | YES | YES | +| VSCodium | YES | YES | YES | +| Fleet | YES | YES | YES | +| Sublime Text | YES | YES | YES | +| Zed | NO | YES | YES | +| Visual Studio | YES | NO | NO | > [!NOTE] > This app will try to find those tools based on some pre-defined or expected locations automatically. If you are using one portable version of these tools, it will not be detected by this app. @@ -135,7 +135,7 @@ This app supports open repository in external tools listed in the table below. ```json { "tools": { - "VSCODE": "D:\\VSCode\\Code.exe" + "Visual Studio Code": "D:\\VSCode\\Code.exe" } } ``` diff --git a/src/Models/ExternalTool.cs b/src/Models/ExternalTool.cs index 960ebde6..103e91bc 100644 --- a/src/Models/ExternalTool.cs +++ b/src/Models/ExternalTool.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Linq; using System.Text.Json; using System.Text.Json.Serialization; @@ -14,17 +13,13 @@ namespace SourceGit.Models public class ExternalTool { public string Name { get; private set; } - public string Executable { get; private set; } - public string OpenCmdArgs { get; private set; } public Bitmap IconImage { get; private set; } = null; - public Func ArgTransform { get; private set; } - public ExternalTool(string name, string icon, string executable, string openCmdArgs, Func argsTransform) + public ExternalTool(string name, string icon, string execFile, Func execArgsGenerator = null) { Name = name; - Executable = executable; - OpenCmdArgs = openCmdArgs; - ArgTransform = argsTransform ?? ((s) => s); + _execFile = execFile; + _execArgsGenerator = execArgsGenerator ?? (repo => $"\"{repo}\""); try { @@ -40,19 +35,17 @@ namespace SourceGit.Models public void Open(string repo) { - string arguments = string.Format(OpenCmdArgs, repo); - - if (ArgTransform != null) - arguments = ArgTransform.Invoke(arguments); - Process.Start(new ProcessStartInfo() { WorkingDirectory = repo, - FileName = Executable, - Arguments = arguments, + FileName = _execFile, + Arguments = _execArgsGenerator.Invoke(repo), UseShellExecute = false, }); } + + private string _execFile = string.Empty; + private Func _execArgsGenerator = null; } public class JetBrainsState @@ -118,67 +111,48 @@ namespace SourceGit.Models _customPaths = new ExternalToolPaths(); } - public void TryAdd(string name, string icon, string args, string key, Func finder, Func argsTransform = null) + public void TryAdd(string name, string icon, Func finder, Func execArgsGenerator = null) { - if (_customPaths.Tools.TryGetValue(key, out var customPath) && File.Exists(customPath)) + if (_customPaths.Tools.TryGetValue(name, out var customPath) && File.Exists(customPath)) { - Founded.Add(new ExternalTool(name, icon, customPath, args, argsTransform)); + Founded.Add(new ExternalTool(name, icon, customPath, execArgsGenerator)); } else { var path = finder(); if (!string.IsNullOrEmpty(path) && File.Exists(path)) - Founded.Add(new ExternalTool(name, icon, path, args, argsTransform)); + Founded.Add(new ExternalTool(name, icon, path, execArgsGenerator)); } } public void VSCode(Func platformFinder) { - TryAdd("Visual Studio Code", "vscode", "\"{0}\"", "VSCODE", platformFinder); + TryAdd("Visual Studio Code", "vscode", platformFinder); } public void VSCodeInsiders(Func platformFinder) { - TryAdd("Visual Studio Code - Insiders", "vscode_insiders", "\"{0}\"", "VSCODE_INSIDERS", platformFinder); + TryAdd("Visual Studio Code - Insiders", "vscode_insiders", platformFinder); } public void VSCodium(Func platformFinder) { - TryAdd("VSCodium", "codium", "\"{0}\"", "VSCODIUM", platformFinder); + TryAdd("VSCodium", "codium", platformFinder); } public void Fleet(Func platformFinder) { - TryAdd("Fleet", "fleet", "\"{0}\"", "FLEET", platformFinder); + TryAdd("Fleet", "fleet", platformFinder); } public void SublimeText(Func platformFinder) { - TryAdd("Sublime Text", "sublime_text", "\"{0}\"", "SUBLIME_TEXT", platformFinder); + TryAdd("Sublime Text", "sublime_text", platformFinder); } public void Zed(Func platformFinder) { - TryAdd("Zed", "zed", "\"{0}\"", "ZED", platformFinder); - } - - public void VisualStudio(Func platformFinder) - { - TryAdd("Visual Studio", "vs", "\"{0}\"", "VISUALSTUDIO", platformFinder, VisualStudioTryFindSolution); - } - - private static string VisualStudioTryFindSolution(string path) - { - try - { - if (Directory.GetFiles(path.Trim('\"'), "*.sln", SearchOption.AllDirectories).FirstOrDefault() is string solutionPath) - return Path.GetFullPath(solutionPath); - } - catch - { - // do nothing - } - return path; + TryAdd("Zed", "zed", platformFinder); } public void FindJetBrainsFromToolbox(Func platformFinder) @@ -197,9 +171,7 @@ namespace SourceGit.Models Founded.Add(new ExternalTool( $"{tool.DisplayName} {tool.DisplayVersion}", supported_icons.Contains(tool.ProductCode) ? $"JetBrains/{tool.ProductCode}" : "JetBrains/JB", - Path.Combine(tool.InstallLocation, tool.LaunchCommand), - "\"{0}\"", - null)); + Path.Combine(tool.InstallLocation, tool.LaunchCommand))); } } } diff --git a/src/Native/Windows.cs b/src/Native/Windows.cs index 0563644c..a57d26d2 100644 --- a/src/Native/Windows.cs +++ b/src/Native/Windows.cs @@ -134,7 +134,7 @@ namespace SourceGit.Native finder.Fleet(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\Programs\\Fleet\\Fleet.exe"); finder.FindJetBrainsFromToolbox(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\JetBrains\\Toolbox"); finder.SublimeText(FindSublimeText); - finder.VisualStudio(FindVisualStudio); + finder.TryAdd("Visual Studio", "vs", FindVisualStudio, GenerateCommandlineArgsForVisualStudio); return finder.Founded; } @@ -325,7 +325,9 @@ namespace SourceGit.Native if (localMachine.OpenSubKey(@"SOFTWARE\Classes\VisualStudio.Launcher.sln\CLSID") is Microsoft.Win32.RegistryKey launcher) { // Get actual path to the executable - if (launcher.GetValue(string.Empty) is string CLSID && localMachine.OpenSubKey(@$"SOFTWARE\Classes\CLSID\{CLSID}\LocalServer32") is Microsoft.Win32.RegistryKey devenv && devenv.GetValue(string.Empty) is string localServer32) + if (launcher.GetValue(string.Empty) is string CLSID && + localMachine.OpenSubKey(@$"SOFTWARE\Classes\CLSID\{CLSID}\LocalServer32") is Microsoft.Win32.RegistryKey devenv && + devenv.GetValue(string.Empty) is string localServer32) { return localServer32!.Trim('\"'); } @@ -348,5 +350,31 @@ namespace SourceGit.Native ILFree(pidl); } } + + private string GenerateCommandlineArgsForVisualStudio(string repo) + { + var sln = FindVSSolutionFile(repo, 4); + return string.IsNullOrEmpty(sln) ? $"\"{repo}\"" : $"\"{sln}\""; + } + + private string FindVSSolutionFile(string path, int leftDepth) + { + var found = Directory.GetFiles(path, "*.sln", SearchOption.TopDirectoryOnly); + if (found != null && found.Length > 0) + return Path.GetFullPath(found[0]); + + if (leftDepth <= 0) + return null; + + var subfolders = Directory.GetDirectories(path); + foreach (var subfolder in subfolders) + { + var first = FindVSSolutionFile(subfolder, leftDepth - 1); + if (!string.IsNullOrEmpty(first)) + return first; + } + + return null; + } } } From 5966b8ac08c2b53e5e956ab69df906c186bcc65c Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 4 Nov 2024 10:06:51 +0800 Subject: [PATCH 68/68] version: Release 8.37 Signed-off-by: leo --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index f42a1bc8..a5e93156 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.36 \ No newline at end of file +8.37 \ No newline at end of file