diff --git a/README.md b/README.md
index 6a688d99..0fdaaa17 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-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-94.80%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-99.13%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-86.56%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-89.60%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 b6c255a1..af9f2973 100644
--- a/TRANSLATION.md
+++ b/TRANSLATION.md
@@ -1,4 +1,4 @@
-### de_DE.axaml: 96.05%
+### de_DE.axaml: 94.80%
@@ -22,11 +22,20 @@
- Text.Configure.OpenAI
- Text.Configure.OpenAI.Prefered
- Text.Configure.OpenAI.Prefered.Tip
+- Text.Diff.SaveAsPatch
+- Text.Diff.VisualLines.All
- Text.ExecuteCustomAction
- Text.ExecuteCustomAction.Name
+- Text.Hotkeys.Repo.CreateBranchOnCommit
+- Text.Hotkeys.Repo.Fetch
+- Text.Hotkeys.Repo.Pull
+- Text.Hotkeys.Repo.Push
+- Text.IssueLinkCM.OpenInBrowser
+- Text.IssueLinkCM.CopyLink
- Text.Preference.AI.AnalyzeDiffPrompt
- Text.Preference.AI.GenerateSubjectPrompt
- Text.Preference.AI.Name
+- Text.Preference.Appearance.EditorFontSize
- Text.Repository.CustomActions
- Text.Repository.CustomActions.Empty
- Text.Stash.KeepIndex
@@ -34,36 +43,22 @@
-### es_ES.axaml: 97.08%
+### es_ES.axaml: 99.13%
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
+- Text.Diff.SaveAsPatch
+- Text.Hotkeys.Repo.CreateBranchOnCommit
+- Text.Hotkeys.Repo.Fetch
+- Text.Hotkeys.Repo.Pull
+- Text.Hotkeys.Repo.Push
+- Text.Preference.Appearance.EditorFontSize
-### fr_FR.axaml: 87.72%
+### fr_FR.axaml: 86.56%
@@ -108,6 +103,8 @@
- Text.ConventionalCommit.ShortDescription
- Text.ConventionalCommit.Type
- Text.Diff.IgnoreWhitespace
+- Text.Diff.SaveAsPatch
+- Text.Diff.VisualLines.All
- Text.Discard.IncludeIgnored
- Text.ExecuteCustomAction
- Text.ExecuteCustomAction.Name
@@ -118,7 +115,13 @@
- Text.Histories.Tips.MacOS
- Text.Histories.Tips.Prefix
- Text.Hotkeys.Repo.CommitWithAutoStage
+- Text.Hotkeys.Repo.CreateBranchOnCommit
- Text.Hotkeys.Repo.DiscardSelected
+- Text.Hotkeys.Repo.Fetch
+- Text.Hotkeys.Repo.Pull
+- Text.Hotkeys.Repo.Push
+- Text.IssueLinkCM.OpenInBrowser
+- Text.IssueLinkCM.CopyLink
- Text.MoveRepositoryNode
- Text.MoveRepositoryNode.Target
- Text.Preference.AI
@@ -128,6 +131,7 @@
- Text.Preference.AI.Model
- Text.Preference.AI.Name
- Text.Preference.AI.Server
+- Text.Preference.Appearance.EditorFontSize
- Text.Preference.General.ShowAuthorTime
- Text.Preference.Integration
- Text.Preference.Shell
@@ -156,7 +160,7 @@
-### pt_BR.axaml: 90.79%
+### pt_BR.axaml: 89.60%
@@ -203,15 +207,24 @@
- Text.ConventionalCommit.ShortDescription
- Text.ConventionalCommit.Type
- Text.CopyAllText
+- Text.Diff.SaveAsPatch
+- Text.Diff.VisualLines.All
- Text.Discard.IncludeIgnored
- Text.ExecuteCustomAction
- Text.ExecuteCustomAction.Name
- Text.FileHistory.FileContent
- Text.FileHistory.FileChange
- Text.GitLFS.Locks.OnlyMine
+- Text.Hotkeys.Repo.CreateBranchOnCommit
+- Text.Hotkeys.Repo.Fetch
+- Text.Hotkeys.Repo.Pull
+- Text.Hotkeys.Repo.Push
+- Text.IssueLinkCM.OpenInBrowser
+- Text.IssueLinkCM.CopyLink
- Text.MoveRepositoryNode
- Text.MoveRepositoryNode.Target
- Text.Preference.AI.Name
+- Text.Preference.Appearance.EditorFontSize
- Text.Push.CheckSubmodules
- Text.Repository.CustomActions
- Text.Repository.CustomActions.Empty
diff --git a/src/Commands/Diff.cs b/src/Commands/Diff.cs
index b9b6e064..04103d68 100644
--- a/src/Commands/Diff.cs
+++ b/src/Commands/Diff.cs
@@ -8,6 +8,10 @@ namespace SourceGit.Commands
{
[GeneratedRegex(@"^@@ \-(\d+),?\d* \+(\d+),?\d* @@")]
private static partial Regex REG_INDICATOR();
+
+ [GeneratedRegex(@"^index\s([0-9a-f]{6,40})\.\.([0-9a-f]{6,40})(\s[1-9]{6})?")]
+ private static partial Regex REG_HASH_CHANGE();
+
private const string PREFIX_LFS_NEW = "+version https://git-lfs.github.com/spec/";
private const string PREFIX_LFS_DEL = "-version https://git-lfs.github.com/spec/";
private const string PREFIX_LFS_MODIFY = " version https://git-lfs.github.com/spec/";
@@ -101,17 +105,31 @@ namespace SourceGit.Commands
if (_result.TextDiff.Lines.Count == 0)
{
- var match = REG_INDICATOR().Match(line);
- if (!match.Success)
+ if (line.StartsWith("Binary", StringComparison.Ordinal))
{
- if (line.StartsWith("Binary", StringComparison.Ordinal))
- _result.IsBinary = true;
+ _result.IsBinary = true;
return;
}
- _oldLine = int.Parse(match.Groups[1].Value);
- _newLine = int.Parse(match.Groups[2].Value);
- _result.TextDiff.Lines.Add(new Models.TextDiffLine(Models.TextDiffLineType.Indicator, line, 0, 0));
+ if (string.IsNullOrEmpty(_result.OldHash))
+ {
+ var match = REG_HASH_CHANGE().Match(line);
+ if (!match.Success)
+ return;
+
+ _result.OldHash = match.Groups[1].Value;
+ _result.NewHash = match.Groups[2].Value;
+ }
+ else
+ {
+ var match = REG_INDICATOR().Match(line);
+ if (!match.Success)
+ return;
+
+ _oldLine = int.Parse(match.Groups[1].Value);
+ _newLine = int.Parse(match.Groups[2].Value);
+ _result.TextDiff.Lines.Add(new Models.TextDiffLine(Models.TextDiffLineType.Indicator, line, 0, 0));
+ }
}
else
{
diff --git a/src/Commands/ExecuteCustomAction.cs b/src/Commands/ExecuteCustomAction.cs
index 253c6b43..f5fec82c 100644
--- a/src/Commands/ExecuteCustomAction.cs
+++ b/src/Commands/ExecuteCustomAction.cs
@@ -30,6 +30,8 @@ namespace SourceGit.Commands
start.Environment.Add("PATH", Native.OS.CustomPathEnv);
var proc = new Process() { StartInfo = start };
+ var builder = new StringBuilder();
+
proc.OutputDataReceived += (_, e) =>
{
if (e.Data != null)
@@ -39,7 +41,10 @@ namespace SourceGit.Commands
proc.ErrorDataReceived += (_, e) =>
{
if (e.Data != null)
+ {
outputHandler?.Invoke(e.Data);
+ builder.AppendLine(e.Data);
+ }
};
try
@@ -57,7 +62,17 @@ namespace SourceGit.Commands
});
}
+ var exitCode = proc.ExitCode;
proc.Close();
+
+ if (exitCode != 0)
+ {
+ var errMsg = builder.ToString();
+ Dispatcher.UIThread.Invoke(() =>
+ {
+ App.RaiseException(repo, errMsg);
+ });
+ }
}
}
}
diff --git a/src/Commands/SaveChangesAsPatch.cs b/src/Commands/SaveChangesAsPatch.cs
index 409127ba..461bbfb5 100644
--- a/src/Commands/SaveChangesAsPatch.cs
+++ b/src/Commands/SaveChangesAsPatch.cs
@@ -9,7 +9,7 @@ namespace SourceGit.Commands
{
public static class SaveChangesAsPatch
{
- public static bool Exec(string repo, List changes, bool isUnstaged, string saveTo)
+ public static bool ProcessLocalChanges(string repo, List changes, bool isUnstaged, string saveTo)
{
using (var sw = File.Create(saveTo))
{
@@ -23,6 +23,20 @@ namespace SourceGit.Commands
return true;
}
+ public static bool ProcessRevisionCompareChanges(string repo, List changes, string baseRevision, string targetRevision, string saveTo)
+ {
+ using (var sw = File.Create(saveTo))
+ {
+ foreach (var change in changes)
+ {
+ if (!ProcessSingleChange(repo, new Models.DiffOption(baseRevision, targetRevision, change), sw))
+ return false;
+ }
+ }
+
+ return true;
+ }
+
private static bool ProcessSingleChange(string repo, Models.DiffOption opt, FileStream writer)
{
var starter = new ProcessStartInfo();
diff --git a/src/Models/CustomAction.cs b/src/Models/CustomAction.cs
index 2a400b02..8452a42d 100644
--- a/src/Models/CustomAction.cs
+++ b/src/Models/CustomAction.cs
@@ -30,7 +30,7 @@ namespace SourceGit.Models
public string Arguments
{
- get => _arguments;
+ get => _arguments;
set => SetProperty(ref _arguments, value);
}
diff --git a/src/Models/DiffResult.cs b/src/Models/DiffResult.cs
index e7cecaa3..e0ae82e0 100644
--- a/src/Models/DiffResult.cs
+++ b/src/Models/DiffResult.cs
@@ -63,7 +63,7 @@ namespace SourceGit.Models
{
public string File { get; set; } = string.Empty;
public List Lines { get; set; } = new List();
- public Vector SyncScrollOffset { get; set; } = Vector.Zero;
+ public Vector ScrollOffset { get; set; } = Vector.Zero;
public int MaxLineNumber = 0;
public string Repo { get; set; } = null;
@@ -674,6 +674,8 @@ namespace SourceGit.Models
{
public bool IsBinary { get; set; } = false;
public bool IsLFS { get; set; } = false;
+ public string OldHash { get; set; } = string.Empty;
+ public string NewHash { get; set; } = string.Empty;
public string OldMode { get; set; } = string.Empty;
public string NewMode { get; set; } = string.Empty;
public TextDiff TextDiff { get; set; } = null;
diff --git a/src/Models/Notification.cs b/src/Models/Notification.cs
index 2261e327..473947b0 100644
--- a/src/Models/Notification.cs
+++ b/src/Models/Notification.cs
@@ -4,10 +4,5 @@
{
public bool IsError { get; set; } = false;
public string Message { get; set; } = string.Empty;
-
- public void CopyMessage()
- {
- App.CopyText(Message);
- }
}
}
diff --git a/src/Native/Windows.cs b/src/Native/Windows.cs
index a57d26d2..48fbb287 100644
--- a/src/Native/Windows.cs
+++ b/src/Native/Windows.cs
@@ -325,8 +325,8 @@ 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 &&
+ 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('\"');
@@ -353,23 +353,26 @@ namespace SourceGit.Native
private string GenerateCommandlineArgsForVisualStudio(string repo)
{
- var sln = FindVSSolutionFile(repo, 4);
+ var sln = FindVSSolutionFile(new DirectoryInfo(repo), 4);
return string.IsNullOrEmpty(sln) ? $"\"{repo}\"" : $"\"{sln}\"";
}
- private string FindVSSolutionFile(string path, int leftDepth)
+ private string FindVSSolutionFile(DirectoryInfo dir, int leftDepth)
{
- var found = Directory.GetFiles(path, "*.sln", SearchOption.TopDirectoryOnly);
- if (found != null && found.Length > 0)
- return Path.GetFullPath(found[0]);
+ var files = dir.GetFiles();
+ foreach (var f in files)
+ {
+ if (f.Name.EndsWith(".sln", StringComparison.OrdinalIgnoreCase))
+ return f.FullName;
+ }
if (leftDepth <= 0)
return null;
- var subfolders = Directory.GetDirectories(path);
- foreach (var subfolder in subfolders)
+ var subDirs = dir.GetDirectories();
+ foreach (var subDir in subDirs)
{
- var first = FindVSSolutionFile(subfolder, leftDepth - 1);
+ var first = FindVSSolutionFile(subDir, leftDepth - 1);
if (!string.IsNullOrEmpty(first))
return first;
}
diff --git a/src/Resources/Icons.axaml b/src/Resources/Icons.axaml
index 6cf53d96..53b2b3d3 100644
--- a/src/Resources/Icons.axaml
+++ b/src/Resources/Icons.axaml
@@ -1,6 +1,6 @@
M41 512c0-128 46-241 138-333C271 87 384 41 512 41s241 46 333 138c92 92 138 205 138 333s-46 241-138 333c-92 92-205 138-333 138s-241-46-333-138C87 753 41 640 41 512zm87 0c0 108 36 195 113 271s164 113 271 113c108 0 195-36 271-113s113-164 113-271-36-195-113-271c-77-77-164-113-271-113-108 0-195 36-271 113C164 317 128 404 128 512zm256 148V292l195 113L768 512l-195 113-195 113v-77zm148-113-61 36V440l61 36 61 36-61 36z
- M951 419a255 255 0 00-22-209 258 258 0 00-278-124A259 259 0 00213 178a255 255 0 00-171 124 258 258 0 0032 303 255 255 0 0022 210 258 258 0 00278 124A255 255 0 00566 1024a258 258 0 00246-179 256 256 0 00171-124 258 258 0 00-32-302zM566 957a191 191 0 01-123-44l6-3 204-118a34 34 0 0017-29v-287l86 50a3 3 0 012 2v238a192 192 0 01-192 192zM154 781a191 191 0 01-23-129l6 4 204 118a33 33 0 0033 0l249-144v99a3 3 0 01-1 3L416 851a192 192 0 01-262-70zM100 337a191 191 0 01101-84V495a33 33 0 0017 29l248 143-86 50a3 3 0 01-3 0l-206-119A192 192 0 01100 336zm708 164-249-145L645 307a3 3 0 013 0l206 119a192 192 0 01-29 346v-242a34 34 0 00-17-28zm86-129-6-4-204-119a33 33 0 00-33 0L401 394V294a3 3 0 011-3l206-119a192 192 0 01285 199zm-539 176-86-50a3 3 0 01-2-2V259a192 192 0 01315-147l-6 3-204 118a34 34 0 00-17 29zm47-101 111-64 111 64v128l-111 64-111-64z
+ M304 464a128 128 0 01128-128c71 0 128 57 128 128v224a32 32 0 01-64 0V592h-128v95a32 32 0 01-64 0v-224zm64 1v64h128v-64a64 64 0 00-64-64c-35 0-64 29-64 64zM688 337c18 0 32 14 32 32v319a32 32 0 01-32 32c-18 0-32-14-32-32v-319a32 32 0 0132-32zM84 911l60-143A446 446 0 0164 512C64 265 265 64 512 64s448 201 448 448-201 448-448 448c-54 0-105-9-153-27l-242 22a32 32 0 01-32-44zm133-150-53 126 203-18 13 5c41 15 85 23 131 23 212 0 384-172 384-384S724 128 512 128 128 300 128 512c0 82 26 157 69 220l20 29z
M296 392h64v64h-64zM296 582v160h128V582h-64v-62h-64v62zm80 48v64h-32v-64h32zM360 328h64v64h-64zM296 264h64v64h-64zM360 456h64v64h-64zM360 200h64v64h-64zM855 289 639 73c-6-6-14-9-23-9H192c-18 0-32 14-32 32v832c0 18 14 32 32 32h640c18 0 32-14 32-32V311c0-9-3-17-9-23zM790 326H602V138L790 326zm2 562H232V136h64v64h64v-64h174v216c0 23 19 42 42 42h216v494z
M71 1024V0h661L953 219V1024H71zm808-731-220-219H145V951h735V293zM439 512h-220V219h220V512zm-74-219H292v146h74v-146zm0 512h74v73h-220v-73H292v-146H218V585h147v219zm294-366h74V512H512v-73h74v-146H512V219h147v219zm74 439H512V585h220v293zm-74-219h-74v146h74v-146z
M128 256h192a64 64 0 110 128H128a64 64 0 110-128zm576 192h192a64 64 0 010 128h-192a64 64 0 010-128zm-576 192h192a64 64 0 010 128H128a64 64 0 010-128zm576 0h192a64 64 0 010 128h-192a64 64 0 010-128zm0-384h192a64 64 0 010 128h-192a64 64 0 010-128zM128 448h192a64 64 0 110 128H128a64 64 0 110-128zm384-320a64 64 0 0164 64v640a64 64 0 01-128 0V192a64 64 0 0164-64z
@@ -65,6 +65,7 @@
M875 117H149C109 117 75 151 75 192v640c0 41 34 75 75 75h725c41 0 75-34 75-75V192c0-41-34-75-75-75zM139 832V192c0-6 4-11 11-11h331v661H149c-6 0-11-4-11-11zm747 0c0 6-4 11-11 11H544v-661H875c6 0 11 4 11 11v640z
M875 117H149C109 117 75 151 75 192v640c0 41 34 75 75 75h725c41 0 75-34 75-75V192c0-41-34-75-75-75zm-725 64h725c6 0 11 4 11 11v288h-747V192c0-6 4-11 11-11zm725 661H149c-6 0-11-4-11-11V544h747V832c0 6-4 11-11 11z
M40 9 15 23 15 31 9 28 9 20 34 5 24 0 0 14 0 34 25 48 25 28 49 14zM26 29 26 48 49 34 49 15z
+ M416 192m32 0 448 0q32 0 32 32l0 0q0 32-32 32l-448 0q-32 0-32-32l0 0q0-32 32-32ZM416 448m32 0 448 0q32 0 32 32l0 0q0 32-32 32l-448 0q-32 0-32-32l0 0q0-32 32-32ZM416 704m32 0 448 0q32 0 32 32l0 0q0 32-32 32l-448 0q-32 0-32-32l0 0q0-32 32-32ZM96 320l128-192 128 192h-256zM96 640l128 192 128-192h-256zM190 320h64v320H190z
M408 232C408 210 426 192 448 192h416a40 40 0 110 80H448a40 40 0 01-40-40zM408 512c0-22 18-40 40-40h416a40 40 0 110 80H448A40 40 0 01408 512zM448 752A40 40 0 00448 832h416a40 40 0 100-80H448zM32 480l132 0 0-128 64 0 0 128 132 0 0 64-132 0 0 128-64 0 0-128-132 0Z
M408 232C408 210 426 192 448 192h416a40 40 0 110 80H448a40 40 0 01-40-40zM408 512c0-22 18-40 40-40h416a40 40 0 110 80H448A40 40 0 01408 512zM448 752A40 40 0 00448 832h416a40 40 0 100-80H448zM32 480l328 0 0 64-328 0Z
M 968 418 l -95 94 c -59 59 -146 71 -218 37 L 874 331 a 64 64 0 0 0 0 -90 L 783 150 a 64 64 0 0 0 -90 0 L 475 368 c -34 -71 -22 -159 37 -218 l 94 -94 c 75 -75 196 -75 271 0 l 90 90 c 75 75 75 196 0 271 z M 332 693 a 64 64 0 0 1 0 -90 l 271 -271 c 25 -25 65 -25 90 0 s 25 65 0 90 L 422 693 a 64 64 0 0 1 -90 0 z M 151 783 l 90 90 a 64 64 0 0 0 90 0 l 218 -218 c 34 71 22 159 -37 218 l -86 94 a 192 192 0 0 1 -271 0 l -98 -98 a 192 192 0 0 1 0 -271 l 94 -86 c 59 -59 146 -71 218 -37 L 151 693 a 64 64 0 0 0 0 90 z
diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml
index 4ec30436..c99acf77 100644
--- a/src/Resources/Locales/de_DE.axaml
+++ b/src/Resources/Locales/de_DE.axaml
@@ -180,15 +180,14 @@
Farbe
Zuletzt geöffnete Tabs beim Starten wiederherstellen
Konventionelle Commit-Hilfe
- Inkompatible Änderung:
+ Breaking Change:
Geschlossenes Ticket:
Änderungen im Detail:
- Geltungsbereich:
+ Gültigkeitsbereich:
Kurzbeschreibung:
- Art der Änderung:
+ Typ der Änderung:
Kopieren
Kopiere gesamten Text
- COMMIT-NACHRICHT KOPIEREN
Pfad kopieren
Dateinamen kopieren
Branch erstellen...
@@ -426,7 +425,6 @@
API Schlüssel
Generiere Nachricht Befehl
Name
-
Server
Modell
DARSTELLUNG
@@ -533,7 +531,7 @@
WEITER
Benutzerdefinierte Aktionen
Keine benutzerdefinierten Aktionen
- Option '--reflog' einschalten
+ Aktiviere '--reflog' Option
Öffne im Datei-Browser
Suche Branches/Tags/Submodule
GEFILTERT:
diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml
index 2e96e391..166ad3ab 100644
--- a/src/Resources/Locales/en_US.axaml
+++ b/src/Resources/Locales/en_US.axaml
@@ -18,8 +18,8 @@
Optional. Default is the destination folder name.
Track Branch:
Tracking remote branch
- OpenAI Assistant
- Use OpenAI to generate commit message
+ AI Assistant
+ Use AI to generate commit message
Patch
Error
Raise errors and refuses to apply the patch
@@ -166,7 +166,7 @@
Rule Name:
Result URL:
Please use $1, $2 to access regex groups values.
- OPEN AI
+ AI
Prefered Service:
If the 'Prefered Service' is set, SourceGit will only use it in this repository. Otherwise, if there is more than one service available, a context menu to choose one of them will be shown.
HTTP Proxy
@@ -185,7 +185,6 @@
Type of Change:
Copy
Copy All Text
- COPY MESSAGE
Copy Path
Copy File Name
Create Branch...
@@ -238,6 +237,7 @@
Next Difference
NO CHANGES OR ONLY EOL CHANGES
Previous Difference
+ Save as Patch
Show hidden symbols
Side-By-Side Diff
SUBMODULE
@@ -246,6 +246,7 @@
Syntax Highlighting
Line Word Wrap
Open in Merge Tool
+ Show All Lines
Decrease Number of Visible Lines
Increase Number of Visible Lines
SELECT FILE TO VIEW CHANGES
@@ -274,7 +275,7 @@
Discard {0} files...
Discard Changes in Selected Line(s)
Open External Merge Tool
- Save As Patch...
+ Save as Patch...
Stage
Stage {0} files
Stage Changes in Selected Line(s)
@@ -362,8 +363,12 @@
Commit staged changes
Commit and push staged changes
Stage all changes and commit
+ Creates a new branch based on selected commit
Discard selected changes
+ Fetch, starts directly
Dashboard mode (Default)
+ Pull, starts directly
+ Push, starts directly
Force to reload this repository
Stage/Unstage selected changes
Commit search mode
@@ -387,6 +392,8 @@
Interactive Rebase
Target Branch:
On:
+ Open in Browser
+ Copy Link
ERROR
NOTICE
Merge Branch
@@ -398,7 +405,7 @@
Name:
Git has NOT been configured. Please to go [Preference] and configure it first.
Open App Data Dir
- Open With...
+ Open with...
Optional.
Create New Page
Bookmark
@@ -418,7 +425,7 @@
Last year
{0} years ago
Preference
- OPEN AI
+ AI
Analyze Diff Prompt
API Key
Generate Subject Prompt
@@ -428,6 +435,7 @@
APPEARANCE
Default Font
Default Font Size
+ Editor Font Size
Monospace Font
Only use monospace font in text editor
Theme
@@ -530,15 +538,15 @@
Custom Actions
No Custom Actions
Enable '--reflog' Option
- Open In File Browser
+ Open in File Browser
Search Branches/Tags/Submodules
FILTERED BY:
LOCAL BRANCHES
- Navigate To HEAD
+ Navigate to HEAD
Enable '--first-parent' Option
Create Branch
- Open In {0}
- Open In External Tools
+ Open in {0}
+ Open in External Tools
Refresh
REMOTES
ADD REMOTE
@@ -556,7 +564,7 @@
UPDATE SUBMODULE
TAGS
NEW TAG
- Open In Terminal
+ Open in Terminal
WORKTREES
ADD WORKTREE
PRUNE
diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml
index f8a2fa68..43296be0 100644
--- a/src/Resources/Locales/es_ES.axaml
+++ b/src/Resources/Locales/es_ES.axaml
@@ -73,6 +73,7 @@
CANCELAR
Resetear a Esta Revisión
Resetear a Revisión Padre
+ Generar mensaje de commit
CAMBIAR MODO DE VISUALIZACIÓN
Mostrar como Lista de Archivos y Directorios
Mostrar como Lista de Rutas
@@ -110,7 +111,10 @@
Comparar con Worktree
Copiar Información
Copiar SHA
+ Acción personalizada
Rebase Interactivo ${0}$ hasta Aquí
+ Abrir en el Navegador
+ Copiar Enlace
Rebase ${0}$ hasta Aquí
Reset ${0}$ hasta Aquí
Revertir Commit
@@ -141,12 +145,21 @@
PLANTILLA DE COMMIT
Nombre de la Plantilla:
Contenido de la Plantilla:
+ ACCIÓN PERSONALIZADA
+ Argumentos:
+ ${REPO} - Ruta del repositorio; ${SHA} - SHA del commit seleccionado
+ Archivo Ejecutable:
+ Nombre:
+ Alcance:
+ Commit
+ Repositorio
Dirección de Email
Dirección de email
GIT
Fetch remotos automáticamente
Minuto(s)
Remoto por Defecto
+ Habilitar --prune para fetch
Habilitar --signoff para commit
SEGUIMIENTO DE INCIDENCIAS
Añadir Regla de Ejemplo para Github
@@ -158,6 +171,9 @@
Nombre de la Regla:
URL Resultante:
Por favor, use $1, $2 para acceder a los valores de los grupos regex.
+ OPEN AI
+ Servicio Preferido:
+ Si el 'Servicio Preferido' está establecido, SourceGit sólo lo usará en este repositorio. De lo contrario, si hay más de un servicio disponible, se mostrará un menú de contexto para elegir uno.
Proxy HTTP
Proxy HTTP utilizado por este repositorio
Nombre de Usuario
@@ -174,7 +190,6 @@
Tipo de Cambio:
Copiar
Copiar Todo el Texto
- COPIAR MENSAJE
Copiar Ruta
Copiar Nombre del Archivo
Crear Rama...
@@ -235,6 +250,7 @@
Resaltado de Sintaxis
Ajuste de Línea
Abrir en Herramienta de Merge
+ Mostrar Todas las Líneas
Disminuir Número de Líneas Visibles
Aumentar Número de Líneas Visibles
SELECCIONA ARCHIVO PARA VER CAMBIOS
@@ -250,6 +266,8 @@
Destino:
Editar Grupo Seleccionado
Editar Repositorio Seleccionado
+ Ejecutar Acción Personalizada
+ Nombre de la Acción:
Fast-Forward (sin checkout)
Fetch
Fetch todos los remotos
@@ -411,6 +429,7 @@
Clave API
Generar Subject Prompt
Modelo
+ Nombre
Servidor
APARIENCIA
Fuente por defecto
@@ -514,6 +533,8 @@
Limpiar todo
Configurar este repositorio
CONTINUAR
+ Acciones Personalizadas
+ No hay ninguna Acción Personalizada
Habilitar Opción '--reflog'
Abrir en el Explorador
Buscar Ramas/Etiquetas/Submódulos
@@ -576,6 +597,7 @@
INICIAR
Stash
Incluir archivos no rastreados
+ Mantener archivos staged
Mensaje:
Opcional. Nombre de este stash
Solo cambios staged
diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml
index e096071f..f50b8f34 100644
--- a/src/Resources/Locales/fr_FR.axaml
+++ b/src/Resources/Locales/fr_FR.axaml
@@ -152,7 +152,6 @@
Copier
Copier tout le texte
Copier le nom de fichier
- COPIER LE MESSAGE
Copier le chemin
Créer une branche...
Basé sur :
diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml
index c9e0f915..0aba0a5d 100644
--- a/src/Resources/Locales/pt_BR.axaml
+++ b/src/Resources/Locales/pt_BR.axaml
@@ -148,7 +148,6 @@
Configurar Repositório
Copiar
Copiar Nome do Arquivo
- COPIAR MENSAGEM
Copiar Caminho
Baseado Em:
Checar o branch criado
diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml
index d2076099..cfca1cc8 100644
--- a/src/Resources/Locales/ru_RU.axaml
+++ b/src/Resources/Locales/ru_RU.axaml
@@ -189,7 +189,6 @@
Тип изменения:
Копировать
Копировать весь текст
- КОПИРОВАТЬ СООБЩЕНИЕ
Копировать путь
Копировать имя файла
Создать ветку...
@@ -243,6 +242,7 @@
Следующее различие
НИКАКИХ ИЗМЕНЕНИЙ ИЛИ МЕНЯЕТСЯ ТОЛЬКО EOL
Предыдущее различие
+ Сохранить как исправление
Различие бок о бок
ПОДМОДУЛЬ
НОВЫЙ
@@ -250,6 +250,7 @@
Подсветка синтаксиса
Перенос слов в строке
Открыть в инструменте слияния
+ Показывать все линии
Уменьшить количество видимых линий
Увеличить количество видимых линий
ВЫБРАТЬ ФАЙЛ ДЛЯ ПРОСМОТРА ИЗМЕНЕНИЙ
@@ -366,9 +367,13 @@
Зафиксировать подготовленные изменения
Зафиксировать и выложить подготовленные изменения
Подготовить все изменения и зафиксировать
+ Создать новую ветку на основе выбранной ветки
Отклонить выбранные изменения
+ Извлечение, запускается непосредственно
Режим доски (по-умолчанию)
Принудительно перезагрузить этот хранилище
+ Забрать, запускается непосредственно
+ Выложить, запускается непосредственно
Подготовленные/Неподготовленные выбранные изменения
Режим поиска фиксаций
Переключить на «Изменения»
@@ -391,7 +396,9 @@
Интерактивное перемещение
Целевая ветка:
На:
- ОШИБКА
+ Открыть в браузере
+ Копировать ссылку
+ ОШИБКА
УВЕДОМЛЕНИЕ
Слить ветку
В:
@@ -432,6 +439,7 @@
ВИД
Шрифт по-умолчанию
Размер шрифта по-умолчанию
+ Размер шрифта редактора
Моноширный шрифт
В текстовом редакторе используется только моноширный шрифт
Тема
diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml
index 469a88bb..5632a3ef 100644
--- a/src/Resources/Locales/zh_CN.axaml
+++ b/src/Resources/Locales/zh_CN.axaml
@@ -21,8 +21,8 @@
选填。默认使用目标文件夹名称。
跟踪分支
设置上游跟踪分支
- OpenAI助手
- 使用OpenAI助手生成提交信息
+ AI助手
+ 使用AI助手生成提交信息
应用补丁(apply)
错误
输出错误,并终止应用补丁
@@ -169,9 +169,9 @@
规则名 :
为ISSUE生成的URL链接 :
可在URL中使用$1,$2等变量填入正则表达式匹配的内容
- OPEN AI
+ AI
启用特定服务 :
- 当【启用特定服务】被设置时,SourceGit将在本仓库中仅使用该服务。否则将弹出可用的OpenAI服务列表供用户选择。
+ 当【启用特定服务】被设置时,SourceGit将在本仓库中仅使用该服务。否则将弹出可用的AI服务列表供用户选择。
HTTP代理
HTTP网络代理
用户名
@@ -188,7 +188,6 @@
类型:
复制
复制全部文本
- 复制内容
复制路径
复制文件名
新建分支 ...
@@ -241,6 +240,7 @@
下一个差异
没有变更或仅有换行符差异
上一个差异
+ 保存为补丁文件
显示隐藏符号
分列对比
子模块
@@ -249,6 +249,7 @@
语法高亮
自动换行
使用外部合并工具查看
+ 显示完整文件
减少可见的行数
增加可见的行数
请选择需要对比的文件
@@ -365,8 +366,12 @@
提交暂存区更改
提交暂存区更改并推送
自动暂存全部变更并提交
+ 基于选中提交创建新分支
丢弃选中的更改
+ 拉取 (fetch) 远程变更
切换左边栏为分支/标签等显示模式(默认)
+ 拉回 (pull) 远程变更
+ 推送本地变更到远程
重新加载仓库状态
将选中的变更暂存或从暂存列表中移除
切换左边栏为提交搜索模式
@@ -390,6 +395,8 @@
交互式变基
目标分支 :
起始提交 :
+ 在浏览器中访问
+ 复制链接地址
出错了
系统提示
合并分支
@@ -421,7 +428,7 @@
一年前
{0}年前
偏好设置
- OPEN AI
+ AI
Analyze Diff Prompt
API密钥
Generate Subject Prompt
@@ -431,6 +438,7 @@
外观配置
缺省字体
默认字体大小
+ 代码字体大小
等宽字体
仅在文本编辑器中使用等宽字体
主题
diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml
index 77a832ff..229a5fdb 100644
--- a/src/Resources/Locales/zh_TW.axaml
+++ b/src/Resources/Locales/zh_TW.axaml
@@ -21,8 +21,8 @@
選填。預設使用目標資料夾名稱。
追蹤分支
設定遠端追蹤分支
- OpenAI 助理
- 使用 OpenAI 產生提交訊息
+ AI 助理
+ 使用 AI 產生提交訊息
套用修補檔 (apply patch)
錯誤
輸出錯誤,並中止套用修補檔
@@ -169,9 +169,9 @@
規則名稱:
為 Issue 產生的網址連結:
可在網址中使用 $1、$2 等變數填入正規表達式相符的內容
- OpenAI
+ AI
偏好服務:
- 設定 [偏好服務] 後,SourceGit 將於此存放庫中使用該服務,否則會顯示 OpenAI 服務列表供使用者選擇。
+ 設定 [偏好服務] 後,SourceGit 將於此存放庫中使用該服務,否則會顯示 AI 服務列表供使用者選擇。
HTTP 代理
HTTP 網路代理
使用者名稱
@@ -188,7 +188,6 @@
類型:
複製
複製全部內容
- 複製內容
複製路徑
複製檔案名稱
新增分支...
@@ -241,6 +240,7 @@
下一個差異
沒有變更或僅有換行字元差異
上一個差異
+ 另存為修補檔
顯示隱藏符號
並排對比
子模組
@@ -249,6 +249,7 @@
語法上色
自動換行
使用外部合併工具檢視
+ 顯示檔案的全部內容
減少可見的行數
增加可見的行數
請選擇需要對比的檔案
@@ -365,8 +366,12 @@
提交暫存區變更
提交暫存區變更並推送
自動暫存全部變更並提交
+ 根據選取的提交建立新的分支
捨棄選取的變更
+ 提取 (fetch) 遠端的變更
切換左邊欄為分支/標籤等顯示模式 (預設)
+ 拉取 (pull) 遠端的變更
+ 推送 (push) 本地變更到遠端存放庫
強制重新載入存放庫
暫存或取消暫存選取的變更
切換左邊欄為歷史搜尋模式
@@ -390,6 +395,8 @@
互動式重定基底
目標分支:
起始提交:
+ 在瀏覽器中存取網址
+ 複製網址
發生錯誤
系統提示
合併分支
@@ -421,7 +428,7 @@
一年前
{0} 年前
偏好設定
- OpenAI
+ AI
伺服器
API 金鑰
模型
@@ -431,6 +438,7 @@
外觀設定
預設字型
預設字型大小
+ 程式碼字型大小
等寬字型
僅在文字編輯器中使用等寬字型
佈景主題
diff --git a/src/SourceGit.csproj b/src/SourceGit.csproj
index fdfb75d5..bc0aa570 100644
--- a/src/SourceGit.csproj
+++ b/src/SourceGit.csproj
@@ -24,7 +24,6 @@
true
true
link
- Speed
diff --git a/src/ViewModels/DiffContext.cs b/src/ViewModels/DiffContext.cs
index 1a48c8e0..87b1a6de 100644
--- a/src/ViewModels/DiffContext.cs
+++ b/src/ViewModels/DiffContext.cs
@@ -33,12 +33,6 @@ namespace SourceGit.ViewModels
private set => SetProperty(ref _fileModeChange, value);
}
- public bool IsLoading
- {
- get => _isLoading;
- private set => SetProperty(ref _isLoading, value);
- }
-
public bool IsTextDiff
{
get => _isTextDiff;
@@ -68,6 +62,7 @@ namespace SourceGit.ViewModels
_content = previous._content;
_unifiedLines = previous._unifiedLines;
_ignoreWhitespace = previous._ignoreWhitespace;
+ _info = previous._info;
}
if (string.IsNullOrEmpty(_option.OrgPath) || _option.OrgPath == "/dev/null")
@@ -78,6 +73,12 @@ namespace SourceGit.ViewModels
LoadDiffContent();
}
+ public void ToggleFullTextDiff()
+ {
+ Preference.Instance.UseFullTextDiff = !Preference.Instance.UseFullTextDiff;
+ LoadDiffContent();
+ }
+
public void IncrUnified()
{
UnifiedLines = _unifiedLines + 1;
@@ -103,15 +104,23 @@ namespace SourceGit.ViewModels
{
Content = null;
IsTextDiff = false;
- IsLoading = false;
return;
}
Task.Run(() =>
{
- var latest = new Commands.Diff(_repo, _option, _unifiedLines, _ignoreWhitespace).Result();
- var rs = null as object;
+ // NOTE: Here we override the UnifiedLines value (if UseFullTextDiff is on).
+ // There is no way to tell a git-diff to use "ALL lines of context",
+ // so instead we set a very high number for the "lines of context" parameter.
+ var numLines = Preference.Instance.UseFullTextDiff ? 999999999 : _unifiedLines;
+ var latest = new Commands.Diff(_repo, _option, numLines, _ignoreWhitespace).Result();
+ var info = new Info(_option, numLines, _ignoreWhitespace, latest);
+ if (_info != null && info.IsSame(_info))
+ return;
+ _info = info;
+
+ var rs = null as object;
if (latest.TextDiff != null)
{
var count = latest.TextDiff.Lines.Count;
@@ -203,12 +212,11 @@ namespace SourceGit.ViewModels
Dispatcher.UIThread.Post(() =>
{
if (_content is Models.TextDiff old && rs is Models.TextDiff cur && old.File == cur.File)
- cur.SyncScrollOffset = old.SyncScrollOffset;
+ cur.ScrollOffset = old.ScrollOffset;
FileModeChange = latest.FileModeChange;
Content = rs;
IsTextDiff = rs is Models.TextDiff;
- IsLoading = false;
});
});
}
@@ -241,14 +249,41 @@ namespace SourceGit.ViewModels
".ico", ".bmp", ".jpg", ".png", ".jpeg", ".webp"
};
+ private class Info
+ {
+ public string Argument { get; set; }
+ public int UnifiedLines { get; set; }
+ public bool IgnoreWhitespace { get; set; }
+ public string OldHash { get; set; }
+ public string NewHash { get; set; }
+
+ public Info(Models.DiffOption option, int unifiedLines, bool ignoreWhitespace, Models.DiffResult result)
+ {
+ Argument = option.ToString();
+ UnifiedLines = unifiedLines;
+ IgnoreWhitespace = ignoreWhitespace;
+ OldHash = result.OldHash;
+ NewHash = result.NewHash;
+ }
+
+ public bool IsSame(Info other)
+ {
+ return Argument.Equals(other.Argument, StringComparison.Ordinal) &&
+ UnifiedLines == other.UnifiedLines &&
+ IgnoreWhitespace == other.IgnoreWhitespace &&
+ OldHash.Equals(other.OldHash, StringComparison.Ordinal) &&
+ NewHash.Equals(other.NewHash, StringComparison.Ordinal);
+ }
+ }
+
private readonly string _repo;
private readonly Models.DiffOption _option = null;
private string _title;
private string _fileModeChange = string.Empty;
private int _unifiedLines = 4;
- private bool _isLoading = true;
private bool _isTextDiff = false;
private bool _ignoreWhitespace = false;
private object _content = null;
+ private Info _info = null;
}
}
diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs
index 713e1635..688dab87 100644
--- a/src/ViewModels/Histories.cs
+++ b/src/ViewModels/Histories.cs
@@ -2,6 +2,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Text;
+using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Platform.Storage;
@@ -258,6 +259,44 @@ namespace SourceGit.ViewModels
multipleMenu.Items.Add(new MenuItem() { Header = "-" });
}
+ var saveToPatchMultiple = new MenuItem();
+ saveToPatchMultiple.Icon = App.CreateMenuIcon("Icons.Diff");
+ saveToPatchMultiple.Header = App.Text("CommitCM.SaveAsPatch");
+ saveToPatchMultiple.Click += async (_, e) =>
+ {
+ var storageProvider = App.GetStorageProvider();
+ if (storageProvider == null)
+ return;
+
+ var options = new FolderPickerOpenOptions() { AllowMultiple = false };
+ try
+ {
+ var picker = await storageProvider.OpenFolderPickerAsync(options);
+ if (picker.Count == 1)
+ {
+ var saveTo = $"{picker[0].Path.LocalPath}/patches";
+ var succ = false;
+ foreach (var c in selected)
+ {
+ succ = await Task.Run(() => new Commands.FormatPatch(_repo.FullPath, c.SHA, saveTo).Exec());
+ if (!succ)
+ break;
+ }
+
+ if (succ)
+ App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess"));
+ }
+ }
+ catch (Exception exception)
+ {
+ App.RaiseException(_repo.FullPath, $"Failed to save as patch: {exception.Message}");
+ }
+
+ e.Handled = true;
+ };
+ multipleMenu.Items.Add(saveToPatchMultiple);
+ multipleMenu.Items.Add(new MenuItem() { Header = "-" });
+
var copyMultipleSHAs = new MenuItem();
copyMultipleSHAs.Header = App.Text("CommitCM.CopySHA");
copyMultipleSHAs.Icon = App.CreateMenuIcon("Icons.Copy");
diff --git a/src/ViewModels/Preference.cs b/src/ViewModels/Preference.cs
index 2741650c..68065df1 100644
--- a/src/ViewModels/Preference.cs
+++ b/src/ViewModels/Preference.cs
@@ -102,6 +102,12 @@ namespace SourceGit.ViewModels
set => SetProperty(ref _defaultFontSize, value);
}
+ public double EditorFontSize
+ {
+ get => _editorFontSize;
+ set => SetProperty(ref _editorFontSize, value);
+ }
+
public LayoutInfo Layout
{
get => _layout;
@@ -186,6 +192,12 @@ namespace SourceGit.ViewModels
set => SetProperty(ref _showHiddenSymbolsInDiffView, value);
}
+ public bool UseFullTextDiff
+ {
+ get => _useFullTextDiff;
+ set => SetProperty(ref _useFullTextDiff, value);
+ }
+
public Models.ChangeViewMode UnstagedChangeViewMode
{
get => _unstagedChangeViewMode;
@@ -573,6 +585,7 @@ namespace SourceGit.ViewModels
private bool _onlyUseMonoFontInEditor = false;
private bool _useSystemWindowFrame = false;
private double _defaultFontSize = 13;
+ private double _editorFontSize = 13;
private LayoutInfo _layout = new LayoutInfo();
private int _maxHistoryCommits = 20000;
@@ -591,6 +604,7 @@ namespace SourceGit.ViewModels
private bool _useSyntaxHighlighting = false;
private bool _enableDiffViewWordWrap = false;
private bool _showHiddenSymbolsInDiffView = false;
+ private bool _useFullTextDiff = false;
private Models.ChangeViewMode _unstagedChangeViewMode = Models.ChangeViewMode.List;
private Models.ChangeViewMode _stagedChangeViewMode = Models.ChangeViewMode.List;
diff --git a/src/ViewModels/RevisionCompare.cs b/src/ViewModels/RevisionCompare.cs
index 55c85129..ffc05643 100644
--- a/src/ViewModels/RevisionCompare.cs
+++ b/src/ViewModels/RevisionCompare.cs
@@ -24,6 +24,11 @@ namespace SourceGit.ViewModels
private set => SetProperty(ref _endPoint, value);
}
+ public bool CanSaveAsPatch
+ {
+ get => _canSaveAsPatch;
+ }
+
public List VisibleChanges
{
get => _visibleChanges;
@@ -73,6 +78,7 @@ namespace SourceGit.ViewModels
_repo = repo;
_startPoint = (object)startPoint ?? new Models.Null();
_endPoint = (object)endPoint ?? new Models.Null();
+ _canSaveAsPatch = startPoint != null && endPoint != null;
Task.Run(Refresh);
}
@@ -105,6 +111,16 @@ namespace SourceGit.ViewModels
Task.Run(Refresh);
}
+ public void SaveAsPatch(string saveTo)
+ {
+ Task.Run(() =>
+ {
+ var succ = Commands.SaveChangesAsPatch.ProcessRevisionCompareChanges(_repo, _changes, GetSHA(_startPoint), GetSHA(_endPoint), saveTo);
+ if (succ)
+ Dispatcher.UIThread.Invoke(() => App.SendNotification(_repo, App.Text("SaveAsPatchSuccess")));
+ });
+ }
+
public void ClearSearchFilter()
{
SearchFilter = string.Empty;
@@ -218,6 +234,7 @@ namespace SourceGit.ViewModels
private string _repo;
private object _startPoint = null;
private object _endPoint = null;
+ private bool _canSaveAsPatch = false;
private List _changes = null;
private List _visibleChanges = null;
private List _selectedChanges = null;
diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs
index 020053f9..00680251 100644
--- a/src/ViewModels/WorkingCopy.cs
+++ b/src/ViewModels/WorkingCopy.cs
@@ -539,7 +539,7 @@ namespace SourceGit.ViewModels
var storageFile = await storageProvider.SaveFilePickerAsync(options);
if (storageFile != null)
{
- var succ = await Task.Run(() => Commands.SaveChangesAsPatch.Exec(_repo.FullPath, _selectedUnstaged, true, storageFile.Path.LocalPath));
+ var succ = await Task.Run(() => Commands.SaveChangesAsPatch.ProcessLocalChanges(_repo.FullPath, _selectedUnstaged, true, storageFile.Path.LocalPath));
if (succ)
App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess"));
}
@@ -599,7 +599,8 @@ namespace SourceGit.ViewModels
byParentFolder.IsVisible = !isRooted;
byParentFolder.Click += (_, e) =>
{
- Commands.GitIgnore.Add(_repo.FullPath, Path.GetDirectoryName(change.Path) + "/");
+ var path = Path.GetDirectoryName(change.Path).Replace("\\", "/");
+ Commands.GitIgnore.Add(_repo.FullPath, path + "/");
e.Handled = true;
};
addToIgnore.Items.Add(byParentFolder);
@@ -620,7 +621,8 @@ namespace SourceGit.ViewModels
byExtensionInSameFolder.IsVisible = !isRooted;
byExtensionInSameFolder.Click += (_, e) =>
{
- Commands.GitIgnore.Add(_repo.FullPath, Path.GetDirectoryName(change.Path) + "/*" + extension);
+ var path = Path.GetDirectoryName(change.Path).Replace("\\", "/");
+ Commands.GitIgnore.Add(_repo.FullPath, path + "/*" + extension);
e.Handled = true;
};
addToIgnore.Items.Add(byExtensionInSameFolder);
@@ -858,7 +860,7 @@ namespace SourceGit.ViewModels
var storageFile = await storageProvider.SaveFilePickerAsync(options);
if (storageFile != null)
{
- var succ = await Task.Run(() => Commands.SaveChangesAsPatch.Exec(_repo.FullPath, _selectedUnstaged, true, storageFile.Path.LocalPath));
+ var succ = await Task.Run(() => Commands.SaveChangesAsPatch.ProcessLocalChanges(_repo.FullPath, _selectedUnstaged, true, storageFile.Path.LocalPath));
if (succ)
App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess"));
}
@@ -981,7 +983,7 @@ namespace SourceGit.ViewModels
var storageFile = await storageProvider.SaveFilePickerAsync(options);
if (storageFile != null)
{
- var succ = await Task.Run(() => Commands.SaveChangesAsPatch.Exec(_repo.FullPath, _selectedStaged, false, storageFile.Path.LocalPath));
+ var succ = await Task.Run(() => Commands.SaveChangesAsPatch.ProcessLocalChanges(_repo.FullPath, _selectedStaged, false, storageFile.Path.LocalPath));
if (succ)
App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess"));
}
@@ -1156,7 +1158,7 @@ namespace SourceGit.ViewModels
var storageFile = await storageProvider.SaveFilePickerAsync(options);
if (storageFile != null)
{
- var succ = await Task.Run(() => Commands.SaveChangesAsPatch.Exec(_repo.FullPath, _selectedStaged, false, storageFile.Path.LocalPath));
+ var succ = await Task.Run(() => Commands.SaveChangesAsPatch.ProcessLocalChanges(_repo.FullPath, _selectedStaged, false, storageFile.Path.LocalPath));
if (succ)
App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess"));
}
diff --git a/src/Views/Blame.axaml b/src/Views/Blame.axaml
index 98e1c4f2..9d3afd77 100644
--- a/src/Views/Blame.axaml
+++ b/src/Views/Blame.axaml
@@ -57,6 +57,7 @@
Background="Transparent"
Foreground="{DynamicResource Brush.FG1}"
FontFamily="{DynamicResource Fonts.Monospace}"
+ FontSize="{Binding Source={x:Static vm:Preference.Instance}, Path=EditorFontSize}"
BlameData="{Binding Data}"/>
diff --git a/src/Views/Blame.axaml.cs b/src/Views/Blame.axaml.cs
index 164b89de..d32e4370 100644
--- a/src/Views/Blame.axaml.cs
+++ b/src/Views/Blame.axaml.cs
@@ -407,8 +407,8 @@ namespace SourceGit.Views
var menu = new ContextMenu();
menu.Items.Add(copy);
+ menu.Open(TextArea.TextView);
- TextArea.TextView.OpenContextMenu(menu);
e.Handled = true;
}
diff --git a/src/Views/BranchCompare.axaml.cs b/src/Views/BranchCompare.axaml.cs
index 90ec1af5..ca90a180 100644
--- a/src/Views/BranchCompare.axaml.cs
+++ b/src/Views/BranchCompare.axaml.cs
@@ -15,7 +15,7 @@ namespace SourceGit.Views
if (DataContext is ViewModels.BranchCompare vm && sender is ChangeCollectionView view)
{
var menu = vm.CreateChangeContextMenu();
- view.OpenContextMenu(menu);
+ menu?.Open(view);
}
e.Handled = true;
diff --git a/src/Views/BranchTree.axaml.cs b/src/Views/BranchTree.axaml.cs
index 081160d0..e96b2594 100644
--- a/src/Views/BranchTree.axaml.cs
+++ b/src/Views/BranchTree.axaml.cs
@@ -374,7 +374,7 @@ namespace SourceGit.Views
if (selected.Count == 1 && selected[0] is ViewModels.BranchTreeNode { Backend: Models.Remote remote })
{
var menu = repo.CreateContextMenuForRemote(remote);
- this.OpenContextMenu(menu);
+ menu?.Open(this);
return;
}
@@ -391,7 +391,7 @@ namespace SourceGit.Views
var menu = branch.IsLocal ?
repo.CreateContextMenuForLocalBranch(branch) :
repo.CreateContextMenuForRemoteBranch(branch);
- this.OpenContextMenu(menu);
+ menu?.Open(this);
}
else if (branches.Find(x => x.IsCurrent) == null)
{
@@ -405,7 +405,7 @@ namespace SourceGit.Views
ev.Handled = true;
};
menu.Items.Add(deleteMulti);
- this.OpenContextMenu(menu);
+ menu?.Open(this);
}
}
diff --git a/src/Views/CommitBaseInfo.axaml b/src/Views/CommitBaseInfo.axaml
index 62117480..a16143ae 100644
--- a/src/Views/CommitBaseInfo.axaml
+++ b/src/Views/CommitBaseInfo.axaml
@@ -141,7 +141,13 @@
Message="{Binding #ThisControl.Message}"
IssueTrackerRules="{Binding #ThisControl.IssueTrackerRules}"
HorizontalAlignment="Stretch"
- TextWrapping="Wrap"/>
+ TextWrapping="Wrap">
+
+
+
+
diff --git a/src/Views/CommitBaseInfo.axaml.cs b/src/Views/CommitBaseInfo.axaml.cs
index e31ddfba..7992b40d 100644
--- a/src/Views/CommitBaseInfo.axaml.cs
+++ b/src/Views/CommitBaseInfo.axaml.cs
@@ -68,7 +68,7 @@ namespace SourceGit.Views
private void OnOpenWebLink(object sender, RoutedEventArgs e)
{
- if (DataContext is ViewModels.CommitDetail detail)
+ if (DataContext is ViewModels.CommitDetail detail && sender is Control control)
{
var links = WebLinks;
if (links.Count > 1)
@@ -88,7 +88,7 @@ namespace SourceGit.Views
menu.Items.Add(item);
}
- (sender as Control)?.OpenContextMenu(menu);
+ menu?.Open(control);
}
else if (links.Count == 1)
{
diff --git a/src/Views/CommitChanges.axaml.cs b/src/Views/CommitChanges.axaml.cs
index f197bdd5..c3d30018 100644
--- a/src/Views/CommitChanges.axaml.cs
+++ b/src/Views/CommitChanges.axaml.cs
@@ -16,7 +16,7 @@ namespace SourceGit.Views
DataContext is ViewModels.CommitDetail vm)
{
var menu = vm.CreateChangeContextMenu(selected[0]);
- view.OpenContextMenu(menu);
+ menu?.Open(view);
}
e.Handled = true;
diff --git a/src/Views/CommitDetail.axaml.cs b/src/Views/CommitDetail.axaml.cs
index 999d1c07..f0599c66 100644
--- a/src/Views/CommitDetail.axaml.cs
+++ b/src/Views/CommitDetail.axaml.cs
@@ -26,7 +26,7 @@ namespace SourceGit.Views
if (DataContext is ViewModels.CommitDetail detail && sender is Grid grid && grid.DataContext is Models.Change change)
{
var menu = detail.CreateChangeContextMenu(change);
- grid.OpenContextMenu(menu);
+ menu?.Open(grid);
}
e.Handled = true;
diff --git a/src/Views/CommitMessagePresenter.cs b/src/Views/CommitMessagePresenter.cs
index 55e1dfb1..862ce9e1 100644
--- a/src/Views/CommitMessagePresenter.cs
+++ b/src/Views/CommitMessagePresenter.cs
@@ -176,7 +176,38 @@ namespace SourceGit.Views
}
else
{
- Native.OS.OpenBrowser(_lastHover.Link);
+ var point = e.GetCurrentPoint(this);
+ var link = _lastHover.Link;
+
+ if (point.Properties.IsLeftButtonPressed)
+ {
+ Native.OS.OpenBrowser(link);
+ }
+ else if (point.Properties.IsRightButtonPressed)
+ {
+ var open = new MenuItem();
+ open.Header = App.Text("IssueLinkCM.OpenInBrowser");
+ open.Icon = App.CreateMenuIcon("Icons.OpenWith");
+ open.Click += (_, ev) =>
+ {
+ Native.OS.OpenBrowser(link);
+ ev.Handled = true;
+ };
+
+ var copy = new MenuItem();
+ copy.Header = App.Text("IssueLinkCM.CopyLink");
+ copy.Icon = App.CreateMenuIcon("Icons.Copy");
+ copy.Click += (_, ev) =>
+ {
+ App.CopyText(link);
+ ev.Handled = true;
+ };
+
+ var menu = new ContextMenu();
+ menu.Items.Add(open);
+ menu.Items.Add(copy);
+ menu.Open(this);
+ }
}
e.Handled = true;
diff --git a/src/Views/CommitMessageTextBox.axaml.cs b/src/Views/CommitMessageTextBox.axaml.cs
index 6eec0379..91f8c47e 100644
--- a/src/Views/CommitMessageTextBox.axaml.cs
+++ b/src/Views/CommitMessageTextBox.axaml.cs
@@ -125,7 +125,7 @@ namespace SourceGit.Views
DescriptionEditor.CaretIndex = 0;
e.Handled = true;
}
- else if (e.Key == Key.V && ((OperatingSystem.IsMacOS() && e.KeyModifiers == KeyModifiers.Meta) || (!OperatingSystem.IsMacOS() && e.KeyModifiers == KeyModifiers.Control)))
+ else if (e.Key == Key.V && e.KeyModifiers == (OperatingSystem.IsMacOS() ? KeyModifiers.Meta : KeyModifiers.Control))
{
e.Handled = true;
diff --git a/src/Views/ContextMenuExtension.cs b/src/Views/ContextMenuExtension.cs
deleted file mode 100644
index 2abcf2b9..00000000
--- a/src/Views/ContextMenuExtension.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System.ComponentModel;
-using Avalonia.Controls;
-
-namespace SourceGit.Views
-{
- public static class ContextMenuExtension
- {
- public static void OpenContextMenu(this Control control, ContextMenu menu)
- {
- if (menu == null)
- return;
-
- menu.PlacementTarget = control;
- menu.Closing += OnContextMenuClosing; // Clear context menu because it is dynamic.
-
- control.ContextMenu = menu;
- control.ContextMenu?.Open();
- }
-
- private static void OnContextMenuClosing(object sender, CancelEventArgs e)
- {
- if (sender is ContextMenu menu && menu.PlacementTarget != null)
- menu.PlacementTarget.ContextMenu = null;
- }
- }
-}
diff --git a/src/Views/DiffView.axaml b/src/Views/DiffView.axaml
index 8ccc25bb..06525abd 100644
--- a/src/Views/DiffView.axaml
+++ b/src/Views/DiffView.axaml
@@ -39,6 +39,9 @@
Command="{Binding IncrUnified}"
IsVisible="{Binding IsTextDiff}"
ToolTip.Tip="{DynamicResource Text.Diff.VisualLines.Incr}">
+
+
+
@@ -46,10 +49,26 @@
Width="32"
Command="{Binding DecrUnified}"
IsVisible="{Binding IsTextDiff}"
- ToolTip.Tip="{DynamicResource Text.Diff.VisualLines.Decr}"
- IsEnabled="{Binding UnifiedLines, Converter={x:Static c:IntConverters.IsGreaterThanFour}}">
+ ToolTip.Tip="{DynamicResource Text.Diff.VisualLines.Decr}">
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/src/Views/Histories.axaml.cs b/src/Views/Histories.axaml.cs
index 137fd298..9f436346 100644
--- a/src/Views/Histories.axaml.cs
+++ b/src/Views/Histories.axaml.cs
@@ -706,7 +706,7 @@ namespace SourceGit.Views
if (DataContext is ViewModels.Histories histories && sender is ListBox { SelectedItems: { Count: > 0 } } list)
{
var menu = histories.MakeContextMenu(list);
- list.OpenContextMenu(menu);
+ menu?.Open(list);
}
e.Handled = true;
}
@@ -722,19 +722,39 @@ namespace SourceGit.Views
private void OnCommitListKeyDown(object sender, KeyEventArgs e)
{
- if (sender is ListBox { SelectedItems: { Count: > 0 } selected } &&
- e.Key == Key.C &&
- e.KeyModifiers.HasFlag(KeyModifiers.Control))
+ if (!e.KeyModifiers.HasFlag(OperatingSystem.IsMacOS() ? KeyModifiers.Meta : KeyModifiers.Control))
+ return;
+
+ // These shortcuts are not mentioned in the Shortcut Reference window. Is this expected?
+ if (sender is ListBox { SelectedItems: { Count: > 0 } selected })
{
- var builder = new StringBuilder();
- foreach (var item in selected)
+ // CTRL/COMMAND + C -> Copy selected commit SHA and subject.
+ if (e.Key == Key.C)
{
- if (item is Models.Commit commit)
- builder.AppendLine($"{commit.SHA.Substring(0, 10)} - {commit.Subject}");
+ var builder = new StringBuilder();
+ foreach (var item in selected)
+ {
+ if (item is Models.Commit commit)
+ builder.AppendLine($"{commit.SHA.Substring(0, 10)} - {commit.Subject}");
+ }
+
+ App.CopyText(builder.ToString());
+ e.Handled = true;
+ return;
}
- App.CopyText(builder.ToString());
- e.Handled = true;
+ // CTRL/COMMAND + B -> shows Create Branch pop-up at selected commit.
+ if (e.Key == Key.B)
+ {
+ if (selected.Count == 1 &&
+ selected[0] is Models.Commit commit &&
+ DataContext is ViewModels.Histories histories &&
+ ViewModels.PopupHost.CanCreatePopup())
+ {
+ ViewModels.PopupHost.ShowPopup(new ViewModels.CreateBranch(histories.Repo, commit));
+ e.Handled = true;
+ }
+ }
}
}
diff --git a/src/Views/Hotkeys.axaml b/src/Views/Hotkeys.axaml
index a28bc566..4fe77066 100644
--- a/src/Views/Hotkeys.axaml
+++ b/src/Views/Hotkeys.axaml
@@ -71,7 +71,7 @@
FontSize="{Binding Source={x:Static vm:Preference.Instance}, Path=DefaultFontSize, Converter={x:Static c:DoubleConverters.Increase}}"
Margin="0,8"/>
-
+
@@ -102,8 +102,20 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -38,103 +39,100 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
diff --git a/src/Views/LauncherPage.axaml.cs b/src/Views/LauncherPage.axaml.cs
index 44a5351b..d37d22bd 100644
--- a/src/Views/LauncherPage.axaml.cs
+++ b/src/Views/LauncherPage.axaml.cs
@@ -27,7 +27,7 @@ namespace SourceGit.Views
e.Handled = true;
}
- private void OnPopupCancelByClickMask(object sender, PointerPressedEventArgs e)
+ private void OnMaskClicked(object sender, PointerPressedEventArgs e)
{
OnPopupCancel(sender, e);
}
diff --git a/src/Views/LauncherTabBar.axaml.cs b/src/Views/LauncherTabBar.axaml.cs
index 3258a09c..f8c9107c 100644
--- a/src/Views/LauncherTabBar.axaml.cs
+++ b/src/Views/LauncherTabBar.axaml.cs
@@ -234,7 +234,7 @@ namespace SourceGit.Views
if (sender is Border border && DataContext is ViewModels.Launcher vm)
{
var menu = vm.CreateContextForPageTab(border.DataContext as ViewModels.LauncherPage);
- border.OpenContextMenu(menu);
+ menu?.Open(border);
}
e.Handled = true;
diff --git a/src/Views/Preference.axaml b/src/Views/Preference.axaml
index 9cf47f9c..73be0f7c 100644
--- a/src/Views/Preference.axaml
+++ b/src/Views/Preference.axaml
@@ -121,7 +121,7 @@
-
+
+
+
+
-
@@ -184,16 +196,16 @@
-
-
-
-