diff --git a/README.md b/README.md
index bf7d77b5a..016642907 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@
* Supports Windows/macOS/Linux
* Opensource/Free
* Fast
-* Deutsch/English/Español/Bahasa Indonesia/Français/Italiano/Português/Русский/Українська/简体中文/繁體中文/日本語/தமிழ் (Tamil)
+* Deutsch/English/Español/Bahasa Indonesia/Français/Italiano/Português/Русский/Українська/简体中文/繁體中文/日本語/தமிழ் (Tamil)/한국어
* Built-in light/dark themes
* Customize theme
* Visual commit graph
@@ -43,7 +43,9 @@
* Issue Link
* Workspace
* Custom Action
+* Create PR on GitHub/Gitlab/Gitea/Gitee/Bitbucket...
* Using AI to generate commit message (C# port of [anjerodev/commitollama](https://github.com/anjerodev/commitollama))
+* Built-in conventional commit message helper.
> [!WARNING]
> **Linux** only tested on **Debian 12** on both **X11** & **Wayland**.
@@ -155,7 +157,7 @@ This app supports open repository in external tools listed in the table below.
| Cursor | YES | YES | YES |
| Fleet | YES | YES | YES |
| Sublime Text | YES | YES | YES |
-| Zed | NO | YES | YES |
+| Zed | YES | YES | YES |
| Visual Studio | YES | NO | NO |
> [!NOTE]
@@ -172,6 +174,27 @@ This app supports open repository in external tools listed in the table below.
> [!NOTE]
> This app also supports a lot of `JetBrains` IDEs, installing `JetBrains Toolbox` will help this app to find them.
+## Conventional Commit Helper
+
+You can define your own conventional commit types (per-repository) by following steps:
+
+1. Create a json file with your own conventional commit type definitions. For example:
+```json
+[
+ {
+ "Name": "New Feature",
+ "Type": "Feature",
+ "Description": "Adding a new feature"
+ },
+ {
+ "Name": "Bug Fixes",
+ "Type": "Fix",
+ "Description": "Fixing a bug"
+ }
+]
+```
+2. Configure the `Conventional Commit Types` in repository configuration window.
+
## Screenshots
* Dark Theme
diff --git a/THIRD-PARTY-LICENSES.md b/THIRD-PARTY-LICENSES.md
index 4734482e6..706edfdb8 100644
--- a/THIRD-PARTY-LICENSES.md
+++ b/THIRD-PARTY-LICENSES.md
@@ -7,7 +7,7 @@ The project uses the following third-party libraries or assets
### AvaloniaUI
- **Source**: https://github.com/AvaloniaUI/Avalonia
-- **Version**: 11.3.7
+- **Version**: 11.3.8
- **License**: MIT License
- **License Link**: https://github.com/AvaloniaUI/Avalonia/blob/master/licence.md
diff --git a/TRANSLATION.md b/TRANSLATION.md
index 50d4cbc22..f781e64f6 100644
--- a/TRANSLATION.md
+++ b/TRANSLATION.md
@@ -8,9 +8,20 @@ This document shows the translation status of each locale file in the repository
### 
-### 
+### 
-### 
+
+Missing keys in es_ES.axaml
+
+- Text.Blame.BlameOnPreviousRevision
+- Text.Configure.CommitMessageTemplate.BuiltinVars
+- Text.Configure.Git.ConventionalTypesOverride
+- Text.ConfigureCustomActionControls.StringValue.Tip
+- Text.Launcher.OpenRepository
+
+
+
+### 
Missing keys in fr_FR.axaml
@@ -30,6 +41,9 @@ This document shows the translation status of each locale file in the repository
- Text.Bisect.Good
- Text.Bisect.Skip
- Text.Bisect.WaitingForRange
+- Text.Blame.BlameOnPreviousRevision
+- Text.BranchCM.CreatePR
+- Text.BranchCM.CreatePRForUpstream
- Text.BranchCM.ResetToSelectedCommit
- Text.BranchCM.SwitchToWorktree
- Text.BranchTree.Ahead
@@ -77,6 +91,7 @@ This document shows the translation status of each locale file in the repository
- Text.Configure.CustomAction.InputControls.Edit
- Text.Configure.CustomAction.Scope.Remote
- Text.Configure.CustomAction.Scope.Tag
+- Text.Configure.Git.ConventionalTypesOverride
- Text.Configure.Git.PreferredMergeMode
- Text.Configure.IssueTracker.AddSampleGerritChangeIdCommit
- Text.Configure.IssueTracker.Share
@@ -89,6 +104,7 @@ This document shows the translation status of each locale file in the repository
- Text.ConfigureCustomActionControls.Label
- Text.ConfigureCustomActionControls.Options
- Text.ConfigureCustomActionControls.Options.Tip
+- Text.ConfigureCustomActionControls.StringValue.Tip
- Text.ConfigureCustomActionControls.Type
- Text.ConfirmEmptyCommit.Continue
- Text.ConfirmEmptyCommit.NoLocalChanges
@@ -122,10 +138,10 @@ This document shows the translation status of each locale file in the repository
- Text.ExecuteCustomAction.Repository
- Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash
-- Text.Hotkeys.Global.SwitchWorkspace
- Text.Hotkeys.Global.SwitchTab
- Text.Hotkeys.TextEditor.OpenExternalMergeTool
- Text.InteractiveRebase.ReorderTip
+- Text.Launcher.OpenRepository
- Text.Launcher.Pages
- Text.Launcher.Workspaces
- Text.Merge.Edit
@@ -144,6 +160,8 @@ This document shows the translation status of each locale file in the repository
- Text.Push.New
- Text.Push.Revision
- Text.Push.Revision.Title
+- Text.PushToNewBranch
+- Text.PushToNewBranch.Title
- Text.RemoteCM.CustomAction
- Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate
@@ -217,25 +235,37 @@ This document shows the translation status of each locale file in the repository
-### 
+### 
Missing keys in id_ID.axaml
- Text.About.ReleaseNotes
+- Text.Blame.BlameOnPreviousRevision
+- Text.BranchCM.CreatePR
+- Text.BranchCM.CreatePRForUpstream
- Text.CommitCM.Drop
+- Text.Configure.CommitMessageTemplate.BuiltinVars
+- Text.Configure.Git.ConventionalTypesOverride
+- Text.ConfigureCustomActionControls.StringValue.Tip
- Text.DropHead
- Text.DropHead.Commit
- Text.DropHead.NewHead
+- Text.Launcher.OpenRepository
+- Text.PushToNewBranch
+- Text.PushToNewBranch.Title
-### 
+### 
Missing keys in it_IT.axaml
- Text.About.ReleaseNotes
+- Text.Blame.BlameOnPreviousRevision
+- Text.BranchCM.CreatePR
+- Text.BranchCM.CreatePRForUpstream
- Text.BranchCM.SwitchToWorktree
- Text.BranchTree.Ahead
- Text.BranchTree.AheadBehind
@@ -247,6 +277,9 @@ This document shows the translation status of each locale file in the repository
- Text.CommitDetail.Info.CopyName
- Text.CommitDetail.Info.CopyNameAndEmail
- Text.CommitMessageTextBox.PasteAndReplaceAll
+- Text.Configure.CommitMessageTemplate.BuiltinVars
+- Text.Configure.Git.ConventionalTypesOverride
+- Text.ConfigureCustomActionControls.StringValue.Tip
- Text.Diff.Image.Difference
- Text.DirtyState.HasLocalChanges
- Text.DirtyState.HasPendingPullOrPush
@@ -254,12 +287,15 @@ This document shows the translation status of each locale file in the repository
- Text.DropHead
- Text.DropHead.Commit
- Text.DropHead.NewHead
+- Text.Launcher.OpenRepository
- Text.Preferences.AI.ReadApiKeyFromEnv
- Text.Preferences.Appearance.UseAutoHideScrollBars
- Text.Preferences.General.EnableCompactFolders
- Text.Preferences.General.ShowChangesPageByDefault
- Text.Preferences.General.ShowChangesTabInCommitDetailByDefault
- Text.Preferences.General.UseGitHubStyleAvatar
+- Text.PushToNewBranch
+- Text.PushToNewBranch.Title
- Text.ScanRepositories.UseCustomDir
- Text.WorkingCopy.ClearCommitHistories
- Text.WorkingCopy.ClearCommitHistories.Confirm
@@ -268,7 +304,7 @@ This document shows the translation status of each locale file in the repository
-### 
+### 
Missing keys in ja_JP.axaml
@@ -288,7 +324,10 @@ This document shows the translation status of each locale file in the repository
- Text.Bisect.Good
- Text.Bisect.Skip
- Text.Bisect.WaitingForRange
+- Text.Blame.BlameOnPreviousRevision
- Text.BranchCM.CompareWithCurrent
+- Text.BranchCM.CreatePR
+- Text.BranchCM.CreatePRForUpstream
- Text.BranchCM.ResetToSelectedCommit
- Text.BranchCM.SwitchToWorktree
- Text.BranchTree.Ahead
@@ -336,6 +375,7 @@ This document shows the translation status of each locale file in the repository
- Text.Configure.CustomAction.InputControls.Edit
- Text.Configure.CustomAction.Scope.Remote
- Text.Configure.CustomAction.Scope.Tag
+- Text.Configure.Git.ConventionalTypesOverride
- Text.Configure.Git.PreferredMergeMode
- Text.Configure.IssueTracker.AddSampleGerritChangeIdCommit
- Text.Configure.IssueTracker.Share
@@ -348,6 +388,7 @@ This document shows the translation status of each locale file in the repository
- Text.ConfigureCustomActionControls.Label
- Text.ConfigureCustomActionControls.Options
- Text.ConfigureCustomActionControls.Options.Tip
+- Text.ConfigureCustomActionControls.StringValue.Tip
- Text.ConfigureCustomActionControls.Type
- Text.ConfirmEmptyCommit.Continue
- Text.ConfirmEmptyCommit.NoLocalChanges
@@ -381,10 +422,10 @@ This document shows the translation status of each locale file in the repository
- Text.ExecuteCustomAction.Repository
- Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash
-- Text.Hotkeys.Global.SwitchWorkspace
- Text.Hotkeys.Global.SwitchTab
- Text.Hotkeys.TextEditor.OpenExternalMergeTool
- Text.InteractiveRebase.ReorderTip
+- Text.Launcher.OpenRepository
- Text.Launcher.Pages
- Text.Launcher.Workspaces
- Text.Merge.Edit
@@ -403,6 +444,8 @@ This document shows the translation status of each locale file in the repository
- Text.Push.New
- Text.Push.Revision
- Text.Push.Revision.Title
+- Text.PushToNewBranch
+- Text.PushToNewBranch.Title
- Text.RemoteCM.CustomAction
- Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate
@@ -475,7 +518,25 @@ This document shows the translation status of each locale file in the repository
-### 
+### 
+
+
+Missing keys in ko_KR.axaml
+
+- Text.Blame.BlameOnPreviousRevision
+- Text.Blame.TypeNotSupported
+- Text.BranchCM.CreatePR
+- Text.BranchCM.CreatePRForUpstream
+- Text.Configure.Git.ConventionalTypesOverride
+- Text.ConfigureCustomActionControls.StringValue.Tip
+- Text.Launcher.OpenRepository
+- Text.PushToNewBranch
+- Text.PushToNewBranch.Title
+- Text.Submodule.Status.Unmerged
+
+
+
+### 
Missing keys in pt_BR.axaml
@@ -501,6 +562,9 @@ This document shows the translation status of each locale file in the repository
- Text.Bisect.Good
- Text.Bisect.Skip
- Text.Bisect.WaitingForRange
+- Text.Blame.BlameOnPreviousRevision
+- Text.BranchCM.CreatePR
+- Text.BranchCM.CreatePRForUpstream
- Text.BranchCM.CustomAction
- Text.BranchCM.MergeMultiBranches
- Text.BranchCM.ResetToSelectedCommit
@@ -557,6 +621,7 @@ This document shows the translation status of each locale file in the repository
- Text.Configure.CustomAction.Scope.Remote
- Text.Configure.CustomAction.Scope.Tag
- Text.Configure.CustomAction.WaitForExit
+- Text.Configure.Git.ConventionalTypesOverride
- Text.Configure.Git.PreferredMergeMode
- Text.Configure.IssueTracker.AddSampleGerritChangeIdCommit
- Text.Configure.IssueTracker.AddSampleGiteeIssue
@@ -571,6 +636,7 @@ This document shows the translation status of each locale file in the repository
- Text.ConfigureCustomActionControls.Label
- Text.ConfigureCustomActionControls.Options
- Text.ConfigureCustomActionControls.Options.Tip
+- Text.ConfigureCustomActionControls.StringValue.Tip
- Text.ConfigureCustomActionControls.Type
- Text.ConfirmEmptyCommit.Continue
- Text.ConfirmEmptyCommit.NoLocalChanges
@@ -613,7 +679,6 @@ This document shows the translation status of each locale file in the repository
- Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash
- Text.Hotkeys.Global.Clone
-- Text.Hotkeys.Global.SwitchWorkspace
- Text.Hotkeys.Global.SwitchTab
- Text.Hotkeys.TextEditor.OpenExternalMergeTool
- Text.InProgress.CherryPick.Head
@@ -621,6 +686,7 @@ This document shows the translation status of each locale file in the repository
- Text.InProgress.Rebase.StoppedAt
- Text.InProgress.Revert.Head
- Text.InteractiveRebase.ReorderTip
+- Text.Launcher.OpenRepository
- Text.Launcher.Pages
- Text.Launcher.Workspaces
- Text.Merge.Edit
@@ -650,6 +716,8 @@ This document shows the translation status of each locale file in the repository
- Text.Push.New
- Text.Push.Revision
- Text.Push.Revision.Title
+- Text.PushToNewBranch
+- Text.PushToNewBranch.Title
- Text.RemoteCM.CustomAction
- Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate
@@ -741,7 +809,7 @@ This document shows the translation status of each locale file in the repository
### 
-### 
+### 
Missing keys in ta_IN.axaml
@@ -761,7 +829,10 @@ This document shows the translation status of each locale file in the repository
- Text.Bisect.Good
- Text.Bisect.Skip
- Text.Bisect.WaitingForRange
+- Text.Blame.BlameOnPreviousRevision
- Text.BranchCM.CompareWithCurrent
+- Text.BranchCM.CreatePR
+- Text.BranchCM.CreatePRForUpstream
- Text.BranchCM.ResetToSelectedCommit
- Text.BranchCM.SwitchToWorktree
- Text.BranchTree.Ahead
@@ -809,6 +880,7 @@ This document shows the translation status of each locale file in the repository
- Text.Configure.CustomAction.InputControls.Edit
- Text.Configure.CustomAction.Scope.Remote
- Text.Configure.CustomAction.Scope.Tag
+- Text.Configure.Git.ConventionalTypesOverride
- Text.Configure.Git.PreferredMergeMode
- Text.Configure.IssueTracker.AddSampleGerritChangeIdCommit
- Text.Configure.IssueTracker.Share
@@ -821,6 +893,7 @@ This document shows the translation status of each locale file in the repository
- Text.ConfigureCustomActionControls.Label
- Text.ConfigureCustomActionControls.Options
- Text.ConfigureCustomActionControls.Options.Tip
+- Text.ConfigureCustomActionControls.StringValue.Tip
- Text.ConfigureCustomActionControls.Type
- Text.ConfirmEmptyCommit.Continue
- Text.ConfirmEmptyCommit.NoLocalChanges
@@ -854,10 +927,10 @@ This document shows the translation status of each locale file in the repository
- Text.ExecuteCustomAction.Repository
- Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash
-- Text.Hotkeys.Global.SwitchWorkspace
- Text.Hotkeys.Global.SwitchTab
- Text.Hotkeys.TextEditor.OpenExternalMergeTool
- Text.InteractiveRebase.ReorderTip
+- Text.Launcher.OpenRepository
- Text.Launcher.Pages
- Text.Launcher.Workspaces
- Text.Merge.Edit
@@ -876,6 +949,8 @@ This document shows the translation status of each locale file in the repository
- Text.Push.New
- Text.Push.Revision
- Text.Push.Revision.Title
+- Text.PushToNewBranch
+- Text.PushToNewBranch.Title
- Text.RemoteCM.CustomAction
- Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate
@@ -947,7 +1022,7 @@ This document shows the translation status of each locale file in the repository
-### 
+### 
Missing keys in uk_UA.axaml
@@ -967,6 +1042,9 @@ This document shows the translation status of each locale file in the repository
- Text.Bisect.Good
- Text.Bisect.Skip
- Text.Bisect.WaitingForRange
+- Text.Blame.BlameOnPreviousRevision
+- Text.BranchCM.CreatePR
+- Text.BranchCM.CreatePRForUpstream
- Text.BranchCM.ResetToSelectedCommit
- Text.BranchCM.SwitchToWorktree
- Text.BranchTree.Ahead
@@ -1014,6 +1092,7 @@ This document shows the translation status of each locale file in the repository
- Text.Configure.CustomAction.InputControls.Edit
- Text.Configure.CustomAction.Scope.Remote
- Text.Configure.CustomAction.Scope.Tag
+- Text.Configure.Git.ConventionalTypesOverride
- Text.Configure.IssueTracker.AddSampleGerritChangeIdCommit
- Text.Configure.IssueTracker.Share
- Text.ConfigureCustomActionControls
@@ -1025,6 +1104,7 @@ This document shows the translation status of each locale file in the repository
- Text.ConfigureCustomActionControls.Label
- Text.ConfigureCustomActionControls.Options
- Text.ConfigureCustomActionControls.Options.Tip
+- Text.ConfigureCustomActionControls.StringValue.Tip
- Text.ConfigureCustomActionControls.Type
- Text.ConfigureWorkspace.Name
- Text.ConfirmRestart.Title
@@ -1055,10 +1135,10 @@ This document shows the translation status of each locale file in the repository
- Text.ExecuteCustomAction.Repository
- Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash
-- Text.Hotkeys.Global.SwitchWorkspace
- Text.Hotkeys.Global.SwitchTab
- Text.Hotkeys.TextEditor.OpenExternalMergeTool
- Text.InteractiveRebase.ReorderTip
+- Text.Launcher.OpenRepository
- Text.Launcher.Pages
- Text.Launcher.Workspaces
- Text.Merge.Edit
@@ -1077,6 +1157,8 @@ This document shows the translation status of each locale file in the repository
- Text.Push.New
- Text.Push.Revision
- Text.Push.Revision.Title
+- Text.PushToNewBranch
+- Text.PushToNewBranch.Title
- Text.RemoteCM.CustomAction
- Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate
diff --git a/VERSION b/VERSION
index 25abceaab..31514320c 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2025.36
\ No newline at end of file
+2025.37
\ No newline at end of file
diff --git a/src/App.JsonCodeGen.cs b/src/App.JsonCodeGen.cs
index d60b76515..9ef93d231 100644
--- a/src/App.JsonCodeGen.cs
+++ b/src/App.JsonCodeGen.cs
@@ -65,6 +65,8 @@ public override void Write(Utf8JsonWriter writer, DataGridLength value, JsonSeri
[JsonSerializable(typeof(Models.ThemeOverrides))]
[JsonSerializable(typeof(Models.Version))]
[JsonSerializable(typeof(Models.RepositorySettings))]
+ [JsonSerializable(typeof(List))]
+ [JsonSerializable(typeof(List))]
[JsonSerializable(typeof(List))]
[JsonSerializable(typeof(ViewModels.Preferences))]
internal partial class JsonCodeGen : JsonSerializerContext { }
diff --git a/src/App.axaml b/src/App.axaml
index 36c17decd..a7a0c17f2 100644
--- a/src/App.axaml
+++ b/src/App.axaml
@@ -24,6 +24,7 @@
+
diff --git a/src/App.axaml.cs b/src/App.axaml.cs
index 242a5f13c..089d8da8b 100644
--- a/src/App.axaml.cs
+++ b/src/App.axaml.cs
@@ -262,7 +262,7 @@ public static void SetTheme(string theme, string themeOverridesFile)
}
}
- public static void SetFonts(string defaultFont, string monospaceFont, bool onlyUseMonospaceFontInEditor)
+ public static void SetFonts(string defaultFont, string monospaceFont)
{
if (Current is not App app)
return;
@@ -285,7 +285,7 @@ public static void SetFonts(string defaultFont, string monospaceFont, bool onlyU
if (!string.IsNullOrEmpty(defaultFont))
{
monospaceFont = $"fonts:SourceGit#JetBrains Mono,{defaultFont}";
- resDic.Add("Fonts.Monospace", new FontFamily(monospaceFont));
+ resDic.Add("Fonts.Monospace", FontFamily.Parse(monospaceFont));
}
}
else
@@ -293,20 +293,7 @@ public static void SetFonts(string defaultFont, string monospaceFont, bool onlyU
if (!string.IsNullOrEmpty(defaultFont) && !monospaceFont.Contains(defaultFont, StringComparison.Ordinal))
monospaceFont = $"{monospaceFont},{defaultFont}";
- resDic.Add("Fonts.Monospace", new FontFamily(monospaceFont));
- }
-
- if (onlyUseMonospaceFontInEditor)
- {
- if (string.IsNullOrEmpty(defaultFont))
- resDic.Add("Fonts.Primary", new FontFamily("fonts:Inter#Inter"));
- else
- resDic.Add("Fonts.Primary", new FontFamily(defaultFont));
- }
- else
- {
- if (!string.IsNullOrEmpty(monospaceFont))
- resDic.Add("Fonts.Primary", new FontFamily(monospaceFont));
+ resDic.Add("Fonts.Monospace", FontFamily.Parse(monospaceFont));
}
if (resDic.Count > 0)
@@ -383,7 +370,7 @@ public override void Initialize()
SetLocale(pref.Locale);
SetTheme(pref.Theme, pref.ThemeOverrides);
- SetFonts(pref.DefaultFontFamily, pref.MonospaceFontFamily, pref.OnlyUseMonoFontInEditor);
+ SetFonts(pref.DefaultFontFamily, pref.MonospaceFontFamily);
}
public override void OnFrameworkInitializationCompleted()
@@ -676,9 +663,8 @@ private string FixFontFamilyName(string input)
if (string.IsNullOrEmpty(t))
continue;
- // Collapse multiple spaces into single space
- var prevChar = '\0';
var sb = new StringBuilder();
+ var prevChar = '\0';
foreach (var c in t)
{
@@ -689,14 +675,16 @@ private string FixFontFamilyName(string input)
}
var name = sb.ToString();
- if (name.Contains('#'))
+ try
{
- if (!name.Equals("fonts:Inter#Inter", StringComparison.Ordinal) &&
- !name.Equals("fonts:SourceGit#JetBrains Mono", StringComparison.Ordinal))
- continue;
+ var fontFamily = FontFamily.Parse(name);
+ if (fontFamily.FamilyTypefaces.Count > 0)
+ trimmed.Add(name);
+ }
+ catch
+ {
+ // Ignore exceptions.
}
-
- trimmed.Add(name);
}
return trimmed.Count > 0 ? string.Join(',', trimmed) : string.Empty;
diff --git a/src/Commands/Checkout.cs b/src/Commands/Checkout.cs
index 23cbd413b..024636bf9 100644
--- a/src/Commands/Checkout.cs
+++ b/src/Commands/Checkout.cs
@@ -72,5 +72,20 @@ public async Task FileWithRevisionAsync(string file, string revision)
Args = $"checkout --no-overlay {revision} -- {file.Quoted()}";
return await ExecAsync().ConfigureAwait(false);
}
+
+ public async Task MultipleFilesWithRevisionAsync(List files, string revision)
+ {
+ var builder = new StringBuilder();
+ builder
+ .Append("checkout --no-overlay ")
+ .Append(revision)
+ .Append(" --");
+
+ foreach (var f in files)
+ builder.Append(' ').Append(f.Quoted());
+
+ Args = builder.ToString();
+ return await ExecAsync().ConfigureAwait(false);
+ }
}
}
diff --git a/src/Commands/CountLocalChangesWithoutUntracked.cs b/src/Commands/CountLocalChanges.cs
similarity index 66%
rename from src/Commands/CountLocalChangesWithoutUntracked.cs
rename to src/Commands/CountLocalChanges.cs
index 769d732e9..17916926d 100644
--- a/src/Commands/CountLocalChangesWithoutUntracked.cs
+++ b/src/Commands/CountLocalChanges.cs
@@ -3,13 +3,14 @@
namespace SourceGit.Commands
{
- public class CountLocalChangesWithoutUntracked : Command
+ public class CountLocalChanges : Command
{
- public CountLocalChangesWithoutUntracked(string repo)
+ public CountLocalChanges(string repo, bool includeUntracked)
{
+ var option = includeUntracked ? "-uall" : "-uno";
WorkingDirectory = repo;
Context = repo;
- Args = "--no-optional-locks status -uno --ignore-submodules=all --porcelain";
+ Args = $"--no-optional-locks status {option} --ignore-submodules=all --porcelain";
}
public async Task GetResultAsync()
diff --git a/src/Commands/LFS.cs b/src/Commands/LFS.cs
index 001002d1d..8c0fd5051 100644
--- a/src/Commands/LFS.cs
+++ b/src/Commands/LFS.cs
@@ -1,16 +1,12 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Text;
-using System.Text.RegularExpressions;
+using System.Text.Json;
using System.Threading.Tasks;
namespace SourceGit.Commands
{
- public partial class LFS : Command
+ public class LFS : Command
{
- [GeneratedRegex(@"^(.+)\s+([\w.]+)\s+\w+:(\d+)$")]
- private static partial Regex REG_LOCK();
-
public LFS(string repo)
{
WorkingDirectory = repo;
@@ -60,30 +56,23 @@ public async Task PruneAsync()
public async Task> GetLocksAsync(string remote)
{
- Args = $"lfs locks --remote={remote}";
+ Args = $"lfs locks --json --remote={remote}";
var rs = await ReadToEndAsync().ConfigureAwait(false);
- var locks = new List();
-
if (rs.IsSuccess)
{
- var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
- foreach (var line in lines)
+ try
+ {
+ var locks = JsonSerializer.Deserialize(rs.StdOut, JsonCodeGen.Default.ListLFSLock);
+ return locks;
+ }
+ catch
{
- var match = REG_LOCK().Match(line);
- if (match.Success)
- {
- locks.Add(new Models.LFSLock()
- {
- File = match.Groups[1].Value,
- User = match.Groups[2].Value,
- ID = long.Parse(match.Groups[3].Value),
- });
- }
+ // Ignore exceptions.
}
}
- return locks;
+ return [];
}
public async Task LockAsync(string remote, string file)
diff --git a/src/Commands/QueryRepositoryStatus.cs b/src/Commands/QueryRepositoryStatus.cs
new file mode 100644
index 000000000..32c2489a6
--- /dev/null
+++ b/src/Commands/QueryRepositoryStatus.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace SourceGit.Commands
+{
+ public partial class QueryRepositoryStatus : Command
+ {
+ [GeneratedRegex(@"ahead\s(\d+)")]
+ private static partial Regex REG_AHEAD();
+
+ [GeneratedRegex(@"behind\s(\d+)")]
+ private static partial Regex REG_BEHIND();
+
+ public QueryRepositoryStatus(string repo)
+ {
+ WorkingDirectory = repo;
+ RaiseError = false;
+ }
+
+ public async Task GetResultAsync()
+ {
+ Args = "branch -l -v --format=\"%(refname:short)%00%(HEAD)%00%(upstream:track,nobracket)\"";
+ var rs = await ReadToEndAsync().ConfigureAwait(false);
+ if (!rs.IsSuccess)
+ return null;
+
+ var status = new Models.RepositoryStatus();
+ var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
+ foreach (var line in lines)
+ {
+ var parts = line.Split('\0');
+ if (parts.Length != 3 || !parts[1].Equals("*", StringComparison.Ordinal))
+ continue;
+
+ status.CurrentBranch = parts[0];
+ if (!string.IsNullOrEmpty(parts[2]))
+ ParseTrackStatus(status, parts[2]);
+ }
+
+ status.LocalChanges = await new CountLocalChanges(WorkingDirectory, true) { RaiseError = false }
+ .GetResultAsync()
+ .ConfigureAwait(false);
+
+ return status;
+ }
+
+ private void ParseTrackStatus(Models.RepositoryStatus status, string input)
+ {
+ var aheadMatch = REG_AHEAD().Match(input);
+ if (aheadMatch.Success)
+ status.Ahead = int.Parse(aheadMatch.Groups[1].Value);
+
+ var behindMatch = REG_BEHIND().Match(input);
+ if (behindMatch.Success)
+ status.Behind = int.Parse(behindMatch.Groups[1].Value);
+ }
+ }
+}
diff --git a/src/Converters/BoolConverters.cs b/src/Converters/BoolConverters.cs
index d101c6411..8a2f31416 100644
--- a/src/Converters/BoolConverters.cs
+++ b/src/Converters/BoolConverters.cs
@@ -5,9 +5,6 @@ namespace SourceGit.Converters
{
public static class BoolConverters
{
- public static readonly FuncValueConverter ToPageTabWidth =
- new FuncValueConverter(x => x ? 200 : double.NaN);
-
public static readonly FuncValueConverter IsBoldToFontWeight =
new FuncValueConverter(x => x ? FontWeight.Bold : FontWeight.Regular);
diff --git a/src/Models/Branch.cs b/src/Models/Branch.cs
index f2c593d31..47aa2153a 100644
--- a/src/Models/Branch.cs
+++ b/src/Models/Branch.cs
@@ -26,7 +26,7 @@ public class Branch
public bool HasWorktree => !IsCurrent && !string.IsNullOrEmpty(WorktreePath);
public string FriendlyName => IsLocal ? Name : $"{Remote}/{Name}";
- public bool IsTrackStatusVisible => Ahead.Count + Behind.Count > 0;
+ public bool IsTrackStatusVisible => Ahead.Count > 0 || Behind.Count > 0;
public string TrackStatusDescription
{
diff --git a/src/Models/CommitLink.cs b/src/Models/CommitLink.cs
index d9f1bb057..e7c3f697a 100644
--- a/src/Models/CommitLink.cs
+++ b/src/Models/CommitLink.cs
@@ -22,9 +22,6 @@ public static List Get(List remotes)
{
if (remote.TryGetVisitURL(out var link))
{
- if (link.EndsWith(".git"))
- link = link.Substring(0, link.Length - 4);
-
var uri = new Uri(link, UriKind.Absolute);
var host = uri.Host;
var route = uri.AbsolutePath.TrimStart('/');
diff --git a/src/Models/ConventionalCommitType.cs b/src/Models/ConventionalCommitType.cs
index 531a16c07..9275ff116 100644
--- a/src/Models/ConventionalCommitType.cs
+++ b/src/Models/ConventionalCommitType.cs
@@ -1,4 +1,6 @@
using System.Collections.Generic;
+using System.IO;
+using System.Text.Json;
namespace SourceGit.Models
{
@@ -8,26 +10,39 @@ public class ConventionalCommitType
public string Type { get; set; }
public string Description { get; set; }
- public static readonly List Supported = [
- new("Features", "feat", "Adding a new feature"),
- new("Bug Fixes", "fix", "Fixing a bug"),
- new("Work In Progress", "wip", "Still being developed and not yet complete"),
- new("Reverts", "revert", "Undoing a previous commit"),
- new("Code Refactoring", "refactor", "Restructuring code without changing its external behavior"),
- new("Performance Improvements", "perf", "Improves performance"),
- new("Builds", "build", "Changes that affect the build system or external dependencies"),
- new("Continuous Integrations", "ci", "Changes to CI configuration files and scripts"),
- new("Documentations", "docs", "Updating documentation"),
- new("Styles", "style", "Elements or code styles without changing the code logic"),
- new("Tests", "test", "Adding or updating tests"),
- new("Chores", "chore", "Other changes that don't modify src or test files"),
- ];
-
public ConventionalCommitType(string name, string type, string description)
{
Name = name;
Type = type;
Description = description;
}
+
+ public static List Load(string storageFile)
+ {
+ try
+ {
+ if (!string.IsNullOrEmpty(storageFile) && File.Exists(storageFile))
+ return JsonSerializer.Deserialize(File.ReadAllText(storageFile), JsonCodeGen.Default.ListConventionalCommitType) ?? [];
+ }
+ catch
+ {
+ // Ignore errors.
+ }
+
+ return new List {
+ new("Features", "feat", "Adding a new feature"),
+ new("Bug Fixes", "fix", "Fixing a bug"),
+ new("Work In Progress", "wip", "Still being developed and not yet complete"),
+ new("Reverts", "revert", "Undoing a previous commit"),
+ new("Code Refactoring", "refactor", "Restructuring code without changing its external behavior"),
+ new("Performance Improvements", "perf", "Improves performance"),
+ new("Builds", "build", "Changes that affect the build system or external dependencies"),
+ new("Continuous Integrations", "ci", "Changes to CI configuration files and scripts"),
+ new("Documentations", "docs", "Updating documentation"),
+ new("Styles", "style", "Elements or code styles without changing the code logic"),
+ new("Tests", "test", "Adding or updating tests"),
+ new("Chores", "chore", "Other changes that don't modify src or test files"),
+ };
+ }
}
}
diff --git a/src/Models/LFSLock.cs b/src/Models/LFSLock.cs
index 0a328cfb2..8d9a4acff 100644
--- a/src/Models/LFSLock.cs
+++ b/src/Models/LFSLock.cs
@@ -1,9 +1,22 @@
-namespace SourceGit.Models
+using System.Text.Json.Serialization;
+
+namespace SourceGit.Models
{
+ public class LFSLockOwner
+ {
+ [JsonPropertyName("name")]
+ public string Name { get; set; } = string.Empty;
+ }
+
public class LFSLock
{
- public string File { get; set; } = string.Empty;
- public string User { get; set; } = string.Empty;
- public long ID { get; set; } = 0;
+ [JsonPropertyName("id")]
+ public string ID { get; set; } = string.Empty;
+
+ [JsonPropertyName("path")]
+ public string Path { get; set; } = string.Empty;
+
+ [JsonPropertyName("owner")]
+ public LFSLockOwner Owner { get; set; } = null;
}
}
diff --git a/src/Models/Locales.cs b/src/Models/Locales.cs
index 42b878208..027433336 100644
--- a/src/Models/Locales.cs
+++ b/src/Models/Locales.cs
@@ -21,6 +21,7 @@ public class Locale
new Locale("繁體中文", "zh_TW"),
new Locale("日本語", "ja_JP"),
new Locale("தமிழ் (Tamil)", "ta_IN"),
+ new Locale("한국어", "ko_KR"),
};
public Locale(string name, string key)
diff --git a/src/Models/Remote.cs b/src/Models/Remote.cs
index b8632223c..3550a4e56 100644
--- a/src/Models/Remote.cs
+++ b/src/Models/Remote.cs
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Text.RegularExpressions;
+using System.Web;
namespace SourceGit.Models
{
@@ -65,7 +66,6 @@ public bool TryGetVisitURL(out string url)
if (URL.StartsWith("http", StringComparison.Ordinal))
{
- // Try to remove the user before host and `.git` extension.
var uri = new Uri(URL.EndsWith(".git", StringComparison.Ordinal) ? URL.Substring(0, URL.Length - 4) : URL);
if (uri.Port != 80 && uri.Port != 443)
url = $"{uri.Scheme}://{uri.Host}:{uri.Port}{uri.LocalPath}";
@@ -84,5 +84,56 @@ public bool TryGetVisitURL(out string url)
return false;
}
+
+ public bool TryGetCreatePullRequestURL(out string url, string mergeBranch)
+ {
+ url = null;
+
+ if (!TryGetVisitURL(out var baseURL))
+ return false;
+
+ var uri = new Uri(baseURL);
+ var host = uri.Host;
+ var route = uri.AbsolutePath.TrimStart('/');
+ var encodedBranch = HttpUtility.UrlEncode(mergeBranch);
+
+ if (host.Contains("github.com", StringComparison.Ordinal))
+ {
+ url = $"{baseURL}/compare/{encodedBranch}?expand=1";
+ return true;
+ }
+
+ if (host.Contains("gitlab", StringComparison.Ordinal))
+ {
+ url = $"{baseURL}/-/merge_requests/new?merge_request%5Bsource_branch%5D={encodedBranch}";
+ return true;
+ }
+
+ if (host.Equals("gitee.com", StringComparison.Ordinal))
+ {
+ url = $"{baseURL}/pulls/new?source={encodedBranch}";
+ return true;
+ }
+
+ if (host.Equals("bitbucket.org", StringComparison.Ordinal))
+ {
+ url = $"{baseURL}/pull-requests/new?source={encodedBranch}";
+ return true;
+ }
+
+ if (host.Equals("gitea.org", StringComparison.Ordinal))
+ {
+ url = $"{baseURL}/compare/{encodedBranch}";
+ return true;
+ }
+
+ if (host.Contains("azure.com", StringComparison.Ordinal))
+ {
+ url = $"{baseURL}/pullrequestcreate?sourceRef={encodedBranch}";
+ return true;
+ }
+
+ return false;
+ }
}
}
diff --git a/src/Models/RepositorySettings.cs b/src/Models/RepositorySettings.cs
index 0ca4eda27..3c310432e 100644
--- a/src/Models/RepositorySettings.cs
+++ b/src/Models/RepositorySettings.cs
@@ -236,6 +236,12 @@ public string LastCommitMessage
set;
} = string.Empty;
+ public string ConventionalTypesOverride
+ {
+ get;
+ set;
+ } = string.Empty;
+
public Dictionary CollectHistoriesFilters()
{
var map = new Dictionary();
diff --git a/src/Models/RepositoryStatus.cs b/src/Models/RepositoryStatus.cs
new file mode 100644
index 000000000..c7c498ae5
--- /dev/null
+++ b/src/Models/RepositoryStatus.cs
@@ -0,0 +1,29 @@
+namespace SourceGit.Models
+{
+ public class RepositoryStatus
+ {
+ public string CurrentBranch { get; set; } = string.Empty;
+ public int Ahead { get; set; } = 0;
+ public int Behind { get; set; } = 0;
+ public int LocalChanges { get; set; } = 0;
+
+ public bool IsTrackingStatusVisible
+ {
+ get
+ {
+ return Ahead > 0 || Behind > 0;
+ }
+ }
+
+ public string TrackingDescription
+ {
+ get
+ {
+ if (Ahead > 0)
+ return Behind > 0 ? $"{Ahead}↑ {Behind}↓" : $"{Ahead}↑";
+
+ return Behind > 0 ? $"{Behind}↓" : string.Empty;
+ }
+ }
+ }
+}
diff --git a/src/Models/TemplateEngine.cs b/src/Models/TemplateEngine.cs
index fc462918b..12280006e 100644
--- a/src/Models/TemplateEngine.cs
+++ b/src/Models/TemplateEngine.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Text;
using System.Text.RegularExpressions;
@@ -349,14 +350,10 @@ private static string EvalVariable(Context context, RegexVariable variable)
private delegate string VariableGetter(Context context);
private static readonly IReadOnlyDictionary s_variables = new Dictionary() {
- // legacy variables
{"branch_name", GetBranchName},
{"files_num", GetFilesCount},
{"files", GetFiles},
- //
- {"BRANCH", GetBranchName},
- {"FILES_COUNT", GetFilesCount},
- {"FILES", GetFiles},
+ {"pure_files", GetPureFiles},
};
private static string GetBranchName(Context context)
@@ -377,13 +374,19 @@ private static string GetFiles(Context context)
return string.Join(", ", paths);
}
+ private static string GetPureFiles(Context context)
+ {
+ var names = new List();
+ foreach (var c in context.changes)
+ names.Add(Path.GetFileName(c.Path));
+ return string.Join(", ", names);
+ }
+
private delegate string VariableSliceGetter(Context context, int count);
private static readonly IReadOnlyDictionary s_slicedVariables = new Dictionary() {
- // legacy variables
{"files", GetFilesSliced},
- //
- {"FILES", GetFilesSliced},
+ {"pure_files", GetPureFilesSliced}
};
private static string GetFilesSliced(Context context, int count)
@@ -400,5 +403,20 @@ private static string GetFilesSliced(Context context, int count)
return sb.ToString();
}
+
+ private static string GetPureFilesSliced(Context context, int count)
+ {
+ var sb = new StringBuilder();
+ var names = new List();
+ var max = Math.Min(count, context.changes.Count);
+ for (int i = 0; i < max; i++)
+ names.Add(Path.GetFileName(context.changes[i].Path));
+
+ sb.AppendJoin(", ", names);
+ if (max < context.changes.Count)
+ sb.Append($" and {context.changes.Count - max} other files");
+
+ return sb.ToString();
+ }
}
}
diff --git a/src/Native/Linux.cs b/src/Native/Linux.cs
index f6eb4ebf3..9cae29f46 100644
--- a/src/Native/Linux.cs
+++ b/src/Native/Linux.cs
@@ -57,7 +57,11 @@ public string FindTerminal(Models.ShellOrTerminal shell)
finder.Fleet(() => FindJetBrainsFleet(localAppDataDir));
finder.FindJetBrainsFromToolbox(() => Path.Combine(localAppDataDir, "JetBrains/Toolbox"));
finder.SublimeText(() => FindExecutable("subl"));
- finder.Zed(() => FindExecutable("zeditor"));
+ finder.Zed(() =>
+ {
+ var exec = FindExecutable("zeditor");
+ return string.IsNullOrEmpty(exec) ? FindExecutable("zed") : exec;
+ });
return finder.Tools;
}
@@ -130,7 +134,8 @@ private string FindExecutable(string filename)
return test;
}
- return string.Empty;
+ var local = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "bin", filename);
+ return File.Exists(local) ? local : string.Empty;
}
private string FindJetBrainsFleet(string localAppDataDir)
diff --git a/src/Native/Windows.cs b/src/Native/Windows.cs
index e63dbbb08..8439d702a 100644
--- a/src/Native/Windows.cs
+++ b/src/Native/Windows.cs
@@ -144,7 +144,7 @@ public string FindTerminal(Models.ShellOrTerminal shell)
break;
var binDir = Path.GetDirectoryName(OS.GitExecutable)!;
- var bash = Path.Combine(binDir, "bash.exe");
+ var bash = Path.GetFullPath(Path.Combine(binDir, "..", "git-bash.exe"));
if (!File.Exists(bash))
break;
@@ -187,10 +187,11 @@ public string FindTerminal(Models.ShellOrTerminal shell)
finder.VSCode(FindVSCode);
finder.VSCodeInsiders(FindVSCodeInsiders);
finder.VSCodium(FindVSCodium);
- finder.Cursor(FindCursor);
+ finder.Cursor(() => Path.Combine(localAppDataDir, @"Programs\Cursor\Cursor.exe"));
finder.Fleet(() => Path.Combine(localAppDataDir, @"Programs\Fleet\Fleet.exe"));
finder.FindJetBrainsFromToolbox(() => Path.Combine(localAppDataDir, @"JetBrains\Toolbox"));
finder.SublimeText(FindSublimeText);
+ finder.Zed(FindZed);
FindVisualStudio(finder);
return finder.Tools;
}
@@ -415,16 +416,20 @@ private void FindVisualStudio(Models.ExternalToolsFinder finder)
}
}
- private string FindCursor()
+ private string FindZed()
{
- var cursorPath = Path.Combine(
- Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
- "Programs",
- "Cursor",
- "Cursor.exe");
-
- if (File.Exists(cursorPath))
- return cursorPath;
+ var currentUser = Microsoft.Win32.RegistryKey.OpenBaseKey(
+ Microsoft.Win32.RegistryHive.CurrentUser,
+ Microsoft.Win32.RegistryView.Registry64);
+
+ // NOTE: this is the official Zed Preview reg data.
+ var preview = currentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{F70E4811-D0E2-4D88-AC99-D63752799F95}_is1");
+ if (preview != null)
+ return preview.GetValue("DisplayIcon") as string;
+
+ var findInPath = new StringBuilder("zed.exe", 512);
+ if (PathFindOnPath(findInPath, null))
+ return findInPath.ToString();
return string.Empty;
}
diff --git a/src/Resources/Icons.axaml b/src/Resources/Icons.axaml
index 4c54dce60..288313b49 100644
--- a/src/Resources/Icons.axaml
+++ b/src/Resources/Icons.axaml
@@ -26,6 +26,7 @@
M645 448l64 64 220-221L704 64l-64 64 115 115H128v90h628zM375 576l-64-64-220 224L314 960l64-64-116-115H896v-90H262z
M608 0q48 0 88 23t63 63 23 87v70h55q35 0 67 14t57 38 38 57 14 67V831q0 34-14 66t-38 57-57 38-67 13H426q-34 0-66-13t-57-38-38-57-14-66v-70h-56q-34 0-66-14t-57-38-38-57-13-67V174q0-47 23-87T109 23 196 0h412m175 244H426q-46 0-86 22T278 328t-26 85v348H608q47 0 86-22t63-62 25-85l1-348m-269 318q18 0 31 13t13 31-13 31-31 13-31-13-13-31 13-31 31-13m0-212q13 0 22 9t11 22v125q0 14-9 23t-22 10-23-7-11-22l-1-126q0-13 10-23t23-10z
M896 811l-128 0c-23 0-43-19-43-43 0-23 19-43 43-43l107 0c13 0 21-9 21-21L896 107c0-13-9-21-21-21L448 85c-13 0-21 9-21 21l0 21c0 23-19 43-43 43-23 0-43-19-43-43L341 85c0-47 38-85 85-85l469 0c47 0 85 38 85 85l0 640C981 772 943 811 896 811zM683 299l0 640c0 47-38 85-85 85L128 1024c-47 0-85-38-85-85L43 299c0-47 38-85 85-85l469 0C644 213 683 252 683 299zM576 299 149 299c-13 0-21 9-21 21l0 597c0 13 9 21 21 21l427 0c13 0 21-9 21-21L597 320C597 307 589 299 576 299z
+ M339 297c17-23 25-51 25-83 2-42-12-79-43-108S255 62 215 65c-32 0-60 8-84 25s-42 39-54 67-15 56-10 86 19 55 40 76c21 21 47 35 76 41v303c-30 6-55 20-76 41-21 21-35 47-40 76-5 30-2 58 10 86s30 50 54 67 52 25 83 25 59-8 84-25c25-17 45-39 57-67 6-19 10-39 10-61 0-30-8-57-25-83-21-34-52-55-92-64v-299l25-6c28-13 50-32 67-57zm-45 471c8 15 12 30 11 46-1 16-6 31-16 46-10 15-23 25-40 32s-34 8-51 5-32-11-46-24-22-28-24-45c-6-28-1-53 18-75s41-33 68-33c17 0 32 4 46 13 14 8 25 20 33 35zM167 288c-15-11-26-24-33-41-7-17-10-34-6-51 3-17 11-32 24-45s28-21 46-25 36-3 53 5c17 7 30 18 40 32 10 14 15 29 16 46 1 17-3 33-11 48-8 15-20 27-33 35-14 8-29 13-46 13s-33-5-48-16zm615 45c2-19-1-38-10-57-11-28-29-50-54-67s-53-25-83-25h-111l76-76-45-41-127 127v41l127 127 45-41-76-76h111c23 0 44 8 62 25 18 17 27 38 27 64v89h57V332zm0 449H960v-61H782V542h-61v178H543v61h178v178h61V781z
M280 145l243 341 0-0 45 63-0 0 79 110a143 143 0 11-36 75l-88-123-92 126c1 4 1 9 1 13l0 5a143 143 0 11-36-95l82-113L221 188l60-43zm473 541a70 70 0 100 140 70 70 0 000-140zm-463 0a70 70 0 100 140 70 70 0 000-140zM772 145l59 43-232 319-45-63L772 145z
M128 183C128 154 154 128 183 128h521c30 0 55 26 55 55v38c0 17-17 34-34 34s-34-17-34-34v-26H196v495h26c17 0 34 17 34 34s-17 34-34 34h-38c-30 0-55-26-55-55V183zM380 896h-34c-26 0-47-21-47-47v-90h68V828h64V896H380c4 0 0 0 0 0zM759 828V896h90c26 0 47-21 47-47v-90h-68V828h-68zM828 435H896V346c0-26-21-47-47-47h-90v68H828v68zM435 299v68H367V439H299V346C299 320 320 299 346 299h90zM367 649H299v-107h68v107zM546 367V299h107v68h-107zM828 546H896v107h-68v-107zM649 828V896h-107v-68h107zM730 508v188c0 17-17 34-34 34h-188c-17 0-34-17-34-34s17-34 34-34h102l-124-124c-13-13-13-34 0-47 13-13 34-13 47 0l124 124V512c0-17 17-34 34-34 21-4 38 9 38 30z
M889 0H135c-32 0-59 26-59 59v906c0 32 26 59 59 59h753c32 0 59-26 59-59v-906c1-33-26-59-58-59zm-165 177c31 0 56 25 56 56s-25 56-56 56-56-25-56-56 25-56 56-56zm-212 0c31 0 56 25 56 56S543 288 512 288s-56-25-56-56S481 177 512 177zm-212 0c31 0 56 25 56 56s-25 56-56 56-56-25-56-56 25-56 56-56zm209 606H285c-25 0-44-20-44-44 0-25 20-44 44-44h224c25 0 44 20 44 44 0 24-20 44-44 44zm230-212H285c-25 0-44-20-44-44 0-25 20-44 44-44h453c25 0 44 20 44 44 1 24-20 44-44 44z
@@ -58,6 +59,7 @@
M884 159l-18-18a43 43 0 00-38-12l-235 43a166 166 0 00-101 60L400 349a128 128 0 00-148 47l-120 171a21 21 0 005 29l17 12a128 128 0 00178-32l27-38 124 124-38 27a128 128 0 00-32 178l12 17a21 21 0 0029 5l171-120a128 128 0 0047-148l117-92A166 166 0 00853 431l43-235a43 43 0 00-12-38zm-177 249a64 64 0 110-90 64 64 0 010 90zm-373 312a21 21 0 010 30l-139 139a21 21 0 01-30 0l-30-30a21 21 0 010-30l139-139a21 21 0 0130 0z
M525 0C235 0 0 235 0 525c0 232 150 429 359 498 26 5 36-11 36-25 0-12-1-54-1-97-146 31-176-63-176-63-23-61-58-76-58-76-48-32 3-32 3-32 53 3 81 54 81 54 47 80 123 57 153 43 4-34 18-57 33-70-116-12-239-57-239-259 0-57 21-104 54-141-5-13-23-67 5-139 0 0 44-14 144 54 42-11 87-17 131-17s90 6 131 17C756 203 801 217 801 217c29 72 10 126 5 139 34 37 54 83 54 141 0 202-123 246-240 259 19 17 36 48 36 97 0 70-1 127-1 144 0 14 10 30 36 25 209-70 359-266 359-498C1050 235 814 0 525 0z
M590 74 859 342V876c0 38-31 68-68 68H233c-38 0-68-31-68-68V142c0-38 31-68 68-68h357zm-12 28H233a40 40 0 00-40 38L193 142v734a40 40 0 0038 40L233 916h558a40 40 0 0040-38L831 876V354L578 102zM855 371h-215c-46 0-83-36-84-82l0-2V74h28v213c0 30 24 54 54 55l2 0h215v28zM57 489m28 0 853 0q28 0 28 28l0 284q0 28-28 28l-853 0q-28 0-28-28l0-284q0-28 28-28ZM157 717c15 0 29-6 37-13v-51h-41v22h17v18c-2 2-6 3-10 3-21 0-30-13-30-34 0-21 12-34 28-34 9 0 15 4 20 9l14-17C184 610 172 603 156 603c-29 0-54 21-54 57 0 37 24 56 54 56zM245 711v-108h-34v108h34zm69 0v-86H341V603H262v22h28V711h24zM393 711v-108h-34v108h34zm66 6c15 0 29-6 37-13v-51h-41v22h17v18c-2 2-6 3-10 3-21 0-30-13-30-34 0-21 12-34 28-34 9 0 15 4 20 9l14-17C485 610 474 603 458 603c-29 0-54 21-54 57 0 37 24 56 54 56zm88-6v-36c0-13-2-28-3-40h1l10 24 25 52H603v-108h-23v36c0 13 2 28 3 40h-1l-10-24L548 603H523v108h23zM677 717c30 0 51-22 51-57 0-36-21-56-51-56-30 0-51 20-51 56 0 36 21 57 51 57zm3-23c-16 0-26-12-26-32 0-19 10-31 26-31 16 0 26 11 26 31S696 694 680 694zm93 17v-38h13l21 38H836l-25-43c12-5 19-15 19-31 0-26-20-34-44-34H745v108h27zm16-51H774v-34h15c16 0 25 4 25 16s-9 18-25 18zM922 711v-22h-43v-23h35v-22h-35V625h41V603H853v108h68z
+ M727 641c-78 0-142 55-157 128H256V320h251c16 108 108 192 221 192 124 0 224-100 224-224S851 64 727 64c-113 0-205 84-221 192H96c-18 0-32 14-32 32s14 32 32 32h96v482c0 18 14 32 32 32h347c15 73 79 128 157 128 88 0 160-72 160-160s-72-160-160-160zm0 256c-53 0-96-43-96-96s43-96 96-96 96 43 96 96-43 96-96 96z
M30 271l241 0 0-241-241 0 0 241zM392 271l241 0 0-241-241 0 0 241zM753 30l0 241 241 0 0-241-241 0zM30 632l241 0 0-241-241 0 0 241zM392 632l241 0 0-241-241 0 0 241zM753 632l241 0 0-241-241 0 0 241zM30 994l241 0 0-241-241 0 0 241zM392 994l241 0 0-241-241 0 0 241zM753 994l241 0 0-241-241 0 0 241z
M566 585l37-146-145 0-37 146 145 0zM1005 297l-32 128q-4 14-18 14l-187 0-37 146 178 0q9 0 14 7 6 8 3 16l-32 128q-3 14-18 14l-187 0-46 187q-4 14-18 14l-128 0q-9 0-15-7-5-7-3-16l45-178-145 0-46 187q-4 14-18 14l-129 0q-9 0-14-7-5-7-3-16l45-178-178 0q-9 0-14-7-5-7-3-16l32-128q4-14 18-14l187 0 37-146-178 0q-9 0-14-7-6-8-3-16l32-128q3-14 18-14l187 0 46-187q4-14 18-14l128 0q9 0 14 7 5 7 3 16l-45 178 145 0 46-187q4-14 18-14l128 0q9 0 14 7 5 7 3 16l-45 178 178 0q9 0 14 7 5 7 3 16z
M0 512M1024 512M512 0M512 1024M955 323q0 23-16 39l-414 414-78 78q-16 16-39 16t-39-16l-78-78-207-207q-16-16-16-39t16-39l78-78q16-16 39-16t39 16l168 169 375-375q16-16 39-16t39 16l78 78q16 16 16 39z
@@ -87,7 +89,6 @@
M0 512M1024 512M512 0M512 1024M64 576h896V448H64z
M896 64H128C96 64 64 96 64 128v768c0 32 32 64 64 64h768c32 0 64-32 64-64V128c0-32-32-64-64-64z m-64 736c0 16-17 32-32 32H224c-18 0-32-12-32-32V224c0-16 16-32 32-32h576c15 0 32 16 32 32v576zM512 384c-71 0-128 57-128 128s57 128 128 128 128-57 128-128-57-128-128-128z
M0 512M1024 512M512 0M512 1024M813 448c-46 0-83 37-83 83 0 46 37 83 83 83 46 0 83-37 83-83 0-46-37-83-83-83zM211 448C165 448 128 485 128 531c0 46 37 83 83 83 46 0 83-37 83-83 0-46-37-83-83-83zM512 448c-46 0-83 37-83 83 0 46 37 83 83 83 46 0 83-37 83-83C595 485 558 448 512 448z
- M299 811 299 725 384 725 384 811 299 811M469 811 469 725 555 725 555 811 469 811M640 811 640 725 725 725 725 811 640 811M299 640 299 555 384 555 384 640 299 640M469 640 469 555 555 555 555 640 469 640M640 640 640 555 725 555 725 640 640 640M299 469 299 384 384 384 384 469 299 469M469 469 469 384 555 384 555 469 469 469M640 469 640 384 725 384 725 469 640 469M299 299 299 213 384 213 384 299 299 299M469 299 469 213 555 213 555 299 469 299M640 299 640 213 725 213 725 299 640 299Z
M64 363l0 204 265 0L329 460c0-11 6-18 14-20C349 437 355 437 362 441c93 60 226 149 226 149 33 22 34 60 0 82 0 0-133 89-226 149-14 9-32-3-32-18l-1-110L64 693l0 117c0 41 34 75 75 75l746 0c41 0 75-34 75-74L960 364c0-0 0-1 0-1L64 363zM64 214l0 75 650 0-33-80c-16-38-62-69-103-69l-440 0C97 139 64 173 64 214z
M683 409v204L1024 308 683 0v191c-413 0-427 526-427 526c117-229 203-307 427-307zm85 492H102V327h153s38-63 114-122H51c-28 0-51 27-51 61v697c0 34 23 61 51 61h768c28 0 51-27 51-61V614l-102 100v187z
M841 627A43 43 0 00811 555h-299v85h196l-183 183A43 43 0 00555 896h299v-85h-196l183-183zM299 170H213v512H85l171 171 171-171H299zM725 128h-85c-18 0-34 11-40 28l-117 313h91L606 384h154l32 85h91l-117-313A43 43 0 00725 128zm-88 171 32-85h26l32 85h-90z
diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml
index a19b4bef0..a2f7ca9b2 100644
--- a/src/Resources/Locales/de_DE.axaml
+++ b/src/Resources/Locales/de_DE.axaml
@@ -56,11 +56,14 @@
Überspringen
Bisecting. Aktuellen Commit als gut oder schlecht markieren und einen anderen auschecken.
Blame
- BLAME WIRD BEI DIESER DATEI NICHT UNTERSTÜTZT!!!
+ Blame auf vorheriger Revision
+ BLAME WIRD BEI DIESER DATEI NICHT UNTERSTÜTZT!!!
Auschecken von ${0}$...
Mit ${0}$ vergleichen
Mit Worktree vergleichen
Branch-Namen kopieren
+ PR erstellen...
+ PR für Upstream ${0}$ erstellen...
Benutzerdefinierte Aktion
Lösche ${0}$...
Lösche alle ausgewählten {0} Branches
@@ -186,7 +189,14 @@
Commit-Nachricht
Repository Einstellungen
COMMIT TEMPLATE
- Du kannst ${files_num}, ${branch_name}, ${files} und ${files:N} verwenden, wobei N die maximale Anzahl an auszugebenden Dateipfaden ist.
+ Vordefinierte Parameter:
+
+ ${branch_name} Name des aktuellen lokalen Branches.
+ ${files_num} Anzahl der geänderten Dateien
+ ${files} Pfade der geänderten Dateien
+ ${files:N} Maximale Anzahl N an Pfaden geänderter Dateien
+ ${pure_files} Wie ${files}, aber nur die reinen Dateinamen
+ ${pure_files:N} Wie ${files:N}, aber ohne Ordner
Template Inhalt:
Template Name:
BENUTZERDEFINIERTE AKTION
@@ -217,6 +227,7 @@
GIT
Remotes automatisch fetchen
Minute(n)
+ Typen für konventionellen Commit
Standard Remote
Bevorzugter Merge Modus
TICKETSYSTEM
@@ -250,6 +261,7 @@
Bezeichnung:
Einträge:
Nutze '|', um Einträge zu trennen
+ Die vordefinierten Parameter ${REPO}, ${REMOTE}, ${BRANCH}, ${BRANCH_FRIENDLY_NAME}, ${SHA}, and ${TAG} bleiben hier verwendbar
Typ:
Arbeitsplätze
Farbe
@@ -463,7 +475,6 @@
Zum vorherigen Tab wechseln
Neuen Tab erstellen
Einstellungen öffnen
- Aktiven Arbeitsplatz wechseln
Aktiven Tab wechseln
REPOSITORY
Gestagte Änderungen committen
@@ -506,6 +517,7 @@
In Browser öffnen
FEHLER
INFO
+ Repositorys öffnen
Tabs
Arbeitsplätze
Branch mergen
@@ -563,11 +575,9 @@
Standard
Texteditor
Monospace-Schriftart
- Verwende die Monospace-Schriftart nur im Texteditor
Design
Design-Anpassungen
Scrollbars automatisch ausblenden
- Fixe Tab-Breite in Titelleiste
Verwende nativen Fensterrahmen
DIFF/MERGE TOOL
Installationspfad
@@ -642,6 +652,8 @@
Zu allen Remotes pushen
Remote:
Tag:
+ Push zu NEUEM Branch
+ Eingabe des Namens des neuen Remote-Branch:
Schließen
Aktuellen Branch rebasen
Lokale Änderungen stashen & wieder anwenden
diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml
index 7884a14d2..fdb1acb85 100644
--- a/src/Resources/Locales/en_US.axaml
+++ b/src/Resources/Locales/en_US.axaml
@@ -52,11 +52,14 @@
Skip
Bisecting. Mark current commit as good or bad and checkout another one.
Blame
- BLAME ON THIS FILE IS NOT SUPPORTED!!!
+ Blame on Previous Revision
+ BLAME ON THIS FILE IS NOT SUPPORTED!!!
Checkout ${0}$...
Compare with ${0}$
Compare with Worktree
Copy Branch Name
+ Create PR...
+ Create PR for upstream ${0}$...
Custom Action
Delete ${0}$...
Delete selected {0} branches
@@ -182,7 +185,14 @@
Enter commit subject
Repository Configure
COMMIT TEMPLATE
- You can use ${files_num}, ${branch_name}, ${files} and ${files:N} where N is the max number of file paths to output.
+ Built-in parameters:
+
+ ${branch_name} Current local branch name.
+ ${files_num} Number of changed files
+ ${files} Paths of changed files
+ ${files:N} Max N number of paths of changed files
+ ${pure_files} Likes ${files}, but only pure file names
+ ${pure_files:N} Likes ${files:N}, but without folders
Template Content:
Template Name:
CUSTOM ACTION
@@ -212,6 +222,7 @@
GIT
Fetch remotes automatically
Minute(s)
+ Conventional Commit Types
Default Remote
Preferred Merge Mode
ISSUE TRACKER
@@ -245,6 +256,7 @@
Label:
Options:
Use '|' as delimiter for options
+ The built-in variables ${REPO}, ${REMOTE}, ${BRANCH}, ${BRANCH_FRIENDLY_NAME}, ${SHA}, and ${TAG} remain available here
Type:
Workspaces
Color
@@ -458,7 +470,6 @@
Go to previous tab
Create new tab
Open Preferences dialog
- Switch active workspace
Switch active tab
REPOSITORY
Commit staged changes
@@ -501,6 +512,7 @@
Open in Browser
ERROR
NOTICE
+ Open Repositories
Tabs
Workspaces
Merge Branch
@@ -558,11 +570,9 @@
Default
Editor
Monospace Font
- Use monospace font only in text editor
Theme
Theme Overrides
Use auto-hide scrollbars
- Use fixed tab width in titlebar
Use native window frame
DIFF/MERGE TOOL
Install Path
@@ -637,6 +647,8 @@
Push to all remotes
Remote:
Tag:
+ Push to a NEW branch
+ Input name of the new remote branch:
Quit
Rebase Current Branch
Stash & reapply local changes
diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml
index 30e793376..44634488a 100644
--- a/src/Resources/Locales/es_ES.axaml
+++ b/src/Resources/Locales/es_ES.axaml
@@ -56,11 +56,13 @@
Saltar
Bisecting. Marcar el commit actual como bueno o malo y revisar otro.
Blame
- ¡BLAME EN ESTE ARCHIVO NO SOPORTADO!
+ ¡BLAME EN ESTE ARCHIVO NO SOPORTADO!
Checkout ${0}$...
Comparar con ${0}$
Comparar con Worktree
Copiar Nombre de la Rama
+ Crear PR...
+ Crear PR para upstream ${0}$...
Acción personalizada
Eliminar ${0}$...
Eliminar {0} ramas seleccionadas
@@ -186,7 +188,6 @@
Introducir asunto del commit
Configurar Repositorio
PLANTILLA DE COMMIT
- Puedes usar ${files_num}, ${branch_name}, ${files} y ${files:N} donde N es el número máximo de rutas de archivo a la salida.
Contenido de la Plantilla:
Nombre de la Plantilla:
ACCIÓN PERSONALIZADA
@@ -462,7 +463,6 @@
Ir a la página anterior
Crear nueva página
Abrir diálogo de preferencias
- Cambiar espacio de trabajo activo
Cambiar página activa
REPOSITORIO
Commit cambios staged
@@ -562,11 +562,9 @@
Por defecto
Editor
Fuente Monospace
- Usar solo fuente monospace en el editor de texto
Tema
Sobreescritura de temas
Usar barras de desplazamiento que se oculten automáticamente
- Usar ancho de pestaña fijo en la barra de título
Usar marco de ventana nativo
HERRAMIENTA DIFF/MERGE
Ruta de instalación
@@ -641,6 +639,8 @@
Push a todos los remotos
Remoto:
Etiqueta:
+ Push a una NUEVA rama
+ Nombre de entrada de la nueva rama remota:
Salir
Rebase Rama Actual
Stash & reaplicar cambios locales
diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml
index 32ae0e9f9..ceebf7363 100644
--- a/src/Resources/Locales/fr_FR.axaml
+++ b/src/Resources/Locales/fr_FR.axaml
@@ -41,7 +41,7 @@
Rafraîchir
FICHIER BINAIRE NON SUPPORTÉ !!!
Blâme
- LE BLÂME SUR CE FICHIER N'EST PAS SUPPORTÉ!!!
+ LE BLÂME SUR CE FICHIER N'EST PAS SUPPORTÉ!!!
Récupérer ${0}$...
Comparer avec ${0}$
Comparer avec le worktree
@@ -436,10 +436,8 @@
Défaut
Éditeur
Police monospace
- N'utiliser que des polices monospace pour l'éditeur de texte
Thème
Dérogations de thème
- Utiliser des onglets de taille fixe dans la barre de titre
Utiliser un cadre de fenêtre natif
OUTIL DIFF/MERGE
Chemin d'installation
diff --git a/src/Resources/Locales/id_ID.axaml b/src/Resources/Locales/id_ID.axaml
index 46d879283..1e8a6c697 100644
--- a/src/Resources/Locales/id_ID.axaml
+++ b/src/Resources/Locales/id_ID.axaml
@@ -55,7 +55,7 @@
Lewati
Bisect berjalan. Tandai commit saat ini sebagai baik atau buruk dan checkout yang lain.
Blame
- BLAME PADA BERKAS INI TIDAK DIDUKUNG!!!
+ BLAME PADA BERKAS INI TIDAK DIDUKUNG!!!
Checkout ${0}$...
Bandingkan dengan ${0}$
Bandingkan dengan Worktree
@@ -184,7 +184,6 @@
Masukkan subjek commit
Konfigurasi Repositori
TEMPLATE COMMIT
- Anda dapat menggunakan ${files_num}, ${branch_name}, ${files} dan ${files:N} dimana N adalah jumlah maksimal jalur berkas yang ditampilkan.
Konten Template:
Nama Template:
AKSI KUSTOM
@@ -457,7 +456,6 @@
Ke tab sebelumnya
Buat tab baru
Buka dialog Preferensi
- Ganti workspace aktif
Ganti tab aktif
REPOSITORI
Commit perubahan yang di-stage
@@ -557,11 +555,9 @@
Default
Editor
Font Monospace
- Gunakan font monospace hanya di text editor
Tema
Override Tema
Gunakan scrollbar auto-hide
- Gunakan lebar tab tetap di titlebar
Gunakan frame window native
DIFF/MERGE TOOL
Jalur Instalasi
diff --git a/src/Resources/Locales/it_IT.axaml b/src/Resources/Locales/it_IT.axaml
index 7d05b8c9f..3ddab9feb 100644
--- a/src/Resources/Locales/it_IT.axaml
+++ b/src/Resources/Locales/it_IT.axaml
@@ -55,7 +55,7 @@
Salta
Bisecando. Marca il commit corrente come buono o cattivo e fai checkout di un altro.
Attribuisci
- L'ATTRIBUZIONE SU QUESTO FILE NON È SUPPORTATA!!!
+ L'ATTRIBUZIONE SU QUESTO FILE NON È SUPPORTATA!!!
Checkout ${0}$...
Confronta con ${0}$
Confronta con Worktree
@@ -174,7 +174,6 @@
Inserisci l'oggetto del commit
Configura Repository
TEMPLATE DI COMMIT
- Puoi usare ${files_num}, ${branch_name}, ${files} e ${files:N} dove N è il numero massimo di percorsi di file da mostrare.
Contenuto Template:
Nome Template:
AZIONE PERSONALIZZATA
@@ -443,7 +442,6 @@
Vai alla pagina precedente
Crea una nuova pagina
Apri la finestra delle preferenze
- Cambia workspace attivo
Cambia scheda attiva
REPOSITORY
Committa le modifiche in tsage
@@ -542,10 +540,8 @@
Dimensione Font Predefinita
Dimensione Font Editor
Font Monospaziato
- Usa solo font monospaziato nell'editor
Tema
Sostituzioni Tema
- Usa larghezza fissa per i tab nella barra del titolo
Usa cornice finestra nativa
STRUMENTO DI DIFFERENZA/UNIONE
Percorso Installazione
diff --git a/src/Resources/Locales/ja_JP.axaml b/src/Resources/Locales/ja_JP.axaml
index 4698a5508..6d7723083 100644
--- a/src/Resources/Locales/ja_JP.axaml
+++ b/src/Resources/Locales/ja_JP.axaml
@@ -41,7 +41,7 @@
更新
バイナリファイルはサポートされていません!!!
Blame
- BLAMEではこのファイルはサポートされていません!!!
+ BLAMEではこのファイルはサポートされていません!!!
${0}$ をチェックアウトする...
ワークツリーと比較
ブランチ名をコピー
@@ -435,10 +435,8 @@
デフォルト
エディタ
等幅フォント
- テキストエディタでは等幅フォントのみを使用する
テーマ
テーマの上書き
- タイトルバーの固定タブ幅を使用
ネイティブウィンドウフレームを使用
差分/マージ ツール
インストール パス
diff --git a/src/Resources/Locales/ko_KR.axaml b/src/Resources/Locales/ko_KR.axaml
new file mode 100644
index 000000000..35769b8bf
--- /dev/null
+++ b/src/Resources/Locales/ko_KR.axaml
@@ -0,0 +1,899 @@
+
+
+ 정보
+ SourceGit 정보
+ 릴리스 노트
+ 오픈소스 & 무료 Git GUI 클라이언트
+ 무시할 파일 추가
+ 패턴:
+ 저장 파일:
+ 워크트리 추가
+ 위치:
+ 이 워크트리의 경로입니다. 상대 경로를 지원합니다.
+ 브랜치 이름:
+ 선택 사항. 기본값은 대상 폴더 이름입니다.
+ 추적할 브랜치:
+ 원격 브랜치 추적
+ 체크아웃할 대상:
+ 새 브랜치 생성
+ 기존 브랜치
+ AI 어시스턴트
+ 재생성
+ AI를 사용하여 커밋 메시지 생성
+ 커밋 메시지로 적용
+ SourceGit 숨기기
+ 모두 보기
+ 패치
+ 패치 파일:
+ 적용할 .patch 파일을 선택하세요
+ 공백 변경 사항 무시
+ 패치 적용
+ 공백:
+ 스태시 적용
+ 적용 후 삭제
+ 인덱스의 변경 사항 복원
+ 스태시:
+ 아카이브...
+ 아카이브 저장 위치:
+ 아카이브 파일 경로 선택
+ 리비전:
+ 아카이브
+ SourceGit Askpass
+ 암호 입력:
+ 변경되지 않음으로 간주된 파일
+ 변경되지 않음으로 간주된 파일 없음
+ 이미지 불러오기...
+ 새로 고침
+ 바이너리 파일은 지원되지 않습니다!!!
+ 이진 탐색
+ 중단
+ 나쁨
+ 이진 탐색 중. 현재 HEAD가 '좋음' 상태입니까, '나쁨' 상태입니까?
+ 좋음
+ 건너뛰기
+ 이진 탐색 중. 현재 커밋을 '좋음' 또는 '나쁨'으로 표시하고 다른 커밋을 체크아웃하세요.
+ 블레임
+ ${0}$ 체크아웃...
+ ${0}$와(과) 비교
+ 워크트리와 비교
+ 브랜치 이름 복사
+ 사용자 지정 작업
+ ${0}$ 삭제...
+ 선택한 {0}개의 브랜치 삭제
+ ${0}$(으)로 Fast-Forward
+ ${0}$에서 ${1}$(으)로 Fetch...
+ Git Flow - ${0}$ 완료
+ ${0}$을(를) ${1}$(으)로 병합...
+ 선택한 {0}개의 브랜치를 현재 브랜치로 병합
+ ${0}$ Pull
+ ${0}$에서 ${1}$(으)로 Pull...
+ ${0}$ Push
+ ${1}$을(를) 기반으로 ${0}$ 리베이스...
+ ${0}$ 이름 바꾸기...
+ ${0}$을(를) ${1}$(으)로 리셋...
+ ${0}$(워크트리)로 전환
+ 추적 브랜치 설정...
+ 브랜치 비교
+ {0}개 커밋 앞섬
+ {0}개 커밋 앞섬, {1}개 커밋 뒤처짐
+ {0}개 커밋 뒤처짐
+ 유효하지 않음
+ 원격
+ 상태
+ 추적 중
+ URL
+ 워크트리
+ 취소
+ 부모 리비전으로 리셋
+ 이 리비전으로 리셋
+ 커밋 메시지 생성
+ 표시 모드 변경
+ 파일 및 디렉터리 목록으로 보기
+ 경로 목록으로 보기
+ 파일 시스템 트리로 보기
+ 서브모듈 URL 변경
+ 서브모듈:
+ URL:
+ 브랜치 체크아웃
+ 커밋 체크아웃
+ 커밋:
+ 경고: 커밋 체크아웃을 하면, HEAD가 분리됩니다(detached)
+ 로컬 변경 사항:
+ 폐기
+ 스태시 & 재적용
+ 모든 서브모듈 업데이트
+ 브랜치:
+ 현재 HEAD에 브랜치/태그에 연결되지 않은 커밋이 있습니다! 계속하시겠습니까?
+ 체크아웃 & Fast-Forward
+ Fast-Forward 대상:
+ 체리픽
+ 커밋 메시지에 원본 추가
+ 커밋:
+ 모든 변경 사항 커밋
+ 메인라인:
+ 어느 쪽을 메인라인으로 간주해야 할지 알 수 없기 때문에 일반적으로 병합(merge)을 체리픽할 수 없습니다. 이 옵션을 사용하면 지정된 부모를 기준으로 변경 사항을 다시 적용할 수 있습니다.
+ 모든 스태시 지우기
+ 모든 스태시를 지우려고 합니다. 계속하시겠습니까?
+ 원격 저장소 복제
+ 추가 파라미터:
+ 저장소 복제 시 추가 인수. 선택 사항.
+ 로컬 이름:
+ 저장소 이름. 선택 사항.
+ 상위 폴더:
+ 서브모듈 초기화 & 업데이트
+ 저장소 URL:
+ 닫기
+ 에디터
+ 커밋 체크아웃
+ 커밋 체리픽
+ 체리픽...
+ HEAD와 비교
+ 워크트리와 비교
+ 작성자
+ 메시지
+ 커밋터
+ SHA
+ 제목
+ 사용자 지정 작업
+ 커밋 삭제
+ 대화형 리베이스
+ 삭제(Drop)...
+ 수정(Edit)...
+ 부모에 합치기(Fixup)...
+ ${1}$을(를) 기반으로 ${0}$ 대화형 리베이스
+ 메시지 수정(Reword)...
+ 부모에 합치기(Squash)...
+ ${0}$(으)로 병합
+ 병합...
+ ${0}$을(를) ${1}$(으)로 푸시
+ ${1}$을(를) 기반으로 ${0}$ 리베이스
+ ${0}$을(를) ${1}$(으)로 리셋
+ 커밋 되돌리기
+ 메시지 수정
+ 패치로 저장...
+ 부모에 합치기
+ 변경 사항
+ 변경된 파일
+ 변경 사항 검색...
+ 파일
+ LFS 파일
+ 파일 검색...
+ 서브모듈
+ 정보
+ 작성자
+ 자식
+ 커밋터
+ 이 커밋을 포함하는 ref 확인
+ 커밋 포함 REF
+ 이메일 복사
+ 이름 복사
+ 이름 & 이메일 복사
+ 처음 100개의 변경 사항만 표시합니다. 모든 변경 사항은 '변경 사항' 탭에서 확인하세요.
+ 키:
+ 메시지
+ 부모
+ REFS
+ SHA
+ 서명자:
+ 브라우저에서 열기
+ 설명
+ 붙여넣기 (모두 바꾸기)
+ 제목
+ 커밋 제목 입력
+ 저장소 설정
+ 커밋 템플릿
+ ${files_num}, ${branch_name}, ${files} 및 ${files:N} (N은 출력할 최대 파일 경로 수)을(를) 사용할 수 있습니다.
+ 템플릿 내용:
+ 템플릿 이름:
+ 사용자 지정 작업
+ 인수:
+ 내장 파라미터:
+
+ ${REPO} 저장소 경로
+ ${REMOTE} 선택한 원격 또는 선택한 브랜치의 원격
+ ${BRANCH} 선택한 브랜치 (원격 브랜치의 경우 ${REMOTE} 부분 제외)
+ ${BRANCH_FRIENDLY_NAME} 선택한 브랜치의 식별하기 쉬운 이름 (원격 브랜치의 경우 ${REMOTE} 부분 포함)
+ ${SHA} 선택한 커밋의 해시
+ ${TAG} 선택한 태그
+ $1, $2 ... 입력 컨트롤 값
+ 실행 파일:
+ 입력 컨트롤:
+ 편집
+ 이름:
+ 범위:
+ 브랜치
+ 커밋
+ 원격
+ 저장소
+ 태그
+ 작업이 끝날 때까지 대기
+ 이메일 주소
+ 이메일 주소
+ GIT
+ 원격 자동 Fetch
+ 분
+ 기본 원격
+ 선호하는 병합 모드
+ 이슈 트래커
+ Azure DevOps 규칙 추가
+ Gerrit Change-Id 커밋 규칙 추가
+ Gitee 이슈 규칙 추가
+ Gitee Pull Request 규칙 추가
+ GitHub 규칙 추가
+ GitLab 이슈 규칙 추가
+ GitLab Merge Request 규칙 추가
+ Jira 규칙 추가
+ 새 규칙
+ 이슈 정규식:
+ 규칙 이름:
+ .issuetracker 파일에 이 규칙 공유
+ 결과 URL:
+ 정규식 그룹 값에 접근하려면 $1, $2를 사용하세요.
+ AI
+ 선호하는 서비스:
+ '선호하는 서비스'가 설정되면, SourceGit은 이 저장소에서 해당 서비스만 사용합니다. 그렇지 않고 사용 가능한 서비스가 두 개 이상인 경우, 하나를 선택할 수 있는 컨텍스트 메뉴가 표시됩니다.
+ HTTP 프록시
+ 이 저장소에서 사용하는 HTTP 프록시
+ 사용자 이름
+ 이 저장소의 사용자 이름
+ 사용자 지정 작업 컨트롤 편집
+ 선택 시 값:
+ 선택 시, 이 값이 명령줄 인수로 사용됩니다
+ 설명:
+ 기본값:
+ 폴더 여부:
+ 레이블:
+ 옵션:
+ 옵션 구분자로 '|'를 사용하세요
+ 유형:
+ 작업 공간
+ 색상
+ 이름
+ 시작 시 탭 복원
+ 계속
+ 빈 커밋이 감지되었습니다! 계속하시겠습니까 (--allow-empty)?
+ 모두 스테이징 & 커밋
+ 빈 커밋이 감지되었습니다! 계속하시겠습니까 (--allow-empty) 아니면 모두 스테이징 후 커밋하시겠습니까?
+ 재시작 필요
+ 변경 사항을 적용하려면 앱을 다시 시작해야 합니다.
+ Conventional Commit 도우미
+ 주요 변경 사항(Breaking Change):
+ 종료된 이슈:
+ 상세 변경 내역:
+ 범위:
+ 간단한 설명:
+ 변경 유형:
+ 복사
+ 전체 텍스트 복사
+ 전체 경로 복사
+ 경로 복사
+ 브랜치 생성...
+ 기준:
+ 생성된 브랜치로 체크아웃
+ 로컬 변경 사항:
+ 폐기
+ 스태시 & 재적용
+ 새 브랜치 이름:
+ 브랜치 이름을 입력하세요.
+ 로컬 브랜치 생성
+ 기존 브랜치 덮어쓰기
+ 태그 생성...
+ 태그 생성 위치:
+ GPG 서명
+ 태그 메시지:
+ 선택 사항.
+ 태그 이름:
+ 권장 형식: v1.0.0-alpha
+ 생성 후 모든 원격에 푸시
+ 새 태그 생성
+ 종류:
+ 주석 태그
+ 경량 태그
+ Ctrl을 누른 채 클릭하면 바로 시작합니다
+ 잘라내기
+ 서브모듈 초기화 해제
+ 로컬 변경 사항이 있어도 강제로 초기화 해제합니다.
+ 서브모듈:
+ 브랜치 삭제
+ 브랜치:
+ 원격 브랜치를 삭제하려고 합니다!!!
+ 원격 브랜치 ${0}$도 함께 삭제
+ 여러 브랜치 삭제
+ 한 번에 여러 브랜치를 삭제하려고 합니다. 실행하기 전에 다시 한번 확인하세요!
+ 여러 태그 삭제
+ 원격 저장소에서도 삭제
+ 한 번에 여러 태그를 삭제하려고 합니다. 실행하기 전에 다시 한번 확인하세요!
+ 원격 삭제
+ 원격:
+ 경로:
+ 대상:
+ 모든 하위 항목이 목록에서 제거됩니다.
+ 목록에서만 제거되며, 디스크에서 삭제되지 않습니다!
+ 그룹 삭제 확인
+ 저장소 삭제 확인
+ 서브모듈 삭제
+ 서브모듈 경로:
+ 태그 삭제
+ 태그:
+ 원격 저장소에서도 삭제
+ 바이너리 비교
+ 파일 모드 변경됨
+ 첫 번째 차이점
+ 모든 공백 변경 사항 무시
+ 혼합
+ 차이점
+ 나란히 보기
+ 스와이프
+ 마지막 차이점
+ LFS 객체 변경
+ 신규
+ 다음 차이점
+ 변경 사항 없음 또는 줄바꿈(EOL) 변경만 있음
+ 기존
+ 이전 차이점
+ 패치로 저장
+ 숨겨진 기호 표시
+ 나란히 비교
+ 서브모듈
+ 삭제됨
+ 신규
+ 전환
+ 구문 강조
+ 줄 바꿈
+ 병합 도구에서 열기
+ 모든 줄 표시
+ 표시 줄 수 줄이기
+ 표시 줄 수 늘리기
+ 파일을 선택하여 변경 사항 보기
+ 디렉터리 히스토리
+ 로컬 변경 사항 있음
+ 업스트림과 불일치
+ 이미 최신 상태
+ 변경 사항 폐기
+ 작업 사본의 모든 로컬 변경 사항.
+ 변경 사항:
+ 무시된 파일 포함
+ 추적하지 않는 파일 포함
+ {0}개의 변경 사항이 폐기됩니다
+ 이 작업은 되돌릴 수 없습니다!!!
+ 커밋 삭제
+ 커밋:
+ 새 HEAD:
+ 북마크:
+ 새 이름:
+ 대상:
+ 선택한 그룹 편집
+ 선택한 저장소 편집
+ 대상:
+ 이 저장소
+ Fetch
+ 모든 원격 Fetch
+ 로컬 ref 강제 덮어쓰기
+ 태그 없이 Fetch
+ 원격:
+ 원격 변경 사항 Fetch
+ 변경되지 않음으로 간주
+ 폐기...
+ {0}개 파일 폐기...
+ ${0}$을(를) 사용하여 해결
+ 패치로 저장...
+ 스테이지
+ {0}개 파일 스테이지
+ 스태시...
+ {0}개 파일 스태시...
+ 언스테이지
+ {0}개 파일 언스테이지
+ 내 것 사용 (checkout --ours)
+ 상대방 것 사용 (checkout --theirs)
+ 파일 히스토리
+ 변경 사항
+ 내용
+ Git-Flow
+ 개발 브랜치:
+ Feature:
+ Feature 접두사:
+ FLOW - Feature 완료
+ FLOW - Hotfix 완료
+ FLOW - Release 완료
+ 대상:
+ 완료 후 원격(들)에 푸시
+ 병합 시 스쿼시
+ 핫픽스:
+ Hotfix 접두사:
+ Git-Flow 초기화
+ 브랜치 유지
+ 운영 브랜치:
+ 릴리스:
+ Release 접두사:
+ Feature 시작...
+ FLOW - Feature 시작
+ Hotfix 시작...
+ FLOW - Hotfix 시작
+ 이름 입력
+ Release 시작...
+ FLOW - Release 시작
+ 버전 태그 접두사:
+ Git LFS
+ 추적 패턴 추가...
+ 패턴이 파일 이름임
+ 사용자 정의 패턴:
+ Git LFS에 추적 패턴 추가
+ Fetch
+ Git LFS 객체를 다운로드하려면 `git lfs fetch`를 실행하세요. 이 작업은 작업 사본을 업데이트하지 않습니다.
+ LFS 객체 Fetch
+ Git LFS 훅(hook) 설치
+ 잠금 보기
+ 잠긴 파일 없음
+ 잠금
+ 내 잠금만 보기
+ LFS 잠금
+ 잠금 해제
+ 강제 잠금 해제
+ 정리
+ 로컬 저장소에서 오래된 LFS 파일을 삭제하려면 `git lfs prune`을 실행하세요
+ Pull
+ 현재 ref 및 체크아웃에 대한 모든 Git LFS 파일을 다운로드하려면 `git lfs pull`을 실행하세요
+ LFS 객체 Pull
+ 푸시
+ 대기 중인 대용량 파일을 Git LFS 엔드포인트로 푸시합니다
+ LFS 객체 푸시
+ 원격:
+ '{0}' 이름의 파일 추적
+ 모든 *{0} 파일 추적
+ 히스토리
+ 작성자
+ 작성 시간
+ 그래프 & 제목
+ SHA
+ 커밋 시간
+ {0}개 커밋 선택됨
+ 'Ctrl' 또는 'Shift' 키를 누른 채로 여러 커밋을 선택하세요.
+ ⌘ 또는 ⇧ 키를 누른 채로 여러 커밋을 선택하세요.
+ 팁:
+ 키보드 단축키 참조
+ 전역
+ 새 저장소 복제
+ 현재 탭 닫기
+ 다음 탭으로 이동
+ 이전 탭으로 이동
+ 새 탭 만들기
+ 환경설정 대화상자 열기
+ 활성 탭 전환
+ 저장소
+ 스테이징된 변경 사항 커밋
+ 스테이징된 변경 사항 커밋 및 푸시
+ 모든 변경 사항 스테이징 후 커밋
+ Fetch (바로 시작)
+ 대시보드 모드 (기본)
+ 커밋 검색 모드 열기
+ Pull (바로 시작)
+ 푸시 (바로 시작)
+ 이 저장소 강제 새로고침
+ '변경 사항'으로 전환
+ '히스토리'로 전환
+ '스태시'로 전환
+ 텍스트 에디터
+ 검색 패널 닫기
+ 다음 일치 항목 찾기
+ 이전 일치 항목 찾기
+ 외부 diff/merge 도구로 열기
+ 검색 패널 열기
+ 폐기
+ 스테이지
+ 언스테이지
+ 저장소 초기화
+ 경로:
+ 체리픽 진행 중.
+ 커밋 처리 중
+ 병합 진행 중.
+ 병합 중
+ 리베이스 진행 중.
+ 중단 지점
+ 되돌리기 진행 중.
+ 커밋 되돌리는 중
+ 대화형 리베이스
+ 로컬 변경 사항 스태시 & 재적용
+ 기준:
+ 드래그 앤 드롭으로 커밋 순서 변경
+ 대상 브랜치:
+ 링크 복사
+ 브라우저에서 열기
+ 오류
+ 알림
+ 탭
+ 작업 공간
+ 브랜치 병합
+ 병합 메시지 수정
+ 대상:
+ 병합 옵션:
+ 소스:
+ 병합 (다중)
+ 모든 변경 사항 커밋
+ 전략:
+ 대상:
+ 서브모듈 이동
+ 이동 위치:
+ 서브모듈:
+ 저장소 노드 이동
+ 상위 노드 선택:
+ 이름:
+ Git이 구성되지 않았습니다. [환경설정]으로 이동하여 먼저 구성하세요.
+ 데이터 저장 디렉터리 열기
+ 병합 도구에서 열기
+ 다음으로 열기...
+ 선택 사항.
+ 새 탭 만들기
+ 북마크
+ 탭 닫기
+ 다른 탭 닫기
+ 오른쪽 탭 닫기
+ 저장소 경로 복사
+ 저장소
+ 붙여넣기
+ {0}일 전
+ 1시간 전
+ {0}시간 전
+ 방금 전
+ 지난 달
+ 작년
+ {0}분 전
+ {0}개월 전
+ {0}년 전
+ 어제
+ 환경설정
+ AI
+ Diff 분석 프롬프트
+ API 키
+ 제목 생성 프롬프트
+ 모델
+ 이름
+ 입력된 값은 환경변수(ENV)에서 API 키를 불러올 이름입니다
+ 서버
+ 스트리밍 활성화
+ 모양
+ 기본 글꼴
+ 에디터 탭 너비
+ 글꼴 크기
+ 기본
+ 에디터
+ 고정폭 글꼴
+ 테마
+ 테마 재정의
+ 스크롤바 자동 숨기기 사용
+ 네이티브 윈도우 프레임 사용
+ DIFF/MERGE 도구
+ 설치 경로
+ diff/merge 도구 경로 입력
+ 도구
+ 일반
+ 시작 시 업데이트 확인
+ 날짜 형식
+ 변경 사항 트리에서 폴더 압축 활성화
+ 언어
+ 히스토리 커밋 수
+ 그래프에 커밋 시간 대신 작성자 시간 표시
+ 기본으로 `로컬 변경 사항` 페이지 표시
+ 커밋 세부 정보에서 기본으로 `변경 사항` 탭 표시
+ 커밋 세부 정보에 자식 커밋 표시
+ 커밋 그래프에 태그 표시
+ 제목 가이드 길이
+ GitHub 스타일 기본 아바타 생성
+ GIT
+ 자동 CRLF 활성화
+ 기본 복제 디렉터리
+ 사용자 이메일
+ 전역 git 사용자 이메일
+ Fetch 시 --prune 활성화
+ diff 시 --ignore-cr-at-eol 활성화
+ 이 앱은 Git (>= 2.25.1)을(를) 필요로 합니다
+ 설치 경로
+ HTTP SSL 검증 활성화
+ git-credential-manager 대신 git-credential-libsecret 사용
+ 사용자 이름
+ 전역 git 사용자 이름
+ Git 버전
+ GPG 서명
+ 커밋 GPG 서명
+ GPG 형식
+ 프로그램 설치 경로
+ 설치된 gpg 프로그램 경로 입력
+ 태그 GPG 서명
+ 사용자 서명 키
+ 사용자의 gpg 서명 키
+ 연동
+ 셸/터미널
+ 경로
+ 셸/터미널
+ 원격 정리
+ 대상:
+ 워크트리 정리
+ `$GIT_COMMON_DIR/worktrees`의 워크트리 정보 정리
+ Pull
+ 원격 브랜치:
+ 대상:
+ 로컬 변경 사항:
+ 폐기
+ 스태시 & 재적용
+ 모든 서브모듈 업데이트
+ 원격:
+ Pull (Fetch & 병합)
+ 병합 대신 리베이스 사용
+ 푸시
+ 서브모듈이 푸시되었는지 확인
+ 강제 푸시
+ 로컬 브랜치:
+ 신규
+ 원격:
+ 리비전:
+ 리비전을 원격에 푸시
+ 변경 사항을 원격에 푸시
+ 원격 브랜치:
+ 추적 브랜치로 설정
+ 모든 태그 푸시
+ 태그를 원격에 푸시
+ 모든 원격에 푸시
+ 원격:
+ 태그:
+ 종료
+ 현재 브랜치 리베이스
+ 로컬 변경 사항 스태시 & 재적용
+ 기준:
+ 원격 추가
+ 원격 편집
+ 이름:
+ 원격 이름
+ 저장소 URL:
+ 원격 git 저장소 URL
+ URL 복사
+ 사용자 지정 작업
+ 삭제...
+ 편집...
+ Fetch
+ 브라우저에서 열기
+ 정리
+ 워크트리 제거 확인
+ `--force` 옵션 활성화
+ 대상:
+ 브랜치 이름 변경
+ 새 이름:
+ 이 브랜치의 고유한 이름
+ 브랜치:
+ 중단
+ 원격에서 변경 사항 자동 Fetch 중...
+ 정렬
+ 커밋 날짜 순
+ 이름 순
+ 정리 (GC & Prune)
+ 이 저장소에 대해 `git gc` 명령을 실행합니다.
+ 모두 지우기
+ 지우기
+ 이 저장소 설정
+ 계속
+ 사용자 지정 작업
+ 사용자 지정 작업 없음
+ 대시보드
+ 모든 변경 사항 폐기
+ 파일 탐색기에서 열기
+ 브랜치/태그/서브모듈 검색
+ 그래프에 표시 여부
+ 설정 안 함
+ 커밋 그래프에서 숨기기
+ 커밋 그래프에서 필터링
+ 레이아웃
+ 수평
+ 수직
+ 커밋 순서
+ 커밋 날짜
+ 위상 정렬
+ 로컬 브랜치
+ 추가 옵션...
+ HEAD로 이동
+ 브랜치 생성
+ 알림 지우기
+ 현재 브랜치만 강조
+ {0}에서 열기
+ 외부 도구에서 열기
+ 원격
+ 원격 추가
+ 커밋 검색
+ 작성자
+ 커밋터
+ 내용
+ 메시지
+ 경로
+ SHA
+ 현재 브랜치
+ 장식된(Decorated) 커밋만
+ 첫 번째 부모만
+ 플래그 표시
+ 유실된(Lost) 커밋 표시
+ 서브모듈을 트리로 표시
+ 태그를 트리로 표시
+ 건너뛰기
+ 통계
+ 서브모듈
+ 서브모듈 추가
+ 서브모듈 업데이트
+ 태그
+ 새 태그
+ 생성 날짜 순
+ 이름 순
+ 정렬
+ 터미널에서 열기
+ 상대 시간 사용
+ 로그 보기
+ 브라우저에서 '{0}' 방문
+ 워크트리
+ 워크트리 추가
+ 정리
+ Git 저장소 URL
+ 현재 브랜치를 리비전으로 리셋
+ 리셋 모드:
+ 이동 대상:
+ 현재 브랜치:
+ 브랜치 리셋 (체크아웃 없음)
+ 이동 대상:
+ 브랜치:
+ 파일 탐색기에서 보기
+ 커밋 되돌리기
+ 커밋:
+ 되돌린 변경 사항 커밋
+ 커밋 메시지 수정
+ 실행 중. 잠시만 기다려주세요...
+ 저장
+ 다른 이름으로 저장...
+ 패치가 성공적으로 저장되었습니다!
+ 저장소 스캔
+ 루트 디렉터리:
+ 다른 사용자 정의 디렉터리 스캔
+ 업데이트 확인...
+ 이 소프트웨어의 새 버전을 사용할 수 있습니다:
+ 업데이트 확인 실패!
+ 다운로드
+ 이 버전 건너뛰기
+ 소프트웨어 업데이트
+ 현재 사용 가능한 업데이트가 없습니다.
+ 서브모듈 브랜치 설정
+ 서브모듈:
+ 현재:
+ 변경:
+ 선택 사항. 비어 있으면 기본값으로 설정됩니다.
+ 추적 브랜치 설정
+ 브랜치:
+ 업스트림 설정 해제
+ 업스트림:
+ SHA 복사
+ 이동
+ 커밋 스쿼시
+ 대상:
+ SSH 개인 키:
+ 개인 SSH 키 저장 경로
+ 시작
+ 스태시
+ 추적하지 않는 파일 포함
+ 메시지:
+ 선택 사항. 이 스태시의 메시지
+ 모드:
+ 스테이징된 변경 사항만
+ 선택한 파일의 스테이징된 변경 사항과 스테이징되지 않은 변경 사항이 모두 스태시됩니다!!!
+ 로컬 변경 사항 스태시
+ 적용
+ 메시지 복사
+ 삭제
+ 패치로 저장...
+ 스태시 삭제
+ 삭제:
+ 스태시
+ 변경 사항
+ 스태시
+ 통계
+ 개요
+ 이번 달
+ 이번 주
+ 작성자:
+ 커밋:
+ 서브모듈
+ 서브모듈 추가
+ 브랜치
+ 브랜치
+ 상대 경로
+ 초기화 해제
+ 중첩된 서브모듈 Fetch
+ 히스토리
+ 이동
+ 저장소 열기
+ 상대 경로:
+ 이 모듈을 저장할 상대 폴더입니다.
+ 삭제
+ 브랜치 설정
+ URL 변경
+ 상태
+ 수정됨
+ 초기화 안 됨
+ 리비전 변경됨
+ 업데이트
+ URL
+ 확인
+ 태그 생성자
+ 시간
+ 메시지
+ 이름
+ 태그 생성자
+ 태그 이름 복사
+ 사용자 지정 작업
+ ${0}$ 삭제...
+ 선택한 {0}개의 태그 삭제...
+ ${0}$을(를) ${1}$(으)로 병합...
+ ${0}$ 푸시...
+ 서브모듈 업데이트
+ 모든 서브모듈
+ 필요시 초기화
+ 서브모듈 재귀적으로 탐색
+ 서브모듈:
+ 서브모듈의 원격 추적 브랜치로 업데이트
+ URL:
+ 로그
+ 모두 지우기
+ 복사
+ 삭제
+ 경고
+ 시작 페이지
+ 그룹 생성
+ 하위 그룹 생성
+ 저장소 복제
+ 삭제
+ 폴더 끌어다 놓기 지원. 사용자 정의 그룹화 지원.
+ 편집
+ 다른 그룹으로 이동
+ 모든 저장소 열기
+ 저장소 열기
+ 터미널 열기
+ 기본 복제 디렉터리의 저장소 다시 스캔
+ 저장소 검색...
+ 로컬 변경 사항
+ Git 무시
+ 모든 *{0} 파일 무시
+ 같은 폴더의 *{0} 파일 무시
+ 이 폴더의 추적하지 않는 파일 무시
+ 이 파일만 무시
+ 수정
+ 이제 이 파일을 스테이징할 수 있습니다.
+ 히스토리 지우기
+ 모든 커밋 메시지 히스토리를 지우시겠습니까? 이 작업은 되돌릴 수 없습니다.
+ 커밋
+ 커밋 & 푸시
+ 템플릿/히스토리
+ 클릭 이벤트 트리거
+ 커밋 (수정)
+ 모든 변경 사항 스테이징 후 커밋
+ 분리된(detached) HEAD에 커밋을 생성하고 있습니다. 계속하시겠습니까?
+ {0}개의 파일을 스테이징했지만 {1}개의 파일만 표시됩니다 ({2}개의 파일은 필터링됨). 계속하시겠습니까?
+ 충돌 감지됨
+ 외부 병합 도구 열기
+ 모든 충돌을 외부 병합 도구에서 열기
+ 파일 충돌 해결됨
+ 내 것 사용
+ 상대방 것 사용
+ 추적하지 않는 파일 포함
+ 최근 입력한 메시지 없음
+ 커밋 템플릿 없음
+ 검증 안 함
+ 작성자 리셋
+ 서명(SignOff)
+ 스테이징됨
+ 언스테이지
+ 모두 언스테이지
+ 스테이징 안 됨
+ 스테이지
+ 모두 스테이지
+ 변경되지 않음으로 간주된 파일 보기
+ 템플릿: ${0}$
+ 작업 공간:
+ 작업 공간 설정...
+ 워크트리
+ 경로 복사
+ 잠금
+ 열기
+ 제거
+ 잠금 해제
+
diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml
index bc1f92ebe..04ececee5 100644
--- a/src/Resources/Locales/pt_BR.axaml
+++ b/src/Resources/Locales/pt_BR.axaml
@@ -35,7 +35,7 @@
Atualizar
ARQUIVO BINÁRIO NÃO SUPORTADO!!!
Blame
- BLAME NESTE ARQUIVO NÃO É SUPORTADO!!!
+ BLAME NESTE ARQUIVO NÃO É SUPORTADO!!!
Checkout ${0}$...
Comparar com ${0}$
Comparar com Worktree
@@ -399,10 +399,8 @@
Padrão
Editor
Fonte Monoespaçada
- Usar fonte monoespaçada apenas no editor de texto
Tema
Substituições de Tema
- Usar largura fixa de aba na barra de título
Usar moldura de janela nativa
FERRAMENTA DE DIFF/MERGE
Caminho de Instalação
diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml
index 776bb7816..b928a006a 100644
--- a/src/Resources/Locales/ru_RU.axaml
+++ b/src/Resources/Locales/ru_RU.axaml
@@ -56,11 +56,14 @@
Пропустить
Раздвоение. Сделать текущую ревизию хорошей или плохой и переключиться на другой.
Расследование
- РАССЛЕДОВАНИЕ В ЭТОМ ФАЙЛЕ НЕ ПОДДЕРЖИВАЕТСЯ!!!
+ Расследование на предыдущей редакции
+ РАССЛЕДОВАНИЕ В ЭТОМ ФАЙЛЕ НЕ ПОДДЕРЖИВАЕТСЯ!!!
Переключиться на ${0}$...
Сравнить с ${0}$
Сравнить с рабочим каталогом
Копировать имя ветки
+ Создать PR...
+ Создать PR для основной ветки ${0}$...
Изменить действие
Удалить ${0}$...
Удалить выбранные {0} ветки
@@ -186,12 +189,19 @@
Введите тему ревизии
Настройка репозитория
ШАБЛОН РЕВИЗИИ
- Вы можете использовать ${files_num}, ${branch_name}, ${files} и ${files:N}, где N — максимальное количество путей к файлам для вывода.
+ Встроенные параметры:
+
+ ${branch_name} Имя текущей локальной ветки
+ ${files_num} Количество изменённых файлов
+ ${files} Пути изменённых файлов
+ ${files:N} Пути изменённых файлов, не более N
+ ${pure_files} То же, что и ${files}, но только имена файлов
+ ${pure_files:N} То же, что и ${files:N}, но только имена файлов
Cодержание:
Название:
ПОЛЬЗОВАТЕЛЬСКОЕ ДЕЙСТВИЕ
Аргументы:
- Built-in parameters:
+ Встроенные параметры:
${REPO} Путь репозитория
${REMOTE} Выбранная удаённая ветка
@@ -216,6 +226,7 @@
GIT
Автозагрузка изменений
Минут(а/ы)
+ Общепринятые типы ревизии
Внешний репозиторий по умолчанию
Предпочтительный режим слияния
ОТСЛЕЖИВАНИЕ ПРОБЛЕМ
@@ -249,6 +260,7 @@
Метка:
Опции:
Используйте разделитель «|» для опций
+ Встроенные переменные ${REPO}, ${REMOTE}, ${BRANCH}, ${BRANCH_FRIENDLY_NAME}, ${SHA}, и ${TAG} останутся здесь доступными
Тип:
Рабочие пространства
Цвет
@@ -257,7 +269,7 @@
ПРОДОЛЖИТЬ
Обнаружена пустая ревизия! Вы хотите продолжить (--allow-empty)?
Сформировать всё и зафиксировать ревизию
- Обнаружена пустая ревизия! Вы хотите продолжить (--allow-empty) или отложить всё, затем зафиксировать ревизию?
+ Обнаружена пустая ревизия! Вы хотите продолжить (--allow-empty) или отложить всё, а затем зафиксировать ревизию?
Требуется перезапуск
Вы должны перезапустить приложение после применения изменений.
Общепринятый помощник по ревизии
@@ -462,7 +474,6 @@
Перейти на предыдущую вкладку
Создать новую вкладку
Открыть диалоговое окно настроек
- Переключиться на рабочее место
Переключиться на вкладку
РЕПОЗИТОРИЙ
Зафиксировать сформированные изменения
@@ -505,6 +516,7 @@
Открыть в браузере
ОШИБКА
УВЕДОМЛЕНИЕ
+ Открыть репозитории
Вкладки
Рабочие места
Влить ветку
@@ -562,11 +574,9 @@
По умолчанию
Редактор
Моноширный шрифт
- В текстовом редакторе используется только моноширный шрифт
Тема
Переопределение темы
Автоматически скрывать прокрутку
- Использовать фиксированную ширину табуляции в строке заголовка.
Использовать системное окно
ИНСТРУМЕНТ СРАВНЕНИЙ/СЛИЯНИЯ
Путь установки
@@ -641,6 +651,8 @@
Выложить на все внешние репозитории
Внешний репозиторий:
Метка:
+ Отправить к НОВОЙ ветке
+ Введитте имя для новой удалённой ветки:
Выйти
Перемещение текущей ветки
Отложить и применить повторно локальные изменения
@@ -759,7 +771,7 @@
Загрузка
Пропустить эту версию
Обновление ПО
- В настоящее время обновления недоступны.
+ Сейчас нет обновлений.
Установить ветку подмодуля
Подмодуль:
Текущий:
diff --git a/src/Resources/Locales/ta_IN.axaml b/src/Resources/Locales/ta_IN.axaml
index a29ccef34..8c1029345 100644
--- a/src/Resources/Locales/ta_IN.axaml
+++ b/src/Resources/Locales/ta_IN.axaml
@@ -41,7 +41,7 @@
புதுப்பி
இருமம் கோப்பு ஆதரிக்கப்படவில்லை!!!
குற்றச்சாட்டு
- இந்த கோப்பில் குற்றம் சாட்ட ஆதரிக்கப்படவில்லை!!!
+ இந்த கோப்பில் குற்றம் சாட்ட ஆதரிக்கப்படவில்லை!!!
${0}$ சரிபார்...
பணிமரத்துடன் ஒப்பிடுக
கிளை பெயரை நகலெடு
@@ -435,10 +435,8 @@
இயல்புநிலை
திருத்தி
ஒற்றைவெளி எழுத்துரு
- ஒற்றைவெளி எழுத்துருவை உரை திருத்தியில் மட்டும் பயன்படுத்து
கருப்பொருள்
கருப்பொருள் மேலெழுதப்படுகிறது
- தலைப்புப்பட்டியில் நிலையான தாவல் அகலத்தைப் பயன்படுத்து
சொந்த சாளர சட்டத்தைப் பயன்படுத்து
வேறு/ஒன்றிணை கருவி
நிறுவல் பாதை
diff --git a/src/Resources/Locales/uk_UA.axaml b/src/Resources/Locales/uk_UA.axaml
index 82e2a0c6f..7c5814ebe 100644
--- a/src/Resources/Locales/uk_UA.axaml
+++ b/src/Resources/Locales/uk_UA.axaml
@@ -41,7 +41,7 @@
Оновити
БІНАРНИЙ ФАЙЛ НЕ ПІДТРИМУЄТЬСЯ!!!
Автор рядка
- ПОШУК АВТОРА РЯДКА ДЛЯ ЦЬОГО ФАЙЛУ НЕ ПІДТРИМУЄТЬСЯ!!!
+ ПОШУК АВТОРА РЯДКА ДЛЯ ЦЬОГО ФАЙЛУ НЕ ПІДТРИМУЄТЬСЯ!!!
Перейти на ${0}$...
Порівняти з ${0}$
Порівняти з робочим деревом
@@ -440,10 +440,8 @@
За замовчуванням
Редактор
Моноширинний шрифт
- Використовувати моноширинний шрифт лише в текстовому редакторі
Тема
Перевизначення теми
- Використовувати фіксовану ширину вкладки в заголовку
Використовувати системну рамку вікна
ІНСТРУМЕНТ DIFF/MERGE
Шлях встановлення
diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml
index cc3b04549..76a334b16 100644
--- a/src/Resources/Locales/zh_CN.axaml
+++ b/src/Resources/Locales/zh_CN.axaml
@@ -56,11 +56,14 @@
无法判定
二分定位进行中。请标记当前的提交是 '正确' 还是 '错误',然后检出另一个提交。
逐行追溯(blame)
- 选中文件不支持该操作!!!
+ 对当前版本的前一版本执行逐行追溯操作
+ 选中文件不支持该操作!!!
检出(checkout) ${0}$...
与当前 ${0}$ 比较
与本地工作树比较
复制分支名
+ 创建合并请求 ...
+ 为上游分支 ${0}$ 创建合并请求 ...
自定义操作
删除 ${0}$...
删除选中的 {0} 个分支
@@ -186,7 +189,14 @@
填写提交信息主题
仓库配置
提交信息模板
- 您可使用 ${files_num}, ${branch_name}, ${files} 或 ${files:N}(N表示最大显示的文件数)
+ 内置变量:
+
+ ${branch_name} 当前分支名
+ ${files_num} 变更文件数量
+ ${files} 变更文件路径列表
+ ${files:N} 变更文件路径列表(仅输出指定 N 条)
+ ${pure_files} 与 ${files} 类似,但仅输出文件名
+ ${pure_files:N} 与 ${files:N} 类似,但仅输出文件名
模板内容 :
模板名 :
自定义操作
@@ -216,6 +226,7 @@
GIT配置
启用定时自动拉取远程更新
分钟
+ 自定义规范化提交类型
默认远程
默认合并方式
ISSUE追踪
@@ -249,6 +260,7 @@
名称 :
选项列表 :
选项之间请使用英文 '|' 作为分隔符
+ 内置变量 ${REPO}, ${REMOTE}, ${BRANCH}, ${BRANCH_FRIENDLY_NAME}, ${SHA} 与 ${TAG} 在这里仍然可用
类型 :
工作区
颜色
@@ -462,7 +474,6 @@
切换到上一个页面
新建页面
打开偏好设置面板
- 切换工作区
切换显示页面
仓库页面快捷键
提交暂存区更改
@@ -505,6 +516,7 @@
在浏览器中访问
出错了
系统提示
+ 打开其他仓库
页面列表
工作区列表
合并分支
@@ -562,11 +574,9 @@
默认
代码编辑器
等宽字体
- 仅在文本编辑器中使用等宽字体
主题
主题自定义
允许滚动条自动隐藏
- 主标签使用固定宽度
使用系统默认窗体样式
对比/合并工具
安装路径
@@ -641,6 +651,8 @@
推送到所有远程仓库
远程仓库 :
标签 :
+ 推送到新的分支
+ 输入新的远端分支名
退出
变基(rebase)操作
自动贮藏并恢复本地变更
diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml
index 14c7509cd..58079e5e2 100644
--- a/src/Resources/Locales/zh_TW.axaml
+++ b/src/Resources/Locales/zh_TW.axaml
@@ -56,11 +56,14 @@
無法確認
二分搜尋進行中。請標記目前的提交為「良好」或「錯誤」,然後簽出另一個提交。
逐行溯源 (blame)
- 所選擇的檔案不支援該操作!
+ 對上一個版本執行逐行溯源
+ 所選擇的檔案不支援該操作!
簽出 (checkout) ${0}$...
與目前 ${0}$ 比較
與本機工作區比較
複製分支名稱
+ 建立拉取請求...
+ 為上游分支 ${0}$ 建立拉取請求...
自訂動作
刪除 ${0}$...
刪除所選的 {0} 個分支
@@ -79,7 +82,7 @@
切換上游分支...
分支比較
領先 {0} 次提交
- 領先 {0} 次提交, 落後 {0} 次提交
+ 領先 {0} 次提交,落後 {0} 次提交
落後 {0} 次提交
無效
遠端
@@ -181,18 +184,25 @@
簽署人:
在瀏覽器中檢視
詳細描述
- 粘貼(替換所有內容)
+ 貼上 (全部取代)
標題
填寫提交訊息標題
存放庫設定
提交訊息範本
- 您可以使用 ${files_num}、${branch_name}、${files} 或 ${files:N},其中 N 是要輸出的檔案路徑的最大數目。
+ 內建參數:
+
+ ${branch_name} 目前分支名稱
+ ${files_num} 已變更檔案數
+ ${files} 已變更檔案路徑清單
+ ${files:N} 已變更檔案路徑清單 (僅列出前 N 個)
+ ${pure_files} 類似 ${files},不含資料夾的純檔案名稱
+ ${pure_files:N} 類似 ${files:N},不含資料夾的純檔案名稱
範本內容:
範本名稱:
自訂動作
指令參數:
- 內建參數:
-
+ 內建參數:
+
${REPO} 存放庫路徑
${REMOTE} 所選的遠端存放庫或所選分支的遠端
${BRANCH} 所選的分支。對於遠端分支,不包含遠端名稱
@@ -216,6 +226,7 @@
Git 設定
啟用定時自動提取 (fetch) 遠端更新
分鐘
+ 自訂約定式提交類型
預設遠端存放庫
預設合併模式
Issue 追蹤
@@ -249,6 +260,7 @@
名稱:
選項列表:
請使用英文「|」符號分隔選項
+ 內建變數 ${REPO}、${REMOTE}、${BRANCH}、${BRANCH_FRIENDLY_NAME}、${SHA} 及 ${TAG} 在此處仍可使用
類型:
工作區
顏色
@@ -325,7 +337,7 @@
第一個差異
忽略空白符號變化
混合對比
- 差異比較
+ 差異對比
並排對比
滑桿對比
最後一個差異
@@ -350,8 +362,8 @@
增加可見的行數
請選擇需要對比的檔案
目錄内容變更歷史
- 未提交的本地變更
- 當前分支的 HEAD 與上游不匹配
+ 未提交的本機變更
+ 目前分支 HEAD 與上游不相符
已更新至最新
捨棄變更
所有本機未提交的變更。
@@ -361,8 +373,8 @@
將捨棄總計 {0} 項已選取的變更
您無法復原此操作,請確認後再繼續!
捨棄提交
- 提交 :
- 捨棄後新的 HEAD :
+ 提交:
+ 捨棄後新的 HEAD:
書籤:
名稱:
目標:
@@ -462,7 +474,6 @@
切換到上一個頁面
新增頁面
開啟偏好設定面板
- 切換工作區
切換目前頁面
存放庫頁面快速鍵
提交暫存區變更
@@ -505,6 +516,7 @@
在瀏覽器中開啟連結
發生錯誤
系統提示
+ 開啟存放庫
頁面列表
工作區列表
合併分支
@@ -552,7 +564,7 @@
產生提交訊息提示詞
模型
名稱
- 從環境變數中(輸入為環境變數名稱)載入金鑰
+ 從環境變數中 (輸入環境變數名稱) 讀取 API 金鑰
伺服器
啟用串流輸出
外觀設定
@@ -562,11 +574,9 @@
預設
程式碼
等寬字型
- 僅在文字編輯器中使用等寬字型
佈景主題
自訂主題
- 允許滾動條自動隱藏
- 使用固定寬度的分頁標籤
+ 允許自動隱藏捲軸
使用系統原生預設視窗樣式
對比/合併工具
安裝路徑
@@ -575,16 +585,16 @@
一般設定
啟動時檢查軟體更新
日期時間格式
- 在變更樹中啟用精簡文件夾顯示模式
+ 在樹狀變更目錄中啟用密集資料夾模式
顯示語言
最大歷史提交數
在提交路線圖中顯示修改時間而非提交時間
- 預設顯示「本機變更」頁面
- 在提交詳細資訊頁面預設顯示【變更對比】
+ 預設顯示 [本機變更] 頁面
+ 在提交詳細資訊頁面預設顯示 [變更對比]
在提交詳細資訊中顯示後續提交
在路線圖中顯示標籤
提交標題字數偵測
- 生成 GitHub 風格的預設頭像
+ 產生 GitHub 風格的預設頭貼
Git 設定
自動換行轉換
預設複製 (clone) 路徑
@@ -641,6 +651,8 @@
推送到所有遠端存放庫
遠端存放庫:
標籤:
+ 推送到新的分支
+ 輸入新的遠端分支名稱:
結束
重定基底 (rebase) 操作
自動擱置變更並復原本機變更
@@ -738,7 +750,7 @@
重設模式:
移至提交:
目前分支:
- 重設選取的分支(非目前分支)
+ 重設選取的分支 (非目前分支)
重設位置:
選取分支:
在檔案瀏覽器中檢視
@@ -867,7 +879,7 @@
修補
現在您已可將其加入暫存區中
清除提交訊息歷史
- 您確定要清除所有提交訊息記錄嗎 (動作無法撤銷) ?
+ 您確定要清除所有提交訊息記錄嗎 (執行後無法復原)?
提 交
提交並推送
歷史輸入/範本
@@ -885,7 +897,7 @@
顯示未追蹤檔案
沒有提交訊息記錄
沒有可套用的提交訊息範本
- 繞過 HOOKS 檢查
+ 繞過 Hooks 檢查
重設作者
署名
已暫存
diff --git a/src/Resources/Styles.axaml b/src/Resources/Styles.axaml
index a86c03714..be43a313b 100644
--- a/src/Resources/Styles.axaml
+++ b/src/Resources/Styles.axaml
@@ -301,9 +301,6 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Views/QuickLauncher.axaml.cs b/src/Views/QuickLauncher.axaml.cs
new file mode 100644
index 000000000..f13029347
--- /dev/null
+++ b/src/Views/QuickLauncher.axaml.cs
@@ -0,0 +1,92 @@
+using Avalonia.Controls;
+using Avalonia.Input;
+
+namespace SourceGit.Views
+{
+ public partial class QuickLauncher : UserControl
+ {
+ public QuickLauncher()
+ {
+ InitializeComponent();
+ }
+
+ protected override void OnKeyDown(KeyEventArgs e)
+ {
+ base.OnKeyDown(e);
+
+ if (DataContext is not ViewModels.QuickLauncher switcher)
+ return;
+
+ if (e.Key == Key.Enter)
+ {
+ switcher.OpenOrSwitchTo();
+ e.Handled = true;
+ }
+ else if (e.Key == Key.Up)
+ {
+ if (RepoListBox.IsKeyboardFocusWithin)
+ {
+ if (switcher.VisiblePages.Count > 0)
+ {
+ PageListBox.Focus(NavigationMethod.Directional);
+ switcher.SelectedPage = switcher.VisiblePages[^1];
+ }
+ else
+ {
+ FilterTextBox.Focus(NavigationMethod.Directional);
+ }
+
+ e.Handled = true;
+ return;
+ }
+
+ if (PageListBox.IsKeyboardFocusWithin)
+ {
+ FilterTextBox.Focus(NavigationMethod.Directional);
+ e.Handled = true;
+ return;
+ }
+ }
+ else if (e.Key == Key.Down)
+ {
+ if (FilterTextBox.IsKeyboardFocusWithin)
+ {
+ if (switcher.VisiblePages.Count > 0)
+ {
+ PageListBox.Focus(NavigationMethod.Directional);
+ switcher.SelectedPage = switcher.VisiblePages[0];
+ }
+ else if (switcher.VisibleRepos.Count > 0)
+ {
+ RepoListBox.Focus(NavigationMethod.Directional);
+ switcher.SelectedRepo = switcher.VisibleRepos[0];
+ }
+
+ e.Handled = true;
+ return;
+ }
+
+ if (PageListBox.IsKeyboardFocusWithin)
+ {
+ if (switcher.VisibleRepos.Count > 0)
+ {
+ RepoListBox.Focus(NavigationMethod.Directional);
+ switcher.SelectedRepo = switcher.VisibleRepos[0];
+ }
+
+ e.Handled = true;
+ return;
+ }
+ }
+ }
+
+ private void OnItemTapped(object sender, TappedEventArgs e)
+ {
+ if (DataContext is ViewModels.QuickLauncher switcher)
+ {
+ switcher.OpenOrSwitchTo();
+ e.Handled = true;
+ }
+ }
+ }
+}
diff --git a/src/Views/Rebase.axaml b/src/Views/Rebase.axaml
index 91c1fab27..d30939b6d 100644
--- a/src/Views/Rebase.axaml
+++ b/src/Views/Rebase.axaml
@@ -38,7 +38,7 @@
-
+
diff --git a/src/Views/RemoveWorktree.axaml b/src/Views/RemoveWorktree.axaml
index 736e6e409..97f01fd27 100644
--- a/src/Views/RemoveWorktree.axaml
+++ b/src/Views/RemoveWorktree.axaml
@@ -17,7 +17,7 @@
Text="{DynamicResource Text.RemoveWorktree.Target}"/>
-
+
diff --git a/src/Views/Repository.axaml b/src/Views/Repository.axaml
index b7c92623c..59512aba2 100644
--- a/src/Views/Repository.axaml
+++ b/src/Views/Repository.axaml
@@ -131,14 +131,19 @@
-
+
+
+
-
+
+
+
-
-
-
@@ -488,7 +498,7 @@
-
+
diff --git a/src/Views/RepositoryConfigure.axaml.cs b/src/Views/RepositoryConfigure.axaml.cs
index 3ce581d76..2c5622df1 100644
--- a/src/Views/RepositoryConfigure.axaml.cs
+++ b/src/Views/RepositoryConfigure.axaml.cs
@@ -21,6 +21,21 @@ protected override async void OnClosing(WindowClosingEventArgs e)
await configure.SaveAsync();
}
+ private async void SelectConventionalTypesFile(object sender, RoutedEventArgs e)
+ {
+ var options = new FilePickerOpenOptions()
+ {
+ FileTypeFilter = [new FilePickerFileType("Conventional Commit Types") { Patterns = ["*.json"] }],
+ AllowMultiple = false,
+ };
+
+ var selected = await StorageProvider.OpenFilePickerAsync(options);
+ if (selected.Count == 1 && DataContext is ViewModels.RepositoryConfigure vm)
+ vm.ConventionalTypesOverride = selected[0].Path.LocalPath;
+
+ e.Handled = true;
+ }
+
private async void SelectExecutableForCustomAction(object sender, RoutedEventArgs e)
{
var options = new FilePickerOpenOptions()
diff --git a/src/Views/RepositoryToolbar.axaml b/src/Views/RepositoryToolbar.axaml
index 844eef8d2..604bcba66 100644
--- a/src/Views/RepositoryToolbar.axaml
+++ b/src/Views/RepositoryToolbar.axaml
@@ -115,7 +115,7 @@
-
+
@@ -123,7 +123,7 @@
-
+
diff --git a/src/Views/Reset.axaml b/src/Views/Reset.axaml
index bce9d747c..9dc0bd7ba 100644
--- a/src/Views/Reset.axaml
+++ b/src/Views/Reset.axaml
@@ -28,7 +28,7 @@
Text="{DynamicResource Text.Reset.MoveTo}"/>
-
+
diff --git a/src/Views/ResetWithoutCheckout.axaml b/src/Views/ResetWithoutCheckout.axaml
index 3808a8dd0..16d2a5c24 100644
--- a/src/Views/ResetWithoutCheckout.axaml
+++ b/src/Views/ResetWithoutCheckout.axaml
@@ -38,7 +38,7 @@
-
+
diff --git a/src/Views/Revert.axaml b/src/Views/Revert.axaml
index cafe1725b..a6aea6fb9 100644
--- a/src/Views/Revert.axaml
+++ b/src/Views/Revert.axaml
@@ -19,7 +19,7 @@
-
+
diff --git a/src/Views/RevisionCompare.axaml b/src/Views/RevisionCompare.axaml
index dd8237b5e..87424f0ab 100644
--- a/src/Views/RevisionCompare.axaml
+++ b/src/Views/RevisionCompare.axaml
@@ -12,7 +12,7 @@
-
+
@@ -20,15 +20,15 @@
-
+
-
+
-
-
+
+
-
+
diff --git a/src/Views/RevisionCompare.axaml.cs b/src/Views/RevisionCompare.axaml.cs
index bb27e7095..3a84baca1 100644
--- a/src/Views/RevisionCompare.axaml.cs
+++ b/src/Views/RevisionCompare.axaml.cs
@@ -1,5 +1,6 @@
using System;
using System.IO;
+using System.Text;
using Avalonia.Controls;
using Avalonia.Input;
@@ -17,59 +18,126 @@ public RevisionCompare()
private void OnChangeContextRequested(object sender, ContextRequestedEventArgs e)
{
- if (DataContext is ViewModels.RevisionCompare { SelectedChanges: { Count: 1 } selected } vm &&
+ if (DataContext is ViewModels.RevisionCompare { SelectedChanges: { Count: > 0 } selected } vm &&
sender is ChangeCollectionView view)
{
- var change = selected[0];
- var changeFullPath = vm.GetAbsPath(change.Path);
- var menu = new ContextMenu();
-
- var openWithMerger = new MenuItem();
- openWithMerger.Header = App.Text("OpenInExternalMergeTool");
- openWithMerger.Icon = App.CreateMenuIcon("Icons.OpenWith");
- openWithMerger.Tag = OperatingSystem.IsMacOS() ? "⌘+⇧+D" : "Ctrl+Shift+D";
- openWithMerger.Click += (_, ev) =>
+ var patch = new MenuItem();
+ patch.Header = App.Text("FileCM.SaveAsPatch");
+ patch.Icon = App.CreateMenuIcon("Icons.Diff");
+ patch.Click += async (_, e) =>
{
- vm.OpenChangeWithExternalDiffTool(change);
- ev.Handled = true;
+ var storageProvider = TopLevel.GetTopLevel(this)?.StorageProvider;
+ if (storageProvider == null)
+ return;
+
+ var options = new FilePickerSaveOptions();
+ options.Title = App.Text("FileCM.SaveAsPatch");
+ options.DefaultExtension = ".patch";
+ options.FileTypeChoices = [new FilePickerFileType("Patch File") { Patterns = ["*.patch"] }];
+
+ var storageFile = await storageProvider.SaveFilePickerAsync(options);
+ if (storageFile != null)
+ {
+ var saveTo = storageFile.Path.LocalPath;
+ await vm.SaveChangesAsPatchAsync(selected, saveTo);
+ }
+
+ e.Handled = true;
};
- menu.Items.Add(openWithMerger);
- if (change.Index != Models.ChangeState.Deleted)
+ var menu = new ContextMenu();
+ if (selected.Count == 1)
{
- var explore = new MenuItem();
- explore.Header = App.Text("RevealFile");
- explore.Icon = App.CreateMenuIcon("Icons.Explore");
- explore.IsEnabled = File.Exists(changeFullPath);
- explore.Click += (_, ev) =>
+ var change = selected[0];
+ var changeFullPath = vm.GetAbsPath(change.Path);
+
+ var openWithMerger = new MenuItem();
+ openWithMerger.Header = App.Text("OpenInExternalMergeTool");
+ openWithMerger.Icon = App.CreateMenuIcon("Icons.OpenWith");
+ openWithMerger.Tag = OperatingSystem.IsMacOS() ? "⌘+⇧+D" : "Ctrl+Shift+D";
+ openWithMerger.Click += (_, ev) =>
{
- Native.OS.OpenInFileManager(changeFullPath, true);
+ vm.OpenChangeWithExternalDiffTool(change);
ev.Handled = true;
};
- menu.Items.Add(explore);
- }
+ menu.Items.Add(openWithMerger);
- var copyPath = new MenuItem();
- copyPath.Header = App.Text("CopyPath");
- copyPath.Icon = App.CreateMenuIcon("Icons.Copy");
- copyPath.Tag = OperatingSystem.IsMacOS() ? "⌘+C" : "Ctrl+C";
- copyPath.Click += async (_, ev) =>
- {
- await App.CopyTextAsync(change.Path);
- ev.Handled = true;
- };
- menu.Items.Add(copyPath);
+ if (change.Index != Models.ChangeState.Deleted)
+ {
+ var explore = new MenuItem();
+ explore.Header = App.Text("RevealFile");
+ explore.Icon = App.CreateMenuIcon("Icons.Explore");
+ explore.IsEnabled = File.Exists(changeFullPath);
+ explore.Click += (_, ev) =>
+ {
+ Native.OS.OpenInFileManager(changeFullPath, true);
+ ev.Handled = true;
+ };
+ menu.Items.Add(explore);
+ }
+
+ var copyPath = new MenuItem();
+ copyPath.Header = App.Text("CopyPath");
+ copyPath.Icon = App.CreateMenuIcon("Icons.Copy");
+ copyPath.Tag = OperatingSystem.IsMacOS() ? "⌘+C" : "Ctrl+C";
+ copyPath.Click += async (_, ev) =>
+ {
+ await App.CopyTextAsync(change.Path);
+ ev.Handled = true;
+ };
- var copyFullPath = new MenuItem();
- copyFullPath.Header = App.Text("CopyFullPath");
- copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy");
- copyFullPath.Tag = OperatingSystem.IsMacOS() ? "⌘+⇧+C" : "Ctrl+Shift+C";
- copyFullPath.Click += async (_, ev) =>
+ var copyFullPath = new MenuItem();
+ copyFullPath.Header = App.Text("CopyFullPath");
+ copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy");
+ copyFullPath.Tag = OperatingSystem.IsMacOS() ? "⌘+⇧+C" : "Ctrl+Shift+C";
+ copyFullPath.Click += async (_, ev) =>
+ {
+ await App.CopyTextAsync(changeFullPath);
+ ev.Handled = true;
+ };
+
+ menu.Items.Add(new MenuItem() { Header = "-" });
+ menu.Items.Add(patch);
+ menu.Items.Add(new MenuItem() { Header = "-" });
+ menu.Items.Add(copyPath);
+ menu.Items.Add(copyFullPath);
+ }
+ else
{
- await App.CopyTextAsync(changeFullPath);
- ev.Handled = true;
- };
- menu.Items.Add(copyFullPath);
+ var copyPath = new MenuItem();
+ copyPath.Header = App.Text("CopyPath");
+ copyPath.Icon = App.CreateMenuIcon("Icons.Copy");
+ copyPath.Tag = OperatingSystem.IsMacOS() ? "⌘+C" : "Ctrl+C";
+ copyPath.Click += async (_, ev) =>
+ {
+ var builder = new StringBuilder();
+ foreach (var c in selected)
+ builder.AppendLine(c.Path);
+
+ await App.CopyTextAsync(builder.ToString());
+ ev.Handled = true;
+ };
+
+ var copyFullPath = new MenuItem();
+ copyFullPath.Header = App.Text("CopyFullPath");
+ copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy");
+ copyFullPath.Tag = OperatingSystem.IsMacOS() ? "⌘+⇧+C" : "Ctrl+Shift+C";
+ copyFullPath.Click += async (_, ev) =>
+ {
+ var builder = new StringBuilder();
+ foreach (var c in selected)
+ builder.AppendLine(vm.GetAbsPath(c.Path));
+
+ await App.CopyTextAsync(builder.ToString());
+ ev.Handled = true;
+ };
+
+ menu.Items.Add(patch);
+ menu.Items.Add(new MenuItem() { Header = "-" });
+ menu.Items.Add(copyPath);
+ menu.Items.Add(copyFullPath);
+ }
+
menu.Open(view);
}
@@ -86,8 +154,8 @@ private void OnPressedSHA(object sender, PointerPressedEventArgs e)
private async void OnSaveAsPatch(object sender, RoutedEventArgs e)
{
- var topLevel = TopLevel.GetTopLevel(this);
- if (topLevel == null)
+ var storage = TopLevel.GetTopLevel(this)?.StorageProvider;
+ if (storage == null)
return;
if (DataContext is not ViewModels.RevisionCompare vm)
@@ -98,9 +166,9 @@ private async void OnSaveAsPatch(object sender, RoutedEventArgs e)
options.DefaultExtension = ".patch";
options.FileTypeChoices = [new FilePickerFileType("Patch File") { Patterns = ["*.patch"] }];
- var storageFile = await topLevel.StorageProvider.SaveFilePickerAsync(options);
+ var storageFile = await storage.SaveFilePickerAsync(options);
if (storageFile != null)
- vm.SaveAsPatch(storageFile.Path.LocalPath);
+ await vm.SaveChangesAsPatchAsync(null, storageFile.Path.LocalPath);
e.Handled = true;
}
@@ -110,17 +178,24 @@ private async void OnChangeCollectionViewKeyDown(object sender, KeyEventArgs e)
if (DataContext is not ViewModels.RevisionCompare vm)
return;
- if (sender is not ChangeCollectionView { SelectedChanges: { Count: 1 } selectedChanges })
+ if (sender is not ChangeCollectionView { SelectedChanges: { Count: > 0 } selectedChanges })
return;
- var change = selectedChanges[0];
if (e.KeyModifiers.HasFlag(OperatingSystem.IsMacOS() ? KeyModifiers.Meta : KeyModifiers.Control) && e.Key == Key.C)
{
- if (e.KeyModifiers.HasFlag(KeyModifiers.Shift))
- await App.CopyTextAsync(vm.GetAbsPath(change.Path));
+ var builder = new StringBuilder();
+ var copyAbsPath = e.KeyModifiers.HasFlag(KeyModifiers.Shift);
+ if (selectedChanges.Count == 1)
+ {
+ builder.Append(copyAbsPath ? vm.GetAbsPath(selectedChanges[0].Path) : selectedChanges[0].Path);
+ }
else
- await App.CopyTextAsync(change.Path);
+ {
+ foreach (var c in selectedChanges)
+ builder.AppendLine(copyAbsPath ? vm.GetAbsPath(c.Path) : c.Path);
+ }
+ await App.CopyTextAsync(builder.ToString());
e.Handled = true;
}
}
diff --git a/src/Views/RevisionFileContentViewer.axaml b/src/Views/RevisionFileContentViewer.axaml
index 99e84d48e..67c67bed2 100644
--- a/src/Views/RevisionFileContentViewer.axaml
+++ b/src/Views/RevisionFileContentViewer.axaml
@@ -14,7 +14,7 @@
-
+
@@ -39,11 +39,11 @@
-
+
-
-
+
+
@@ -54,7 +54,7 @@
-
+
diff --git a/src/Views/RevisionFileTreeView.axaml b/src/Views/RevisionFileTreeView.axaml
index 7266c4295..025ba4d79 100644
--- a/src/Views/RevisionFileTreeView.axaml
+++ b/src/Views/RevisionFileTreeView.axaml
@@ -42,7 +42,7 @@
IsChecked="{Binding IsExpanded, Mode=OneWay}"
IsVisible="{Binding IsFolder}"/>
-
+
diff --git a/src/Views/RevisionFileTreeView.axaml.cs b/src/Views/RevisionFileTreeView.axaml.cs
index be8b8f572..626a02b33 100644
--- a/src/Views/RevisionFileTreeView.axaml.cs
+++ b/src/Views/RevisionFileTreeView.axaml.cs
@@ -8,6 +8,7 @@
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
+using Avalonia.Interactivity;
using Avalonia.Layout;
using Avalonia.Media;
using Avalonia.Platform.Storage;
@@ -301,34 +302,19 @@ protected override async void OnPropertyChanged(AvaloniaPropertyChangedEventArgs
_tree.Clear();
_searchResult.Clear();
- var vm = DataContext as ViewModels.CommitDetail;
- if (vm?.Commit == null)
- {
- Rows.Clear();
- GC.Collect();
- return;
- }
-
- var objects = await vm.GetRevisionFilesUnderFolderAsync(null);
- if (objects == null || objects.Count == 0)
- {
+ if (DataContext is ViewModels.CommitDetail { ActiveTabIndex: 2 } vm)
+ await ReloadTreeData(vm);
+ else
Rows.Clear();
- GC.Collect();
- return;
- }
-
- foreach (var obj in objects)
- _tree.Add(new ViewModels.RevisionFileTreeNode { Backend = obj });
-
- SortNodes(_tree);
+ }
+ }
- var topTree = new List();
- MakeRows(topTree, _tree, 0);
+ protected override async void OnLoaded(RoutedEventArgs e)
+ {
+ base.OnLoaded(e);
- Rows.Clear();
- Rows.AddRange(topTree);
- GC.Collect();
- }
+ if (DataContext is ViewModels.CommitDetail vm && _tree.Count == 0)
+ await ReloadTreeData(vm);
}
private void OnTreeNodeContextRequested(object sender, ContextRequestedEventArgs e)
@@ -416,7 +402,42 @@ private void SortNodes(List nodes)
});
}
- public ContextMenu CreateRevisionFileContextMenuByFolder(ViewModels.Repository repo, ViewModels.CommitDetail vm, Models.Commit commit, string path)
+ private async Task ReloadTreeData(ViewModels.CommitDetail vm)
+ {
+ if (_isReloadingTreeData)
+ return;
+
+ _isReloadingTreeData = true;
+
+ if (vm?.Commit == null)
+ {
+ Rows.Clear();
+ _isReloadingTreeData = false;
+ return;
+ }
+
+ var objects = await vm.GetRevisionFilesUnderFolderAsync(null);
+ if (objects == null || objects.Count == 0)
+ {
+ Rows.Clear();
+ _isReloadingTreeData = false;
+ return;
+ }
+
+ foreach (var obj in objects)
+ _tree.Add(new ViewModels.RevisionFileTreeNode { Backend = obj });
+
+ SortNodes(_tree);
+
+ var topTree = new List();
+ MakeRows(topTree, _tree, 0);
+
+ Rows.Clear();
+ Rows.AddRange(topTree);
+ _isReloadingTreeData = false;
+ }
+
+ private ContextMenu CreateRevisionFileContextMenuByFolder(ViewModels.Repository repo, ViewModels.CommitDetail vm, Models.Commit commit, string path)
{
var fullPath = Native.OS.GetAbsPath(repo.FullPath, path);
var explore = new MenuItem();
@@ -468,7 +489,7 @@ public ContextMenu CreateRevisionFileContextMenuByFolder(ViewModels.Repository r
return menu;
}
- public ContextMenu CreateRevisionFileContextMenu(ViewModels.Repository repo, ViewModels.CommitDetail vm, Models.Commit commit, Models.Object file)
+ private ContextMenu CreateRevisionFileContextMenu(ViewModels.Repository repo, ViewModels.CommitDetail vm, Models.Commit commit, Models.Object file)
{
var fullPath = Native.OS.GetAbsPath(repo.FullPath, file.Path);
var menu = new ContextMenu();
@@ -674,5 +695,6 @@ public ContextMenu CreateRevisionFileContextMenu(ViewModels.Repository repo, Vie
private List _tree = [];
private bool _disableSelectionChangingEvent = false;
private List _searchResult = [];
+ private bool _isReloadingTreeData = false;
}
}
diff --git a/src/Views/RevisionFiles.axaml b/src/Views/RevisionFiles.axaml
index 0583c35a8..4144f3ed1 100644
--- a/src/Views/RevisionFiles.axaml
+++ b/src/Views/RevisionFiles.axaml
@@ -88,9 +88,9 @@
-
+
-
+
@@ -122,7 +122,6 @@
-
+
diff --git a/src/Views/ScanRepositories.axaml b/src/Views/ScanRepositories.axaml
index 9ca7bbd7d..83264bf19 100644
--- a/src/Views/ScanRepositories.axaml
+++ b/src/Views/ScanRepositories.axaml
@@ -33,7 +33,7 @@
-
+
diff --git a/src/Views/SelfUpdate.axaml b/src/Views/SelfUpdate.axaml
index 2d5990e70..a65812339 100644
--- a/src/Views/SelfUpdate.axaml
+++ b/src/Views/SelfUpdate.axaml
@@ -47,7 +47,7 @@
-
+
diff --git a/src/Views/SetUpstream.axaml b/src/Views/SetUpstream.axaml
index a2318d0bd..a7d9c4099 100644
--- a/src/Views/SetUpstream.axaml
+++ b/src/Views/SetUpstream.axaml
@@ -26,12 +26,12 @@
Margin="0,0,8,0"
Text="{DynamicResource Text.SetUpstream.Upstream}"/>
diff --git a/src/Views/SetUpstream.axaml.cs b/src/Views/SetUpstream.axaml.cs
index 2c766a7ce..e7b7f3568 100644
--- a/src/Views/SetUpstream.axaml.cs
+++ b/src/Views/SetUpstream.axaml.cs
@@ -1,6 +1,4 @@
using Avalonia.Controls;
-using Avalonia.Controls.Primitives;
-using Avalonia.Data;
namespace SourceGit.Views
{
@@ -9,7 +7,6 @@ public partial class SetUpstream : UserControl
public SetUpstream()
{
InitializeComponent();
- TextSearch.SetTextBinding(RemoteBranchesComboBox, new Binding("Name"));
}
}
}
diff --git a/src/Views/Squash.axaml b/src/Views/Squash.axaml
index 3786b29b1..939591b96 100644
--- a/src/Views/Squash.axaml
+++ b/src/Views/Squash.axaml
@@ -22,7 +22,6 @@
Fill="{DynamicResource Brush.FG1}"
Data="{StaticResource Icons.Commit}"/>
diff --git a/src/Views/StashesPage.axaml b/src/Views/StashesPage.axaml
index b6742a17c..f755dbf1b 100644
--- a/src/Views/StashesPage.axaml
+++ b/src/Views/StashesPage.axaml
@@ -92,8 +92,8 @@
ToolTip.Tip="{Binding Message}">
-
-
+
+
0 } selected } vm &&
sender is ChangeCollectionView view)
{
- var change = selected[0];
- var fullPath = vm.GetAbsPath(change.Path);
-
- var openWithMerger = new MenuItem();
- openWithMerger.Header = App.Text("OpenInExternalMergeTool");
- openWithMerger.Icon = App.CreateMenuIcon("Icons.OpenWith");
- openWithMerger.Tag = OperatingSystem.IsMacOS() ? "⌘+⇧+D" : "Ctrl+Shift+D";
- openWithMerger.Click += (_, ev) =>
+ if (selected.Count == 1)
{
- vm.OpenChangeWithExternalDiffTool(change);
- ev.Handled = true;
- };
+ var change = selected[0];
+ var fullPath = vm.GetAbsPath(change.Path);
- var explore = new MenuItem();
- explore.Header = App.Text("RevealFile");
- explore.Icon = App.CreateMenuIcon("Icons.Explore");
- explore.IsEnabled = File.Exists(fullPath);
- explore.Click += (_, ev) =>
- {
- Native.OS.OpenInFileManager(fullPath, true);
- ev.Handled = true;
- };
+ var openWithMerger = new MenuItem();
+ openWithMerger.Header = App.Text("OpenInExternalMergeTool");
+ openWithMerger.Icon = App.CreateMenuIcon("Icons.OpenWith");
+ openWithMerger.Tag = OperatingSystem.IsMacOS() ? "⌘+⇧+D" : "Ctrl+Shift+D";
+ openWithMerger.Click += (_, ev) =>
+ {
+ vm.OpenChangeWithExternalDiffTool(change);
+ ev.Handled = true;
+ };
- var resetToThisRevision = new MenuItem();
- resetToThisRevision.Header = App.Text("ChangeCM.CheckoutThisRevision");
- resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout");
- resetToThisRevision.Click += async (_, ev) =>
- {
- await vm.CheckoutSingleFileAsync(change);
- ev.Handled = true;
- };
+ var explore = new MenuItem();
+ explore.Header = App.Text("RevealFile");
+ explore.Icon = App.CreateMenuIcon("Icons.Explore");
+ explore.IsEnabled = File.Exists(fullPath);
+ explore.Click += (_, ev) =>
+ {
+ Native.OS.OpenInFileManager(fullPath, true);
+ ev.Handled = true;
+ };
- var copyPath = new MenuItem();
- copyPath.Header = App.Text("CopyPath");
- copyPath.Icon = App.CreateMenuIcon("Icons.Copy");
- copyPath.Tag = OperatingSystem.IsMacOS() ? "⌘+C" : "Ctrl+C";
- copyPath.Click += async (_, ev) =>
- {
- await App.CopyTextAsync(change.Path);
- ev.Handled = true;
- };
+ var resetToThisRevision = new MenuItem();
+ resetToThisRevision.Header = App.Text("ChangeCM.CheckoutThisRevision");
+ resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout");
+ resetToThisRevision.Click += async (_, ev) =>
+ {
+ await vm.CheckoutSingleFileAsync(change);
+ ev.Handled = true;
+ };
+
+ var copyPath = new MenuItem();
+ copyPath.Header = App.Text("CopyPath");
+ copyPath.Icon = App.CreateMenuIcon("Icons.Copy");
+ copyPath.Tag = OperatingSystem.IsMacOS() ? "⌘+C" : "Ctrl+C";
+ copyPath.Click += async (_, ev) =>
+ {
+ await App.CopyTextAsync(change.Path);
+ ev.Handled = true;
+ };
- var copyFullPath = new MenuItem();
- copyFullPath.Header = App.Text("CopyFullPath");
- copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy");
- copyFullPath.Tag = OperatingSystem.IsMacOS() ? "⌘+⇧+C" : "Ctrl+Shift+C";
- copyFullPath.Click += async (_, ev) =>
+ var copyFullPath = new MenuItem();
+ copyFullPath.Header = App.Text("CopyFullPath");
+ copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy");
+ copyFullPath.Tag = OperatingSystem.IsMacOS() ? "⌘+⇧+C" : "Ctrl+Shift+C";
+ copyFullPath.Click += async (_, ev) =>
+ {
+ await App.CopyTextAsync(fullPath);
+ ev.Handled = true;
+ };
+
+ var menu = new ContextMenu();
+ menu.Items.Add(openWithMerger);
+ menu.Items.Add(explore);
+ menu.Items.Add(new MenuItem { Header = "-" });
+ menu.Items.Add(resetToThisRevision);
+ menu.Items.Add(new MenuItem { Header = "-" });
+ menu.Items.Add(copyPath);
+ menu.Items.Add(copyFullPath);
+ menu.Open(view);
+ }
+ else
{
- await App.CopyTextAsync(fullPath);
- ev.Handled = true;
- };
+ var resetToThisRevision = new MenuItem();
+ resetToThisRevision.Header = App.Text("ChangeCM.CheckoutThisRevision");
+ resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout");
+ resetToThisRevision.Click += async (_, ev) =>
+ {
+ await vm.CheckoutMultipleFileAsync(selected);
+ ev.Handled = true;
+ };
- var menu = new ContextMenu();
- menu.Items.Add(openWithMerger);
- menu.Items.Add(explore);
- menu.Items.Add(new MenuItem { Header = "-" });
- menu.Items.Add(resetToThisRevision);
- menu.Items.Add(new MenuItem { Header = "-" });
- menu.Items.Add(copyPath);
- menu.Items.Add(copyFullPath);
- menu.Open(view);
+ var copyPath = new MenuItem();
+ copyPath.Header = App.Text("CopyPath");
+ copyPath.Icon = App.CreateMenuIcon("Icons.Copy");
+ copyPath.Tag = OperatingSystem.IsMacOS() ? "⌘+C" : "Ctrl+C";
+ copyPath.Click += async (_, ev) =>
+ {
+ var builder = new StringBuilder();
+ foreach (var c in selected)
+ builder.AppendLine(c.Path);
+
+ await App.CopyTextAsync(builder.ToString());
+ ev.Handled = true;
+ };
+
+ var copyFullPath = new MenuItem();
+ copyFullPath.Header = App.Text("CopyFullPath");
+ copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy");
+ copyFullPath.Tag = OperatingSystem.IsMacOS() ? "⌘+⇧+C" : "Ctrl+Shift+C";
+ copyFullPath.Click += async (_, ev) =>
+ {
+ var builder = new StringBuilder();
+ foreach (var c in selected)
+ builder.AppendLine(vm.GetAbsPath(c.Path));
+
+ await App.CopyTextAsync(builder.ToString());
+ ev.Handled = true;
+ };
+
+ var menu = new ContextMenu();
+ menu.Items.Add(resetToThisRevision);
+ menu.Items.Add(new MenuItem { Header = "-" });
+ menu.Items.Add(copyPath);
+ menu.Items.Add(copyFullPath);
+ menu.Open(view);
+ }
}
e.Handled = true;
@@ -197,17 +247,24 @@ private async void OnChangeCollectionViewKeyDown(object sender, KeyEventArgs e)
if (DataContext is not ViewModels.StashesPage vm)
return;
- if (sender is not ChangeCollectionView { SelectedChanges: { Count: 1 } selectedChanges })
+ if (sender is not ChangeCollectionView { SelectedChanges: { Count: > 0 } selectedChanges })
return;
- var change = selectedChanges[0];
if (e.KeyModifiers.HasFlag(OperatingSystem.IsMacOS() ? KeyModifiers.Meta : KeyModifiers.Control) && e.Key == Key.C)
{
- if (e.KeyModifiers.HasFlag(KeyModifiers.Shift))
- await App.CopyTextAsync(vm.GetAbsPath(change.Path));
+ var builder = new StringBuilder();
+ var copyAbsPath = e.KeyModifiers.HasFlag(KeyModifiers.Shift);
+ if (selectedChanges.Count == 1)
+ {
+ builder.Append(copyAbsPath ? vm.GetAbsPath(selectedChanges[0].Path) : selectedChanges[0].Path);
+ }
else
- await App.CopyTextAsync(change.Path);
+ {
+ foreach (var c in selectedChanges)
+ builder.AppendLine(copyAbsPath ? vm.GetAbsPath(c.Path) : c.Path);
+ }
+ await App.CopyTextAsync(builder.ToString());
e.Handled = true;
}
}
diff --git a/src/Views/Statistics.axaml b/src/Views/Statistics.axaml
index 83c46e738..bc2259976 100644
--- a/src/Views/Statistics.axaml
+++ b/src/Views/Statistics.axaml
@@ -186,14 +186,14 @@
-
-
+
+
-
-
+
+
diff --git a/src/Views/SubmodulesView.axaml b/src/Views/SubmodulesView.axaml
index 4e21088fd..963ae1b65 100644
--- a/src/Views/SubmodulesView.axaml
+++ b/src/Views/SubmodulesView.axaml
@@ -119,7 +119,6 @@
IsExpanded="{Binding IsExpanded, Mode=OneWay}"/>
@@ -233,7 +232,7 @@
-
+
-
+
@@ -92,7 +90,6 @@
Data="{StaticResource Icons.Tag}"/>
@@ -111,7 +108,7 @@
-
+
diff --git a/src/Views/ViewLogs.axaml b/src/Views/ViewLogs.axaml
index bba5da8eb..53dbe6e8b 100644
--- a/src/Views/ViewLogs.axaml
+++ b/src/Views/ViewLogs.axaml
@@ -88,7 +88,6 @@
IsVisible="{Binding !IsComplete}"/>
diff --git a/src/Views/Welcome.axaml b/src/Views/Welcome.axaml
index 771073bd0..7d23c60a9 100644
--- a/src/Views/Welcome.axaml
+++ b/src/Views/Welcome.axaml
@@ -3,6 +3,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:c="using:SourceGit.Converters"
+ xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
@@ -106,7 +107,7 @@
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Views/Welcome.axaml.cs b/src/Views/Welcome.axaml.cs
index 365a7cbee..7a3565c02 100644
--- a/src/Views/Welcome.axaml.cs
+++ b/src/Views/Welcome.axaml.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
@@ -61,6 +62,18 @@ public Welcome()
InitializeComponent();
}
+ protected override async void OnLoaded(RoutedEventArgs e)
+ {
+ base.OnLoaded(e);
+ await ViewModels.Welcome.Instance.UpdateStatusAsync(false, _cancellation.Token);
+ }
+
+ protected override void OnUnloaded(RoutedEventArgs e)
+ {
+ _cancellation.Cancel();
+ base.OnUnloaded(e);
+ }
+
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
@@ -266,7 +279,7 @@ private async void DropOnTreeView(object sender, DragEventArgs e)
var path = await ViewModels.Welcome.Instance.GetRepositoryRootAsync(item.Path.LocalPath);
if (!string.IsNullOrEmpty(path))
{
- ViewModels.Welcome.Instance.AddRepository(path, null, true, false);
+ await ViewModels.Welcome.Instance.AddRepositoryAsync(path, null, true, false);
refresh = true;
}
}
@@ -325,7 +338,7 @@ private async void DropOnTreeNode(object sender, DragEventArgs e)
var path = await ViewModels.Welcome.Instance.GetRepositoryRootAsync(item.Path.LocalPath);
if (!string.IsNullOrEmpty(path))
{
- ViewModels.Welcome.Instance.AddRepository(path, to, true, false);
+ await ViewModels.Welcome.Instance.AddRepositoryAsync(path, to, true, false);
refresh = true;
}
}
@@ -355,5 +368,6 @@ private void OnDoubleTappedTreeNode(object sender, TappedEventArgs e)
private Point _pressedTreeNodePosition = new Point();
private bool _startDragTreeNode = false;
private readonly DataFormat _dndRepoNode = DataFormat.CreateStringApplicationFormat("sourcegit-dnd-repo-node");
+ private CancellationTokenSource _cancellation = new CancellationTokenSource();
}
}
diff --git a/src/Views/WelcomeToolbar.axaml.cs b/src/Views/WelcomeToolbar.axaml.cs
index 65b4ca129..7d901e35c 100644
--- a/src/Views/WelcomeToolbar.axaml.cs
+++ b/src/Views/WelcomeToolbar.axaml.cs
@@ -47,7 +47,7 @@ private async void OpenLocalRepository(object _1, RoutedEventArgs e)
var repoPath = await ViewModels.Welcome.Instance.GetRepositoryRootAsync(folderPath);
if (!string.IsNullOrEmpty(repoPath))
{
- ViewModels.Welcome.Instance.AddRepository(repoPath, null, false, true);
+ await ViewModels.Welcome.Instance.AddRepositoryAsync(repoPath, null, false, true);
ViewModels.Welcome.Instance.Refresh();
}
else if (Directory.Exists(folderPath))
diff --git a/src/Views/WorkingCopy.axaml b/src/Views/WorkingCopy.axaml
index e5eed5e71..ce940299f 100644
--- a/src/Views/WorkingCopy.axaml
+++ b/src/Views/WorkingCopy.axaml
@@ -126,7 +126,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Views/WorkspaceSwitcher.axaml.cs b/src/Views/WorkspaceSwitcher.axaml.cs
deleted file mode 100644
index 7b708dd91..000000000
--- a/src/Views/WorkspaceSwitcher.axaml.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-using Avalonia.Controls;
-using Avalonia.Input;
-
-namespace SourceGit.Views
-{
- public partial class WorkspaceSwitcher : UserControl
- {
- public WorkspaceSwitcher()
- {
- InitializeComponent();
- }
-
- protected override void OnKeyDown(KeyEventArgs e)
- {
- base.OnKeyDown(e);
-
- if (e.Key == Key.Enter && DataContext is ViewModels.WorkspaceSwitcher switcher)
- {
- switcher.Switch();
- e.Handled = true;
- }
- }
-
- private void OnItemTapped(object sender, TappedEventArgs e)
- {
- if (DataContext is ViewModels.WorkspaceSwitcher switcher)
- {
- switcher.Switch();
- e.Handled = true;
- }
- }
-
- private void OnSearchBoxKeyDown(object sender, KeyEventArgs e)
- {
- if (WorkspaceListBox.ItemCount == 0)
- return;
-
- if (e.Key == Key.Down)
- {
- WorkspaceListBox.Focus(NavigationMethod.Directional);
-
- if (WorkspaceListBox.SelectedIndex < WorkspaceListBox.ItemCount - 1)
- WorkspaceListBox.SelectedIndex++;
- else
- WorkspaceListBox.SelectedIndex = 0;
-
- e.Handled = true;
- }
- else if (e.Key == Key.Up)
- {
- WorkspaceListBox.Focus(NavigationMethod.Directional);
-
- if (WorkspaceListBox.SelectedIndex > 0)
- WorkspaceListBox.SelectedIndex--;
- else
- WorkspaceListBox.SelectedIndex = WorkspaceListBox.ItemCount - 1;
-
- e.Handled = true;
- }
- }
- }
-}