From 0641a2223075b66b5f362a2b40a38670021af669 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 26 May 2025 12:28:00 +0800 Subject: [PATCH 01/35] feature: allow to reset author when `--amend` is enabled for committing --- src/Commands/Commit.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/Reword.cs | 4 +++- src/ViewModels/Squash.cs | 3 ++- src/ViewModels/WorkingCopy.cs | 11 ++++++++++- src/Views/WorkingCopy.axaml | 23 +++++++++++++++++------ 8 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/Commands/Commit.cs b/src/Commands/Commit.cs index 5be08cef..17410bc9 100644 --- a/src/Commands/Commit.cs +++ b/src/Commands/Commit.cs @@ -4,7 +4,7 @@ namespace SourceGit.Commands { public class Commit : Command { - public Commit(string repo, string message, bool amend, bool signOff) + public Commit(string repo, string message, bool signOff, bool amend, bool resetAuthor) { _tmpFile = Path.GetTempFileName(); File.WriteAllText(_tmpFile, message); @@ -12,10 +12,10 @@ namespace SourceGit.Commands WorkingDirectory = repo; Context = repo; Args = $"commit --allow-empty --file=\"{_tmpFile}\""; - if (amend) - Args += " --amend --no-edit"; if (signOff) Args += " --signoff"; + if (amend) + Args += resetAuthor ? " --amend --reset-author --no-edit" : " --amend --no-edit"; } public bool Run() diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index c12396ec..07ebc675 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -781,6 +781,7 @@ INCLUDE UNTRACKED FILES NO RECENT INPUT MESSAGES NO COMMIT TEMPLATES + Reset Author Right-click the selected file(s), and make your choice to resolve conflicts. SignOff STAGED diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 00939656..2703f5a2 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -785,6 +785,7 @@ 显示未跟踪文件 没有提交信息记录 没有可应用的提交信息模板 + 重置提交者 请选中冲突文件,打开右键菜单,选择合适的解决方式 署名 已暂存 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 026a41ed..f810ea15 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -785,6 +785,7 @@ 顯示未追蹤檔案 沒有提交訊息記錄 沒有可套用的提交訊息範本 + 重設作者 請選擇發生衝突的檔案,開啟右鍵選單,選擇合適的解決方式 署名 已暫存 diff --git a/src/ViewModels/Reword.cs b/src/ViewModels/Reword.cs index 82fa3169..72dd9e58 100644 --- a/src/ViewModels/Reword.cs +++ b/src/ViewModels/Reword.cs @@ -37,9 +37,11 @@ namespace SourceGit.ViewModels var log = _repo.CreateLog("Reword HEAD"); Use(log); + var signOff = _repo.Settings.EnableSignOffForCommit; return Task.Run(() => { - var succ = new Commands.Commit(_repo.FullPath, _message, true, _repo.Settings.EnableSignOffForCommit).Use(log).Run(); + // For reword (only changes the commit message), disable `--reset-author` + var succ = new Commands.Commit(_repo.FullPath, _message, signOff, true, false).Use(log).Run(); log.Complete(); CallUIThread(() => _repo.SetWatcherEnabled(true)); return succ; diff --git a/src/ViewModels/Squash.cs b/src/ViewModels/Squash.cs index fa9d98e1..0d680d20 100644 --- a/src/ViewModels/Squash.cs +++ b/src/ViewModels/Squash.cs @@ -34,6 +34,7 @@ namespace SourceGit.ViewModels return Task.Run(() => { + var signOff = _repo.Settings.EnableSignOffForCommit; var autoStashed = false; var succ = false; @@ -52,7 +53,7 @@ namespace SourceGit.ViewModels succ = new Commands.Reset(_repo.FullPath, Target.SHA, "--soft").Use(log).Exec(); if (succ) - succ = new Commands.Commit(_repo.FullPath, _message, true, _repo.Settings.EnableSignOffForCommit).Use(log).Run(); + succ = new Commands.Commit(_repo.FullPath, _message, signOff, true, true).Use(log).Run(); if (succ && autoStashed) new Commands.Stash(_repo.FullPath).Use(log).Pop("stash@{0}"); diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 7c2d95f9..64c7b31d 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -91,6 +91,7 @@ namespace SourceGit.ViewModels else { CommitMessage = string.Empty; + ResetAuthor = false; } Staged = GetStagedChanges(); @@ -100,6 +101,12 @@ namespace SourceGit.ViewModels } } + public bool ResetAuthor + { + get => _resetAuthor; + set => SetProperty(ref _resetAuthor, value); + } + public string Filter { get => _filter; @@ -1717,6 +1724,7 @@ namespace SourceGit.ViewModels _repo.Settings.PushCommitMessage(_commitMessage); _repo.SetWatcherEnabled(false); + var signOff = _repo.Settings.EnableSignOffForCommit; var log = _repo.CreateLog("Commit"); Task.Run(() => { @@ -1725,7 +1733,7 @@ namespace SourceGit.ViewModels succ = new Commands.Add(_repo.FullPath, _repo.IncludeUntracked).Use(log).Exec(); if (succ) - succ = new Commands.Commit(_repo.FullPath, _commitMessage, _useAmend, _repo.Settings.EnableSignOffForCommit).Use(log).Run(); + succ = new Commands.Commit(_repo.FullPath, _commitMessage, signOff, _useAmend, _resetAuthor).Use(log).Run(); log.Complete(); @@ -1785,6 +1793,7 @@ namespace SourceGit.ViewModels private bool _isUnstaging = false; private bool _isCommitting = false; private bool _useAmend = false; + private bool _resetAuthor = false; private bool _hasRemotes = false; private List _cached = []; private List _unstaged = []; diff --git a/src/Views/WorkingCopy.axaml b/src/Views/WorkingCopy.axaml index ee8619f3..8c600956 100644 --- a/src/Views/WorkingCopy.axaml +++ b/src/Views/WorkingCopy.axaml @@ -235,7 +235,7 @@ - + - + + - - - - + + diff --git a/src/Views/StashesPage.axaml b/src/Views/StashesPage.axaml index 27305aac..15427b93 100644 --- a/src/Views/StashesPage.axaml +++ b/src/Views/StashesPage.axaml @@ -19,20 +19,12 @@ - + - From 3437f5f4a95dfded9fb8d721aa9f3763058ada67 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 28 May 2025 02:19:23 +0000 Subject: [PATCH 08/35] doc: Update translation status and sort locale files --- TRANSLATION.md | 27 ++++++++++++++++++--------- src/Resources/Locales/ta_IN.axaml | 2 +- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/TRANSLATION.md b/TRANSLATION.md index 9df04a52..a6789484 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -6,7 +6,7 @@ This document shows the translation status of each locale file in the repository ### ![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen) -### ![de__DE](https://img.shields.io/badge/de__DE-96.63%25-yellow) +### ![de__DE](https://img.shields.io/badge/de__DE-96.50%25-yellow)
Missing keys in de_DE.axaml @@ -26,6 +26,7 @@ This document shows the translation status of each locale file in the repository - Text.Launcher.Workspaces - Text.Launcher.Pages - Text.Pull.RecurseSubmodules +- Text.Repository.ClearStashes - Text.Repository.ShowSubmodulesAsTree - Text.ResetWithoutCheckout - Text.ResetWithoutCheckout.MoveTo @@ -41,17 +42,18 @@ This document shows the translation status of each locale file in the repository
-### ![es__ES](https://img.shields.io/badge/es__ES-99.75%25-yellow) +### ![es__ES](https://img.shields.io/badge/es__ES-99.63%25-yellow)
Missing keys in es_ES.axaml - Text.CreateBranch.OverwriteExisting +- Text.Repository.ClearStashes - Text.WorkingCopy.ResetAuthor
-### ![fr__FR](https://img.shields.io/badge/fr__FR-92.50%25-yellow) +### ![fr__FR](https://img.shields.io/badge/fr__FR-92.38%25-yellow)
Missing keys in fr_FR.axaml @@ -92,6 +94,7 @@ This document shows the translation status of each locale file in the repository - Text.Repository.BranchSort - Text.Repository.BranchSort.ByCommitterDate - Text.Repository.BranchSort.ByName +- Text.Repository.ClearStashes - Text.Repository.Search.ByContent - Text.Repository.ShowSubmodulesAsTree - Text.Repository.ViewLogs @@ -119,7 +122,7 @@ This document shows the translation status of each locale file in the repository
-### ![it__IT](https://img.shields.io/badge/it__IT-97.88%25-yellow) +### ![it__IT](https://img.shields.io/badge/it__IT-97.75%25-yellow)
Missing keys in it_IT.axaml @@ -136,6 +139,7 @@ This document shows the translation status of each locale file in the repository - Text.Launcher.Workspaces - Text.Launcher.Pages - Text.Pull.RecurseSubmodules +- Text.Repository.ClearStashes - Text.ResetWithoutCheckout - Text.ResetWithoutCheckout.MoveTo - Text.ResetWithoutCheckout.Target @@ -144,7 +148,7 @@ This document shows the translation status of each locale file in the repository
-### ![ja__JP](https://img.shields.io/badge/ja__JP-92.25%25-yellow) +### ![ja__JP](https://img.shields.io/badge/ja__JP-92.13%25-yellow)
Missing keys in ja_JP.axaml @@ -185,6 +189,7 @@ This document shows the translation status of each locale file in the repository - Text.Repository.BranchSort - Text.Repository.BranchSort.ByCommitterDate - Text.Repository.BranchSort.ByName +- Text.Repository.ClearStashes - Text.Repository.FilterCommits - Text.Repository.Search.ByContent - Text.Repository.ShowSubmodulesAsTree @@ -214,7 +219,7 @@ This document shows the translation status of each locale file in the repository
-### ![pt__BR](https://img.shields.io/badge/pt__BR-84.13%25-yellow) +### ![pt__BR](https://img.shields.io/badge/pt__BR-84.02%25-yellow)
Missing keys in pt_BR.axaml @@ -299,6 +304,7 @@ This document shows the translation status of each locale file in the repository - Text.Repository.BranchSort - Text.Repository.BranchSort.ByCommitterDate - Text.Repository.BranchSort.ByName +- Text.Repository.ClearStashes - Text.Repository.FilterCommits - Text.Repository.HistoriesLayout - Text.Repository.HistoriesLayout.Horizontal @@ -349,16 +355,17 @@ This document shows the translation status of each locale file in the repository
-### ![ru__RU](https://img.shields.io/badge/ru__RU-99.88%25-yellow) +### ![ru__RU](https://img.shields.io/badge/ru__RU-99.75%25-yellow)
Missing keys in ru_RU.axaml +- Text.Repository.ClearStashes - Text.WorkingCopy.ResetAuthor
-### ![ta__IN](https://img.shields.io/badge/ta__IN-92.50%25-yellow) +### ![ta__IN](https://img.shields.io/badge/ta__IN-92.38%25-yellow)
Missing keys in ta_IN.axaml @@ -399,6 +406,7 @@ This document shows the translation status of each locale file in the repository - Text.Repository.BranchSort - Text.Repository.BranchSort.ByCommitterDate - Text.Repository.BranchSort.ByName +- Text.Repository.ClearStashes - Text.Repository.Search.ByContent - Text.Repository.ShowSubmodulesAsTree - Text.Repository.ViewLogs @@ -426,7 +434,7 @@ This document shows the translation status of each locale file in the repository
-### ![uk__UA](https://img.shields.io/badge/uk__UA-93.63%25-yellow) +### ![uk__UA](https://img.shields.io/badge/uk__UA-93.51%25-yellow)
Missing keys in uk_UA.axaml @@ -463,6 +471,7 @@ This document shows the translation status of each locale file in the repository - Text.Repository.BranchSort - Text.Repository.BranchSort.ByCommitterDate - Text.Repository.BranchSort.ByName +- Text.Repository.ClearStashes - Text.Repository.Search.ByContent - Text.Repository.ShowSubmodulesAsTree - Text.Repository.ViewLogs diff --git a/src/Resources/Locales/ta_IN.axaml b/src/Resources/Locales/ta_IN.axaml index 685434a1..f7d7f405 100644 --- a/src/Resources/Locales/ta_IN.axaml +++ b/src/Resources/Locales/ta_IN.axaml @@ -561,9 +561,9 @@ தொடர்க தனிப்பயன் செயல்கள் தனிப்பயன் செயல்கள் இல்லை + எல்லா மாற்றங்களையும் நிராகரி '--குறிபதிவு' விருப்பத்தை இயக்கு கோப்பு உலாவியில் திற - எல்லா மாற்றங்களையும் நிராகரி கிளைகள்/குறிச்சொற்கள்/துணைத் தொகுதிகளைத் தேடு வரைபடத்தில் தெரிவுநிலை அமைவை நீக்கு From fbc8edcc13a336a674d2c46077462de5e1eda3f0 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 28 May 2025 14:20:31 +0800 Subject: [PATCH 09/35] feature: show conflict reason Signed-off-by: leo --- src/Commands/QueryLocalChanges.cs | 20 ++++++++++ src/Models/Change.cs | 14 +++++++ src/ViewModels/Conflict.cs | 66 ++++++++++++++++++++++++++++++- src/Views/Conflict.axaml | 12 +++++- 4 files changed, 108 insertions(+), 4 deletions(-) diff --git a/src/Commands/QueryLocalChanges.cs b/src/Commands/QueryLocalChanges.cs index 9abf433e..db29531a 100644 --- a/src/Commands/QueryLocalChanges.cs +++ b/src/Commands/QueryLocalChanges.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text.RegularExpressions; + using Avalonia.Threading; namespace SourceGit.Commands @@ -128,12 +129,31 @@ namespace SourceGit.Commands change.Set(Models.ChangeState.Deleted, Models.ChangeState.Copied); break; case "DD": + change.ConflictReason = Models.ConflictReason.BothDeleted; + change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted); + break; case "AU": + change.ConflictReason = Models.ConflictReason.AddedByUs; + change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted); + break; case "UD": + change.ConflictReason = Models.ConflictReason.DeletedByThem; + change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted); + break; case "UA": + change.ConflictReason = Models.ConflictReason.AddedByThem; + change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted); + break; case "DU": + change.ConflictReason = Models.ConflictReason.DeletedByUs; + change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted); + break; case "AA": + change.ConflictReason = Models.ConflictReason.BothAdded; + change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted); + break; case "UU": + change.ConflictReason = Models.ConflictReason.BothModified; change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted); break; case "??": diff --git a/src/Models/Change.cs b/src/Models/Change.cs index 7d772d3e..4e0e23ae 100644 --- a/src/Models/Change.cs +++ b/src/Models/Change.cs @@ -22,6 +22,18 @@ namespace SourceGit.Models Conflicted, } + public enum ConflictReason + { + None, + BothDeleted, + AddedByUs, + DeletedByThem, + AddedByThem, + DeletedByUs, + BothAdded, + BothModified, + } + public class ChangeDataForAmend { public string FileMode { get; set; } = ""; @@ -36,6 +48,8 @@ namespace SourceGit.Models public string Path { get; set; } = ""; public string OriginalPath { get; set; } = ""; public ChangeDataForAmend DataForAmend { get; set; } = null; + public ConflictReason ConflictReason { get; set; } = ConflictReason.None; + public bool IsSubmodule { get; set; } = false; public bool IsConflicted => WorkTree == ChangeState.Conflicted; public void Set(ChangeState index, ChangeState workTree = ChangeState.None) diff --git a/src/ViewModels/Conflict.cs b/src/ViewModels/Conflict.cs index add365a3..db6492cc 100644 --- a/src/ViewModels/Conflict.cs +++ b/src/ViewModels/Conflict.cs @@ -25,6 +25,18 @@ namespace SourceGit.ViewModels public class Conflict { + public string Marker + { + get; + private set; + } + + public string Description + { + get; + private set; + } + public object Theirs { get; @@ -41,7 +53,13 @@ namespace SourceGit.ViewModels { get; private set; - } + } = false; + + public bool CanUseExternalMergeTool + { + get; + private set; + } = false; public Conflict(Repository repo, WorkingCopy wc, Models.Change change) { @@ -49,7 +67,51 @@ namespace SourceGit.ViewModels _change = change; var isSubmodule = repo.Submodules.Find(x => x.Path.Equals(change.Path, StringComparison.Ordinal)) != null; - IsResolved = !isSubmodule && new Commands.IsConflictResolved(repo.FullPath, change).Result(); + switch (change.ConflictReason) + { + case Models.ConflictReason.BothDeleted: + Marker = "DD"; + Description = "Both deleted"; + break; + case Models.ConflictReason.AddedByUs: + Marker = "AU"; + Description = "Added by us"; + break; + case Models.ConflictReason.DeletedByThem: + Marker = "UD"; + Description = "Deleted by them"; + break; + case Models.ConflictReason.AddedByThem: + Marker = "UA"; + Description = "Added by them"; + break; + case Models.ConflictReason.DeletedByUs: + Marker = "DU"; + Description = "Deleted by us"; + break; + case Models.ConflictReason.BothAdded: + Marker = "AA"; + Description = "Both added"; + if (!isSubmodule) + { + CanUseExternalMergeTool = true; + IsResolved = new Commands.IsConflictResolved(repo.FullPath, change).Result(); + } + break; + case Models.ConflictReason.BothModified: + Marker = "UU"; + Description = "Both modified"; + if (!isSubmodule) + { + CanUseExternalMergeTool = true; + IsResolved = new Commands.IsConflictResolved(repo.FullPath, change).Result(); + } + break; + default: + Marker = string.Empty; + Description = string.Empty; + break; + } var context = wc.InProgressContext; if (context is CherryPickInProgress cherryPick) diff --git a/src/Views/Conflict.axaml b/src/Views/Conflict.axaml index 6e8aceb3..a324b50f 100644 --- a/src/Views/Conflict.axaml +++ b/src/Views/Conflict.axaml @@ -14,7 +14,15 @@ - + + + + + + + + + @@ -117,7 +125,7 @@ -
-### ![ja__JP](https://img.shields.io/badge/ja__JP-92.13%25-yellow) +### ![ja__JP](https://img.shields.io/badge/ja__JP-92.01%25-yellow)
Missing keys in ja_JP.axaml @@ -160,6 +160,7 @@ This document shows the translation status of each locale file in the repository - Text.Bisect.Good - Text.Bisect.Skip - Text.Bisect.WaitingForRange +- Text.BranchCM.CompareWithCurrent - Text.BranchCM.ResetToSelectedCommit - Text.Checkout.RecurseSubmodules - Text.CommitCM.CopyAuthor @@ -355,17 +356,18 @@ This document shows the translation status of each locale file in the repository
-### ![ru__RU](https://img.shields.io/badge/ru__RU-99.75%25-yellow) +### ![ru__RU](https://img.shields.io/badge/ru__RU-99.63%25-yellow)
Missing keys in ru_RU.axaml +- Text.BranchCM.CompareWithCurrent - Text.Repository.ClearStashes - Text.WorkingCopy.ResetAuthor
-### ![ta__IN](https://img.shields.io/badge/ta__IN-92.38%25-yellow) +### ![ta__IN](https://img.shields.io/badge/ta__IN-92.26%25-yellow)
Missing keys in ta_IN.axaml @@ -377,6 +379,7 @@ This document shows the translation status of each locale file in the repository - Text.Bisect.Good - Text.Bisect.Skip - Text.Bisect.WaitingForRange +- Text.BranchCM.CompareWithCurrent - Text.BranchCM.ResetToSelectedCommit - Text.Checkout.RecurseSubmodules - Text.CommitCM.CopyAuthor From a9734ea8e961de4cf5100b4f5cad692299c6eeee Mon Sep 17 00:00:00 2001 From: leo Date: Sat, 31 May 2025 11:33:22 +0800 Subject: [PATCH 21/35] code_style: remove unused code Signed-off-by: leo --- src/Commands/QueryLocalChanges.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Commands/QueryLocalChanges.cs b/src/Commands/QueryLocalChanges.cs index db29531a..788ed617 100644 --- a/src/Commands/QueryLocalChanges.cs +++ b/src/Commands/QueryLocalChanges.cs @@ -122,12 +122,6 @@ namespace SourceGit.Commands case "CD": change.Set(Models.ChangeState.Copied, Models.ChangeState.Deleted); break; - case "DR": - change.Set(Models.ChangeState.Deleted, Models.ChangeState.Renamed); - break; - case "DC": - change.Set(Models.ChangeState.Deleted, Models.ChangeState.Copied); - break; case "DD": change.ConflictReason = Models.ConflictReason.BothDeleted; change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted); From 8e5d5b946e49e201b91a0394f635ea97d305f072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20J=2E=20Mart=C3=ADnez=20M=2E?= <56406225+jjesus-dev@users.noreply.github.com> Date: Fri, 30 May 2025 22:15:06 -0600 Subject: [PATCH 22/35] localization: update spanish translations (#1379) add missing translations --- 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 fcbefcd8..d2d7c071 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -220,6 +220,7 @@ Introduzca el nombre de la rama. Los espacios serán reemplazados con guiones. Crear Rama Local + Sobrescribir la rama existente Crear Etiqueta... Nueva Etiqueta En: Firma GPG @@ -592,6 +593,7 @@ Limpiar (GC & Prune) Ejecutar comando `git gc` para este repositorio. Limpiar todo + Limpiar Configurar este repositorio CONTINUAR Acciones Personalizadas @@ -784,6 +786,7 @@ INCLUIR ARCHIVOS NO RASTREADOS NO HAY MENSAJES DE ENTRADA RECIENTES NO HAY PLANTILLAS DE COMMIT + Restablecer Autor Haz clic derecho en el(los) archivo(s) seleccionado(s) y elige tu opción para resolver conflictos. Firmar STAGED From b94f26a9372b4b67ff229a034d7afac198181200 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 31 May 2025 04:15:23 +0000 Subject: [PATCH 23/35] doc: Update translation status and sort locale files --- TRANSLATION.md | 11 +---------- src/Resources/Locales/es_ES.axaml | 2 +- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/TRANSLATION.md b/TRANSLATION.md index ae66ddf5..94ff684b 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -42,16 +42,7 @@ This document shows the translation status of each locale file in the repository
-### ![es__ES](https://img.shields.io/badge/es__ES-99.63%25-yellow) - -
-Missing keys in es_ES.axaml - -- Text.CreateBranch.OverwriteExisting -- Text.Repository.ClearStashes -- Text.WorkingCopy.ResetAuthor - -
+### ![es__ES](https://img.shields.io/badge/es__ES-%E2%88%9A-brightgreen) ### ![fr__FR](https://img.shields.io/badge/fr__FR-92.38%25-yellow) diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index d2d7c071..0a558dfa 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -220,7 +220,7 @@ Introduzca el nombre de la rama. Los espacios serán reemplazados con guiones. Crear Rama Local - Sobrescribir la rama existente + Sobrescribir la rama existente Crear Etiqueta... Nueva Etiqueta En: Firma GPG From dd432c63e85eada01f8afb7c55bf8217568b51b8 Mon Sep 17 00:00:00 2001 From: leo Date: Sat, 31 May 2025 18:52:15 +0800 Subject: [PATCH 24/35] enhance: when counting commits in `Statistics`, if the authors have the same e-mail address, the commits are considered to be from the same person (#1380) Signed-off-by: leo --- src/Models/Statistics.cs | 53 +++++++++++++++++++++----------------- src/Views/Statistics.axaml | 4 ++- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/Models/Statistics.cs b/src/Models/Statistics.cs index d982a3ed..d6f5870d 100644 --- a/src/Models/Statistics.cs +++ b/src/Models/Statistics.cs @@ -26,25 +26,23 @@ namespace SourceGit.Models public class StatisticsReport { - public static readonly string[] WEEKDAYS = ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"]; - public int Total { get; set; } = 0; - public List Authors { get; set; } = new List(); - public List Series { get; set; } = new List(); - public List XAxes { get; set; } = new List(); - public List YAxes { get; set; } = new List(); + public List Authors { get; set; } = new(); + public List Series { get; set; } = new(); + public List XAxes { get; set; } = new(); + public List YAxes { get; set; } = new(); public StatisticsAuthor SelectedAuthor { get => _selectedAuthor; set => ChangeAuthor(value); } public StatisticsReport(StatisticsMode mode, DateTime start) { _mode = mode; - YAxes = [new Axis() + YAxes.Add(new Axis() { TextSize = 10, MinLimit = 0, SeparatorsPaint = new SolidColorPaint(new SKColor(0x40808080)) { StrokeThickness = 1 } - }]; + }); if (mode == StatisticsMode.ThisWeek) { @@ -72,7 +70,7 @@ namespace SourceGit.Models { Total++; - var normalized = DateTime.MinValue; + DateTime normalized; if (_mode == StatisticsMode.ThisWeek || _mode == StatisticsMode.ThisMonth) normalized = time.Date; else @@ -172,26 +170,27 @@ namespace SourceGit.Models ChangeColor(_fillColor); } - private StatisticsMode _mode = StatisticsMode.All; - private Dictionary _mapUsers = new Dictionary(); - private Dictionary _mapSamples = new Dictionary(); - private Dictionary> _mapUserSamples = new Dictionary>(); + private static readonly string[] WEEKDAYS = ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"]; + private StatisticsMode _mode; + private Dictionary _mapUsers = new(); + private Dictionary _mapSamples = new(); + private Dictionary> _mapUserSamples = new(); private StatisticsAuthor _selectedAuthor = null; private uint _fillColor = 255; } public class Statistics { - public StatisticsReport All { get; set; } - public StatisticsReport Month { get; set; } - public StatisticsReport Week { get; set; } + public StatisticsReport All { get; } + public StatisticsReport Month { get; } + public StatisticsReport Week { get; } public Statistics() { - _today = DateTime.Now.ToLocalTime().Date; - var weekOffset = (7 + (int)_today.DayOfWeek - (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek) % 7; - _thisWeekStart = _today.AddDays(-weekOffset); - _thisMonthStart = _today.AddDays(1 - _today.Day); + var today = DateTime.Now.ToLocalTime().Date; + var weekOffset = (7 + (int)today.DayOfWeek - (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek) % 7; + _thisWeekStart = today.AddDays(-weekOffset); + _thisMonthStart = today.AddDays(1 - today.Day); All = new StatisticsReport(StatisticsMode.All, DateTime.MinValue); Month = new StatisticsReport(StatisticsMode.ThisMonth, _thisMonthStart); @@ -200,7 +199,13 @@ namespace SourceGit.Models public void AddCommit(string author, double timestamp) { - var user = User.FindOrAdd(author); + var emailIdx = author.IndexOf('±', StringComparison.Ordinal); + var email = author.Substring(emailIdx + 1).ToLower(CultureInfo.CurrentCulture); + if (!_users.TryGetValue(email, out var user)) + { + user = User.FindOrAdd(author); + _users.Add(email, user); + } var time = DateTime.UnixEpoch.AddSeconds(timestamp).ToLocalTime(); if (time >= _thisWeekStart) @@ -214,13 +219,15 @@ namespace SourceGit.Models public void Complete() { + _users.Clear(); + All.Complete(); Month.Complete(); Week.Complete(); } - - private readonly DateTime _today; + private readonly DateTime _thisMonthStart; private readonly DateTime _thisWeekStart; + private readonly Dictionary _users = new(); } } diff --git a/src/Views/Statistics.axaml b/src/Views/Statistics.axaml index 577849df..a2d18393 100644 --- a/src/Views/Statistics.axaml +++ b/src/Views/Statistics.axaml @@ -162,7 +162,9 @@ - + Date: Sat, 31 May 2025 21:26:01 +0800 Subject: [PATCH 25/35] fix: must convert the relative path to absolute before send it to first instance (#1376) Signed-off-by: leo --- src/App.axaml.cs | 12 +++++++++++- src/Models/Statistics.cs | 4 ++-- src/Views/ChangeStatusIcon.cs | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/App.axaml.cs b/src/App.axaml.cs index 0664ee25..411f5cfb 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -393,7 +393,17 @@ namespace SourceGit _ipcChannel = new Models.IpcChannel(); if (!_ipcChannel.IsFirstInstance) { - _ipcChannel.SendToFirstInstance(desktop.Args is { Length: 1 } ? desktop.Args[0] : string.Empty); + var arg = desktop.Args is { Length: > 0 } ? desktop.Args[0].Trim() : string.Empty; + if (!string.IsNullOrEmpty(arg)) + { + if (arg.StartsWith('"') && arg.EndsWith('"')) + arg = arg.Substring(1, arg.Length - 2).Trim(); + + if (arg.Length > 0 && !Path.IsPathFullyQualified(arg)) + arg = Path.GetFullPath(arg); + } + + _ipcChannel.SendToFirstInstance(arg); Environment.Exit(0); } else diff --git a/src/Models/Statistics.cs b/src/Models/Statistics.cs index d6f5870d..a86380c3 100644 --- a/src/Models/Statistics.cs +++ b/src/Models/Statistics.cs @@ -220,12 +220,12 @@ namespace SourceGit.Models public void Complete() { _users.Clear(); - + All.Complete(); Month.Complete(); Week.Complete(); } - + private readonly DateTime _thisMonthStart; private readonly DateTime _thisWeekStart; private readonly Dictionary _users = new(); diff --git a/src/Views/ChangeStatusIcon.cs b/src/Views/ChangeStatusIcon.cs index ade46537..0f0e8da1 100644 --- a/src/Views/ChangeStatusIcon.cs +++ b/src/Views/ChangeStatusIcon.cs @@ -135,7 +135,7 @@ namespace SourceGit.Views else { ToolTip.SetTip(this, TIPS[(int)c.Index]); - } + } InvalidateVisual(); } From 26307e2343b82939247553cfbe39ec8889c016a1 Mon Sep 17 00:00:00 2001 From: leo Date: Sun, 1 Jun 2025 10:34:24 +0800 Subject: [PATCH 26/35] refactor: new tooltip for change Signed-off-by: leo --- src/Models/Change.cs | 17 +++++++++- src/Views/ChangeCollectionView.axaml | 6 ++-- src/Views/ChangeCollectionView.axaml.cs | 41 ++++++++++++++++++++++++- src/Views/ChangeStatusIcon.cs | 26 +--------------- 4 files changed, 60 insertions(+), 30 deletions(-) diff --git a/src/Models/Change.cs b/src/Models/Change.cs index a7be1f64..aaa2633f 100644 --- a/src/Models/Change.cs +++ b/src/Models/Change.cs @@ -53,6 +53,9 @@ namespace SourceGit.Models public bool IsConflicted => WorkTree == ChangeState.Conflicted; public string ConflictMarker => CONFLICT_MARKERS[(int)ConflictReason]; public string ConflictDesc => CONFLICT_DESCS[(int)ConflictReason]; + + public string WorkTreeDesc => TYPE_DESCS[(int)WorkTree]; + public string IndexDesc => TYPE_DESCS[(int)Index]; public void Set(ChangeState index, ChangeState workTree = ChangeState.None) { @@ -84,7 +87,19 @@ namespace SourceGit.Models if (!string.IsNullOrEmpty(OriginalPath) && OriginalPath[0] == '"') OriginalPath = OriginalPath.Substring(1, OriginalPath.Length - 2); } - + + private static readonly string[] TYPE_DESCS = + [ + "Unknown", + "Modified", + "Type Changed", + "Added", + "Deleted", + "Renamed", + "Copied", + "Untracked", + "Conflict" + ]; private static readonly string[] CONFLICT_MARKERS = [ string.Empty, diff --git a/src/Views/ChangeCollectionView.axaml b/src/Views/ChangeCollectionView.axaml index 11c9e706..43af3a9a 100644 --- a/src/Views/ChangeCollectionView.axaml +++ b/src/Views/ChangeCollectionView.axaml @@ -41,7 +41,7 @@ Margin="{Binding Depth, Converter={x:Static c:IntConverters.ToTreeMargin}}" Background="Transparent" DoubleTapped="OnRowDoubleTapped" - ToolTip.Tip="{Binding FullPath}"> + DataContextChanged="OnRowDataContextChanged"> + DataContextChanged="OnRowDataContextChanged"> + DataContextChanged="OnRowDataContextChanged"> AutoSelectFirstChangeProperty = - AvaloniaProperty.Register(nameof(AutoSelectFirstChange), false); + AvaloniaProperty.Register(nameof(AutoSelectFirstChange)); public bool AutoSelectFirstChange { @@ -229,6 +231,28 @@ namespace SourceGit.Views UpdateSelection(); } + private void OnRowDataContextChanged(object sender, EventArgs e) + { + if (sender is not Control control) + return; + + if (control.DataContext is ViewModels.ChangeTreeNode node) + { + if (node.Change is {} c) + UpdateRowTips(control, c); + else + ToolTip.SetTip(control, node.FullPath); + } + else if (control.DataContext is Models.Change change) + { + UpdateRowTips(control, change); + } + else + { + ToolTip.SetTip(control, null); + } + } + private void OnRowDoubleTapped(object sender, TappedEventArgs e) { var grid = sender as Grid; @@ -466,6 +490,21 @@ namespace SourceGit.Views } } + private void UpdateRowTips(Control control, Models.Change change) + { + var tip = new TextBlock() { TextWrapping = TextWrapping.Wrap }; + tip.Inlines!.Add(new Run(change.Path)); + tip.Inlines!.Add(new Run(" • ") { Foreground = Brushes.Gray }); + tip.Inlines!.Add(new Run(IsUnstagedChange ? change.WorkTreeDesc : change.IndexDesc) { Foreground = Brushes.Gray }); + if (change.IsConflicted) + { + tip.Inlines!.Add(new Run(" • ") { Foreground = Brushes.Gray }); + tip.Inlines!.Add(new Run(change.ConflictDesc) { Foreground = Brushes.Gray }); + } + + ToolTip.SetTip(control, tip); + } + private bool _disableSelectionChangingEvent = false; } } diff --git a/src/Views/ChangeStatusIcon.cs b/src/Views/ChangeStatusIcon.cs index 0f0e8da1..d66ac11d 100644 --- a/src/Views/ChangeStatusIcon.cs +++ b/src/Views/ChangeStatusIcon.cs @@ -9,6 +9,7 @@ namespace SourceGit.Views { public class ChangeStatusIcon : Control { + private static readonly string[] INDICATOR = ["?", "±", "T", "+", "−", "➜", "❏", "★", "!"]; private static readonly IBrush[] BACKGROUNDS = [ Brushes.Transparent, new LinearGradientBrush @@ -56,9 +57,6 @@ namespace SourceGit.Views Brushes.OrangeRed, ]; - private static readonly string[] INDICATOR = ["?", "±", "T", "+", "−", "➜", "❏", "★", "!"]; - private static readonly string[] TIPS = ["Unknown", "Modified", "Type Changed", "Added", "Deleted", "Renamed", "Copied", "Untracked", "Conflict"]; - public static readonly StyledProperty IsUnstagedChangeProperty = AvaloniaProperty.Register(nameof(IsUnstagedChange)); @@ -116,29 +114,7 @@ namespace SourceGit.Views base.OnPropertyChanged(change); if (change.Property == IsUnstagedChangeProperty || change.Property == ChangeProperty) - { - var isUnstaged = IsUnstagedChange; - var c = Change; - if (c == null) - { - ToolTip.SetTip(this, null); - return; - } - - if (isUnstaged) - { - if (c.IsConflicted) - ToolTip.SetTip(this, $"Conflict ({c.ConflictDesc})"); - else - ToolTip.SetTip(this, TIPS[(int)c.WorkTree]); - } - else - { - ToolTip.SetTip(this, TIPS[(int)c.Index]); - } - InvalidateVisual(); - } } } } From 6620bd193e65328d0a69abf888d599dc05030991 Mon Sep 17 00:00:00 2001 From: leo Date: Sun, 1 Jun 2025 11:09:31 +0800 Subject: [PATCH 27/35] ux: remove tooltip for `USE THEIRS` and `USE MINE` button Signed-off-by: leo --- src/Views/Conflict.axaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Views/Conflict.axaml b/src/Views/Conflict.axaml index d074bb72..71bb0b41 100644 --- a/src/Views/Conflict.axaml +++ b/src/Views/Conflict.axaml @@ -113,13 +113,13 @@ - -