diff --git a/.editorconfig b/.editorconfig
index 22c741b9..56725e7b 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -100,7 +100,7 @@ dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
dotnet_naming_style.camel_case_underscore_style.required_prefix = _
-dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
+dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
# use accessibility modifiers
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
diff --git a/TRANSLATION.md b/TRANSLATION.md
index ba51b82c..051440f0 100644
--- a/TRANSLATION.md
+++ b/TRANSLATION.md
@@ -6,13 +6,15 @@ This document shows the translation status of each locale file in the repository
### 
-### 
+### 
Missing keys in de_DE.axaml
- Text.Avatar.Load
- Text.BranchCM.ResetToSelectedCommit
+- Text.Checkout.WithFastForward
+- Text.Checkout.WithFastForward.Upstream
- Text.CommitDetail.Changes.Count
- Text.CreateBranch.OverwriteExisting
- Text.DeinitSubmodule
@@ -43,16 +45,9 @@ This document shows the translation status of each locale file in the repository
-### 
+### 
-
-Missing keys in es_ES.axaml
-
-- Text.Avatar.Load
-
-
-
-### 
+### 
Missing keys in fr_FR.axaml
@@ -67,6 +62,8 @@ This document shows the translation status of each locale file in the repository
- Text.Bisect.WaitingForRange
- Text.BranchCM.ResetToSelectedCommit
- Text.Checkout.RecurseSubmodules
+- Text.Checkout.WithFastForward
+- Text.Checkout.WithFastForward.Upstream
- Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject
@@ -122,13 +119,15 @@ This document shows the translation status of each locale file in the repository
-### 
+### 
Missing keys in it_IT.axaml
- Text.Avatar.Load
- Text.BranchCM.ResetToSelectedCommit
+- Text.Checkout.WithFastForward
+- Text.Checkout.WithFastForward.Upstream
- Text.CommitDetail.Changes.Count
- Text.CreateBranch.OverwriteExisting
- Text.DeinitSubmodule
@@ -149,7 +148,7 @@ This document shows the translation status of each locale file in the repository
-### 
+### 
Missing keys in ja_JP.axaml
@@ -165,6 +164,8 @@ This document shows the translation status of each locale file in the repository
- Text.BranchCM.CompareWithCurrent
- Text.BranchCM.ResetToSelectedCommit
- Text.Checkout.RecurseSubmodules
+- Text.Checkout.WithFastForward
+- Text.Checkout.WithFastForward.Upstream
- Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject
@@ -221,7 +222,7 @@ This document shows the translation status of each locale file in the repository
-### 
+### 
Missing keys in pt_BR.axaml
@@ -245,6 +246,8 @@ This document shows the translation status of each locale file in the repository
- Text.BranchCM.ResetToSelectedCommit
- Text.BranchUpstreamInvalid
- Text.Checkout.RecurseSubmodules
+- Text.Checkout.WithFastForward
+- Text.Checkout.WithFastForward.Upstream
- Text.Clone.RecurseSubmodules
- Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter
@@ -357,9 +360,17 @@ This document shows the translation status of each locale file in the repository
-### 
+### 
-### 
+
+Missing keys in ru_RU.axaml
+
+- Text.Checkout.WithFastForward
+- Text.Checkout.WithFastForward.Upstream
+
+
+
+### 
Missing keys in ta_IN.axaml
@@ -375,6 +386,8 @@ This document shows the translation status of each locale file in the repository
- Text.BranchCM.CompareWithCurrent
- Text.BranchCM.ResetToSelectedCommit
- Text.Checkout.RecurseSubmodules
+- Text.Checkout.WithFastForward
+- Text.Checkout.WithFastForward.Upstream
- Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject
@@ -430,7 +443,7 @@ This document shows the translation status of each locale file in the repository
-### 
+### 
Missing keys in uk_UA.axaml
@@ -445,6 +458,8 @@ This document shows the translation status of each locale file in the repository
- Text.Bisect.WaitingForRange
- Text.BranchCM.ResetToSelectedCommit
- Text.Checkout.RecurseSubmodules
+- Text.Checkout.WithFastForward
+- Text.Checkout.WithFastForward.Upstream
- Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject
diff --git a/VERSION b/VERSION
index b89504d0..d3e094ba 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2025.21
\ No newline at end of file
+2025.22
\ No newline at end of file
diff --git a/src/App.axaml.cs b/src/App.axaml.cs
index b5868ca1..8e579373 100644
--- a/src/App.axaml.cs
+++ b/src/App.axaml.cs
@@ -301,7 +301,7 @@ namespace SourceGit
return await clipboard.GetTextAsync();
}
}
- return default;
+ return null;
}
public static string Text(string key, params object[] args)
@@ -323,8 +323,7 @@ namespace SourceGit
icon.Height = 12;
icon.Stretch = Stretch.Uniform;
- var geo = Current?.FindResource(key) as StreamGeometry;
- if (geo != null)
+ if (Current?.FindResource(key) is StreamGeometry geo)
icon.Data = geo;
return icon;
@@ -682,8 +681,7 @@ namespace SourceGit
}
var name = sb.ToString();
- var idx = name.IndexOf('#');
- if (idx >= 0)
+ if (name.Contains('#', StringComparison.Ordinal))
{
if (!name.Equals("fonts:Inter#Inter", StringComparison.Ordinal) &&
!name.Equals("fonts:SourceGit#JetBrains Mono", StringComparison.Ordinal))
diff --git a/src/Commands/Blame.cs b/src/Commands/Blame.cs
index 4fa8b317..1fc51fa4 100644
--- a/src/Commands/Blame.cs
+++ b/src/Commands/Blame.cs
@@ -51,7 +51,7 @@ namespace SourceGit.Commands
private void ParseLine(string line)
{
- if (line.IndexOf('\0', StringComparison.Ordinal) >= 0)
+ if (line.Contains('\0', StringComparison.Ordinal))
{
_result.IsBinary = true;
_result.LineInfos.Clear();
diff --git a/src/Commands/Command.cs b/src/Commands/Command.cs
index 9bfa1c15..975922fc 100644
--- a/src/Commands/Command.cs
+++ b/src/Commands/Command.cs
@@ -194,7 +194,7 @@ namespace SourceGit.Commands
private void HandleOutput(string line, List errs)
{
- line = line ?? string.Empty;
+ line ??= string.Empty;
Log?.AppendLine(line);
// Lines to hide in error message.
diff --git a/src/Commands/Commit.cs b/src/Commands/Commit.cs
index 17410bc9..1585e7e3 100644
--- a/src/Commands/Commit.cs
+++ b/src/Commands/Commit.cs
@@ -34,6 +34,6 @@ namespace SourceGit.Commands
return succ;
}
- private string _tmpFile = string.Empty;
+ private readonly string _tmpFile;
}
}
diff --git a/src/Commands/CompareRevisions.cs b/src/Commands/CompareRevisions.cs
index 7b4a496d..c88e087a 100644
--- a/src/Commands/CompareRevisions.cs
+++ b/src/Commands/CompareRevisions.cs
@@ -39,7 +39,7 @@ namespace SourceGit.Commands
foreach (var line in lines)
ParseLine(line);
- _changes.Sort((l, r) => string.Compare(l.Path, r.Path, StringComparison.Ordinal));
+ _changes.Sort((l, r) => Models.NumericSort.Compare(l.Path, r.Path));
return _changes;
}
diff --git a/src/Commands/LFS.cs b/src/Commands/LFS.cs
index e621ed7d..18d2ba93 100644
--- a/src/Commands/LFS.cs
+++ b/src/Commands/LFS.cs
@@ -10,7 +10,7 @@ namespace SourceGit.Commands
[GeneratedRegex(@"^(.+)\s+([\w.]+)\s+\w+:(\d+)$")]
private static partial Regex REG_LOCK();
- class SubCmd : Command
+ private class SubCmd : Command
{
public SubCmd(string repo, string args, Models.ICommandLog log)
{
diff --git a/src/Commands/QueryCommitsForInteractiveRebase.cs b/src/Commands/QueryCommitsForInteractiveRebase.cs
index 615060a5..9f238319 100644
--- a/src/Commands/QueryCommitsForInteractiveRebase.cs
+++ b/src/Commands/QueryCommitsForInteractiveRebase.cs
@@ -90,6 +90,6 @@ namespace SourceGit.Commands
private List _commits = [];
private Models.InteractiveCommit _current = null;
- private string _boundary = "";
+ private readonly string _boundary;
}
}
diff --git a/src/Commands/QueryFileSize.cs b/src/Commands/QueryFileSize.cs
index 9016d826..30af7715 100644
--- a/src/Commands/QueryFileSize.cs
+++ b/src/Commands/QueryFileSize.cs
@@ -16,9 +16,6 @@ namespace SourceGit.Commands
public long Result()
{
- if (_result != 0)
- return _result;
-
var rs = ReadToEnd();
if (rs.IsSuccess)
{
@@ -29,7 +26,5 @@ namespace SourceGit.Commands
return 0;
}
-
- private readonly long _result = 0;
}
}
diff --git a/src/Commands/UnstageChangesForAmend.cs b/src/Commands/UnstageChangesForAmend.cs
index c930f136..19def067 100644
--- a/src/Commands/UnstageChangesForAmend.cs
+++ b/src/Commands/UnstageChangesForAmend.cs
@@ -23,13 +23,11 @@ namespace SourceGit.Commands
_patchBuilder.Append(c.DataForAmend.ObjectHash);
_patchBuilder.Append("\t");
_patchBuilder.Append(c.OriginalPath);
- _patchBuilder.Append("\n");
}
else if (c.Index == Models.ChangeState.Added)
{
_patchBuilder.Append("0 0000000000000000000000000000000000000000\t");
_patchBuilder.Append(c.Path);
- _patchBuilder.Append("\n");
}
else if (c.Index == Models.ChangeState.Deleted)
{
@@ -37,7 +35,6 @@ namespace SourceGit.Commands
_patchBuilder.Append(c.DataForAmend.ObjectHash);
_patchBuilder.Append("\t");
_patchBuilder.Append(c.Path);
- _patchBuilder.Append("\n");
}
else
{
@@ -46,8 +43,9 @@ namespace SourceGit.Commands
_patchBuilder.Append(c.DataForAmend.ObjectHash);
_patchBuilder.Append("\t");
_patchBuilder.Append(c.Path);
- _patchBuilder.Append("\n");
}
+
+ _patchBuilder.Append("\n");
}
}
diff --git a/src/Models/AvatarManager.cs b/src/Models/AvatarManager.cs
index 2edcb619..fa07975d 100644
--- a/src/Models/AvatarManager.cs
+++ b/src/Models/AvatarManager.cs
@@ -38,7 +38,7 @@ namespace SourceGit.Models
[GeneratedRegex(@"^(?:(\d+)\+)?(.+?)@.+\.github\.com$")]
private static partial Regex REG_GITHUB_USER_EMAIL();
- private object _synclock = new object();
+ private readonly Lock _synclock = new();
private string _storePath;
private List _avatars = new List();
private Dictionary _resources = new Dictionary();
@@ -144,8 +144,7 @@ namespace SourceGit.Models
if (_defaultAvatars.Contains(email))
return null;
- if (_resources.ContainsKey(email))
- _resources.Remove(email);
+ _resources.Remove(email);
var localFile = Path.Combine(_storePath, GetEmailHash(email));
if (File.Exists(localFile))
@@ -179,8 +178,7 @@ namespace SourceGit.Models
lock (_synclock)
{
- if (!_requesting.Contains(email))
- _requesting.Add(email);
+ _requesting.Add(email);
}
return null;
@@ -200,10 +198,7 @@ namespace SourceGit.Models
if (image == null)
return;
- if (_resources.ContainsKey(email))
- _resources[email] = image;
- else
- _resources.Add(email, image);
+ _resources[email] = image;
_requesting.Remove(email);
diff --git a/src/Models/Commit.cs b/src/Models/Commit.cs
index 865b3ac1..f0f4b39b 100644
--- a/src/Models/Commit.cs
+++ b/src/Models/Commit.cs
@@ -19,7 +19,7 @@ namespace SourceGit.Models
public class Commit
{
// As retrieved by: git mktree chunks, Dictionary hashes, string data, int start)
{
- int hash;
- if (hashes.TryGetValue(data, out hash))
+ if (hashes.TryGetValue(data, out var hash))
{
chunks.Add(new Chunk(hash, start, data.Length));
}
diff --git a/src/Models/User.cs b/src/Models/User.cs
index 066ab747..0b4816fe 100644
--- a/src/Models/User.cs
+++ b/src/Models/User.cs
@@ -26,11 +26,7 @@ namespace SourceGit.Models
public override bool Equals(object obj)
{
- if (obj == null || !(obj is User))
- return false;
-
- var other = obj as User;
- return Name == other.Name && Email == other.Email;
+ return obj is User other && Name == other.Name && Email == other.Email;
}
public override int GetHashCode()
diff --git a/src/Models/Watcher.cs b/src/Models/Watcher.cs
index ccdc645f..a3cfc329 100644
--- a/src/Models/Watcher.cs
+++ b/src/Models/Watcher.cs
@@ -246,7 +246,7 @@ namespace SourceGit.Models
private long _updateStashes = 0;
private long _updateTags = 0;
- private object _lockSubmodule = new object();
+ private readonly Lock _lockSubmodule = new();
private List _submodules = new List();
}
}
diff --git a/src/Native/Windows.cs b/src/Native/Windows.cs
index adca05f3..07cf51fb 100644
--- a/src/Native/Windows.cs
+++ b/src/Native/Windows.cs
@@ -127,23 +127,17 @@ namespace SourceGit.Native
Microsoft.Win32.RegistryHive.LocalMachine,
Microsoft.Win32.RegistryView.Registry64);
- var git = reg.OpenSubKey("SOFTWARE\\GitForWindows");
- if (git != null && git.GetValue("InstallPath") is string installPath)
- {
+ var git = reg.OpenSubKey(@"SOFTWARE\GitForWindows");
+ if (git?.GetValue("InstallPath") is string installPath)
return Path.Combine(installPath, "bin", "git.exe");
- }
var builder = new StringBuilder("git.exe", 259);
if (!PathFindOnPath(builder, null))
- {
return null;
- }
var exePath = builder.ToString();
if (!string.IsNullOrEmpty(exePath))
- {
return exePath;
- }
return null;
}
@@ -181,7 +175,7 @@ namespace SourceGit.Native
break;
case "cmd":
- return "C:\\Windows\\System32\\cmd.exe";
+ return @"C:\Windows\System32\cmd.exe";
case "wt":
var wtFinder = new StringBuilder("wt.exe", 512);
if (PathFindOnPath(wtFinder, null))
@@ -199,8 +193,8 @@ namespace SourceGit.Native
finder.VSCode(FindVSCode);
finder.VSCodeInsiders(FindVSCodeInsiders);
finder.VSCodium(FindVSCodium);
- finder.Fleet(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\Programs\\Fleet\\Fleet.exe");
- finder.FindJetBrainsFromToolbox(() => $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\\JetBrains\\Toolbox");
+ finder.Fleet(() => $@"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\Programs\Fleet\Fleet.exe");
+ finder.FindJetBrainsFromToolbox(() => $@"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)}\JetBrains\Toolbox");
finder.SublimeText(FindSublimeText);
finder.TryAdd("Visual Studio", "vs", FindVisualStudio, GenerateCommandlineArgsForVisualStudio);
return finder.Founded;
@@ -299,9 +293,7 @@ namespace SourceGit.Native
// VSCode (system)
var systemVScode = localMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{EA457B21-F73E-494C-ACAB-524FDE069978}_is1");
if (systemVScode != null)
- {
return systemVScode.GetValue("DisplayIcon") as string;
- }
var currentUser = Microsoft.Win32.RegistryKey.OpenBaseKey(
Microsoft.Win32.RegistryHive.CurrentUser,
@@ -310,9 +302,7 @@ namespace SourceGit.Native
// VSCode (user)
var vscode = currentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{771FD6B0-FA20-440A-A002-3B3BAC16DC50}_is1");
if (vscode != null)
- {
return vscode.GetValue("DisplayIcon") as string;
- }
return string.Empty;
}
@@ -326,9 +316,7 @@ namespace SourceGit.Native
// VSCode - Insiders (system)
var systemVScodeInsiders = localMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{1287CAD5-7C8D-410D-88B9-0D1EE4A83FF2}_is1");
if (systemVScodeInsiders != null)
- {
return systemVScodeInsiders.GetValue("DisplayIcon") as string;
- }
var currentUser = Microsoft.Win32.RegistryKey.OpenBaseKey(
Microsoft.Win32.RegistryHive.CurrentUser,
@@ -337,9 +325,7 @@ namespace SourceGit.Native
// VSCode - Insiders (user)
var vscodeInsiders = currentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{217B4C08-948D-4276-BFBB-BEE930AE5A2C}_is1");
if (vscodeInsiders != null)
- {
return vscodeInsiders.GetValue("DisplayIcon") as string;
- }
return string.Empty;
}
@@ -353,9 +339,7 @@ namespace SourceGit.Native
// VSCodium (system)
var systemVSCodium = localMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{88DA3577-054F-4CA1-8122-7D820494CFFB}_is1");
if (systemVSCodium != null)
- {
return systemVSCodium.GetValue("DisplayIcon") as string;
- }
var currentUser = Microsoft.Win32.RegistryKey.OpenBaseKey(
Microsoft.Win32.RegistryHive.CurrentUser,
@@ -364,9 +348,7 @@ namespace SourceGit.Native
// VSCodium (user)
var vscodium = currentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{2E1F05D1-C245-4562-81EE-28188DB6FD17}_is1");
if (vscodium != null)
- {
return vscodium.GetValue("DisplayIcon") as string;
- }
return string.Empty;
}
@@ -409,9 +391,7 @@ namespace SourceGit.Native
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;
diff --git a/src/Resources/Images/github.png b/src/Resources/Images/github.png
index 3a7abb16..d3c211da 100644
Binary files a/src/Resources/Images/github.png and b/src/Resources/Images/github.png differ
diff --git a/src/Resources/Images/unreal.png b/src/Resources/Images/unreal.png
index 4faae92b..01ceeb31 100644
Binary files a/src/Resources/Images/unreal.png and b/src/Resources/Images/unreal.png differ
diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml
index afdff5da..ee035551 100644
--- a/src/Resources/Locales/en_US.axaml
+++ b/src/Resources/Locales/en_US.axaml
@@ -86,6 +86,8 @@
Stash & Reapply
Update all submodules
Branch:
+ Checkout & Fast-Forward
+ Fast-Forward to:
Cherry Pick
Append source to commit message
Commit(s):
diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml
index 1d97cb6f..4f1a4452 100644
--- a/src/Resources/Locales/es_ES.axaml
+++ b/src/Resources/Locales/es_ES.axaml
@@ -39,6 +39,7 @@
ARCHIVOS ASUMIDOS COMO SIN CAMBIOS
NO HAY ARCHIVOS ASUMIDOS COMO SIN CAMBIOS
REMOVER
+ Cargar Imagen...
Refrescar
¡ARCHIVO BINARIO NO SOPORTADO!
Bisect
@@ -89,6 +90,8 @@
Stash & Reaplicar
Actualizar todos los submódulos
Rama:
+ Checkout & Fast-Forward
+ Fast-Forward a:
Cherry Pick
Añadir fuente al mensaje de commit
Commit(s):
diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml
index c7e57c97..2a117fb8 100644
--- a/src/Resources/Locales/zh_CN.axaml
+++ b/src/Resources/Locales/zh_CN.axaml
@@ -90,6 +90,8 @@
贮藏并自动恢复
同时更新所有子模块
目标分支 :
+ 检出分支并快进
+ 上游分支 :
挑选提交
提交信息中追加来源信息
提交列表 :
diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml
index 18a3b04e..29a5346d 100644
--- a/src/Resources/Locales/zh_TW.axaml
+++ b/src/Resources/Locales/zh_TW.axaml
@@ -90,6 +90,8 @@
擱置變更並自動復原
同時更新所有子模組
目標分支:
+ 簽出分支並快轉
+ 上游分支 :
揀選提交
提交資訊中追加來源資訊
提交列表:
diff --git a/src/Resources/Styles.axaml b/src/Resources/Styles.axaml
index 42d9dc3e..15704775 100644
--- a/src/Resources/Styles.axaml
+++ b/src/Resources/Styles.axaml
@@ -16,7 +16,7 @@
12
-
+
@@ -38,7 +38,7 @@
-
+
@@ -206,7 +206,7 @@
-
+
-
+
-
+
-
+
-
+
@@ -737,7 +737,7 @@
-
+
@@ -956,7 +956,7 @@
-
+
-
+
-
+