Merge branch 'release/v2025.23'

This commit is contained in:
leo 2025-06-23 09:59:54 +08:00
commit 190d2eec73
No known key found for this signature in database
97 changed files with 1309 additions and 745 deletions

View file

@ -71,20 +71,20 @@ dotnet_style_predefined_type_for_member_access = true:suggestion
# name all constant fields using PascalCase # name all constant fields using PascalCase
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
dotnet_naming_symbols.constant_fields.applicable_kinds = field dotnet_naming_symbols.constant_fields.applicable_kinds = field
dotnet_naming_symbols.constant_fields.required_modifiers = const dotnet_naming_symbols.constant_fields.required_modifiers = const
dotnet_naming_style.pascal_case_style.capitalization = pascal_case dotnet_naming_style.pascal_case_style.capitalization = pascal_case
# private static fields should have s_ prefix # private static fields should have s_ prefix
dotnet_naming_rule.private_static_fields_should_have_prefix.severity = suggestion dotnet_naming_rule.private_static_fields_should_have_prefix.severity = suggestion
dotnet_naming_rule.private_static_fields_should_have_prefix.symbols = private_static_fields dotnet_naming_rule.private_static_fields_should_have_prefix.symbols = private_static_fields
dotnet_naming_rule.private_static_fields_should_have_prefix.style = private_static_prefix_style dotnet_naming_rule.private_static_fields_should_have_prefix.style = private_static_prefix_style
dotnet_naming_symbols.private_static_fields.applicable_kinds = field dotnet_naming_symbols.private_static_fields.applicable_kinds = field
dotnet_naming_symbols.private_static_fields.required_modifiers = static dotnet_naming_symbols.private_static_fields.required_modifiers = static
dotnet_naming_symbols.private_static_fields.applicable_accessibilities = private dotnet_naming_symbols.private_static_fields.applicable_accessibilities = private
@ -93,7 +93,7 @@ dotnet_naming_style.private_static_prefix_style.capitalization = camel_case
# internal and private fields should be _camelCase # internal and private fields should be _camelCase
dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion
dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields
dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style
dotnet_naming_symbols.private_internal_fields.applicable_kinds = field dotnet_naming_symbols.private_internal_fields.applicable_kinds = field

View file

@ -6,48 +6,24 @@ This document shows the translation status of each locale file in the repository
### ![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen) ### ![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen)
### ![de__DE](https://img.shields.io/badge/de__DE-96.14%25-yellow) ### ![de__DE](https://img.shields.io/badge/de__DE-%E2%88%9A-brightgreen)
### ![es__ES](https://img.shields.io/badge/es__ES-99.13%25-yellow)
<details> <details>
<summary>Missing keys in de_DE.axaml</summary> <summary>Missing keys in es_ES.axaml</summary>
- Text.Avatar.Load - Text.CommitCM.PushRevision
- Text.BranchCM.ResetToSelectedCommit - Text.Merge.Edit
- Text.Checkout.WithFastForward - Text.Push.Revision
- Text.Checkout.WithFastForward.Upstream - Text.Push.Revision.Title
- Text.CommitDetail.Changes.Count - Text.Stash.Mode
- Text.CreateBranch.OverwriteExisting - Text.StashCM.CopyMessage
- Text.DeinitSubmodule - Text.WorkingCopy.AddToGitIgnore.InFolder
- Text.DeinitSubmodule.Force
- Text.DeinitSubmodule.Path
- Text.Diff.Submodule.Deleted
- Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash
- Text.Hotkeys.Global.SwitchWorkspace
- Text.Hotkeys.Global.SwitchTab
- Text.Hotkeys.TextEditor.OpenExternalMergeTool
- Text.Launcher.Workspaces
- Text.Launcher.Pages
- Text.Pull.RecurseSubmodules
- Text.Repository.ClearStashes
- Text.Repository.ShowSubmodulesAsTree
- Text.ResetWithoutCheckout
- Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target
- Text.Submodule.Deinit
- Text.Submodule.Status
- Text.Submodule.Status.Modified
- Text.Submodule.Status.NotInited
- Text.Submodule.Status.RevisionChanged
- Text.Submodule.Status.Unmerged
- Text.Submodule.URL
- Text.WorkingCopy.ResetAuthor
</details> </details>
### ![es__ES](https://img.shields.io/badge/es__ES-%E2%88%9A-brightgreen) ### ![fr__FR](https://img.shields.io/badge/fr__FR-91.19%25-yellow)
### ![fr__FR](https://img.shields.io/badge/fr__FR-92.03%25-yellow)
<details> <details>
<summary>Missing keys in fr_FR.axaml</summary> <summary>Missing keys in fr_FR.axaml</summary>
@ -67,6 +43,7 @@ This document shows the translation status of each locale file in the repository
- Text.CommitCM.CopyAuthor - Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter - Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject - Text.CommitCM.CopySubject
- Text.CommitCM.PushRevision
- Text.CommitDetail.Changes.Count - Text.CommitDetail.Changes.Count
- Text.CommitMessageTextBox.SubjectCount - Text.CommitMessageTextBox.SubjectCount
- Text.Configure.Git.PreferredMergeMode - Text.Configure.Git.PreferredMergeMode
@ -86,8 +63,11 @@ This document shows the translation status of each locale file in the repository
- Text.Hotkeys.TextEditor.OpenExternalMergeTool - Text.Hotkeys.TextEditor.OpenExternalMergeTool
- Text.Launcher.Workspaces - Text.Launcher.Workspaces
- Text.Launcher.Pages - Text.Launcher.Pages
- Text.Merge.Edit
- Text.Preferences.Git.IgnoreCRAtEOLInDiff - Text.Preferences.Git.IgnoreCRAtEOLInDiff
- Text.Pull.RecurseSubmodules - Text.Pull.RecurseSubmodules
- Text.Push.Revision
- Text.Push.Revision.Title
- Text.Repository.BranchSort - Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate - Text.Repository.BranchSort.ByCommitterDate
- Text.Repository.BranchSort.ByName - Text.Repository.BranchSort.ByName
@ -99,6 +79,8 @@ This document shows the translation status of each locale file in the repository
- Text.ResetWithoutCheckout - Text.ResetWithoutCheckout
- Text.ResetWithoutCheckout.MoveTo - Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target - Text.ResetWithoutCheckout.Target
- Text.Stash.Mode
- Text.StashCM.CopyMessage
- Text.Submodule.Deinit - Text.Submodule.Deinit
- Text.Submodule.Status - Text.Submodule.Status
- Text.Submodule.Status.Modified - Text.Submodule.Status.Modified
@ -110,6 +92,7 @@ This document shows the translation status of each locale file in the repository
- Text.ViewLogs.Clear - Text.ViewLogs.Clear
- Text.ViewLogs.CopyLog - Text.ViewLogs.CopyLog
- Text.ViewLogs.Delete - Text.ViewLogs.Delete
- Text.WorkingCopy.AddToGitIgnore.InFolder
- Text.WorkingCopy.ConfirmCommitWithFilter - Text.WorkingCopy.ConfirmCommitWithFilter
- Text.WorkingCopy.Conflicts.OpenExternalMergeTool - Text.WorkingCopy.Conflicts.OpenExternalMergeTool
- Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts - Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts
@ -119,7 +102,7 @@ This document shows the translation status of each locale file in the repository
</details> </details>
### ![it__IT](https://img.shields.io/badge/it__IT-97.38%25-yellow) ### ![it__IT](https://img.shields.io/badge/it__IT-96.53%25-yellow)
<details> <details>
<summary>Missing keys in it_IT.axaml</summary> <summary>Missing keys in it_IT.axaml</summary>
@ -128,6 +111,7 @@ This document shows the translation status of each locale file in the repository
- Text.BranchCM.ResetToSelectedCommit - Text.BranchCM.ResetToSelectedCommit
- Text.Checkout.WithFastForward - Text.Checkout.WithFastForward
- Text.Checkout.WithFastForward.Upstream - Text.Checkout.WithFastForward.Upstream
- Text.CommitCM.PushRevision
- Text.CommitDetail.Changes.Count - Text.CommitDetail.Changes.Count
- Text.CreateBranch.OverwriteExisting - Text.CreateBranch.OverwriteExisting
- Text.DeinitSubmodule - Text.DeinitSubmodule
@ -138,17 +122,23 @@ This document shows the translation status of each locale file in the repository
- Text.Hotkeys.Global.SwitchTab - Text.Hotkeys.Global.SwitchTab
- Text.Launcher.Workspaces - Text.Launcher.Workspaces
- Text.Launcher.Pages - Text.Launcher.Pages
- Text.Merge.Edit
- Text.Pull.RecurseSubmodules - Text.Pull.RecurseSubmodules
- Text.Push.Revision
- Text.Push.Revision.Title
- Text.Repository.ClearStashes - Text.Repository.ClearStashes
- Text.ResetWithoutCheckout - Text.ResetWithoutCheckout
- Text.ResetWithoutCheckout.MoveTo - Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target - Text.ResetWithoutCheckout.Target
- Text.Stash.Mode
- Text.StashCM.CopyMessage
- Text.Submodule.Deinit - Text.Submodule.Deinit
- Text.WorkingCopy.AddToGitIgnore.InFolder
- Text.WorkingCopy.ResetAuthor - Text.WorkingCopy.ResetAuthor
</details> </details>
### ![ja__JP](https://img.shields.io/badge/ja__JP-91.78%25-yellow) ### ![ja__JP](https://img.shields.io/badge/ja__JP-90.94%25-yellow)
<details> <details>
<summary>Missing keys in ja_JP.axaml</summary> <summary>Missing keys in ja_JP.axaml</summary>
@ -169,6 +159,7 @@ This document shows the translation status of each locale file in the repository
- Text.CommitCM.CopyAuthor - Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter - Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject - Text.CommitCM.CopySubject
- Text.CommitCM.PushRevision
- Text.CommitDetail.Changes.Count - Text.CommitDetail.Changes.Count
- Text.CommitMessageTextBox.SubjectCount - Text.CommitMessageTextBox.SubjectCount
- Text.Configure.Git.PreferredMergeMode - Text.Configure.Git.PreferredMergeMode
@ -188,8 +179,11 @@ This document shows the translation status of each locale file in the repository
- Text.Hotkeys.TextEditor.OpenExternalMergeTool - Text.Hotkeys.TextEditor.OpenExternalMergeTool
- Text.Launcher.Workspaces - Text.Launcher.Workspaces
- Text.Launcher.Pages - Text.Launcher.Pages
- Text.Merge.Edit
- Text.Preferences.Git.IgnoreCRAtEOLInDiff - Text.Preferences.Git.IgnoreCRAtEOLInDiff
- Text.Pull.RecurseSubmodules - Text.Pull.RecurseSubmodules
- Text.Push.Revision
- Text.Push.Revision.Title
- Text.Repository.BranchSort - Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate - Text.Repository.BranchSort.ByCommitterDate
- Text.Repository.BranchSort.ByName - Text.Repository.BranchSort.ByName
@ -202,6 +196,8 @@ This document shows the translation status of each locale file in the repository
- Text.ResetWithoutCheckout - Text.ResetWithoutCheckout
- Text.ResetWithoutCheckout.MoveTo - Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target - Text.ResetWithoutCheckout.Target
- Text.Stash.Mode
- Text.StashCM.CopyMessage
- Text.Submodule.Deinit - Text.Submodule.Deinit
- Text.Submodule.Status - Text.Submodule.Status
- Text.Submodule.Status.Modified - Text.Submodule.Status.Modified
@ -213,6 +209,7 @@ This document shows the translation status of each locale file in the repository
- Text.ViewLogs.Clear - Text.ViewLogs.Clear
- Text.ViewLogs.CopyLog - Text.ViewLogs.CopyLog
- Text.ViewLogs.Delete - Text.ViewLogs.Delete
- Text.WorkingCopy.AddToGitIgnore.InFolder
- Text.WorkingCopy.ConfirmCommitWithFilter - Text.WorkingCopy.ConfirmCommitWithFilter
- Text.WorkingCopy.Conflicts.OpenExternalMergeTool - Text.WorkingCopy.Conflicts.OpenExternalMergeTool
- Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts - Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts
@ -222,7 +219,7 @@ This document shows the translation status of each locale file in the repository
</details> </details>
### ![pt__BR](https://img.shields.io/badge/pt__BR-83.81%25-yellow) ### ![pt__BR](https://img.shields.io/badge/pt__BR-83.25%25-yellow)
<details> <details>
<summary>Missing keys in pt_BR.axaml</summary> <summary>Missing keys in pt_BR.axaml</summary>
@ -254,6 +251,7 @@ This document shows the translation status of each locale file in the repository
- Text.CommitCM.CopySubject - Text.CommitCM.CopySubject
- Text.CommitCM.Merge - Text.CommitCM.Merge
- Text.CommitCM.MergeMultiple - Text.CommitCM.MergeMultiple
- Text.CommitCM.PushRevision
- Text.CommitDetail.Changes.Count - Text.CommitDetail.Changes.Count
- Text.CommitDetail.Files.Search - Text.CommitDetail.Files.Search
- Text.CommitDetail.Info.Children - Text.CommitDetail.Info.Children
@ -294,6 +292,7 @@ This document shows the translation status of each locale file in the repository
- Text.InProgress.Revert.Head - Text.InProgress.Revert.Head
- Text.Launcher.Workspaces - Text.Launcher.Workspaces
- Text.Launcher.Pages - Text.Launcher.Pages
- Text.Merge.Edit
- Text.Merge.Source - Text.Merge.Source
- Text.MergeMultiple - Text.MergeMultiple
- Text.MergeMultiple.CommitChanges - Text.MergeMultiple.CommitChanges
@ -307,6 +306,8 @@ This document shows the translation status of each locale file in the repository
- Text.Preferences.Git.IgnoreCRAtEOLInDiff - Text.Preferences.Git.IgnoreCRAtEOLInDiff
- Text.Preferences.Git.SSLVerify - Text.Preferences.Git.SSLVerify
- Text.Pull.RecurseSubmodules - Text.Pull.RecurseSubmodules
- Text.Push.Revision
- Text.Push.Revision.Title
- Text.Repository.BranchSort - Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate - Text.Repository.BranchSort.ByCommitterDate
- Text.Repository.BranchSort.ByName - Text.Repository.BranchSort.ByName
@ -335,8 +336,8 @@ This document shows the translation status of each locale file in the repository
- Text.SetUpstream.Unset - Text.SetUpstream.Unset
- Text.SetUpstream.Upstream - Text.SetUpstream.Upstream
- Text.SHALinkCM.NavigateTo - Text.SHALinkCM.NavigateTo
- Text.Stash.AutoRestore - Text.Stash.Mode
- Text.Stash.AutoRestore.Tip - Text.StashCM.CopyMessage
- Text.StashCM.SaveAsPatch - Text.StashCM.SaveAsPatch
- Text.Submodule.Deinit - Text.Submodule.Deinit
- Text.Submodule.Status - Text.Submodule.Status
@ -349,6 +350,7 @@ This document shows the translation status of each locale file in the repository
- Text.ViewLogs.Clear - Text.ViewLogs.Clear
- Text.ViewLogs.CopyLog - Text.ViewLogs.CopyLog
- Text.ViewLogs.Delete - Text.ViewLogs.Delete
- Text.WorkingCopy.AddToGitIgnore.InFolder
- Text.WorkingCopy.CommitToEdit - Text.WorkingCopy.CommitToEdit
- Text.WorkingCopy.ConfirmCommitWithFilter - Text.WorkingCopy.ConfirmCommitWithFilter
- Text.WorkingCopy.Conflicts.OpenExternalMergeTool - Text.WorkingCopy.Conflicts.OpenExternalMergeTool
@ -360,17 +362,9 @@ This document shows the translation status of each locale file in the repository
</details> </details>
### ![ru__RU](https://img.shields.io/badge/ru__RU-99.75%25-yellow) ### ![ru__RU](https://img.shields.io/badge/ru__RU-%E2%88%9A-brightgreen)
<details> ### ![ta__IN](https://img.shields.io/badge/ta__IN-91.07%25-yellow)
<summary>Missing keys in ru_RU.axaml</summary>
- Text.Checkout.WithFastForward
- Text.Checkout.WithFastForward.Upstream
</details>
### ![ta__IN](https://img.shields.io/badge/ta__IN-91.91%25-yellow)
<details> <details>
<summary>Missing keys in ta_IN.axaml</summary> <summary>Missing keys in ta_IN.axaml</summary>
@ -391,6 +385,7 @@ This document shows the translation status of each locale file in the repository
- Text.CommitCM.CopyAuthor - Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter - Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject - Text.CommitCM.CopySubject
- Text.CommitCM.PushRevision
- Text.CommitDetail.Changes.Count - Text.CommitDetail.Changes.Count
- Text.CommitMessageTextBox.SubjectCount - Text.CommitMessageTextBox.SubjectCount
- Text.Configure.Git.PreferredMergeMode - Text.Configure.Git.PreferredMergeMode
@ -410,8 +405,11 @@ This document shows the translation status of each locale file in the repository
- Text.Hotkeys.TextEditor.OpenExternalMergeTool - Text.Hotkeys.TextEditor.OpenExternalMergeTool
- Text.Launcher.Workspaces - Text.Launcher.Workspaces
- Text.Launcher.Pages - Text.Launcher.Pages
- Text.Merge.Edit
- Text.Preferences.Git.IgnoreCRAtEOLInDiff - Text.Preferences.Git.IgnoreCRAtEOLInDiff
- Text.Pull.RecurseSubmodules - Text.Pull.RecurseSubmodules
- Text.Push.Revision
- Text.Push.Revision.Title
- Text.Repository.BranchSort - Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate - Text.Repository.BranchSort.ByCommitterDate
- Text.Repository.BranchSort.ByName - Text.Repository.BranchSort.ByName
@ -423,6 +421,8 @@ This document shows the translation status of each locale file in the repository
- Text.ResetWithoutCheckout - Text.ResetWithoutCheckout
- Text.ResetWithoutCheckout.MoveTo - Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target - Text.ResetWithoutCheckout.Target
- Text.Stash.Mode
- Text.StashCM.CopyMessage
- Text.Submodule.Deinit - Text.Submodule.Deinit
- Text.Submodule.Status - Text.Submodule.Status
- Text.Submodule.Status.Modified - Text.Submodule.Status.Modified
@ -435,6 +435,7 @@ This document shows the translation status of each locale file in the repository
- Text.ViewLogs.Clear - Text.ViewLogs.Clear
- Text.ViewLogs.CopyLog - Text.ViewLogs.CopyLog
- Text.ViewLogs.Delete - Text.ViewLogs.Delete
- Text.WorkingCopy.AddToGitIgnore.InFolder
- Text.WorkingCopy.Conflicts.OpenExternalMergeTool - Text.WorkingCopy.Conflicts.OpenExternalMergeTool
- Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts - Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts
- Text.WorkingCopy.Conflicts.UseMine - Text.WorkingCopy.Conflicts.UseMine
@ -443,7 +444,7 @@ This document shows the translation status of each locale file in the repository
</details> </details>
### ![uk__UA](https://img.shields.io/badge/uk__UA-93.15%25-yellow) ### ![uk__UA](https://img.shields.io/badge/uk__UA-92.31%25-yellow)
<details> <details>
<summary>Missing keys in uk_UA.axaml</summary> <summary>Missing keys in uk_UA.axaml</summary>
@ -463,6 +464,7 @@ This document shows the translation status of each locale file in the repository
- Text.CommitCM.CopyAuthor - Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter - Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject - Text.CommitCM.CopySubject
- Text.CommitCM.PushRevision
- Text.CommitDetail.Changes.Count - Text.CommitDetail.Changes.Count
- Text.CommitMessageTextBox.SubjectCount - Text.CommitMessageTextBox.SubjectCount
- Text.ConfigureWorkspace.Name - Text.ConfigureWorkspace.Name
@ -478,8 +480,11 @@ This document shows the translation status of each locale file in the repository
- Text.Hotkeys.TextEditor.OpenExternalMergeTool - Text.Hotkeys.TextEditor.OpenExternalMergeTool
- Text.Launcher.Workspaces - Text.Launcher.Workspaces
- Text.Launcher.Pages - Text.Launcher.Pages
- Text.Merge.Edit
- Text.Preferences.Git.IgnoreCRAtEOLInDiff - Text.Preferences.Git.IgnoreCRAtEOLInDiff
- Text.Pull.RecurseSubmodules - Text.Pull.RecurseSubmodules
- Text.Push.Revision
- Text.Push.Revision.Title
- Text.Repository.BranchSort - Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate - Text.Repository.BranchSort.ByCommitterDate
- Text.Repository.BranchSort.ByName - Text.Repository.BranchSort.ByName
@ -491,6 +496,8 @@ This document shows the translation status of each locale file in the repository
- Text.ResetWithoutCheckout - Text.ResetWithoutCheckout
- Text.ResetWithoutCheckout.MoveTo - Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target - Text.ResetWithoutCheckout.Target
- Text.Stash.Mode
- Text.StashCM.CopyMessage
- Text.Submodule.Deinit - Text.Submodule.Deinit
- Text.Submodule.Status - Text.Submodule.Status
- Text.Submodule.Status.Modified - Text.Submodule.Status.Modified
@ -502,6 +509,7 @@ This document shows the translation status of each locale file in the repository
- Text.ViewLogs.Clear - Text.ViewLogs.Clear
- Text.ViewLogs.CopyLog - Text.ViewLogs.CopyLog
- Text.ViewLogs.Delete - Text.ViewLogs.Delete
- Text.WorkingCopy.AddToGitIgnore.InFolder
- Text.WorkingCopy.ResetAuthor - Text.WorkingCopy.ResetAuthor
</details> </details>

View file

@ -1 +1 @@
2025.22 2025.23

View file

@ -521,7 +521,7 @@ namespace SourceGit
private bool TryLaunchAsCoreEditor(IClassicDesktopStyleApplicationLifetime desktop) private bool TryLaunchAsCoreEditor(IClassicDesktopStyleApplicationLifetime desktop)
{ {
var args = desktop.Args; var args = desktop.Args;
if (args == null || args.Length <= 1 || !args[0].Equals("--core-editor", StringComparison.Ordinal)) if (args is not { Length: > 1 } || !args[0].Equals("--core-editor", StringComparison.Ordinal))
return false; return false;
var file = args[1]; var file = args[1];
@ -531,8 +531,8 @@ namespace SourceGit
return true; return true;
} }
var editor = new Views.StandaloneCommitMessageEditor(); var editor = new Views.CommitMessageEditor();
editor.SetFile(file); editor.AsStandalone(file);
desktop.MainWindow = editor; desktop.MainWindow = editor;
return true; return true;
} }

View file

@ -5,11 +5,20 @@ namespace SourceGit.Commands
{ {
public class Merge : Command public class Merge : Command
{ {
public Merge(string repo, string source, string mode) public Merge(string repo, string source, string mode, bool edit)
{ {
WorkingDirectory = repo; WorkingDirectory = repo;
Context = repo; Context = repo;
Args = $"merge --progress {source} {mode}"; Editor = EditorType.CoreEditor;
var builder = new StringBuilder();
builder.Append("merge --progress ");
builder.Append(edit ? "--edit " : "--no-edit ");
builder.Append(source);
builder.Append(' ');
builder.Append(mode);
Args = builder.ToString();
} }
public Merge(string repo, List<string> targets, bool autoCommit, string strategy) public Merge(string repo, List<string> targets, bool autoCommit, string strategy)

View file

@ -48,16 +48,12 @@ namespace SourceGit.Commands
if (remoteHeads.TryGetValue(b.Upstream, out var upstreamHead)) if (remoteHeads.TryGetValue(b.Upstream, out var upstreamHead))
{ {
b.IsUpstreamGone = false; b.IsUpstreamGone = false;
b.TrackStatus ??= new QueryTrackStatus(WorkingDirectory, b.Head, upstreamHead).Result();
if (b.TrackStatus == null)
b.TrackStatus = new QueryTrackStatus(WorkingDirectory, b.Head, upstreamHead).Result();
} }
else else
{ {
b.IsUpstreamGone = true; b.IsUpstreamGone = true;
b.TrackStatus ??= new Models.BranchTrackStatus();
if (b.TrackStatus == null)
b.TrackStatus = new Models.BranchTrackStatus();
} }
} }
} }

View file

@ -9,7 +9,7 @@ namespace SourceGit.Commands
{ {
WorkingDirectory = repo; WorkingDirectory = repo;
Context = repo; Context = repo;
Args = "stash list --format=%H%n%P%n%ct%n%gd%n%s"; Args = $"stash list -z --no-show-signature --format=\"%H%n%P%n%ct%n%gd%n%B\"";
} }
public List<Models.Stash> Result() public List<Models.Stash> Result()
@ -19,55 +19,50 @@ namespace SourceGit.Commands
if (!rs.IsSuccess) if (!rs.IsSuccess)
return outs; return outs;
var nextPartIdx = 0; var items = rs.StdOut.Split('\0', StringSplitOptions.RemoveEmptyEntries);
var start = 0; foreach (var item in items)
var end = rs.StdOut.IndexOf('\n', start);
while (end > 0)
{ {
var line = rs.StdOut.Substring(start, end - start); var current = new Models.Stash();
switch (nextPartIdx) var nextPartIdx = 0;
var start = 0;
var end = item.IndexOf('\n', start);
while (end > 0 && nextPartIdx < 4)
{ {
case 0: var line = item.Substring(start, end - start);
_current = new Models.Stash() { SHA = line };
outs.Add(_current); switch (nextPartIdx)
break; {
case 1: case 0:
ParseParent(line); current.SHA = line;
break; break;
case 2: case 1:
_current.Time = ulong.Parse(line); if (line.Length > 6)
break; current.Parents.AddRange(line.Split(' ', StringSplitOptions.RemoveEmptyEntries));
case 3: break;
_current.Name = line; case 2:
break; current.Time = ulong.Parse(line);
case 4: break;
_current.Message = line; case 3:
current.Name = line;
break;
}
nextPartIdx++;
start = end + 1;
if (start >= item.Length - 1)
break; break;
end = item.IndexOf('\n', start);
} }
nextPartIdx++; if (start < item.Length)
if (nextPartIdx > 4) current.Message = item.Substring(start);
nextPartIdx = 0;
start = end + 1; outs.Add(current);
end = rs.StdOut.IndexOf('\n', start);
} }
if (start < rs.StdOut.Length)
_current.Message = rs.StdOut.Substring(start);
return outs; return outs;
} }
private void ParseParent(string data)
{
if (data.Length < 8)
return;
_current.Parents.AddRange(data.Split(separator: ' ', options: StringSplitOptions.RemoveEmptyEntries));
}
private Models.Stash _current = null;
} }
} }

View file

@ -24,7 +24,7 @@ namespace SourceGit.Commands
var records = rs.StdOut.Split(_boundary, StringSplitOptions.RemoveEmptyEntries); var records = rs.StdOut.Split(_boundary, StringSplitOptions.RemoveEmptyEntries);
foreach (var record in records) foreach (var record in records)
{ {
var subs = record.Split('\0', StringSplitOptions.None); var subs = record.Split('\0');
if (subs.Length != 6) if (subs.Length != 6)
continue; continue;

View file

@ -10,6 +10,10 @@ namespace SourceGit.Commands
{ {
public static void Run(string repo, string revision, string file, string saveTo) public static void Run(string repo, string revision, string file, string saveTo)
{ {
var dir = Path.GetDirectoryName(saveTo);
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
var isLFSFiltered = new IsLFSFiltered(repo, revision, file).Result(); var isLFSFiltered = new IsLFSFiltered(repo, revision, file).Result();
if (isLFSFiltered) if (isLFSFiltered)
{ {
@ -22,7 +26,7 @@ namespace SourceGit.Commands
} }
} }
private static bool ExecCmd(string repo, string args, string outputFile, Stream input = null) private static void ExecCmd(string repo, string args, string outputFile, Stream input = null)
{ {
var starter = new ProcessStartInfo(); var starter = new ProcessStartInfo();
starter.WorkingDirectory = repo; starter.WorkingDirectory = repo;
@ -45,10 +49,7 @@ namespace SourceGit.Commands
proc.StandardInput.Write(new StreamReader(input).ReadToEnd()); proc.StandardInput.Write(new StreamReader(input).ReadToEnd());
proc.StandardOutput.BaseStream.CopyTo(sw); proc.StandardOutput.BaseStream.CopyTo(sw);
proc.WaitForExit(); proc.WaitForExit();
var rs = proc.ExitCode == 0;
proc.Close(); proc.Close();
return rs;
} }
catch (Exception e) catch (Exception e)
{ {
@ -56,7 +57,6 @@ namespace SourceGit.Commands
{ {
App.RaiseException(repo, "Save file failed: " + e.Message); App.RaiseException(repo, "Save file failed: " + e.Message);
}); });
return false;
} }
} }
} }

View file

@ -26,10 +26,7 @@ namespace SourceGit.Models
{ {
get get
{ {
if (_instance == null) return _instance ??= new AvatarManager();
_instance = new AvatarManager();
return _instance;
} }
} }

View file

@ -0,0 +1,22 @@
using System.Collections.Generic;
namespace SourceGit.Models
{
public class DealWithChangesAfterStashing
{
public string Label { get; set; }
public string Desc { get; set; }
public static readonly List<DealWithChangesAfterStashing> Supported = [
new ("Discard", "All (or selected) changes will be discarded"),
new ("Keep Index", "Staged changes are left intact"),
new ("Keep All", "All (or selected) changes are left intact"),
];
public DealWithChangesAfterStashing(string label, string desc)
{
Label = label;
Desc = desc;
}
}
}

View file

@ -16,11 +16,10 @@ namespace SourceGit.Models
Deleted, Deleted,
} }
public class TextInlineRange public class TextInlineRange(int p, int n)
{ {
public int Start { get; set; } public int Start { get; set; } = p;
public int End { get; set; } public int End { get; set; } = p + n - 1;
public TextInlineRange(int p, int n) { Start = p; End = p + n - 1; }
} }
public class TextDiffLine public class TextDiffLine
@ -556,7 +555,7 @@ namespace SourceGit.Models
} }
else if (test.Type == TextDiffLineType.Added) else if (test.Type == TextDiffLineType.Added)
{ {
if (i < start - 1) if (i < start - 1 || isOldSide)
{ {
if (revert) if (revert)
{ {
@ -566,18 +565,7 @@ namespace SourceGit.Models
} }
else else
{ {
if (isOldSide) newCount++;
{
if (revert)
{
newCount++;
oldCount++;
}
}
else
{
newCount++;
}
} }
if (i == end - 1 && tailed) if (i == end - 1 && tailed)
@ -655,9 +643,7 @@ namespace SourceGit.Models
public string NewImageSize => New != null ? $"{New.PixelSize.Width} x {New.PixelSize.Height}" : "0 x 0"; public string NewImageSize => New != null ? $"{New.PixelSize.Width} x {New.PixelSize.Height}" : "0 x 0";
} }
public class NoOrEOLChange public class NoOrEOLChange;
{
}
public class FileModeDiff public class FileModeDiff
{ {

View file

@ -107,8 +107,7 @@ namespace SourceGit.Models
// Ignore // Ignore
} }
if (_customPaths == null) _customPaths ??= new ExternalToolPaths();
_customPaths = new ExternalToolPaths();
} }
public void TryAdd(string name, string icon, Func<string> finder, Func<string, string> execArgsGenerator = null) public void TryAdd(string name, string icon, Func<string> finder, Func<string, string> execArgsGenerator = null)

View file

@ -8,10 +8,7 @@ namespace SourceGit.Models
{ {
public class IpcChannel : IDisposable public class IpcChannel : IDisposable
{ {
public bool IsFirstInstance public bool IsFirstInstance { get; }
{
get => _isFirstInstance;
}
public event Action<string> MessageReceived; public event Action<string> MessageReceived;
@ -20,7 +17,7 @@ namespace SourceGit.Models
try try
{ {
_singletonLock = File.Open(Path.Combine(Native.OS.DataDir, "process.lock"), FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); _singletonLock = File.Open(Path.Combine(Native.OS.DataDir, "process.lock"), FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
_isFirstInstance = true; IsFirstInstance = true;
_server = new NamedPipeServerStream( _server = new NamedPipeServerStream(
"SourceGitIPCChannel" + Environment.UserName, "SourceGitIPCChannel" + Environment.UserName,
PipeDirection.In, PipeDirection.In,
@ -32,7 +29,7 @@ namespace SourceGit.Models
} }
catch catch
{ {
_isFirstInstance = false; IsFirstInstance = false;
} }
} }
@ -97,7 +94,6 @@ namespace SourceGit.Models
} }
private FileStream _singletonLock = null; private FileStream _singletonLock = null;
private bool _isFirstInstance = false;
private NamedPipeServerStream _server = null; private NamedPipeServerStream _server = null;
private CancellationTokenSource _cancellationTokenSource = null; private CancellationTokenSource _cancellationTokenSource = null;
} }

View file

@ -1,6 +1,4 @@
namespace SourceGit.Models namespace SourceGit.Models
{ {
public class Null public class Null;
{
}
} }

View file

@ -176,17 +176,11 @@ namespace SourceGit.Models
set; set;
} = false; } = false;
public bool KeepIndexWhenStash public int ChangesAfterStashing
{ {
get; get;
set; set;
} = false; } = 0;
public bool AutoRestoreAfterStash
{
get;
set;
} = false;
public string PreferredOpenAIService public string PreferredOpenAIService
{ {

View file

@ -33,9 +33,7 @@ namespace SourceGit.Models
} }
} }
public class AlreadyUpToDate public class AlreadyUpToDate;
{
}
public class SelfUpdateFailed public class SelfUpdateFailed
{ {

View file

@ -11,6 +11,24 @@ namespace SourceGit.Models
public ulong Time { get; set; } = 0; public ulong Time { get; set; } = 0;
public string Message { get; set; } = ""; public string Message { get; set; } = "";
public string TimeStr => DateTime.UnixEpoch.AddSeconds(Time).ToLocalTime().ToString(DateTimeFormat.Active.DateTime); public string Subject
{
get
{
var idx = Message.IndexOf('\n', StringComparison.Ordinal);
return idx > 0 ? Message.Substring(0, idx).Trim() : Message;
}
}
public string TimeStr
{
get
{
return DateTime.UnixEpoch
.AddSeconds(Time)
.ToLocalTime()
.ToString(DateTimeFormat.Active.DateTime);
}
}
} }
} }

View file

@ -102,7 +102,7 @@ namespace SourceGit.Models
private int? Integer() private int? Integer()
{ {
var start = _pos; var start = _pos;
while (Peek() is char c && c >= '0' && c <= '9') while (Peek() is >= '0' and <= '9')
{ {
_pos++; _pos++;
} }
@ -118,7 +118,7 @@ namespace SourceGit.Models
// text token start // text token start
var tok = _pos; var tok = _pos;
bool esc = false; bool esc = false;
while (Next() is char c) while (Next() is { } c)
{ {
if (esc) if (esc)
{ {
@ -129,7 +129,7 @@ namespace SourceGit.Models
{ {
case ESCAPE: case ESCAPE:
// allow to escape only \ and $ // allow to escape only \ and $
if (Peek() is char nc && (nc == ESCAPE || nc == VARIABLE_ANCHOR)) if (Peek() is { } nc && (nc == ESCAPE || nc == VARIABLE_ANCHOR))
{ {
esc = true; esc = true;
FlushText(tok, _pos - 1); FlushText(tok, _pos - 1);
@ -173,7 +173,7 @@ namespace SourceGit.Models
if (Next() != VARIABLE_START) if (Next() != VARIABLE_START)
return null; return null;
int name_start = _pos; int name_start = _pos;
while (Next() is char c) while (Next() is { } c)
{ {
// name character, continue advancing // name character, continue advancing
if (IsNameChar(c)) if (IsNameChar(c))
@ -228,7 +228,7 @@ namespace SourceGit.Models
var sb = new StringBuilder(); var sb = new StringBuilder();
var tok = _pos; var tok = _pos;
var esc = false; var esc = false;
while (Next() is char c) while (Next() is { } c)
{ {
if (esc) if (esc)
{ {
@ -277,7 +277,7 @@ namespace SourceGit.Models
var sb = new StringBuilder(); var sb = new StringBuilder();
var tok = _pos; var tok = _pos;
var esc = false; var esc = false;
while (Next() is char c) while (Next() is { } c)
{ {
if (esc) if (esc)
{ {

View file

@ -2,27 +2,19 @@
namespace SourceGit.Models namespace SourceGit.Models
{ {
public class TextInlineChange public class TextInlineChange(int dp, int dc, int ap, int ac)
{ {
public int DeletedStart { get; set; } public int DeletedStart { get; set; } = dp;
public int DeletedCount { get; set; } public int DeletedCount { get; set; } = dc;
public int AddedStart { get; set; } public int AddedStart { get; set; } = ap;
public int AddedCount { get; set; } public int AddedCount { get; set; } = ac;
private class Chunk private class Chunk(int hash, int start, int size)
{ {
public int Hash; public readonly int Hash = hash;
public readonly int Start = start;
public readonly int Size = size;
public bool Modified; public bool Modified;
public int Start;
public int Size;
public Chunk(int hash, int start, int size)
{
Hash = hash;
Modified = false;
Start = start;
Size = size;
}
} }
private enum Edit private enum Edit
@ -43,14 +35,6 @@ namespace SourceGit.Models
public int AddEnd; public int AddEnd;
} }
public TextInlineChange(int dp, int dc, int ap, int ac)
{
DeletedStart = dp;
DeletedCount = dc;
AddedStart = ap;
AddedCount = ac;
}
public static List<TextInlineChange> Compare(string oldValue, string newValue) public static List<TextInlineChange> Compare(string oldValue, string newValue)
{ {
var hashes = new Dictionary<string, int>(); var hashes = new Dictionary<string, int>();

View file

@ -12,27 +12,50 @@ namespace SourceGit.Models
{ {
_repo = repo; _repo = repo;
_wcWatcher = new FileSystemWatcher(); var testGitDir = new DirectoryInfo(Path.Combine(fullpath, ".git")).FullName;
_wcWatcher.Path = fullpath; var desiredDir = new DirectoryInfo(gitDir).FullName;
_wcWatcher.Filter = "*"; if (testGitDir.Equals(desiredDir, StringComparison.Ordinal))
_wcWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.CreationTime; {
_wcWatcher.IncludeSubdirectories = true; var combined = new FileSystemWatcher();
_wcWatcher.Created += OnWorkingCopyChanged; combined.Path = fullpath;
_wcWatcher.Renamed += OnWorkingCopyChanged; combined.Filter = "*";
_wcWatcher.Changed += OnWorkingCopyChanged; combined.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.CreationTime;
_wcWatcher.Deleted += OnWorkingCopyChanged; combined.IncludeSubdirectories = true;
_wcWatcher.EnableRaisingEvents = true; combined.Created += OnRepositoryChanged;
combined.Renamed += OnRepositoryChanged;
combined.Changed += OnRepositoryChanged;
combined.Deleted += OnRepositoryChanged;
combined.EnableRaisingEvents = true;
_repoWatcher = new FileSystemWatcher(); _watchers.Add(combined);
_repoWatcher.Path = gitDir; }
_repoWatcher.Filter = "*"; else
_repoWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName; {
_repoWatcher.IncludeSubdirectories = true; var wc = new FileSystemWatcher();
_repoWatcher.Created += OnRepositoryChanged; wc.Path = fullpath;
_repoWatcher.Renamed += OnRepositoryChanged; wc.Filter = "*";
_repoWatcher.Changed += OnRepositoryChanged; wc.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.CreationTime;
_repoWatcher.Deleted += OnRepositoryChanged; wc.IncludeSubdirectories = true;
_repoWatcher.EnableRaisingEvents = true; wc.Created += OnWorkingCopyChanged;
wc.Renamed += OnWorkingCopyChanged;
wc.Changed += OnWorkingCopyChanged;
wc.Deleted += OnWorkingCopyChanged;
wc.EnableRaisingEvents = true;
var git = new FileSystemWatcher();
git.Path = gitDir;
git.Filter = "*";
git.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName;
git.IncludeSubdirectories = true;
git.Created += OnGitDirChanged;
git.Renamed += OnGitDirChanged;
git.Changed += OnGitDirChanged;
git.Deleted += OnGitDirChanged;
git.EnableRaisingEvents = true;
_watchers.Add(wc);
_watchers.Add(git);
}
_timer = new Timer(Tick, null, 100, 100); _timer = new Timer(Tick, null, 100, 100);
} }
@ -77,22 +100,13 @@ namespace SourceGit.Models
public void Dispose() public void Dispose()
{ {
_repoWatcher.EnableRaisingEvents = false; foreach (var watcher in _watchers)
_repoWatcher.Created -= OnRepositoryChanged; {
_repoWatcher.Renamed -= OnRepositoryChanged; watcher.EnableRaisingEvents = false;
_repoWatcher.Changed -= OnRepositoryChanged; watcher.Dispose();
_repoWatcher.Deleted -= OnRepositoryChanged; }
_repoWatcher.Dispose();
_repoWatcher = null;
_wcWatcher.EnableRaisingEvents = false;
_wcWatcher.Created -= OnWorkingCopyChanged;
_wcWatcher.Renamed -= OnWorkingCopyChanged;
_wcWatcher.Changed -= OnWorkingCopyChanged;
_wcWatcher.Deleted -= OnWorkingCopyChanged;
_wcWatcher.Dispose();
_wcWatcher = null;
_watchers.Clear();
_timer.Dispose(); _timer.Dispose();
_timer = null; _timer = null;
} }
@ -153,11 +167,45 @@ namespace SourceGit.Models
} }
private void OnRepositoryChanged(object o, FileSystemEventArgs e) private void OnRepositoryChanged(object o, FileSystemEventArgs e)
{
if (string.IsNullOrEmpty(e.Name) || e.Name.Equals(".git", StringComparison.Ordinal))
return;
var name = e.Name.Replace('\\', '/').TrimEnd('/');
if (name.EndsWith("/.git", StringComparison.Ordinal))
return;
if (name.StartsWith(".git/", StringComparison.Ordinal))
HandleGitDirFileChanged(name.Substring(5));
else
HandleWorkingCopyFileChanged(name);
}
private void OnGitDirChanged(object o, FileSystemEventArgs e)
{ {
if (string.IsNullOrEmpty(e.Name)) if (string.IsNullOrEmpty(e.Name))
return; return;
var name = e.Name.Replace('\\', '/').TrimEnd('/'); var name = e.Name.Replace('\\', '/').TrimEnd('/');
HandleGitDirFileChanged(name);
}
private void OnWorkingCopyChanged(object o, FileSystemEventArgs e)
{
if (string.IsNullOrEmpty(e.Name))
return;
var name = e.Name.Replace('\\', '/').TrimEnd('/');
if (name.Equals(".git", StringComparison.Ordinal) ||
name.StartsWith(".git/", StringComparison.Ordinal) ||
name.EndsWith("/.git", StringComparison.Ordinal))
return;
HandleWorkingCopyFileChanged(name);
}
private void HandleGitDirFileChanged(string name)
{
if (name.Contains("fsmonitor--daemon/", StringComparison.Ordinal) || if (name.Contains("fsmonitor--daemon/", StringComparison.Ordinal) ||
name.EndsWith(".lock", StringComparison.Ordinal) || name.EndsWith(".lock", StringComparison.Ordinal) ||
name.StartsWith("lfs/", StringComparison.Ordinal)) name.StartsWith("lfs/", StringComparison.Ordinal))
@ -200,17 +248,8 @@ namespace SourceGit.Models
} }
} }
private void OnWorkingCopyChanged(object o, FileSystemEventArgs e) private void HandleWorkingCopyFileChanged(string name)
{ {
if (string.IsNullOrEmpty(e.Name))
return;
var name = e.Name.Replace('\\', '/').TrimEnd('/');
if (name.Equals(".git", StringComparison.Ordinal) ||
name.StartsWith(".git/", StringComparison.Ordinal) ||
name.EndsWith("/.git", StringComparison.Ordinal))
return;
if (name.StartsWith(".vs/", StringComparison.Ordinal)) if (name.StartsWith(".vs/", StringComparison.Ordinal))
return; return;
@ -236,8 +275,7 @@ namespace SourceGit.Models
} }
private readonly IRepository _repo = null; private readonly IRepository _repo = null;
private FileSystemWatcher _repoWatcher = null; private List<FileSystemWatcher> _watchers = [];
private FileSystemWatcher _wcWatcher = null;
private Timer _timer = null; private Timer _timer = null;
private int _lockCount = 0; private int _lockCount = 0;
private long _updateWC = 0; private long _updateWC = 0;

View file

@ -54,7 +54,7 @@ namespace SourceGit.Native
public void SetupApp(AppBuilder builder) public void SetupApp(AppBuilder builder)
{ {
// Fix drop shadow issue on Windows 10 // Fix drop shadow issue on Windows 10
if (!OperatingSystem.IsWindowsVersionAtLeast(10, 22000, 0)) if (!OperatingSystem.IsWindowsVersionAtLeast(10, 22000))
{ {
Window.WindowStateProperty.Changed.AddClassHandler<Window>((w, _) => FixWindowFrameOnWin10(w)); Window.WindowStateProperty.Changed.AddClassHandler<Window>((w, _) => FixWindowFrameOnWin10(w));
Control.LoadedEvent.AddClassHandler<Window>((w, _) => FixWindowFrameOnWin10(w)); Control.LoadedEvent.AddClassHandler<Window>((w, _) => FixWindowFrameOnWin10(w));
@ -385,11 +385,11 @@ namespace SourceGit.Native
Microsoft.Win32.RegistryView.Registry64); Microsoft.Win32.RegistryView.Registry64);
// Get default class for VisualStudio.Launcher.sln - the handler for *.sln files // Get default class for VisualStudio.Launcher.sln - the handler for *.sln files
if (localMachine.OpenSubKey(@"SOFTWARE\Classes\VisualStudio.Launcher.sln\CLSID") is Microsoft.Win32.RegistryKey launcher) if (localMachine.OpenSubKey(@"SOFTWARE\Classes\VisualStudio.Launcher.sln\CLSID") is { } launcher)
{ {
// Get actual path to the executable // Get actual path to the executable
if (launcher.GetValue(string.Empty) is string CLSID && if (launcher.GetValue(string.Empty) is string CLSID &&
localMachine.OpenSubKey(@$"SOFTWARE\Classes\CLSID\{CLSID}\LocalServer32") is Microsoft.Win32.RegistryKey devenv && localMachine.OpenSubKey(@$"SOFTWARE\Classes\CLSID\{CLSID}\LocalServer32") is { } devenv &&
devenv.GetValue(string.Empty) is string localServer32) devenv.GetValue(string.Empty) is string localServer32)
return localServer32!.Trim('\"'); return localServer32!.Trim('\"');
} }

View file

@ -39,6 +39,7 @@
<x:String x:Key="Text.AssumeUnchanged" xml:space="preserve">ALS UNVERÄNDERT ANGENOMMENE DATEIEN</x:String> <x:String x:Key="Text.AssumeUnchanged" xml:space="preserve">ALS UNVERÄNDERT ANGENOMMENE DATEIEN</x:String>
<x:String x:Key="Text.AssumeUnchanged.Empty" xml:space="preserve">KEINE ALS UNVERÄNDERT ANGENOMMENEN DATEIEN</x:String> <x:String x:Key="Text.AssumeUnchanged.Empty" xml:space="preserve">KEINE ALS UNVERÄNDERT ANGENOMMENEN DATEIEN</x:String>
<x:String x:Key="Text.AssumeUnchanged.Remove" xml:space="preserve">ENTFERNEN</x:String> <x:String x:Key="Text.AssumeUnchanged.Remove" xml:space="preserve">ENTFERNEN</x:String>
<x:String x:Key="Text.Avatar.Load" xml:space="preserve">Bild laden...</x:String>
<x:String x:Key="Text.Avatar.Refetch" xml:space="preserve">Aktualisieren</x:String> <x:String x:Key="Text.Avatar.Refetch" xml:space="preserve">Aktualisieren</x:String>
<x:String x:Key="Text.BinaryNotSupported" xml:space="preserve">BINÄRE DATEI NICHT UNTERSTÜTZT!!!</x:String> <x:String x:Key="Text.BinaryNotSupported" xml:space="preserve">BINÄRE DATEI NICHT UNTERSTÜTZT!!!</x:String>
<x:String x:Key="Text.Bisect">Bisect</x:String> <x:String x:Key="Text.Bisect">Bisect</x:String>
@ -67,6 +68,7 @@
<x:String x:Key="Text.BranchCM.Push" xml:space="preserve">Push ${0}$</x:String> <x:String x:Key="Text.BranchCM.Push" xml:space="preserve">Push ${0}$</x:String>
<x:String x:Key="Text.BranchCM.Rebase" xml:space="preserve">Rebase ${0}$ auf ${1}$...</x:String> <x:String x:Key="Text.BranchCM.Rebase" xml:space="preserve">Rebase ${0}$ auf ${1}$...</x:String>
<x:String x:Key="Text.BranchCM.Rename" xml:space="preserve">Benenne ${0}$ um...</x:String> <x:String x:Key="Text.BranchCM.Rename" xml:space="preserve">Benenne ${0}$ um...</x:String>
<x:String x:Key="Text.BranchCM.ResetToSelectedCommit" xml:space="preserve">Setze ${0}$ zurück auf ${1}$...</x:String>
<x:String x:Key="Text.BranchCM.Tracking" xml:space="preserve">Setze verfolgten Branch...</x:String> <x:String x:Key="Text.BranchCM.Tracking" xml:space="preserve">Setze verfolgten Branch...</x:String>
<x:String x:Key="Text.BranchCompare" xml:space="preserve">Branch Vergleich</x:String> <x:String x:Key="Text.BranchCompare" xml:space="preserve">Branch Vergleich</x:String>
<x:String x:Key="Text.BranchUpstreamInvalid" xml:space="preserve">Ungültiger upstream!</x:String> <x:String x:Key="Text.BranchUpstreamInvalid" xml:space="preserve">Ungültiger upstream!</x:String>
@ -88,6 +90,8 @@
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Stashen &amp; wieder anwenden</x:String> <x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Stashen &amp; wieder anwenden</x:String>
<x:String x:Key="Text.Checkout.RecurseSubmodules" xml:space="preserve">Alle Submodule updaten</x:String> <x:String x:Key="Text.Checkout.RecurseSubmodules" xml:space="preserve">Alle Submodule updaten</x:String>
<x:String x:Key="Text.Checkout.Target" xml:space="preserve">Branch:</x:String> <x:String x:Key="Text.Checkout.Target" xml:space="preserve">Branch:</x:String>
<x:String x:Key="Text.Checkout.WithFastForward" xml:space="preserve">Auschecken &amp; Fast-Forward</x:String>
<x:String x:Key="Text.Checkout.WithFastForward.Upstream" xml:space="preserve">Fast-Forward zu:</x:String>
<x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry Pick</x:String> <x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry Pick</x:String>
<x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">Quelle an Commit-Nachricht anhängen</x:String> <x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">Quelle an Commit-Nachricht anhängen</x:String>
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">Commit(s):</x:String> <x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">Commit(s):</x:String>
@ -120,6 +124,7 @@
<x:String x:Key="Text.CommitCM.InteractiveRebase" xml:space="preserve">Interactives Rebase von ${0}$ auf diesen Commit</x:String> <x:String x:Key="Text.CommitCM.InteractiveRebase" xml:space="preserve">Interactives Rebase von ${0}$ auf diesen Commit</x:String>
<x:String x:Key="Text.CommitCM.Merge" xml:space="preserve">Merge in ${0}$ hinein</x:String> <x:String x:Key="Text.CommitCM.Merge" xml:space="preserve">Merge in ${0}$ hinein</x:String>
<x:String x:Key="Text.CommitCM.MergeMultiple" xml:space="preserve">Merge ...</x:String> <x:String x:Key="Text.CommitCM.MergeMultiple" xml:space="preserve">Merge ...</x:String>
<x:String x:Key="Text.CommitCM.PushRevision" xml:space="preserve">Push ${0}$ zu ${1}$</x:String>
<x:String x:Key="Text.CommitCM.Rebase" xml:space="preserve">Rebase von ${0}$ auf diesen Commit</x:String> <x:String x:Key="Text.CommitCM.Rebase" xml:space="preserve">Rebase von ${0}$ auf diesen Commit</x:String>
<x:String x:Key="Text.CommitCM.Reset" xml:space="preserve">Reset ${0}$ auf diesen Commit</x:String> <x:String x:Key="Text.CommitCM.Reset" xml:space="preserve">Reset ${0}$ auf diesen Commit</x:String>
<x:String x:Key="Text.CommitCM.Revert" xml:space="preserve">Commit rückgängig machen</x:String> <x:String x:Key="Text.CommitCM.Revert" xml:space="preserve">Commit rückgängig machen</x:String>
@ -128,6 +133,7 @@
<x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">Squash in den Vorgänger</x:String> <x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">Squash in den Vorgänger</x:String>
<x:String x:Key="Text.CommitCM.SquashCommitsSinceThis" xml:space="preserve">Squash Nachfolger Commits bis hier</x:String> <x:String x:Key="Text.CommitCM.SquashCommitsSinceThis" xml:space="preserve">Squash Nachfolger Commits bis hier</x:String>
<x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">ÄNDERUNGEN</x:String> <x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">ÄNDERUNGEN</x:String>
<x:String x:Key="Text.CommitDetail.Changes.Count" xml:space="preserve">geänderte Datei(en)</x:String>
<x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">Änderungen durchsuchen...</x:String> <x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">Änderungen durchsuchen...</x:String>
<x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">DATEIEN</x:String> <x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">DATEIEN</x:String>
<x:String x:Key="Text.CommitDetail.Files.LFS" xml:space="preserve">LFS DATEI</x:String> <x:String x:Key="Text.CommitDetail.Files.LFS" xml:space="preserve">LFS DATEI</x:String>
@ -219,6 +225,7 @@
<x:String x:Key="Text.CreateBranch.Name.Placeholder" xml:space="preserve">Branch-Namen eingeben.</x:String> <x:String x:Key="Text.CreateBranch.Name.Placeholder" xml:space="preserve">Branch-Namen eingeben.</x:String>
<x:String x:Key="Text.CreateBranch.Name.WarnSpace" xml:space="preserve">Leerzeichen werden durch Bindestriche ersetzt.</x:String> <x:String x:Key="Text.CreateBranch.Name.WarnSpace" xml:space="preserve">Leerzeichen werden durch Bindestriche ersetzt.</x:String>
<x:String x:Key="Text.CreateBranch.Title" xml:space="preserve">Lokalen Branch erstellen</x:String> <x:String x:Key="Text.CreateBranch.Title" xml:space="preserve">Lokalen Branch erstellen</x:String>
<x:String x:Key="Text.CreateBranch.OverwriteExisting" xml:space="preserve">Überschreibe existierenden Branch</x:String>
<x:String x:Key="Text.CreateTag" xml:space="preserve">Tag erstellen...</x:String> <x:String x:Key="Text.CreateTag" xml:space="preserve">Tag erstellen...</x:String>
<x:String x:Key="Text.CreateTag.BasedOn" xml:space="preserve">Neuer Tag auf:</x:String> <x:String x:Key="Text.CreateTag.BasedOn" xml:space="preserve">Neuer Tag auf:</x:String>
<x:String x:Key="Text.CreateTag.GPGSign" xml:space="preserve">Mit GPG signieren</x:String> <x:String x:Key="Text.CreateTag.GPGSign" xml:space="preserve">Mit GPG signieren</x:String>
@ -233,6 +240,9 @@
<x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">Ohne Anmerkung</x:String> <x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">Ohne Anmerkung</x:String>
<x:String x:Key="Text.CtrlClickTip" xml:space="preserve">Halte Strg gedrückt, um direkt auszuführen</x:String> <x:String x:Key="Text.CtrlClickTip" xml:space="preserve">Halte Strg gedrückt, um direkt auszuführen</x:String>
<x:String x:Key="Text.Cut" xml:space="preserve">Ausschneiden</x:String> <x:String x:Key="Text.Cut" xml:space="preserve">Ausschneiden</x:String>
<x:String x:Key="Text.DeinitSubmodule" xml:space="preserve">De-initialisiere Submodul</x:String>
<x:String x:Key="Text.DeinitSubmodule.Force" xml:space="preserve">Erzwinge De-Initialisierung, selbst wenn es lokale Änderungen enthält.</x:String>
<x:String x:Key="Text.DeinitSubmodule.Path" xml:space="preserve">Submodul:</x:String>
<x:String x:Key="Text.DeleteBranch" xml:space="preserve">Branch löschen</x:String> <x:String x:Key="Text.DeleteBranch" xml:space="preserve">Branch löschen</x:String>
<x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">Branch:</x:String> <x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">Branch:</x:String>
<x:String x:Key="Text.DeleteBranch.IsRemoteTip" xml:space="preserve">Du löscht gerade einen Remote-Branch!!!</x:String> <x:String x:Key="Text.DeleteBranch.IsRemoteTip" xml:space="preserve">Du löscht gerade einen Remote-Branch!!!</x:String>
@ -268,6 +278,7 @@
<x:String x:Key="Text.Diff.ShowHiddenSymbols" xml:space="preserve">Zeige versteckte Symbole</x:String> <x:String x:Key="Text.Diff.ShowHiddenSymbols" xml:space="preserve">Zeige versteckte Symbole</x:String>
<x:String x:Key="Text.Diff.SideBySide" xml:space="preserve">Nebeneinander</x:String> <x:String x:Key="Text.Diff.SideBySide" xml:space="preserve">Nebeneinander</x:String>
<x:String x:Key="Text.Diff.Submodule" xml:space="preserve">SUBMODUL</x:String> <x:String x:Key="Text.Diff.Submodule" xml:space="preserve">SUBMODUL</x:String>
<x:String x:Key="Text.Diff.Submodule.Deleted" xml:space="preserve">GELÖSCHT</x:String>
<x:String x:Key="Text.Diff.Submodule.New" xml:space="preserve">NEU</x:String> <x:String x:Key="Text.Diff.Submodule.New" xml:space="preserve">NEU</x:String>
<x:String x:Key="Text.Diff.SwapCommits" xml:space="preserve">Seiten wechseln</x:String> <x:String x:Key="Text.Diff.SwapCommits" xml:space="preserve">Seiten wechseln</x:String>
<x:String x:Key="Text.Diff.SyntaxHighlight" xml:space="preserve">Syntax Hervorhebung</x:String> <x:String x:Key="Text.Diff.SyntaxHighlight" xml:space="preserve">Syntax Hervorhebung</x:String>
@ -326,6 +337,8 @@
<x:String x:Key="Text.GitFlow.FinishHotfix" xml:space="preserve">FLOW - Finish Hotfix</x:String> <x:String x:Key="Text.GitFlow.FinishHotfix" xml:space="preserve">FLOW - Finish Hotfix</x:String>
<x:String x:Key="Text.GitFlow.FinishRelease" xml:space="preserve">FLOW - Finish Release</x:String> <x:String x:Key="Text.GitFlow.FinishRelease" xml:space="preserve">FLOW - Finish Release</x:String>
<x:String x:Key="Text.GitFlow.FinishTarget" xml:space="preserve">Ziel:</x:String> <x:String x:Key="Text.GitFlow.FinishTarget" xml:space="preserve">Ziel:</x:String>
<x:String x:Key="Text.GitFlow.FinishWithPush" xml:space="preserve">Push zu Remote(s) nach Durchführung des Finish</x:String>
<x:String x:Key="Text.GitFlow.FinishWithSquash" xml:space="preserve">Squash beim Merge</x:String>
<x:String x:Key="Text.GitFlow.Hotfix" xml:space="preserve">Hotfix:</x:String> <x:String x:Key="Text.GitFlow.Hotfix" xml:space="preserve">Hotfix:</x:String>
<x:String x:Key="Text.GitFlow.HotfixPrefix" xml:space="preserve">Hotfix-Prefix:</x:String> <x:String x:Key="Text.GitFlow.HotfixPrefix" xml:space="preserve">Hotfix-Prefix:</x:String>
<x:String x:Key="Text.GitFlow.Init" xml:space="preserve">Git-Flow initialisieren</x:String> <x:String x:Key="Text.GitFlow.Init" xml:space="preserve">Git-Flow initialisieren</x:String>
@ -387,6 +400,8 @@
<x:String x:Key="Text.Hotkeys.Global.GotoPrevTab" xml:space="preserve">Zum vorherigen Tab wechseln</x:String> <x:String x:Key="Text.Hotkeys.Global.GotoPrevTab" xml:space="preserve">Zum vorherigen Tab wechseln</x:String>
<x:String x:Key="Text.Hotkeys.Global.NewTab" xml:space="preserve">Neuen Tab erstellen</x:String> <x:String x:Key="Text.Hotkeys.Global.NewTab" xml:space="preserve">Neuen Tab erstellen</x:String>
<x:String x:Key="Text.Hotkeys.Global.OpenPreferences" xml:space="preserve">Einstellungen öffnen</x:String> <x:String x:Key="Text.Hotkeys.Global.OpenPreferences" xml:space="preserve">Einstellungen öffnen</x:String>
<x:String x:Key="Text.Hotkeys.Global.SwitchWorkspace" xml:space="preserve">Aktiven Arbeitsplatz wechseln</x:String>
<x:String x:Key="Text.Hotkeys.Global.SwitchTab" xml:space="preserve">Aktiven Tab wechseln</x:String>
<x:String x:Key="Text.Hotkeys.Repo" xml:space="preserve">REPOSITORY</x:String> <x:String x:Key="Text.Hotkeys.Repo" xml:space="preserve">REPOSITORY</x:String>
<x:String x:Key="Text.Hotkeys.Repo.Commit" xml:space="preserve">Gestagte Änderungen committen</x:String> <x:String x:Key="Text.Hotkeys.Repo.Commit" xml:space="preserve">Gestagte Änderungen committen</x:String>
<x:String x:Key="Text.Hotkeys.Repo.CommitAndPush" xml:space="preserve">Gestagte Änderungen committen und pushen</x:String> <x:String x:Key="Text.Hotkeys.Repo.CommitAndPush" xml:space="preserve">Gestagte Änderungen committen und pushen</x:String>
@ -407,6 +422,7 @@
<x:String x:Key="Text.Hotkeys.TextEditor.CloseSearch" xml:space="preserve">Suchpanel schließen</x:String> <x:String x:Key="Text.Hotkeys.TextEditor.CloseSearch" xml:space="preserve">Suchpanel schließen</x:String>
<x:String x:Key="Text.Hotkeys.TextEditor.GotoNextMatch" xml:space="preserve">Suche nächste Übereinstimmung</x:String> <x:String x:Key="Text.Hotkeys.TextEditor.GotoNextMatch" xml:space="preserve">Suche nächste Übereinstimmung</x:String>
<x:String x:Key="Text.Hotkeys.TextEditor.GotoPrevMatch" xml:space="preserve">Suche vorherige Übereinstimmung</x:String> <x:String x:Key="Text.Hotkeys.TextEditor.GotoPrevMatch" xml:space="preserve">Suche vorherige Übereinstimmung</x:String>
<x:String x:Key="Text.Hotkeys.TextEditor.OpenExternalMergeTool" xml:space="preserve">Öffne mit externem Diff/Merge Tool</x:String>
<x:String x:Key="Text.Hotkeys.TextEditor.Search" xml:space="preserve">Öffne Suchpanel</x:String> <x:String x:Key="Text.Hotkeys.TextEditor.Search" xml:space="preserve">Öffne Suchpanel</x:String>
<x:String x:Key="Text.Hunk.Discard" xml:space="preserve">Verwerfen</x:String> <x:String x:Key="Text.Hunk.Discard" xml:space="preserve">Verwerfen</x:String>
<x:String x:Key="Text.Hunk.Stage" xml:space="preserve">Stagen</x:String> <x:String x:Key="Text.Hunk.Stage" xml:space="preserve">Stagen</x:String>
@ -428,7 +444,10 @@
<x:String x:Key="Text.IssueLinkCM.OpenInBrowser" xml:space="preserve">In Browser öffnen</x:String> <x:String x:Key="Text.IssueLinkCM.OpenInBrowser" xml:space="preserve">In Browser öffnen</x:String>
<x:String x:Key="Text.Launcher.Error" xml:space="preserve">FEHLER</x:String> <x:String x:Key="Text.Launcher.Error" xml:space="preserve">FEHLER</x:String>
<x:String x:Key="Text.Launcher.Info" xml:space="preserve">INFO</x:String> <x:String x:Key="Text.Launcher.Info" xml:space="preserve">INFO</x:String>
<x:String x:Key="Text.Launcher.Workspaces" xml:space="preserve">Arbeitsplätze</x:String>
<x:String x:Key="Text.Launcher.Pages" xml:space="preserve">Tabs</x:String>
<x:String x:Key="Text.Merge" xml:space="preserve">Branch mergen</x:String> <x:String x:Key="Text.Merge" xml:space="preserve">Branch mergen</x:String>
<x:String x:Key="Text.Merge.Edit" xml:space="preserve">Merge-Nachricht anpassen</x:String>
<x:String x:Key="Text.Merge.Into" xml:space="preserve">Ziel-Branch:</x:String> <x:String x:Key="Text.Merge.Into" xml:space="preserve">Ziel-Branch:</x:String>
<x:String x:Key="Text.Merge.Mode" xml:space="preserve">Merge Option:</x:String> <x:String x:Key="Text.Merge.Mode" xml:space="preserve">Merge Option:</x:String>
<x:String x:Key="Text.Merge.Source" xml:space="preserve">Quelle:</x:String> <x:String x:Key="Text.Merge.Source" xml:space="preserve">Quelle:</x:String>
@ -461,6 +480,7 @@
<x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">Vor {0} Monaten</x:String> <x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">Vor {0} Monaten</x:String>
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">Vor {0} Jahren</x:String> <x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">Vor {0} Jahren</x:String>
<x:String x:Key="Text.Period.Yesterday" xml:space="preserve">Gestern</x:String> <x:String x:Key="Text.Period.Yesterday" xml:space="preserve">Gestern</x:String>
<x:String x:Key="Text.PopupEnterKeyTip" xml:space="preserve">Verwende 'Shift+Enter' um eine neue Zeile einzufügen. 'Enter' ist das Kürzel für den OK Button</x:String>
<x:String x:Key="Text.Preferences" xml:space="preserve">Einstellungen</x:String> <x:String x:Key="Text.Preferences" xml:space="preserve">Einstellungen</x:String>
<x:String x:Key="Text.Preferences.AI" xml:space="preserve">OPEN AI</x:String> <x:String x:Key="Text.Preferences.AI" xml:space="preserve">OPEN AI</x:String>
<x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">Analysierung des Diff Befehl</x:String> <x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">Analysierung des Diff Befehl</x:String>
@ -530,6 +550,7 @@
<x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">Lokale Änderungen:</x:String> <x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">Lokale Änderungen:</x:String>
<x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">Verwerfen</x:String> <x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">Verwerfen</x:String>
<x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">Stashen &amp; wieder anwenden</x:String> <x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">Stashen &amp; wieder anwenden</x:String>
<x:String x:Key="Text.Pull.RecurseSubmodules" xml:space="preserve">Alle Submodule aktualisieren</x:String>
<x:String x:Key="Text.Pull.Remote" xml:space="preserve">Remote:</x:String> <x:String x:Key="Text.Pull.Remote" xml:space="preserve">Remote:</x:String>
<x:String x:Key="Text.Pull.Title" xml:space="preserve">Pull (Fetch &amp; Merge)</x:String> <x:String x:Key="Text.Pull.Title" xml:space="preserve">Pull (Fetch &amp; Merge)</x:String>
<x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">Rebase anstatt Merge verwenden</x:String> <x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">Rebase anstatt Merge verwenden</x:String>
@ -538,6 +559,8 @@
<x:String x:Key="Text.Push.Force" xml:space="preserve">Erzwinge Push</x:String> <x:String x:Key="Text.Push.Force" xml:space="preserve">Erzwinge Push</x:String>
<x:String x:Key="Text.Push.Local" xml:space="preserve">Lokaler Branch:</x:String> <x:String x:Key="Text.Push.Local" xml:space="preserve">Lokaler Branch:</x:String>
<x:String x:Key="Text.Push.Remote" xml:space="preserve">Remote:</x:String> <x:String x:Key="Text.Push.Remote" xml:space="preserve">Remote:</x:String>
<x:String x:Key="Text.Push.Revision" xml:space="preserve">Revision:</x:String>
<x:String x:Key="Text.Push.Revision.Title" xml:space="preserve">Push Revision zu Remote-Branch</x:String>
<x:String x:Key="Text.Push.Title" xml:space="preserve">Push</x:String> <x:String x:Key="Text.Push.Title" xml:space="preserve">Push</x:String>
<x:String x:Key="Text.Push.To" xml:space="preserve">Remote-Branch:</x:String> <x:String x:Key="Text.Push.To" xml:space="preserve">Remote-Branch:</x:String>
<x:String x:Key="Text.Push.Tracking" xml:space="preserve">Remote-Branch verfolgen</x:String> <x:String x:Key="Text.Push.Tracking" xml:space="preserve">Remote-Branch verfolgen</x:String>
@ -578,6 +601,7 @@
<x:String x:Key="Text.Repository.Clean" xml:space="preserve">Aufräumen (GC &amp; Prune)</x:String> <x:String x:Key="Text.Repository.Clean" xml:space="preserve">Aufräumen (GC &amp; Prune)</x:String>
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">Führt `git gc` auf diesem Repository aus.</x:String> <x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">Führt `git gc` auf diesem Repository aus.</x:String>
<x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">Filter aufheben</x:String> <x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">Filter aufheben</x:String>
<x:String x:Key="Text.Repository.ClearStashes" xml:space="preserve">Löschen</x:String>
<x:String x:Key="Text.Repository.Configure" xml:space="preserve">Repository Einstellungen</x:String> <x:String x:Key="Text.Repository.Configure" xml:space="preserve">Repository Einstellungen</x:String>
<x:String x:Key="Text.Repository.Continue" xml:space="preserve">WEITER</x:String> <x:String x:Key="Text.Repository.Continue" xml:space="preserve">WEITER</x:String>
<x:String x:Key="Text.Repository.CustomActions" xml:space="preserve">Benutzerdefinierte Aktionen</x:String> <x:String x:Key="Text.Repository.CustomActions" xml:space="preserve">Benutzerdefinierte Aktionen</x:String>
@ -615,6 +639,7 @@
<x:String x:Key="Text.Repository.Search.ByMessage" xml:space="preserve">Commit-Nachricht</x:String> <x:String x:Key="Text.Repository.Search.ByMessage" xml:space="preserve">Commit-Nachricht</x:String>
<x:String x:Key="Text.Repository.Search.BySHA" xml:space="preserve">SHA</x:String> <x:String x:Key="Text.Repository.Search.BySHA" xml:space="preserve">SHA</x:String>
<x:String x:Key="Text.Repository.Search.InCurrentBranch" xml:space="preserve">Aktueller Branch</x:String> <x:String x:Key="Text.Repository.Search.InCurrentBranch" xml:space="preserve">Aktueller Branch</x:String>
<x:String x:Key="Text.Repository.ShowSubmodulesAsTree" xml:space="preserve">Submodule als Baum anzeigen</x:String>
<x:String x:Key="Text.Repository.ShowTagsAsTree" xml:space="preserve">Zeige Tags als Baum</x:String> <x:String x:Key="Text.Repository.ShowTagsAsTree" xml:space="preserve">Zeige Tags als Baum</x:String>
<x:String x:Key="Text.Repository.Skip" xml:space="preserve">ÜBERSPRINGEN</x:String> <x:String x:Key="Text.Repository.Skip" xml:space="preserve">ÜBERSPRINGEN</x:String>
<x:String x:Key="Text.Repository.Statistics" xml:space="preserve">Statistiken</x:String> <x:String x:Key="Text.Repository.Statistics" xml:space="preserve">Statistiken</x:String>
@ -638,12 +663,14 @@
<x:String x:Key="Text.Reset.Mode" xml:space="preserve">Rücksetzmodus:</x:String> <x:String x:Key="Text.Reset.Mode" xml:space="preserve">Rücksetzmodus:</x:String>
<x:String x:Key="Text.Reset.MoveTo" xml:space="preserve">Verschiebe zu:</x:String> <x:String x:Key="Text.Reset.MoveTo" xml:space="preserve">Verschiebe zu:</x:String>
<x:String x:Key="Text.Reset.Target" xml:space="preserve">Aktueller Branch:</x:String> <x:String x:Key="Text.Reset.Target" xml:space="preserve">Aktueller Branch:</x:String>
<x:String x:Key="Text.ResetWithoutCheckout" xml:space="preserve">Reset Branch (ohne Checkout)</x:String>
<x:String x:Key="Text.ResetWithoutCheckout.MoveTo" xml:space="preserve">Auf:</x:String>
<x:String x:Key="Text.ResetWithoutCheckout.Target" xml:space="preserve">Branch:</x:String>
<x:String x:Key="Text.RevealFile" xml:space="preserve">Zeige im Datei-Explorer</x:String> <x:String x:Key="Text.RevealFile" xml:space="preserve">Zeige im Datei-Explorer</x:String>
<x:String x:Key="Text.Revert" xml:space="preserve">Commit rückgängig machen</x:String> <x:String x:Key="Text.Revert" xml:space="preserve">Commit rückgängig machen</x:String>
<x:String x:Key="Text.Revert.Commit" xml:space="preserve">Commit:</x:String> <x:String x:Key="Text.Revert.Commit" xml:space="preserve">Commit:</x:String>
<x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">Commit Änderungen rückgängig machen</x:String> <x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">Commit Änderungen rückgängig machen</x:String>
<x:String x:Key="Text.Reword" xml:space="preserve">Commit Nachricht umformulieren</x:String> <x:String x:Key="Text.Reword" xml:space="preserve">Commit Nachricht umformulieren</x:String>
<x:String x:Key="Text.Reword.Tip" xml:space="preserve">Verwende 'Shift+Enter' um eine neue Zeile einzufügen. 'Enter' ist das Kürzel für den OK Button</x:String>
<x:String x:Key="Text.Running" xml:space="preserve">Bitte warten...</x:String> <x:String x:Key="Text.Running" xml:space="preserve">Bitte warten...</x:String>
<x:String x:Key="Text.Save" xml:space="preserve">SPEICHERN</x:String> <x:String x:Key="Text.Save" xml:space="preserve">SPEICHERN</x:String>
<x:String x:Key="Text.SaveAs" xml:space="preserve">Speichern als...</x:String> <x:String x:Key="Text.SaveAs" xml:space="preserve">Speichern als...</x:String>
@ -669,16 +696,15 @@
<x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Pfad zum privaten SSH Schlüssel</x:String> <x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Pfad zum privaten SSH Schlüssel</x:String>
<x:String x:Key="Text.Start" xml:space="preserve">START</x:String> <x:String x:Key="Text.Start" xml:space="preserve">START</x:String>
<x:String x:Key="Text.Stash" xml:space="preserve">Stash</x:String> <x:String x:Key="Text.Stash" xml:space="preserve">Stash</x:String>
<x:String x:Key="Text.Stash.AutoRestore" xml:space="preserve">Automatisch wiederherstellen nach dem Stashen</x:String>
<x:String x:Key="Text.Stash.AutoRestore.Tip" xml:space="preserve">Die Arbeitsdateien bleiben unverändert, aber ein Stash wird gespeichert.</x:String>
<x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">Inklusive nicht-verfolgter Dateien</x:String> <x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">Inklusive nicht-verfolgter Dateien</x:String>
<x:String x:Key="Text.Stash.KeepIndex" xml:space="preserve">Behalte gestagte Dateien</x:String>
<x:String x:Key="Text.Stash.Message" xml:space="preserve">Name:</x:String> <x:String x:Key="Text.Stash.Message" xml:space="preserve">Name:</x:String>
<x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">Optional. Name dieses Stashes</x:String> <x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">Optional. Informationen zu dieses Stashes</x:String>
<x:String x:Key="Text.Stash.Mode" xml:space="preserve">Modus:</x:String>
<x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">Nur gestagte Änderungen</x:String> <x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">Nur gestagte Änderungen</x:String>
<x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">Gestagte und unstagte Änderungen der ausgewähleten Datei(en) werden gestasht!!!</x:String> <x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">Gestagte und unstagte Änderungen der ausgewähleten Datei(en) werden gestasht!!!</x:String>
<x:String x:Key="Text.Stash.Title" xml:space="preserve">Lokale Änderungen stashen</x:String> <x:String x:Key="Text.Stash.Title" xml:space="preserve">Lokale Änderungen stashen</x:String>
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">Anwenden</x:String> <x:String x:Key="Text.StashCM.Apply" xml:space="preserve">Anwenden</x:String>
<x:String x:Key="Text.StashCM.CopyMessage" xml:space="preserve">Kopiere Nachricht</x:String>
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">Entfernen</x:String> <x:String x:Key="Text.StashCM.Drop" xml:space="preserve">Entfernen</x:String>
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">Als Path speichern...</x:String> <x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">Als Path speichern...</x:String>
<x:String x:Key="Text.StashDropConfirm" xml:space="preserve">Stash entfernen</x:String> <x:String x:Key="Text.StashDropConfirm" xml:space="preserve">Stash entfernen</x:String>
@ -697,11 +723,18 @@
<x:String x:Key="Text.Submodule" xml:space="preserve">SUBMODULE</x:String> <x:String x:Key="Text.Submodule" xml:space="preserve">SUBMODULE</x:String>
<x:String x:Key="Text.Submodule.Add" xml:space="preserve">Submodul hinzufügen</x:String> <x:String x:Key="Text.Submodule.Add" xml:space="preserve">Submodul hinzufügen</x:String>
<x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">Relativen Pfad kopieren</x:String> <x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">Relativen Pfad kopieren</x:String>
<x:String x:Key="Text.Submodule.Deinit" xml:space="preserve">De-initialisiere Submodul</x:String>
<x:String x:Key="Text.Submodule.FetchNested" xml:space="preserve">Untergeordnete Submodule fetchen</x:String> <x:String x:Key="Text.Submodule.FetchNested" xml:space="preserve">Untergeordnete Submodule fetchen</x:String>
<x:String x:Key="Text.Submodule.Open" xml:space="preserve">Öffne Submodul Repository</x:String> <x:String x:Key="Text.Submodule.Open" xml:space="preserve">Öffne Submodul Repository</x:String>
<x:String x:Key="Text.Submodule.RelativePath" xml:space="preserve">Relativer Pfad:</x:String> <x:String x:Key="Text.Submodule.RelativePath" xml:space="preserve">Relativer Pfad:</x:String>
<x:String x:Key="Text.Submodule.RelativePath.Placeholder" xml:space="preserve">Relativer Ordner um dieses Submodul zu speichern.</x:String> <x:String x:Key="Text.Submodule.RelativePath.Placeholder" xml:space="preserve">Relativer Ordner um dieses Submodul zu speichern.</x:String>
<x:String x:Key="Text.Submodule.Remove" xml:space="preserve">Submodul löschen</x:String> <x:String x:Key="Text.Submodule.Remove" xml:space="preserve">Submodul löschen</x:String>
<x:String x:Key="Text.Submodule.Status" xml:space="preserve">STATUS</x:String>
<x:String x:Key="Text.Submodule.Status.Modified" xml:space="preserve">geändert</x:String>
<x:String x:Key="Text.Submodule.Status.NotInited" xml:space="preserve">nicht initialisiert</x:String>
<x:String x:Key="Text.Submodule.Status.RevisionChanged" xml:space="preserve">Revision geändert</x:String>
<x:String x:Key="Text.Submodule.Status.Unmerged" xml:space="preserve">nicht gemerged</x:String>
<x:String x:Key="Text.Submodule.URL" xml:space="preserve">URL</x:String>
<x:String x:Key="Text.Sure" xml:space="preserve">OK</x:String> <x:String x:Key="Text.Sure" xml:space="preserve">OK</x:String>
<x:String x:Key="Text.TagCM.Copy" xml:space="preserve">Tag-Namen kopieren</x:String> <x:String x:Key="Text.TagCM.Copy" xml:space="preserve">Tag-Namen kopieren</x:String>
<x:String x:Key="Text.TagCM.CopyMessage" xml:space="preserve">Tag-Nachricht kopieren</x:String> <x:String x:Key="Text.TagCM.CopyMessage" xml:space="preserve">Tag-Nachricht kopieren</x:String>
@ -738,7 +771,7 @@
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Ignoriere alle *{0} Dateien</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Ignoriere alle *{0} Dateien</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Ignoriere *{0} Datein im selben Ordner</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Ignoriere *{0} Datein im selben Ordner</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">Ignoriere Dateien im selben Ordner</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InFolder" xml:space="preserve">Ignoriere nicht-verfolgte Dateien in diesem Ordner</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ignoriere nur diese Datei</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ignoriere nur diese Datei</x:String>
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Amend</x:String> <x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Amend</x:String>
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Du kannst diese Datei jetzt stagen.</x:String> <x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Du kannst diese Datei jetzt stagen.</x:String>
@ -758,6 +791,7 @@
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">NICHT-VERFOLGTE DATEIEN INKLUDIEREN</x:String> <x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">NICHT-VERFOLGTE DATEIEN INKLUDIEREN</x:String>
<x:String x:Key="Text.WorkingCopy.NoCommitHistories" xml:space="preserve">KEINE BISHERIGEN COMMIT-NACHRICHTEN</x:String> <x:String x:Key="Text.WorkingCopy.NoCommitHistories" xml:space="preserve">KEINE BISHERIGEN COMMIT-NACHRICHTEN</x:String>
<x:String x:Key="Text.WorkingCopy.NoCommitTemplates" xml:space="preserve">KEINE COMMIT TEMPLATES</x:String> <x:String x:Key="Text.WorkingCopy.NoCommitTemplates" xml:space="preserve">KEINE COMMIT TEMPLATES</x:String>
<x:String x:Key="Text.WorkingCopy.ResetAuthor" xml:space="preserve">Autor zurücksetzen</x:String>
<x:String x:Key="Text.WorkingCopy.ResolveTip" xml:space="preserve">Rechtsklick auf selektierte Dateien und wähle die Konfliktlösungen aus.</x:String> <x:String x:Key="Text.WorkingCopy.ResolveTip" xml:space="preserve">Rechtsklick auf selektierte Dateien und wähle die Konfliktlösungen aus.</x:String>
<x:String x:Key="Text.WorkingCopy.SignOff" xml:space="preserve">SignOff</x:String> <x:String x:Key="Text.WorkingCopy.SignOff" xml:space="preserve">SignOff</x:String>
<x:String x:Key="Text.WorkingCopy.Staged" xml:space="preserve">GESTAGED</x:String> <x:String x:Key="Text.WorkingCopy.Staged" xml:space="preserve">GESTAGED</x:String>

View file

@ -120,6 +120,7 @@
<x:String x:Key="Text.CommitCM.InteractiveRebase" xml:space="preserve">Interactively Rebase ${0}$ on Here</x:String> <x:String x:Key="Text.CommitCM.InteractiveRebase" xml:space="preserve">Interactively Rebase ${0}$ on Here</x:String>
<x:String x:Key="Text.CommitCM.Merge" xml:space="preserve">Merge to ${0}$</x:String> <x:String x:Key="Text.CommitCM.Merge" xml:space="preserve">Merge to ${0}$</x:String>
<x:String x:Key="Text.CommitCM.MergeMultiple" xml:space="preserve">Merge ...</x:String> <x:String x:Key="Text.CommitCM.MergeMultiple" xml:space="preserve">Merge ...</x:String>
<x:String x:Key="Text.CommitCM.PushRevision" xml:space="preserve">Push ${0}$ to ${1}$</x:String>
<x:String x:Key="Text.CommitCM.Rebase" xml:space="preserve">Rebase ${0}$ on Here</x:String> <x:String x:Key="Text.CommitCM.Rebase" xml:space="preserve">Rebase ${0}$ on Here</x:String>
<x:String x:Key="Text.CommitCM.Reset" xml:space="preserve">Reset ${0}$ to Here</x:String> <x:String x:Key="Text.CommitCM.Reset" xml:space="preserve">Reset ${0}$ to Here</x:String>
<x:String x:Key="Text.CommitCM.Revert" xml:space="preserve">Revert Commit</x:String> <x:String x:Key="Text.CommitCM.Revert" xml:space="preserve">Revert Commit</x:String>
@ -442,6 +443,7 @@
<x:String x:Key="Text.Launcher.Workspaces" xml:space="preserve">Workspaces</x:String> <x:String x:Key="Text.Launcher.Workspaces" xml:space="preserve">Workspaces</x:String>
<x:String x:Key="Text.Launcher.Pages" xml:space="preserve">Pages</x:String> <x:String x:Key="Text.Launcher.Pages" xml:space="preserve">Pages</x:String>
<x:String x:Key="Text.Merge" xml:space="preserve">Merge Branch</x:String> <x:String x:Key="Text.Merge" xml:space="preserve">Merge Branch</x:String>
<x:String x:Key="Text.Merge.Edit" xml:space="preserve">Customize merge message</x:String>
<x:String x:Key="Text.Merge.Into" xml:space="preserve">Into:</x:String> <x:String x:Key="Text.Merge.Into" xml:space="preserve">Into:</x:String>
<x:String x:Key="Text.Merge.Mode" xml:space="preserve">Merge Option:</x:String> <x:String x:Key="Text.Merge.Mode" xml:space="preserve">Merge Option:</x:String>
<x:String x:Key="Text.Merge.Source" xml:space="preserve">Source:</x:String> <x:String x:Key="Text.Merge.Source" xml:space="preserve">Source:</x:String>
@ -474,6 +476,7 @@
<x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">{0} months ago</x:String> <x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">{0} months ago</x:String>
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} years ago</x:String> <x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} years ago</x:String>
<x:String x:Key="Text.Period.Yesterday" xml:space="preserve">Yesterday</x:String> <x:String x:Key="Text.Period.Yesterday" xml:space="preserve">Yesterday</x:String>
<x:String x:Key="Text.PopupEnterKeyTip" xml:space="preserve">Use 'Shift+Enter' to input a new line. 'Enter' is the hotkey of OK button</x:String>
<x:String x:Key="Text.Preferences" xml:space="preserve">Preferences</x:String> <x:String x:Key="Text.Preferences" xml:space="preserve">Preferences</x:String>
<x:String x:Key="Text.Preferences.AI" xml:space="preserve">AI</x:String> <x:String x:Key="Text.Preferences.AI" xml:space="preserve">AI</x:String>
<x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">Analyze Diff Prompt</x:String> <x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">Analyze Diff Prompt</x:String>
@ -552,6 +555,8 @@
<x:String x:Key="Text.Push.Force" xml:space="preserve">Force push</x:String> <x:String x:Key="Text.Push.Force" xml:space="preserve">Force push</x:String>
<x:String x:Key="Text.Push.Local" xml:space="preserve">Local Branch:</x:String> <x:String x:Key="Text.Push.Local" xml:space="preserve">Local Branch:</x:String>
<x:String x:Key="Text.Push.Remote" xml:space="preserve">Remote:</x:String> <x:String x:Key="Text.Push.Remote" xml:space="preserve">Remote:</x:String>
<x:String x:Key="Text.Push.Revision" xml:space="preserve">Revision:</x:String>
<x:String x:Key="Text.Push.Revision.Title" xml:space="preserve">Push Revision To Remote</x:String>
<x:String x:Key="Text.Push.Title" xml:space="preserve">Push Changes To Remote</x:String> <x:String x:Key="Text.Push.Title" xml:space="preserve">Push Changes To Remote</x:String>
<x:String x:Key="Text.Push.To" xml:space="preserve">Remote Branch:</x:String> <x:String x:Key="Text.Push.To" xml:space="preserve">Remote Branch:</x:String>
<x:String x:Key="Text.Push.Tracking" xml:space="preserve">Set as tracking branch</x:String> <x:String x:Key="Text.Push.Tracking" xml:space="preserve">Set as tracking branch</x:String>
@ -662,7 +667,6 @@
<x:String x:Key="Text.Revert.Commit" xml:space="preserve">Commit:</x:String> <x:String x:Key="Text.Revert.Commit" xml:space="preserve">Commit:</x:String>
<x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">Commit revert changes</x:String> <x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">Commit revert changes</x:String>
<x:String x:Key="Text.Reword" xml:space="preserve">Reword Commit Message</x:String> <x:String x:Key="Text.Reword" xml:space="preserve">Reword Commit Message</x:String>
<x:String x:Key="Text.Reword.Tip" xml:space="preserve">Use 'Shift+Enter' to input a new line. 'Enter' is the hotkey of OK button</x:String>
<x:String x:Key="Text.Running" xml:space="preserve">Running. Please wait...</x:String> <x:String x:Key="Text.Running" xml:space="preserve">Running. Please wait...</x:String>
<x:String x:Key="Text.Save" xml:space="preserve">SAVE</x:String> <x:String x:Key="Text.Save" xml:space="preserve">SAVE</x:String>
<x:String x:Key="Text.SaveAs" xml:space="preserve">Save As...</x:String> <x:String x:Key="Text.SaveAs" xml:space="preserve">Save As...</x:String>
@ -688,16 +692,15 @@
<x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Private SSH key store path</x:String> <x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Private SSH key store path</x:String>
<x:String x:Key="Text.Start" xml:space="preserve">START</x:String> <x:String x:Key="Text.Start" xml:space="preserve">START</x:String>
<x:String x:Key="Text.Stash" xml:space="preserve">Stash</x:String> <x:String x:Key="Text.Stash" xml:space="preserve">Stash</x:String>
<x:String x:Key="Text.Stash.AutoRestore" xml:space="preserve">Auto-restore after stashing</x:String>
<x:String x:Key="Text.Stash.AutoRestore.Tip" xml:space="preserve">Your working files remain unchanged, but a stash is saved.</x:String>
<x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">Include untracked files</x:String> <x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">Include untracked files</x:String>
<x:String x:Key="Text.Stash.KeepIndex" xml:space="preserve">Keep staged files</x:String>
<x:String x:Key="Text.Stash.Message" xml:space="preserve">Message:</x:String> <x:String x:Key="Text.Stash.Message" xml:space="preserve">Message:</x:String>
<x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">Optional. Name of this stash</x:String> <x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">Optional. Message of this stash</x:String>
<x:String x:Key="Text.Stash.Mode" xml:space="preserve">Mode:</x:String>
<x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">Only staged changes</x:String> <x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">Only staged changes</x:String>
<x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">Both staged and unstaged changes of selected file(s) will be stashed!!!</x:String> <x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">Both staged and unstaged changes of selected file(s) will be stashed!!!</x:String>
<x:String x:Key="Text.Stash.Title" xml:space="preserve">Stash Local Changes</x:String> <x:String x:Key="Text.Stash.Title" xml:space="preserve">Stash Local Changes</x:String>
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">Apply</x:String> <x:String x:Key="Text.StashCM.Apply" xml:space="preserve">Apply</x:String>
<x:String x:Key="Text.StashCM.CopyMessage" xml:space="preserve">Copy Message</x:String>
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">Drop</x:String> <x:String x:Key="Text.StashCM.Drop" xml:space="preserve">Drop</x:String>
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">Save as Patch...</x:String> <x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">Save as Patch...</x:String>
<x:String x:Key="Text.StashDropConfirm" xml:space="preserve">Drop Stash</x:String> <x:String x:Key="Text.StashDropConfirm" xml:space="preserve">Drop Stash</x:String>
@ -764,7 +767,7 @@
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Ignore all *{0} files</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Ignore all *{0} files</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Ignore *{0} files in the same folder</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Ignore *{0} files in the same folder</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">Ignore files in the same folder</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InFolder" xml:space="preserve">Ignore untracked files in this folder</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ignore this file only</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ignore this file only</x:String>
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Amend</x:String> <x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Amend</x:String>
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">You can stage this file now.</x:String> <x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">You can stage this file now.</x:String>

View file

@ -478,6 +478,7 @@
<x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">Hace {0} meses</x:String> <x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">Hace {0} meses</x:String>
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">Hace {0} años</x:String> <x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">Hace {0} años</x:String>
<x:String x:Key="Text.Period.Yesterday" xml:space="preserve">Ayer</x:String> <x:String x:Key="Text.Period.Yesterday" xml:space="preserve">Ayer</x:String>
<x:String x:Key="Text.PopupEnterKeyTip" xml:space="preserve">Usa 'Shift+Enter' para introducir una nueva línea. 'Enter' es el atajo del botón OK</x:String>
<x:String x:Key="Text.Preferences" xml:space="preserve">Preferencias</x:String> <x:String x:Key="Text.Preferences" xml:space="preserve">Preferencias</x:String>
<x:String x:Key="Text.Preferences.AI" xml:space="preserve">OPEN AI</x:String> <x:String x:Key="Text.Preferences.AI" xml:space="preserve">OPEN AI</x:String>
<x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">Analizar Diff Prompt</x:String> <x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">Analizar Diff Prompt</x:String>
@ -666,7 +667,6 @@
<x:String x:Key="Text.Revert.Commit" xml:space="preserve">Commit:</x:String> <x:String x:Key="Text.Revert.Commit" xml:space="preserve">Commit:</x:String>
<x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">Commit revertir cambios</x:String> <x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">Commit revertir cambios</x:String>
<x:String x:Key="Text.Reword" xml:space="preserve">Reescribir Mensaje de Commit</x:String> <x:String x:Key="Text.Reword" xml:space="preserve">Reescribir Mensaje de Commit</x:String>
<x:String x:Key="Text.Reword.Tip" xml:space="preserve">Usa 'Shift+Enter' para introducir una nueva línea. 'Enter' es el atajo del botón OK</x:String>
<x:String x:Key="Text.Running" xml:space="preserve">Ejecutando. Por favor espera...</x:String> <x:String x:Key="Text.Running" xml:space="preserve">Ejecutando. Por favor espera...</x:String>
<x:String x:Key="Text.Save" xml:space="preserve">GUARDAR</x:String> <x:String x:Key="Text.Save" xml:space="preserve">GUARDAR</x:String>
<x:String x:Key="Text.SaveAs" xml:space="preserve">Guardar Como...</x:String> <x:String x:Key="Text.SaveAs" xml:space="preserve">Guardar Como...</x:String>
@ -692,12 +692,9 @@
<x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Ruta de almacenamiento de la clave privada SSH</x:String> <x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Ruta de almacenamiento de la clave privada SSH</x:String>
<x:String x:Key="Text.Start" xml:space="preserve">INICIAR</x:String> <x:String x:Key="Text.Start" xml:space="preserve">INICIAR</x:String>
<x:String x:Key="Text.Stash" xml:space="preserve">Stash</x:String> <x:String x:Key="Text.Stash" xml:space="preserve">Stash</x:String>
<x:String x:Key="Text.Stash.AutoRestore" xml:space="preserve">Restaurar automáticamente después del stashing</x:String>
<x:String x:Key="Text.Stash.AutoRestore.Tip" xml:space="preserve">Tus archivos de trabajo permanecen sin cambios, pero se guarda un stash.</x:String>
<x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">Incluir archivos no rastreados</x:String> <x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">Incluir archivos no rastreados</x:String>
<x:String x:Key="Text.Stash.KeepIndex" xml:space="preserve">Mantener archivos staged</x:String>
<x:String x:Key="Text.Stash.Message" xml:space="preserve">Mensaje:</x:String> <x:String x:Key="Text.Stash.Message" xml:space="preserve">Mensaje:</x:String>
<x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">Opcional. Nombre de este stash</x:String> <x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">Opcional. Información de este stash</x:String>
<x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">Solo cambios staged</x:String> <x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">Solo cambios staged</x:String>
<x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">¡Tanto los cambios staged como los no staged de los archivos seleccionados serán stashed!</x:String> <x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">¡Tanto los cambios staged como los no staged de los archivos seleccionados serán stashed!</x:String>
<x:String x:Key="Text.Stash.Title" xml:space="preserve">Stash Cambios Locales</x:String> <x:String x:Key="Text.Stash.Title" xml:space="preserve">Stash Cambios Locales</x:String>
@ -768,7 +765,6 @@
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Ignorar todos los archivos *{0}</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Ignorar todos los archivos *{0}</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Ignorar archivos *{0} en la misma carpeta</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Ignorar archivos *{0} en la misma carpeta</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">Ignorar archivos en la misma carpeta</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ignorar solo este archivo</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ignorar solo este archivo</x:String>
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Enmendar</x:String> <x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Enmendar</x:String>
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Puedes hacer stage a este archivo ahora.</x:String> <x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Puedes hacer stage a este archivo ahora.</x:String>

View file

@ -444,6 +444,7 @@
<x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">il y a {0} mois</x:String> <x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">il y a {0} mois</x:String>
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">il y a {0} ans</x:String> <x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">il y a {0} ans</x:String>
<x:String x:Key="Text.Period.Yesterday" xml:space="preserve">Hier</x:String> <x:String x:Key="Text.Period.Yesterday" xml:space="preserve">Hier</x:String>
<x:String x:Key="Text.PopupEnterKeyTip" xml:space="preserve">Utiliser 'Maj+Entrée' pour insérer une nouvelle ligne. 'Entrée' est la touche pour valider</x:String>
<x:String x:Key="Text.Preferences" xml:space="preserve">Préférences</x:String> <x:String x:Key="Text.Preferences" xml:space="preserve">Préférences</x:String>
<x:String x:Key="Text.Preferences.AI" xml:space="preserve">IA</x:String> <x:String x:Key="Text.Preferences.AI" xml:space="preserve">IA</x:String>
<x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">Analyser Diff Prompt</x:String> <x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">Analyser Diff Prompt</x:String>
@ -619,7 +620,6 @@
<x:String x:Key="Text.Revert.Commit" xml:space="preserve">Commit :</x:String> <x:String x:Key="Text.Revert.Commit" xml:space="preserve">Commit :</x:String>
<x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">Commit les changements de l'annulation</x:String> <x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">Commit les changements de l'annulation</x:String>
<x:String x:Key="Text.Reword" xml:space="preserve">Reformuler le message de commit</x:String> <x:String x:Key="Text.Reword" xml:space="preserve">Reformuler le message de commit</x:String>
<x:String x:Key="Text.Reword.Tip" xml:space="preserve">Utiliser 'Maj+Entrée' pour insérer une nouvelle ligne. 'Entrée' est la touche pour valider</x:String>
<x:String x:Key="Text.Running" xml:space="preserve">En exécution. Veuillez patienter...</x:String> <x:String x:Key="Text.Running" xml:space="preserve">En exécution. Veuillez patienter...</x:String>
<x:String x:Key="Text.Save" xml:space="preserve">SAUVEGARDER</x:String> <x:String x:Key="Text.Save" xml:space="preserve">SAUVEGARDER</x:String>
<x:String x:Key="Text.SaveAs" xml:space="preserve">Sauvegarder en tant que...</x:String> <x:String x:Key="Text.SaveAs" xml:space="preserve">Sauvegarder en tant que...</x:String>
@ -645,12 +645,9 @@
<x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Chemin du magasin de clés privées SSH</x:String> <x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Chemin du magasin de clés privées SSH</x:String>
<x:String x:Key="Text.Start" xml:space="preserve">START</x:String> <x:String x:Key="Text.Start" xml:space="preserve">START</x:String>
<x:String x:Key="Text.Stash" xml:space="preserve">Stash</x:String> <x:String x:Key="Text.Stash" xml:space="preserve">Stash</x:String>
<x:String x:Key="Text.Stash.AutoRestore" xml:space="preserve">Auto-restauration après le stash</x:String>
<x:String x:Key="Text.Stash.AutoRestore.Tip" xml:space="preserve">Vos fichiers de travail restent inchangés, mais une sauvegarde est enregistrée.</x:String>
<x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">Inclure les fichiers non-suivis</x:String> <x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">Inclure les fichiers non-suivis</x:String>
<x:String x:Key="Text.Stash.KeepIndex" xml:space="preserve">Garder les fichiers indexés</x:String>
<x:String x:Key="Text.Stash.Message" xml:space="preserve">Message :</x:String> <x:String x:Key="Text.Stash.Message" xml:space="preserve">Message :</x:String>
<x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">Optionnel. Nom de ce stash</x:String> <x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">Optionnel. Information de ce stash</x:String>
<x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">Seulement les changements indexés</x:String> <x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">Seulement les changements indexés</x:String>
<x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">Les modifications indexées et non-indexées des fichiers sélectionnés seront stockées!!!</x:String> <x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">Les modifications indexées et non-indexées des fichiers sélectionnés seront stockées!!!</x:String>
<x:String x:Key="Text.Stash.Title" xml:space="preserve">Stash les changements locaux</x:String> <x:String x:Key="Text.Stash.Title" xml:space="preserve">Stash les changements locaux</x:String>
@ -710,7 +707,6 @@
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Ignorer tous les *{0} fichiers</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Ignorer tous les *{0} fichiers</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Ignorer *{0} fichiers dans le même dossier</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Ignorer *{0} fichiers dans le même dossier</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">Ignorer les fichiers dans le même dossier</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">N'ignorer que ce fichier</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">N'ignorer que ce fichier</x:String>
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Amender</x:String> <x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Amender</x:String>
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Vous pouvez indexer ce fichier.</x:String> <x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Vous pouvez indexer ce fichier.</x:String>

View file

@ -464,6 +464,7 @@
<x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">{0} mesi fa</x:String> <x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">{0} mesi fa</x:String>
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} anni fa</x:String> <x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} anni fa</x:String>
<x:String x:Key="Text.Period.Yesterday" xml:space="preserve">Ieri</x:String> <x:String x:Key="Text.Period.Yesterday" xml:space="preserve">Ieri</x:String>
<x:String x:Key="Text.PopupEnterKeyTip" xml:space="preserve">Usa 'Shift+Enter' per inserire una nuova riga. 'Enter' è il tasto rapido per il pulsante OK</x:String>
<x:String x:Key="Text.Preferences" xml:space="preserve">Preferenze</x:String> <x:String x:Key="Text.Preferences" xml:space="preserve">Preferenze</x:String>
<x:String x:Key="Text.Preferences.AI" xml:space="preserve">AI</x:String> <x:String x:Key="Text.Preferences.AI" xml:space="preserve">AI</x:String>
<x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">Analizza il Prompt Differenza</x:String> <x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">Analizza il Prompt Differenza</x:String>
@ -647,7 +648,6 @@
<x:String x:Key="Text.Revert.Commit" xml:space="preserve">Commit:</x:String> <x:String x:Key="Text.Revert.Commit" xml:space="preserve">Commit:</x:String>
<x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">Commit delle modifiche di ripristino</x:String> <x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">Commit delle modifiche di ripristino</x:String>
<x:String x:Key="Text.Reword" xml:space="preserve">Modifica Messaggio di Commit</x:String> <x:String x:Key="Text.Reword" xml:space="preserve">Modifica Messaggio di Commit</x:String>
<x:String x:Key="Text.Reword.Tip" xml:space="preserve">Usa 'Shift+Enter' per inserire una nuova riga. 'Enter' è il tasto rapido per il pulsante OK</x:String>
<x:String x:Key="Text.Running" xml:space="preserve">In esecuzione. Attendere...</x:String> <x:String x:Key="Text.Running" xml:space="preserve">In esecuzione. Attendere...</x:String>
<x:String x:Key="Text.Save" xml:space="preserve">SALVA</x:String> <x:String x:Key="Text.Save" xml:space="preserve">SALVA</x:String>
<x:String x:Key="Text.SaveAs" xml:space="preserve">Salva come...</x:String> <x:String x:Key="Text.SaveAs" xml:space="preserve">Salva come...</x:String>
@ -673,12 +673,9 @@
<x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Percorso per la chiave SSH privata</x:String> <x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Percorso per la chiave SSH privata</x:String>
<x:String x:Key="Text.Start" xml:space="preserve">AVVIA</x:String> <x:String x:Key="Text.Start" xml:space="preserve">AVVIA</x:String>
<x:String x:Key="Text.Stash" xml:space="preserve">Stasha</x:String> <x:String x:Key="Text.Stash" xml:space="preserve">Stasha</x:String>
<x:String x:Key="Text.Stash.AutoRestore" xml:space="preserve">Auto-ripristino dopo lo stash</x:String>
<x:String x:Key="Text.Stash.AutoRestore.Tip" xml:space="preserve">I tuoi file di lavoro rimangono inalterati, ma viene salvato uno stash.</x:String>
<x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">Includi file non tracciati</x:String> <x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">Includi file non tracciati</x:String>
<x:String x:Key="Text.Stash.KeepIndex" xml:space="preserve">Mantieni file in stage</x:String>
<x:String x:Key="Text.Stash.Message" xml:space="preserve">Messaggio:</x:String> <x:String x:Key="Text.Stash.Message" xml:space="preserve">Messaggio:</x:String>
<x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">Opzionale. Nome di questo stash</x:String> <x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">Opzionale. Informazioni di questo stash</x:String>
<x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">Solo modifiche in stage</x:String> <x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">Solo modifiche in stage</x:String>
<x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">Sia le modifiche in stage che quelle non in stage dei file selezionati saranno stashate!!!</x:String> <x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">Sia le modifiche in stage che quelle non in stage dei file selezionati saranno stashate!!!</x:String>
<x:String x:Key="Text.Stash.Title" xml:space="preserve">Stasha Modifiche Locali</x:String> <x:String x:Key="Text.Stash.Title" xml:space="preserve">Stasha Modifiche Locali</x:String>
@ -748,7 +745,6 @@
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Ignora tutti i file *{0}</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Ignora tutti i file *{0}</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Ignora i file *{0} nella stessa cartella</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Ignora i file *{0} nella stessa cartella</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">Ignora i file nella stessa cartella</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ignora solo questo file</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ignora solo questo file</x:String>
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Modifica</x:String> <x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Modifica</x:String>
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Puoi aggiungere in stage questo file ora.</x:String> <x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Puoi aggiungere in stage questo file ora.</x:String>

View file

@ -443,6 +443,7 @@
<x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">{0} ヶ月前</x:String> <x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">{0} ヶ月前</x:String>
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} 年前</x:String> <x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} 年前</x:String>
<x:String x:Key="Text.Period.Yesterday" xml:space="preserve">昨日</x:String> <x:String x:Key="Text.Period.Yesterday" xml:space="preserve">昨日</x:String>
<x:String x:Key="Text.PopupEnterKeyTip" xml:space="preserve">改行には'Shift+Enter'キーを使用します。 'Enter"はOKボタンのホットキーとして機能します。</x:String>
<x:String x:Key="Text.Preferences" xml:space="preserve">設定</x:String> <x:String x:Key="Text.Preferences" xml:space="preserve">設定</x:String>
<x:String x:Key="Text.Preferences.AI" xml:space="preserve">AI</x:String> <x:String x:Key="Text.Preferences.AI" xml:space="preserve">AI</x:String>
<x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">差分分析プロンプト</x:String> <x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">差分分析プロンプト</x:String>
@ -617,7 +618,6 @@
<x:String x:Key="Text.Revert.Commit" xml:space="preserve">コミット:</x:String> <x:String x:Key="Text.Revert.Commit" xml:space="preserve">コミット:</x:String>
<x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">コミットの変更を戻す</x:String> <x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">コミットの変更を戻す</x:String>
<x:String x:Key="Text.Reword" xml:space="preserve">コミットメッセージを書き直す</x:String> <x:String x:Key="Text.Reword" xml:space="preserve">コミットメッセージを書き直す</x:String>
<x:String x:Key="Text.Reword.Tip" xml:space="preserve">改行には'Shift+Enter'キーを使用します。 'Enter"はOKボタンのホットキーとして機能します。</x:String>
<x:String x:Key="Text.Running" xml:space="preserve">実行中です。しばらくお待ちください...</x:String> <x:String x:Key="Text.Running" xml:space="preserve">実行中です。しばらくお待ちください...</x:String>
<x:String x:Key="Text.Save" xml:space="preserve">保存</x:String> <x:String x:Key="Text.Save" xml:space="preserve">保存</x:String>
<x:String x:Key="Text.SaveAs" xml:space="preserve">名前を付けて保存...</x:String> <x:String x:Key="Text.SaveAs" xml:space="preserve">名前を付けて保存...</x:String>
@ -643,12 +643,9 @@
<x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">プライベートSSHキーストアのパス</x:String> <x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">プライベートSSHキーストアのパス</x:String>
<x:String x:Key="Text.Start" xml:space="preserve">スタート</x:String> <x:String x:Key="Text.Start" xml:space="preserve">スタート</x:String>
<x:String x:Key="Text.Stash" xml:space="preserve">スタッシュ</x:String> <x:String x:Key="Text.Stash" xml:space="preserve">スタッシュ</x:String>
<x:String x:Key="Text.Stash.AutoRestore" xml:space="preserve">スタッシュ後に自動で復元</x:String>
<x:String x:Key="Text.Stash.AutoRestore.Tip" xml:space="preserve">作業ファイルは変更されず、スタッシュが保存されます。</x:String>
<x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">追跡されていないファイルを含める</x:String> <x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">追跡されていないファイルを含める</x:String>
<x:String x:Key="Text.Stash.KeepIndex" xml:space="preserve">ステージされたファイルを保持</x:String>
<x:String x:Key="Text.Stash.Message" xml:space="preserve">メッセージ:</x:String> <x:String x:Key="Text.Stash.Message" xml:space="preserve">メッセージ:</x:String>
<x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">オプション. このスタッシュの名前を入力</x:String> <x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">オプション. このスタッシュの情報</x:String>
<x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">ステージされた変更のみ</x:String> <x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">ステージされた変更のみ</x:String>
<x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">選択したファイルの、ステージされた変更とステージされていない変更の両方がスタッシュされます!!!</x:String> <x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">選択したファイルの、ステージされた変更とステージされていない変更の両方がスタッシュされます!!!</x:String>
<x:String x:Key="Text.Stash.Title" xml:space="preserve">ローカルの変更をスタッシュ</x:String> <x:String x:Key="Text.Stash.Title" xml:space="preserve">ローカルの変更をスタッシュ</x:String>
@ -708,7 +705,6 @@
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">すべての*{0}ファイルを無視</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">すべての*{0}ファイルを無視</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">同じフォルダ内の*{0}ファイルを無視</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">同じフォルダ内の*{0}ファイルを無視</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">同じフォルダ内のファイルを無視</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">このファイルのみを無視</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">このファイルのみを無視</x:String>
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Amend</x:String> <x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Amend</x:String>
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">このファイルを今すぐステージできます。</x:String> <x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">このファイルを今すぐステージできます。</x:String>

View file

@ -406,6 +406,7 @@
<x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">{0} meses atrás</x:String> <x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">{0} meses atrás</x:String>
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} anos atrás</x:String> <x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} anos atrás</x:String>
<x:String x:Key="Text.Period.Yesterday" xml:space="preserve">Ontem</x:String> <x:String x:Key="Text.Period.Yesterday" xml:space="preserve">Ontem</x:String>
<x:String x:Key="Text.PopupEnterKeyTip" xml:space="preserve">Use 'Shift+Enter' para inserir uma nova linha. 'Enter' é a tecla de atalho do botão OK</x:String>
<x:String x:Key="Text.Preferences" xml:space="preserve">Preferências</x:String> <x:String x:Key="Text.Preferences" xml:space="preserve">Preferências</x:String>
<x:String x:Key="Text.Preferences.AI" xml:space="preserve">INTELIGÊNCIA ARTIFICIAL</x:String> <x:String x:Key="Text.Preferences.AI" xml:space="preserve">INTELIGÊNCIA ARTIFICIAL</x:String>
<x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">Prompt para Analisar Diff</x:String> <x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">Prompt para Analisar Diff</x:String>
@ -563,7 +564,6 @@
<x:String x:Key="Text.Revert.Commit" xml:space="preserve">Commit:</x:String> <x:String x:Key="Text.Revert.Commit" xml:space="preserve">Commit:</x:String>
<x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">Commitar alterações de reversão</x:String> <x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">Commitar alterações de reversão</x:String>
<x:String x:Key="Text.Reword" xml:space="preserve">Reescrever Mensagem do Commit</x:String> <x:String x:Key="Text.Reword" xml:space="preserve">Reescrever Mensagem do Commit</x:String>
<x:String x:Key="Text.Reword.Tip" xml:space="preserve">Use 'Shift+Enter' para inserir uma nova linha. 'Enter' é a tecla de atalho do botão OK</x:String>
<x:String x:Key="Text.Running" xml:space="preserve">Executando. Por favor, aguarde...</x:String> <x:String x:Key="Text.Running" xml:space="preserve">Executando. Por favor, aguarde...</x:String>
<x:String x:Key="Text.Save" xml:space="preserve">SALVAR</x:String> <x:String x:Key="Text.Save" xml:space="preserve">SALVAR</x:String>
<x:String x:Key="Text.SaveAs" xml:space="preserve">Salvar Como...</x:String> <x:String x:Key="Text.SaveAs" xml:space="preserve">Salvar Como...</x:String>
@ -585,9 +585,8 @@
<x:String x:Key="Text.Start" xml:space="preserve">INICIAR</x:String> <x:String x:Key="Text.Start" xml:space="preserve">INICIAR</x:String>
<x:String x:Key="Text.Stash" xml:space="preserve">Stash</x:String> <x:String x:Key="Text.Stash" xml:space="preserve">Stash</x:String>
<x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">Incluir arquivos não rastreados</x:String> <x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">Incluir arquivos não rastreados</x:String>
<x:String x:Key="Text.Stash.KeepIndex" xml:space="preserve">Manter arquivos em stage</x:String>
<x:String x:Key="Text.Stash.Message" xml:space="preserve">Mensagem:</x:String> <x:String x:Key="Text.Stash.Message" xml:space="preserve">Mensagem:</x:String>
<x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">Opcional. Nome deste stash</x:String> <x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">Opcional. Informações deste stash</x:String>
<x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">Apenas mudanças em stage</x:String> <x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">Apenas mudanças em stage</x:String>
<x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">Tanto mudanças em stage e fora de stage dos arquivos selecionados serão enviadas para stash!!!</x:String> <x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">Tanto mudanças em stage e fora de stage dos arquivos selecionados serão enviadas para stash!!!</x:String>
<x:String x:Key="Text.Stash.Title" xml:space="preserve">Guardar Alterações Locais</x:String> <x:String x:Key="Text.Stash.Title" xml:space="preserve">Guardar Alterações Locais</x:String>
@ -646,7 +645,6 @@
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Ignorar todos os arquivos *{0}</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Ignorar todos os arquivos *{0}</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Ignorar arquivos *{0} na mesma pasta</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Ignorar arquivos *{0} na mesma pasta</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">Ignorar arquivos na mesma pasta</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ignorar apenas este arquivo</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ignorar apenas este arquivo</x:String>
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Corrigir</x:String> <x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Corrigir</x:String>
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Você pode stagear este arquivo agora.</x:String> <x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Você pode stagear este arquivo agora.</x:String>

View file

@ -90,6 +90,8 @@
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Отложить и примненить повторно</x:String> <x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Отложить и примненить повторно</x:String>
<x:String x:Key="Text.Checkout.RecurseSubmodules" xml:space="preserve">Обновить все подкаталоги</x:String> <x:String x:Key="Text.Checkout.RecurseSubmodules" xml:space="preserve">Обновить все подкаталоги</x:String>
<x:String x:Key="Text.Checkout.Target" xml:space="preserve">Ветка:</x:String> <x:String x:Key="Text.Checkout.Target" xml:space="preserve">Ветка:</x:String>
<x:String x:Key="Text.Checkout.WithFastForward" xml:space="preserve">Переключиться и перемотать</x:String>
<x:String x:Key="Text.Checkout.WithFastForward.Upstream" xml:space="preserve">Перемотать к:</x:String>
<x:String x:Key="Text.CherryPick" xml:space="preserve"> Частичный выбор</x:String> <x:String x:Key="Text.CherryPick" xml:space="preserve"> Частичный выбор</x:String>
<x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">Добавить источник для ревизии сообщения</x:String> <x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">Добавить источник для ревизии сообщения</x:String>
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">Ревизия(и):</x:String> <x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">Ревизия(и):</x:String>
@ -122,6 +124,7 @@
<x:String x:Key="Text.CommitCM.InteractiveRebase" xml:space="preserve">Интерактивное перемещение (rebase -i) ${0}$ сюда</x:String> <x:String x:Key="Text.CommitCM.InteractiveRebase" xml:space="preserve">Интерактивное перемещение (rebase -i) ${0}$ сюда</x:String>
<x:String x:Key="Text.CommitCM.Merge" xml:space="preserve">Влить в ${0}$</x:String> <x:String x:Key="Text.CommitCM.Merge" xml:space="preserve">Влить в ${0}$</x:String>
<x:String x:Key="Text.CommitCM.MergeMultiple" xml:space="preserve">Влить ...</x:String> <x:String x:Key="Text.CommitCM.MergeMultiple" xml:space="preserve">Влить ...</x:String>
<x:String x:Key="Text.CommitCM.PushRevision" xml:space="preserve">Выложить ${0}$ в ${1}$</x:String>
<x:String x:Key="Text.CommitCM.Rebase" xml:space="preserve">Переместить ${0}$ сюда</x:String> <x:String x:Key="Text.CommitCM.Rebase" xml:space="preserve">Переместить ${0}$ сюда</x:String>
<x:String x:Key="Text.CommitCM.Reset" xml:space="preserve">Сбросить ${0}$ сюда</x:String> <x:String x:Key="Text.CommitCM.Reset" xml:space="preserve">Сбросить ${0}$ сюда</x:String>
<x:String x:Key="Text.CommitCM.Revert" xml:space="preserve">Отменить ревизию</x:String> <x:String x:Key="Text.CommitCM.Revert" xml:space="preserve">Отменить ревизию</x:String>
@ -444,6 +447,7 @@
<x:String x:Key="Text.Launcher.Workspaces" xml:space="preserve">Рабочие места</x:String> <x:String x:Key="Text.Launcher.Workspaces" xml:space="preserve">Рабочие места</x:String>
<x:String x:Key="Text.Launcher.Pages" xml:space="preserve">Страницы</x:String> <x:String x:Key="Text.Launcher.Pages" xml:space="preserve">Страницы</x:String>
<x:String x:Key="Text.Merge" xml:space="preserve">Влить ветку</x:String> <x:String x:Key="Text.Merge" xml:space="preserve">Влить ветку</x:String>
<x:String x:Key="Text.Merge.Edit" xml:space="preserve">Изменить сообщение слияния</x:String>
<x:String x:Key="Text.Merge.Into" xml:space="preserve">В:</x:String> <x:String x:Key="Text.Merge.Into" xml:space="preserve">В:</x:String>
<x:String x:Key="Text.Merge.Mode" xml:space="preserve">Опции слияния:</x:String> <x:String x:Key="Text.Merge.Mode" xml:space="preserve">Опции слияния:</x:String>
<x:String x:Key="Text.Merge.Source" xml:space="preserve">Источник:</x:String> <x:String x:Key="Text.Merge.Source" xml:space="preserve">Источник:</x:String>
@ -476,6 +480,7 @@
<x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">{0} месяцев назад</x:String> <x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">{0} месяцев назад</x:String>
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} лет назад</x:String> <x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} лет назад</x:String>
<x:String x:Key="Text.Period.Yesterday" xml:space="preserve">Вчера</x:String> <x:String x:Key="Text.Period.Yesterday" xml:space="preserve">Вчера</x:String>
<x:String x:Key="Text.PopupEnterKeyTip" xml:space="preserve">Используйте «Shift+Enter» для ввода новой строки. «Enter» - это горячая клавиша кнопки «OK»</x:String>
<x:String x:Key="Text.Preferences" xml:space="preserve">Параметры</x:String> <x:String x:Key="Text.Preferences" xml:space="preserve">Параметры</x:String>
<x:String x:Key="Text.Preferences.AI" xml:space="preserve">ОТКРЫТЬ ИИ</x:String> <x:String x:Key="Text.Preferences.AI" xml:space="preserve">ОТКРЫТЬ ИИ</x:String>
<x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">Запрос на анализ сравнения</x:String> <x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">Запрос на анализ сравнения</x:String>
@ -554,6 +559,8 @@
<x:String x:Key="Text.Push.Force" xml:space="preserve">Принудительно выложить</x:String> <x:String x:Key="Text.Push.Force" xml:space="preserve">Принудительно выложить</x:String>
<x:String x:Key="Text.Push.Local" xml:space="preserve">Локальная ветка:</x:String> <x:String x:Key="Text.Push.Local" xml:space="preserve">Локальная ветка:</x:String>
<x:String x:Key="Text.Push.Remote" xml:space="preserve">Внешний репозиторий:</x:String> <x:String x:Key="Text.Push.Remote" xml:space="preserve">Внешний репозиторий:</x:String>
<x:String x:Key="Text.Push.Revision" xml:space="preserve">Ревизия:</x:String>
<x:String x:Key="Text.Push.Revision.Title" xml:space="preserve">Выложить ревизию на удалёную</x:String>
<x:String x:Key="Text.Push.Title" xml:space="preserve">Выложить изменения на внешний репозиторий</x:String> <x:String x:Key="Text.Push.Title" xml:space="preserve">Выложить изменения на внешний репозиторий</x:String>
<x:String x:Key="Text.Push.To" xml:space="preserve">Ветка внешнего репозитория:</x:String> <x:String x:Key="Text.Push.To" xml:space="preserve">Ветка внешнего репозитория:</x:String>
<x:String x:Key="Text.Push.Tracking" xml:space="preserve">Отслеживать ветку</x:String> <x:String x:Key="Text.Push.Tracking" xml:space="preserve">Отслеживать ветку</x:String>
@ -664,7 +671,6 @@
<x:String x:Key="Text.Revert.Commit" xml:space="preserve">Ревизия:</x:String> <x:String x:Key="Text.Revert.Commit" xml:space="preserve">Ревизия:</x:String>
<x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">Отмена ревизии</x:String> <x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">Отмена ревизии</x:String>
<x:String x:Key="Text.Reword" xml:space="preserve">Изменить комментарий ревизии</x:String> <x:String x:Key="Text.Reword" xml:space="preserve">Изменить комментарий ревизии</x:String>
<x:String x:Key="Text.Reword.Tip" xml:space="preserve">Используйте «Shift+Enter» для ввода новой строки. «Enter» - это горячая клавиша кнопки «OK»</x:String>
<x:String x:Key="Text.Running" xml:space="preserve">Запуск. Подождите пожалуйста...</x:String> <x:String x:Key="Text.Running" xml:space="preserve">Запуск. Подождите пожалуйста...</x:String>
<x:String x:Key="Text.Save" xml:space="preserve">СОХРАНИТЬ</x:String> <x:String x:Key="Text.Save" xml:space="preserve">СОХРАНИТЬ</x:String>
<x:String x:Key="Text.SaveAs" xml:space="preserve">Сохранить как...</x:String> <x:String x:Key="Text.SaveAs" xml:space="preserve">Сохранить как...</x:String>
@ -690,16 +696,15 @@
<x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Путь хранения приватного ключа SSH</x:String> <x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Путь хранения приватного ключа SSH</x:String>
<x:String x:Key="Text.Start" xml:space="preserve">ЗАПУСК</x:String> <x:String x:Key="Text.Start" xml:space="preserve">ЗАПУСК</x:String>
<x:String x:Key="Text.Stash" xml:space="preserve">Отложить</x:String> <x:String x:Key="Text.Stash" xml:space="preserve">Отложить</x:String>
<x:String x:Key="Text.Stash.AutoRestore" xml:space="preserve">Автоматически восстанавливать после откладывания</x:String>
<x:String x:Key="Text.Stash.AutoRestore.Tip" xml:space="preserve">Ваши рабочие файлы остаются неизменными, но отложенные сохранятся.</x:String>
<x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">Включить неотслеживаемые файлы</x:String> <x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">Включить неотслеживаемые файлы</x:String>
<x:String x:Key="Text.Stash.KeepIndex" xml:space="preserve">Хранить отложенные файлы</x:String>
<x:String x:Key="Text.Stash.Message" xml:space="preserve">Сообщение:</x:String> <x:String x:Key="Text.Stash.Message" xml:space="preserve">Сообщение:</x:String>
<x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">Имя тайника (необязательно)</x:String> <x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">Имя тайника (необязательно)</x:String>
<x:String x:Key="Text.Stash.Mode" xml:space="preserve">Режим:</x:String>
<x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">Только сформированные изменения</x:String> <x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">Только сформированные изменения</x:String>
<x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">Сформированные так и несформированные изменения выбранных файлов будут сохранены!!!</x:String> <x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">Сформированные так и несформированные изменения выбранных файлов будут сохранены!!!</x:String>
<x:String x:Key="Text.Stash.Title" xml:space="preserve">Отложить локальные изменения</x:String> <x:String x:Key="Text.Stash.Title" xml:space="preserve">Отложить локальные изменения</x:String>
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">Принять</x:String> <x:String x:Key="Text.StashCM.Apply" xml:space="preserve">Принять</x:String>
<x:String x:Key="Text.StashCM.CopyMessage" xml:space="preserve">Копировать сообщение</x:String>
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">Отбросить</x:String> <x:String x:Key="Text.StashCM.Drop" xml:space="preserve">Отбросить</x:String>
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">Сохранить как заплатку...</x:String> <x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">Сохранить как заплатку...</x:String>
<x:String x:Key="Text.StashDropConfirm" xml:space="preserve">Отбросить тайник</x:String> <x:String x:Key="Text.StashDropConfirm" xml:space="preserve">Отбросить тайник</x:String>
@ -766,7 +771,7 @@
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Игнорировать Git</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Игнорировать Git</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Игнорировать все *{0} файлы</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Игнорировать все *{0} файлы</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Игнорировать *{0} файлы в том же каталоге</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Игнорировать *{0} файлы в том же каталоге</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">Игнорировать файлы в том же каталоге</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InFolder" xml:space="preserve">Игнорировать неотслеживаемые файлы в этом каталоге</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Игнорировать только эти файлы</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Игнорировать только эти файлы</x:String>
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Изменить</x:String> <x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Изменить</x:String>
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Теперь вы можете сформировать этот файл.</x:String> <x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Теперь вы можете сформировать этот файл.</x:String>

View file

@ -443,6 +443,7 @@
<x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">{0} திங்களுக்கு முன்பு</x:String> <x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">{0} திங்களுக்கு முன்பு</x:String>
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} ஆண்டுகளுக்கு முன்பு</x:String> <x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} ஆண்டுகளுக்கு முன்பு</x:String>
<x:String x:Key="Text.Period.Yesterday" xml:space="preserve">நேற்று</x:String> <x:String x:Key="Text.Period.Yesterday" xml:space="preserve">நேற்று</x:String>
<x:String x:Key="Text.PopupEnterKeyTip" xml:space="preserve">புதிய வரியை உள்ளிட 'உயர்த்து+நுழை' ஐப் பயன்படுத்தவும். 'நுழை' என்பது சரி பொத்தானின் சூடானவிசை ஆகும்</x:String>
<x:String x:Key="Text.Preferences" xml:space="preserve">விருப்பத்தேர்வுகள்</x:String> <x:String x:Key="Text.Preferences" xml:space="preserve">விருப்பத்தேர்வுகள்</x:String>
<x:String x:Key="Text.Preferences.AI" xml:space="preserve">செநு</x:String> <x:String x:Key="Text.Preferences.AI" xml:space="preserve">செநு</x:String>
<x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">வேறுபாடு உடனடியாக பகுப்பாய்வு செய்</x:String> <x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">வேறுபாடு உடனடியாக பகுப்பாய்வு செய்</x:String>
@ -618,7 +619,6 @@
<x:String x:Key="Text.Revert.Commit" xml:space="preserve">உறுதிமொழி:</x:String> <x:String x:Key="Text.Revert.Commit" xml:space="preserve">உறுதிமொழி:</x:String>
<x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">பின்வாங்கு மாற்றங்களை உறுதிமொழி</x:String> <x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">பின்வாங்கு மாற்றங்களை உறுதிமொழி</x:String>
<x:String x:Key="Text.Reword" xml:space="preserve">மாறுசொல் உறுதிமொழி செய்தி</x:String> <x:String x:Key="Text.Reword" xml:space="preserve">மாறுசொல் உறுதிமொழி செய்தி</x:String>
<x:String x:Key="Text.Reword.Tip" xml:space="preserve">புதிய வரியை உள்ளிட 'உயர்த்து+நுழை' ஐப் பயன்படுத்தவும். 'நுழை' என்பது சரி பொத்தானின் சூடானவிசை ஆகும்</x:String>
<x:String x:Key="Text.Running" xml:space="preserve">இயங்குகிறது. காத்திருக்கவும்...</x:String> <x:String x:Key="Text.Running" xml:space="preserve">இயங்குகிறது. காத்திருக்கவும்...</x:String>
<x:String x:Key="Text.Save" xml:space="preserve">சேமி</x:String> <x:String x:Key="Text.Save" xml:space="preserve">சேமி</x:String>
<x:String x:Key="Text.SaveAs" xml:space="preserve">எனச் சேமி...</x:String> <x:String x:Key="Text.SaveAs" xml:space="preserve">எனச் சேமி...</x:String>
@ -644,10 +644,7 @@
<x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">தனியார் பாஓடு திறவுகோல் கடை பாதை</x:String> <x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">தனியார் பாஓடு திறவுகோல் கடை பாதை</x:String>
<x:String x:Key="Text.Start" xml:space="preserve">தொடங்கு</x:String> <x:String x:Key="Text.Start" xml:space="preserve">தொடங்கு</x:String>
<x:String x:Key="Text.Stash" xml:space="preserve">பதுக்கிவை</x:String> <x:String x:Key="Text.Stash" xml:space="preserve">பதுக்கிவை</x:String>
<x:String x:Key="Text.Stash.AutoRestore" xml:space="preserve">பதுக்கிவைத்த பிறகு தானியங்கி மீட்டமை</x:String>
<x:String x:Key="Text.Stash.AutoRestore.Tip" xml:space="preserve">உங்கள் செயல்படும் கோப்புகள் மாறாமல் இருக்கும், ஆனால் ஒரு பதுக்கிவைக்கப்படும்.</x:String>
<x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">கண்காணிக்கப்படாத கோப்புகளைச் சேர்</x:String> <x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">கண்காணிக்கப்படாத கோப்புகளைச் சேர்</x:String>
<x:String x:Key="Text.Stash.KeepIndex" xml:space="preserve">நிலைப்படுத்தப்பட்ட கோப்புகளை வைத்திரு</x:String>
<x:String x:Key="Text.Stash.Message" xml:space="preserve">செய்தி:</x:String> <x:String x:Key="Text.Stash.Message" xml:space="preserve">செய்தி:</x:String>
<x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">விருப்பத்தேர்வு. இந்த பதுக்கலின் பெயர்</x:String> <x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">விருப்பத்தேர்வு. இந்த பதுக்கலின் பெயர்</x:String>
<x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">நிலைப்படுத்தப்பட்ட மாற்றங்கள் மட்டும்</x:String> <x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">நிலைப்படுத்தப்பட்ட மாற்றங்கள் மட்டும்</x:String>
@ -708,7 +705,6 @@
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">அறிவிலி புறக்கணி</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">அறிவிலி புறக்கணி</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">எல்லா *{0} கோப்புகளையும் புறக்கணி</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">எல்லா *{0} கோப்புகளையும் புறக்கணி</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">ஒரே கோப்புறையில் *{0} கோப்புகளைப் புறக்கணி</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">ஒரே கோப்புறையில் *{0} கோப்புகளைப் புறக்கணி</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">ஒரே கோப்புறையில் கோப்புகளைப் புறக்கணி</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">இந்த கோப்பை மட்டும் புறக்கணி</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">இந்த கோப்பை மட்டும் புறக்கணி</x:String>
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">பின்னொட்டு</x:String> <x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">பின்னொட்டு</x:String>
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">இந்த கோப்பை இப்போது நீங்கள் நிலைப்படுத்தலாம்.</x:String> <x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">இந்த கோப்பை இப்போது நீங்கள் நிலைப்படுத்தலாம்.</x:String>

View file

@ -448,6 +448,7 @@
<x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">{0} місяців тому</x:String> <x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">{0} місяців тому</x:String>
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} років тому</x:String> <x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} років тому</x:String>
<x:String x:Key="Text.Period.Yesterday" xml:space="preserve">Вчора</x:String> <x:String x:Key="Text.Period.Yesterday" xml:space="preserve">Вчора</x:String>
<x:String x:Key="Text.PopupEnterKeyTip" xml:space="preserve">Використовуйте 'Shift+Enter' для введення нового рядка. 'Enter' - гаряча клавіша кнопки OK</x:String>
<x:String x:Key="Text.Preferences" xml:space="preserve">Налаштування</x:String> <x:String x:Key="Text.Preferences" xml:space="preserve">Налаштування</x:String>
<x:String x:Key="Text.Preferences.AI" xml:space="preserve">AI</x:String> <x:String x:Key="Text.Preferences.AI" xml:space="preserve">AI</x:String>
<x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">Промпт для аналізу різниці</x:String> <x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">Промпт для аналізу різниці</x:String>
@ -623,7 +624,6 @@
<x:String x:Key="Text.Revert.Commit" xml:space="preserve">Коміт:</x:String> <x:String x:Key="Text.Revert.Commit" xml:space="preserve">Коміт:</x:String>
<x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">Закомітити зміни скасування</x:String> <x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">Закомітити зміни скасування</x:String>
<x:String x:Key="Text.Reword" xml:space="preserve">Змінити повідомлення коміту</x:String> <x:String x:Key="Text.Reword" xml:space="preserve">Змінити повідомлення коміту</x:String>
<x:String x:Key="Text.Reword.Tip" xml:space="preserve">Використовуйте 'Shift+Enter' для введення нового рядка. 'Enter' - гаряча клавіша кнопки OK</x:String>
<x:String x:Key="Text.Running" xml:space="preserve">Виконується. Будь ласка, зачекайте...</x:String> <x:String x:Key="Text.Running" xml:space="preserve">Виконується. Будь ласка, зачекайте...</x:String>
<x:String x:Key="Text.Save" xml:space="preserve">ЗБЕРЕГТИ</x:String> <x:String x:Key="Text.Save" xml:space="preserve">ЗБЕРЕГТИ</x:String>
<x:String x:Key="Text.SaveAs" xml:space="preserve">Зберегти як...</x:String> <x:String x:Key="Text.SaveAs" xml:space="preserve">Зберегти як...</x:String>
@ -649,10 +649,7 @@
<x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Шлях до сховища приватного ключа SSH</x:String> <x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Шлях до сховища приватного ключа SSH</x:String>
<x:String x:Key="Text.Start" xml:space="preserve">ПОЧАТИ</x:String> <x:String x:Key="Text.Start" xml:space="preserve">ПОЧАТИ</x:String>
<x:String x:Key="Text.Stash" xml:space="preserve">Stash (Сховати)</x:String> <x:String x:Key="Text.Stash" xml:space="preserve">Stash (Сховати)</x:String>
<x:String x:Key="Text.Stash.AutoRestore" xml:space="preserve">Автоматично відновити після схову</x:String>
<x:String x:Key="Text.Stash.AutoRestore.Tip" xml:space="preserve">Ваші робочі файли залишаться без змін, але буде збережено схованку.</x:String>
<x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">Включити невідстежувані файли</x:String> <x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">Включити невідстежувані файли</x:String>
<x:String x:Key="Text.Stash.KeepIndex" xml:space="preserve">Зберегти проіндексовані файли</x:String>
<x:String x:Key="Text.Stash.Message" xml:space="preserve">Повідомлення:</x:String> <x:String x:Key="Text.Stash.Message" xml:space="preserve">Повідомлення:</x:String>
<x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">Необов'язково. Назва цієї схованки</x:String> <x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">Необов'язково. Назва цієї схованки</x:String>
<x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">Лише проіндексовані зміни</x:String> <x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">Лише проіндексовані зміни</x:String>
@ -714,7 +711,6 @@
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Ігнорувати всі файли *{0}</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Ігнорувати всі файли *{0}</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Ігнорувати файли *{0} у цій же теці</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Ігнорувати файли *{0} у цій же теці</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">Ігнорувати файли у цій же теці</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ігнорувати лише цей файл</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ігнорувати лише цей файл</x:String>
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Amend (Доповнити)</x:String> <x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Amend (Доповнити)</x:String>
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Тепер ви можете проіндексувати цей файл.</x:String> <x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Тепер ви можете проіндексувати цей файл.</x:String>

View file

@ -124,6 +124,7 @@
<x:String x:Key="Text.CommitCM.InteractiveRebase" xml:space="preserve">交互式变基(rebase -i) ${0}$ 到此处</x:String> <x:String x:Key="Text.CommitCM.InteractiveRebase" xml:space="preserve">交互式变基(rebase -i) ${0}$ 到此处</x:String>
<x:String x:Key="Text.CommitCM.Merge" xml:space="preserve">合并(merge)此提交至 ${0}$</x:String> <x:String x:Key="Text.CommitCM.Merge" xml:space="preserve">合并(merge)此提交至 ${0}$</x:String>
<x:String x:Key="Text.CommitCM.MergeMultiple" xml:space="preserve">合并(merge)...</x:String> <x:String x:Key="Text.CommitCM.MergeMultiple" xml:space="preserve">合并(merge)...</x:String>
<x:String x:Key="Text.CommitCM.PushRevision" xml:space="preserve">推送(push) ${0}$ 到 ${1}$</x:String>
<x:String x:Key="Text.CommitCM.Rebase" xml:space="preserve">变基(rebase) ${0}$ 到此处</x:String> <x:String x:Key="Text.CommitCM.Rebase" xml:space="preserve">变基(rebase) ${0}$ 到此处</x:String>
<x:String x:Key="Text.CommitCM.Reset" xml:space="preserve">重置(reset) ${0}$ 到此处</x:String> <x:String x:Key="Text.CommitCM.Reset" xml:space="preserve">重置(reset) ${0}$ 到此处</x:String>
<x:String x:Key="Text.CommitCM.Revert" xml:space="preserve">回滚此提交</x:String> <x:String x:Key="Text.CommitCM.Revert" xml:space="preserve">回滚此提交</x:String>
@ -446,6 +447,7 @@
<x:String x:Key="Text.Launcher.Workspaces" xml:space="preserve">工作区列表</x:String> <x:String x:Key="Text.Launcher.Workspaces" xml:space="preserve">工作区列表</x:String>
<x:String x:Key="Text.Launcher.Pages" xml:space="preserve">页面列表</x:String> <x:String x:Key="Text.Launcher.Pages" xml:space="preserve">页面列表</x:String>
<x:String x:Key="Text.Merge" xml:space="preserve">合并分支</x:String> <x:String x:Key="Text.Merge" xml:space="preserve">合并分支</x:String>
<x:String x:Key="Text.Merge.Edit" xml:space="preserve">编辑合并信息</x:String>
<x:String x:Key="Text.Merge.Into" xml:space="preserve">目标分支 </x:String> <x:String x:Key="Text.Merge.Into" xml:space="preserve">目标分支 </x:String>
<x:String x:Key="Text.Merge.Mode" xml:space="preserve">合并方式 </x:String> <x:String x:Key="Text.Merge.Mode" xml:space="preserve">合并方式 </x:String>
<x:String x:Key="Text.Merge.Source" xml:space="preserve">合并目标 </x:String> <x:String x:Key="Text.Merge.Source" xml:space="preserve">合并目标 </x:String>
@ -478,6 +480,7 @@
<x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">{0}个月前</x:String> <x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">{0}个月前</x:String>
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0}年前</x:String> <x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0}年前</x:String>
<x:String x:Key="Text.Period.Yesterday" xml:space="preserve">昨天</x:String> <x:String x:Key="Text.Period.Yesterday" xml:space="preserve">昨天</x:String>
<x:String x:Key="Text.PopupEnterKeyTip" xml:space="preserve">请使用Shift+Enter换行。Enter键已被【确 定】按钮占用。</x:String>
<x:String x:Key="Text.Preferences" xml:space="preserve">偏好设置</x:String> <x:String x:Key="Text.Preferences" xml:space="preserve">偏好设置</x:String>
<x:String x:Key="Text.Preferences.AI" xml:space="preserve">AI</x:String> <x:String x:Key="Text.Preferences.AI" xml:space="preserve">AI</x:String>
<x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">Analyze Diff Prompt</x:String> <x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">Analyze Diff Prompt</x:String>
@ -556,6 +559,8 @@
<x:String x:Key="Text.Push.Force" xml:space="preserve">启用强制推送</x:String> <x:String x:Key="Text.Push.Force" xml:space="preserve">启用强制推送</x:String>
<x:String x:Key="Text.Push.Local" xml:space="preserve">本地分支 </x:String> <x:String x:Key="Text.Push.Local" xml:space="preserve">本地分支 </x:String>
<x:String x:Key="Text.Push.Remote" xml:space="preserve">远程仓库 </x:String> <x:String x:Key="Text.Push.Remote" xml:space="preserve">远程仓库 </x:String>
<x:String x:Key="Text.Push.Revision" xml:space="preserve">修订 </x:String>
<x:String x:Key="Text.Push.Revision.Title" xml:space="preserve">推送指定修订到远程仓库</x:String>
<x:String x:Key="Text.Push.Title" xml:space="preserve">推送到远程仓库</x:String> <x:String x:Key="Text.Push.Title" xml:space="preserve">推送到远程仓库</x:String>
<x:String x:Key="Text.Push.To" xml:space="preserve">远程分支 </x:String> <x:String x:Key="Text.Push.To" xml:space="preserve">远程分支 </x:String>
<x:String x:Key="Text.Push.Tracking" xml:space="preserve">跟踪远程分支</x:String> <x:String x:Key="Text.Push.Tracking" xml:space="preserve">跟踪远程分支</x:String>
@ -666,7 +671,6 @@
<x:String x:Key="Text.Revert.Commit" xml:space="preserve">目标提交 </x:String> <x:String x:Key="Text.Revert.Commit" xml:space="preserve">目标提交 </x:String>
<x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">回滚后提交更改</x:String> <x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">回滚后提交更改</x:String>
<x:String x:Key="Text.Reword" xml:space="preserve">编辑提交信息</x:String> <x:String x:Key="Text.Reword" xml:space="preserve">编辑提交信息</x:String>
<x:String x:Key="Text.Reword.Tip" xml:space="preserve">请使用Shift+Enter换行。Enter键已被【确 定】按钮占用。</x:String>
<x:String x:Key="Text.Running" xml:space="preserve">执行操作中,请耐心等待...</x:String> <x:String x:Key="Text.Running" xml:space="preserve">执行操作中,请耐心等待...</x:String>
<x:String x:Key="Text.Save" xml:space="preserve">保 存</x:String> <x:String x:Key="Text.Save" xml:space="preserve">保 存</x:String>
<x:String x:Key="Text.SaveAs" xml:space="preserve">另存为...</x:String> <x:String x:Key="Text.SaveAs" xml:space="preserve">另存为...</x:String>
@ -692,16 +696,15 @@
<x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">SSH密钥文件</x:String> <x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">SSH密钥文件</x:String>
<x:String x:Key="Text.Start" xml:space="preserve">开 始</x:String> <x:String x:Key="Text.Start" xml:space="preserve">开 始</x:String>
<x:String x:Key="Text.Stash" xml:space="preserve">贮藏(stash)</x:String> <x:String x:Key="Text.Stash" xml:space="preserve">贮藏(stash)</x:String>
<x:String x:Key="Text.Stash.AutoRestore" xml:space="preserve">贮藏后自动恢复工作区</x:String>
<x:String x:Key="Text.Stash.AutoRestore.Tip" xml:space="preserve">工作区文件保持未修改状态,但贮藏内容已保存。</x:String>
<x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">包含未跟踪的文件</x:String> <x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">包含未跟踪的文件</x:String>
<x:String x:Key="Text.Stash.KeepIndex" xml:space="preserve">保留暂存区文件</x:String>
<x:String x:Key="Text.Stash.Message" xml:space="preserve">信息 </x:String> <x:String x:Key="Text.Stash.Message" xml:space="preserve">信息 </x:String>
<x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">选填,用于命名此贮藏</x:String> <x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">选填,此贮藏的描述信息</x:String>
<x:String x:Key="Text.Stash.Mode" xml:space="preserve">模式 </x:String>
<x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">仅贮藏暂存区的变更</x:String> <x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">仅贮藏暂存区的变更</x:String>
<x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">选中文件的所有变更均会被贮藏!</x:String> <x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">选中文件的所有变更均会被贮藏!</x:String>
<x:String x:Key="Text.Stash.Title" xml:space="preserve">贮藏本地变更</x:String> <x:String x:Key="Text.Stash.Title" xml:space="preserve">贮藏本地变更</x:String>
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">应用(apply)</x:String> <x:String x:Key="Text.StashCM.Apply" xml:space="preserve">应用(apply)</x:String>
<x:String x:Key="Text.StashCM.CopyMessage" xml:space="preserve">复制描述信息</x:String>
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">删除(drop)</x:String> <x:String x:Key="Text.StashCM.Drop" xml:space="preserve">删除(drop)</x:String>
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">另存为补丁...</x:String> <x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">另存为补丁...</x:String>
<x:String x:Key="Text.StashDropConfirm" xml:space="preserve">丢弃贮藏确认</x:String> <x:String x:Key="Text.StashDropConfirm" xml:space="preserve">丢弃贮藏确认</x:String>
@ -768,7 +771,7 @@
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">添加至 .gitignore 忽略列表</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">添加至 .gitignore 忽略列表</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">忽略所有 *{0} 文件</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">忽略所有 *{0} 文件</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">忽略同目录下所有 *{0} 文件</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">忽略同目录下所有 *{0} 文件</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">忽略同目录下所有文件</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InFolder" xml:space="preserve">忽略该目录下的新文件</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">忽略本文件</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">忽略本文件</x:String>
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">修补</x:String> <x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">修补</x:String>
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">现在您已可将其加入暂存区中</x:String> <x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">现在您已可将其加入暂存区中</x:String>

View file

@ -124,6 +124,7 @@
<x:String x:Key="Text.CommitCM.InteractiveRebase" xml:space="preserve">互動式重定基底 (rebase -i) ${0}$ 到此處</x:String> <x:String x:Key="Text.CommitCM.InteractiveRebase" xml:space="preserve">互動式重定基底 (rebase -i) ${0}$ 到此處</x:String>
<x:String x:Key="Text.CommitCM.Merge" xml:space="preserve">合併 (merge) 此提交到 ${0}$</x:String> <x:String x:Key="Text.CommitCM.Merge" xml:space="preserve">合併 (merge) 此提交到 ${0}$</x:String>
<x:String x:Key="Text.CommitCM.MergeMultiple" xml:space="preserve">合併 (merge)...</x:String> <x:String x:Key="Text.CommitCM.MergeMultiple" xml:space="preserve">合併 (merge)...</x:String>
<x:String x:Key="Text.CommitCM.PushRevision" xml:space="preserve">推送(push) ${0}$ 至 ${1}$</x:String>
<x:String x:Key="Text.CommitCM.Rebase" xml:space="preserve">重定基底 (rebase) ${0}$ 到此處</x:String> <x:String x:Key="Text.CommitCM.Rebase" xml:space="preserve">重定基底 (rebase) ${0}$ 到此處</x:String>
<x:String x:Key="Text.CommitCM.Reset" xml:space="preserve">重設 (reset) ${0}$ 到此處</x:String> <x:String x:Key="Text.CommitCM.Reset" xml:space="preserve">重設 (reset) ${0}$ 到此處</x:String>
<x:String x:Key="Text.CommitCM.Revert" xml:space="preserve">復原此提交</x:String> <x:String x:Key="Text.CommitCM.Revert" xml:space="preserve">復原此提交</x:String>
@ -446,6 +447,7 @@
<x:String x:Key="Text.Launcher.Workspaces" xml:space="preserve">工作區列表</x:String> <x:String x:Key="Text.Launcher.Workspaces" xml:space="preserve">工作區列表</x:String>
<x:String x:Key="Text.Launcher.Pages" xml:space="preserve">頁面列表</x:String> <x:String x:Key="Text.Launcher.Pages" xml:space="preserve">頁面列表</x:String>
<x:String x:Key="Text.Merge" xml:space="preserve">合併分支</x:String> <x:String x:Key="Text.Merge" xml:space="preserve">合併分支</x:String>
<x:String x:Key="Text.Merge.Edit" xml:space="preserve">編輯合併訊息</x:String>
<x:String x:Key="Text.Merge.Into" xml:space="preserve">目標分支:</x:String> <x:String x:Key="Text.Merge.Into" xml:space="preserve">目標分支:</x:String>
<x:String x:Key="Text.Merge.Mode" xml:space="preserve">合併方式:</x:String> <x:String x:Key="Text.Merge.Mode" xml:space="preserve">合併方式:</x:String>
<x:String x:Key="Text.Merge.Source" xml:space="preserve">合併來源:</x:String> <x:String x:Key="Text.Merge.Source" xml:space="preserve">合併來源:</x:String>
@ -478,6 +480,7 @@
<x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">{0} 個月前</x:String> <x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">{0} 個月前</x:String>
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} 年前</x:String> <x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} 年前</x:String>
<x:String x:Key="Text.Period.Yesterday" xml:space="preserve">昨天</x:String> <x:String x:Key="Text.Period.Yesterday" xml:space="preserve">昨天</x:String>
<x:String x:Key="Text.PopupEnterKeyTip" xml:space="preserve">請使用 Shift + Enter 換行。Enter 鍵已被 [確定] 按鈕佔用。</x:String>
<x:String x:Key="Text.Preferences" xml:space="preserve">偏好設定</x:String> <x:String x:Key="Text.Preferences" xml:space="preserve">偏好設定</x:String>
<x:String x:Key="Text.Preferences.AI" xml:space="preserve">AI</x:String> <x:String x:Key="Text.Preferences.AI" xml:space="preserve">AI</x:String>
<x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">分析變更差異提示詞</x:String> <x:String x:Key="Text.Preferences.AI.AnalyzeDiffPrompt" xml:space="preserve">分析變更差異提示詞</x:String>
@ -556,6 +559,8 @@
<x:String x:Key="Text.Push.Force" xml:space="preserve">啟用強制推送</x:String> <x:String x:Key="Text.Push.Force" xml:space="preserve">啟用強制推送</x:String>
<x:String x:Key="Text.Push.Local" xml:space="preserve">本機分支:</x:String> <x:String x:Key="Text.Push.Local" xml:space="preserve">本機分支:</x:String>
<x:String x:Key="Text.Push.Remote" xml:space="preserve">遠端存放庫:</x:String> <x:String x:Key="Text.Push.Remote" xml:space="preserve">遠端存放庫:</x:String>
<x:String x:Key="Text.Push.Revision" xml:space="preserve">修訂:</x:String>
<x:String x:Key="Text.Push.Revision.Title" xml:space="preserve">推送修訂到遠端存放庫</x:String>
<x:String x:Key="Text.Push.Title" xml:space="preserve">推送到遠端存放庫</x:String> <x:String x:Key="Text.Push.Title" xml:space="preserve">推送到遠端存放庫</x:String>
<x:String x:Key="Text.Push.To" xml:space="preserve">遠端分支:</x:String> <x:String x:Key="Text.Push.To" xml:space="preserve">遠端分支:</x:String>
<x:String x:Key="Text.Push.Tracking" xml:space="preserve">追蹤遠端分支</x:String> <x:String x:Key="Text.Push.Tracking" xml:space="preserve">追蹤遠端分支</x:String>
@ -666,7 +671,6 @@
<x:String x:Key="Text.Revert.Commit" xml:space="preserve">目標提交:</x:String> <x:String x:Key="Text.Revert.Commit" xml:space="preserve">目標提交:</x:String>
<x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">復原後提交變更</x:String> <x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">復原後提交變更</x:String>
<x:String x:Key="Text.Reword" xml:space="preserve">編輯提交訊息</x:String> <x:String x:Key="Text.Reword" xml:space="preserve">編輯提交訊息</x:String>
<x:String x:Key="Text.Reword.Tip" xml:space="preserve">請使用 Shift + Enter 換行。Enter 鍵已被 [確定] 按鈕佔用。</x:String>
<x:String x:Key="Text.Running" xml:space="preserve">執行操作中,請耐心等待...</x:String> <x:String x:Key="Text.Running" xml:space="preserve">執行操作中,請耐心等待...</x:String>
<x:String x:Key="Text.Save" xml:space="preserve">儲存</x:String> <x:String x:Key="Text.Save" xml:space="preserve">儲存</x:String>
<x:String x:Key="Text.SaveAs" xml:space="preserve">另存新檔...</x:String> <x:String x:Key="Text.SaveAs" xml:space="preserve">另存新檔...</x:String>
@ -692,16 +696,15 @@
<x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">SSH 金鑰檔案</x:String> <x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">SSH 金鑰檔案</x:String>
<x:String x:Key="Text.Start" xml:space="preserve">開 始</x:String> <x:String x:Key="Text.Start" xml:space="preserve">開 始</x:String>
<x:String x:Key="Text.Stash" xml:space="preserve">擱置變更 (stash)</x:String> <x:String x:Key="Text.Stash" xml:space="preserve">擱置變更 (stash)</x:String>
<x:String x:Key="Text.Stash.AutoRestore" xml:space="preserve">擱置變更後自動復原工作區</x:String>
<x:String x:Key="Text.Stash.AutoRestore.Tip" xml:space="preserve">工作區檔案保持未修改,但擱置內容已儲存。</x:String>
<x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">包含未追蹤的檔案</x:String> <x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">包含未追蹤的檔案</x:String>
<x:String x:Key="Text.Stash.KeepIndex" xml:space="preserve">保留已暫存的變更</x:String>
<x:String x:Key="Text.Stash.Message" xml:space="preserve">擱置變更訊息:</x:String> <x:String x:Key="Text.Stash.Message" xml:space="preserve">擱置變更訊息:</x:String>
<x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">選填,用於命名此擱置變更</x:String> <x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">選填,用於描述此擱置變更</x:String>
<x:String x:Key="Text.Stash.Mode" xml:space="preserve">操作模式:</x:String>
<x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">僅擱置已暫存的變更</x:String> <x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">僅擱置已暫存的變更</x:String>
<x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">已選取的檔案中的變更均會被擱置!</x:String> <x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">已選取的檔案中的變更均會被擱置!</x:String>
<x:String x:Key="Text.Stash.Title" xml:space="preserve">擱置本機變更</x:String> <x:String x:Key="Text.Stash.Title" xml:space="preserve">擱置本機變更</x:String>
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">套用 (apply)</x:String> <x:String x:Key="Text.StashCM.Apply" xml:space="preserve">套用 (apply)</x:String>
<x:String x:Key="Text.StashCM.CopyMessage" xml:space="preserve">複製描述訊息</x:String>
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">刪除 (drop)</x:String> <x:String x:Key="Text.StashCM.Drop" xml:space="preserve">刪除 (drop)</x:String>
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">另存為修補檔 (patch)...</x:String> <x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">另存為修補檔 (patch)...</x:String>
<x:String x:Key="Text.StashDropConfirm" xml:space="preserve">捨棄擱置變更確認</x:String> <x:String x:Key="Text.StashDropConfirm" xml:space="preserve">捨棄擱置變更確認</x:String>
@ -768,7 +771,7 @@
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">加入至 .gitignore 忽略清單</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">加入至 .gitignore 忽略清單</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">忽略所有 *{0} 檔案</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">忽略所有 *{0} 檔案</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">忽略同路徑下所有 *{0} 檔案</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">忽略同路徑下所有 *{0} 檔案</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">忽略同路徑下所有檔案</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InFolder" xml:space="preserve">忽略本路徑下的新增檔案</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">忽略本檔案</x:String> <x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">忽略本檔案</x:String>
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">修補</x:String> <x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">修補</x:String>
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">現在您已可將其加入暫存區中</x:String> <x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">現在您已可將其加入暫存區中</x:String>

View file

@ -529,13 +529,7 @@
<Setter Property="MinHeight" Value="24"/> <Setter Property="MinHeight" Value="24"/>
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Grid> <Grid ColumnDefinitions="*,1,Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="1" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button x:Name="PART_PrimaryButton" <Button x:Name="PART_PrimaryButton"
Grid.Column="0" Grid.Column="0"
Classes="flat primary" Classes="flat primary"
@ -1001,12 +995,7 @@
<Setter Property="VerticalAlignment" Value="Center"/> <Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Grid Background="Transparent"> <Grid Background="Transparent" ColumnDefinitions="Auto,*">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border x:Name="Border" Grid.Column="0" Width="16" Height="16" VerticalAlignment="Center" BorderBrush="{DynamicResource Brush.Border1}" BorderThickness="1" Background="Transparent" CornerRadius="2"> <Border x:Name="Border" Grid.Column="0" Width="16" Height="16" VerticalAlignment="Center" BorderBrush="{DynamicResource Brush.Border1}" BorderThickness="1" Background="Transparent" CornerRadius="2">
<Path x:Name="Icon" Height="12" Width="12" Data="{DynamicResource Icons.Check}" Fill="{DynamicResource Brush.Accent}" IsVisible="False" Margin="0,2,0,0"/> <Path x:Name="Icon" Height="12" Width="12" Data="{DynamicResource Icons.Check}" Fill="{DynamicResource Brush.Accent}" IsVisible="False" Margin="0,2,0,0"/>
</Border> </Border>

View file

@ -118,7 +118,7 @@ namespace SourceGit.ViewModels
public ContextMenu CreateChangeContextMenu() public ContextMenu CreateChangeContextMenu()
{ {
if (_selectedChanges == null || _selectedChanges.Count != 1) if (_selectedChanges is not { Count: 1 })
return null; return null;
var change = _selectedChanges[0]; var change = _selectedChanges[0];

View file

@ -74,9 +74,9 @@ namespace SourceGit.ViewModels
public class Builder public class Builder
{ {
public List<BranchTreeNode> Locals => _locals; public List<BranchTreeNode> Locals { get; } = [];
public List<BranchTreeNode> Remotes => _remotes; public List<BranchTreeNode> Remotes { get; } = [];
public List<string> InvalidExpandedNodes => _invalidExpandedNodes; public List<string> InvalidExpandedNodes { get; } = [];
public Builder(Models.BranchSortMode localSortMode, Models.BranchSortMode remoteSortMode) public Builder(Models.BranchSortMode localSortMode, Models.BranchSortMode remoteSortMode)
{ {
@ -109,14 +109,14 @@ namespace SourceGit.ViewModels
fakeRemoteTime--; fakeRemoteTime--;
folders.Add(path, node); folders.Add(path, node);
_remotes.Add(node); Remotes.Add(node);
} }
foreach (var branch in branches) foreach (var branch in branches)
{ {
if (branch.IsLocal) if (branch.IsLocal)
{ {
MakeBranchNode(branch, _locals, folders, "refs/heads", bForceExpanded); MakeBranchNode(branch, Locals, folders, "refs/heads", bForceExpanded);
continue; continue;
} }
@ -131,20 +131,20 @@ namespace SourceGit.ViewModels
foreach (var path in _expanded) foreach (var path in _expanded)
{ {
if (!folders.ContainsKey(path)) if (!folders.ContainsKey(path))
_invalidExpandedNodes.Add(path); InvalidExpandedNodes.Add(path);
} }
folders.Clear(); folders.Clear();
if (_localSortMode == Models.BranchSortMode.Name) if (_localSortMode == Models.BranchSortMode.Name)
SortNodesByName(_locals); SortNodesByName(Locals);
else else
SortNodesByTime(_locals); SortNodesByTime(Locals);
if (_remoteSortMode == Models.BranchSortMode.Name) if (_remoteSortMode == Models.BranchSortMode.Name)
SortNodesByName(_remotes); SortNodesByName(Remotes);
else else
SortNodesByTime(_remotes); SortNodesByTime(Remotes);
} }
private void MakeBranchNode(Models.Branch branch, List<BranchTreeNode> roots, Dictionary<string, BranchTreeNode> folders, string prefix, bool bForceExpanded) private void MakeBranchNode(Models.Branch branch, List<BranchTreeNode> roots, Dictionary<string, BranchTreeNode> folders, string prefix, bool bForceExpanded)
@ -269,9 +269,6 @@ namespace SourceGit.ViewModels
private readonly Models.BranchSortMode _localSortMode = Models.BranchSortMode.Name; private readonly Models.BranchSortMode _localSortMode = Models.BranchSortMode.Name;
private readonly Models.BranchSortMode _remoteSortMode = Models.BranchSortMode.Name; private readonly Models.BranchSortMode _remoteSortMode = Models.BranchSortMode.Name;
private readonly List<BranchTreeNode> _locals = new List<BranchTreeNode>();
private readonly List<BranchTreeNode> _remotes = new List<BranchTreeNode>();
private readonly List<string> _invalidExpandedNodes = new List<string>();
private readonly HashSet<string> _expanded = new HashSet<string>(); private readonly HashSet<string> _expanded = new HashSet<string>();
} }
} }

View file

@ -81,7 +81,7 @@ namespace SourceGit.ViewModels
{ {
if (SetProperty(ref _selectedChanges, value)) if (SetProperty(ref _selectedChanges, value))
{ {
if (value == null || value.Count != 1) if (value is not { Count: 1 })
DiffContext = null; DiffContext = null;
else else
DiffContext = new DiffContext(_repo.FullPath, new Models.DiffOption(_commit, value[0]), _diffContext); DiffContext = new DiffContext(_repo.FullPath, new Models.DiffOption(_commit, value[0]), _diffContext);
@ -133,6 +133,12 @@ namespace SourceGit.ViewModels
private set => SetProperty(ref _revisionFileSearchSuggestion, value); private set => SetProperty(ref _revisionFileSearchSuggestion, value);
} }
public bool CanOpenRevisionFileWithDefaultEditor
{
get => _canOpenRevisionFileWithDefaultEditor;
private set => SetProperty(ref _canOpenRevisionFileWithDefaultEditor, value);
}
public CommitDetail(Repository repo) public CommitDetail(Repository repo)
{ {
_repo = repo; _repo = repo;
@ -197,6 +203,7 @@ namespace SourceGit.ViewModels
{ {
ViewRevisionFilePath = string.Empty; ViewRevisionFilePath = string.Empty;
ViewRevisionFileContent = null; ViewRevisionFileContent = null;
CanOpenRevisionFileWithDefaultEditor = false;
return; return;
} }
@ -205,6 +212,7 @@ namespace SourceGit.ViewModels
switch (file.Type) switch (file.Type)
{ {
case Models.ObjectType.Blob: case Models.ObjectType.Blob:
CanOpenRevisionFileWithDefaultEditor = true;
Task.Run(() => Task.Run(() =>
{ {
var isBinary = new Commands.IsBinary(_repo.FullPath, _commit.SHA, file.Path).Result(); var isBinary = new Commands.IsBinary(_repo.FullPath, _commit.SHA, file.Path).Result();
@ -252,6 +260,7 @@ namespace SourceGit.ViewModels
}); });
break; break;
case Models.ObjectType.Commit: case Models.ObjectType.Commit:
CanOpenRevisionFileWithDefaultEditor = false;
Task.Run(() => Task.Run(() =>
{ {
var submoduleRoot = Path.Combine(_repo.FullPath, file.Path).Replace('\\', '/').Trim('/'); var submoduleRoot = Path.Combine(_repo.FullPath, file.Path).Replace('\\', '/').Trim('/');
@ -267,11 +276,26 @@ namespace SourceGit.ViewModels
}); });
break; break;
default: default:
CanOpenRevisionFileWithDefaultEditor = false;
ViewRevisionFileContent = null; ViewRevisionFileContent = null;
break; break;
} }
} }
public Task OpenRevisionFileWithDefaultEditor(string file)
{
return Task.Run(() =>
{
var fullPath = Native.OS.GetAbsPath(_repo.FullPath, file);
var fileName = Path.GetFileNameWithoutExtension(fullPath) ?? "";
var fileExt = Path.GetExtension(fullPath) ?? "";
var tmpFile = Path.Combine(Path.GetTempPath(), $"{fileName}~{_commit.SHA.Substring(0, 10)}{fileExt}");
Commands.SaveRevisionFile.Run(_repo.FullPath, _commit.SHA, file, tmpFile);
Native.OS.OpenWithDefaultEditor(tmpFile);
});
}
public ContextMenu CreateChangeContextMenu(Models.Change change) public ContextMenu CreateChangeContextMenu(Models.Change change)
{ {
var diffWithMerger = new MenuItem(); var diffWithMerger = new MenuItem();
@ -421,13 +445,10 @@ namespace SourceGit.ViewModels
var openWith = new MenuItem(); var openWith = new MenuItem();
openWith.Header = App.Text("OpenWith"); openWith.Header = App.Text("OpenWith");
openWith.Icon = App.CreateMenuIcon("Icons.OpenWith"); openWith.Icon = App.CreateMenuIcon("Icons.OpenWith");
openWith.IsEnabled = file.Type == Models.ObjectType.Blob;
openWith.Click += async (_, ev) => openWith.Click += async (_, ev) =>
{ {
var fileName = Path.GetFileNameWithoutExtension(fullPath) ?? ""; await OpenRevisionFileWithDefaultEditor(file.Path);
var fileExt = Path.GetExtension(fullPath) ?? "";
var tmpFile = Path.Combine(Path.GetTempPath(), $"{fileName}~{_commit.SHA.Substring(0, 10)}{fileExt}");
await Task.Run(() => Commands.SaveRevisionFile.Run(_repo.FullPath, _commit.SHA, file.Path, tmpFile));
Native.OS.OpenWithDefaultEditor(tmpFile);
ev.Handled = true; ev.Handled = true;
}; };
@ -549,6 +570,8 @@ namespace SourceGit.ViewModels
SignInfo = null; SignInfo = null;
ViewRevisionFileContent = null; ViewRevisionFileContent = null;
ViewRevisionFilePath = string.Empty;
CanOpenRevisionFileWithDefaultEditor = false;
Children = null; Children = null;
RevisionFileSearchFilter = string.Empty; RevisionFileSearchFilter = string.Empty;
RevisionFileSearchSuggestion = null; RevisionFileSearchSuggestion = null;
@ -887,5 +910,6 @@ namespace SourceGit.ViewModels
private List<string> _revisionFiles = null; private List<string> _revisionFiles = null;
private string _revisionFileSearchFilter = string.Empty; private string _revisionFileSearchFilter = string.Empty;
private List<string> _revisionFileSearchSuggestion = null; private List<string> _revisionFileSearchSuggestion = null;
private bool _canOpenRevisionFileWithDefaultEditor = false;
} }
} }

View file

@ -46,10 +46,7 @@ namespace SourceGit.ViewModels
else if (!string.IsNullOrEmpty(_repo.Settings.DefaultRemote)) else if (!string.IsNullOrEmpty(_repo.Settings.DefaultRemote))
{ {
var def = _repo.Remotes.Find(r => r.Name == _repo.Settings.DefaultRemote); var def = _repo.Remotes.Find(r => r.Name == _repo.Settings.DefaultRemote);
if (def != null) SelectedRemote = def ?? _repo.Remotes[0];
SelectedRemote = def;
else
SelectedRemote = _repo.Remotes[0];
} }
else else
{ {

View file

@ -9,10 +9,11 @@ using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.ViewModels namespace SourceGit.ViewModels
{ {
public class FileHistoriesRevisionFile(string path, object content) public class FileHistoriesRevisionFile(string path, object content = null, bool canOpenWithDefaultEditor = false)
{ {
public string Path { get; set; } = path; public string Path { get; set; } = path;
public object Content { get; set; } = content; public object Content { get; set; } = content;
public bool CanOpenWithDefaultEditor { get; set; } = canOpenWithDefaultEditor;
} }
public class FileHistoriesSingleRevision : ObservableObject public class FileHistoriesSingleRevision : ObservableObject
@ -49,6 +50,23 @@ namespace SourceGit.ViewModels
return Task.Run(() => new Commands.Checkout(_repo.FullPath).FileWithRevision(_file, $"{_revision.SHA}")); return Task.Run(() => new Commands.Checkout(_repo.FullPath).FileWithRevision(_file, $"{_revision.SHA}"));
} }
public Task OpenWithDefaultEditor()
{
if (_viewContent is not FileHistoriesRevisionFile { CanOpenWithDefaultEditor: true })
return null;
return Task.Run(() =>
{
var fullPath = Native.OS.GetAbsPath(_repo.FullPath, _file);
var fileName = Path.GetFileNameWithoutExtension(fullPath) ?? "";
var fileExt = Path.GetExtension(fullPath) ?? "";
var tmpFile = Path.Combine(Path.GetTempPath(), $"{fileName}~{_revision.SHA.Substring(0, 10)}{fileExt}");
Commands.SaveRevisionFile.Run(_repo.FullPath, _revision.SHA, _file, tmpFile);
Native.OS.OpenWithDefaultEditor(tmpFile);
});
}
private void RefreshViewContent() private void RefreshViewContent()
{ {
if (_isDiffMode) if (_isDiffMode)
@ -62,7 +80,7 @@ namespace SourceGit.ViewModels
var objs = new Commands.QueryRevisionObjects(_repo.FullPath, _revision.SHA, _file).Result(); var objs = new Commands.QueryRevisionObjects(_repo.FullPath, _revision.SHA, _file).Result();
if (objs.Count == 0) if (objs.Count == 0)
{ {
ViewContent = new FileHistoriesRevisionFile(_file, null); ViewContent = new FileHistoriesRevisionFile(_file);
return; return;
} }
@ -80,13 +98,13 @@ namespace SourceGit.ViewModels
{ {
var source = ImageSource.FromRevision(_repo.FullPath, _revision.SHA, _file, imgDecoder); var source = ImageSource.FromRevision(_repo.FullPath, _revision.SHA, _file, imgDecoder);
var image = new Models.RevisionImageFile(_file, source.Bitmap, source.Size); var image = new Models.RevisionImageFile(_file, source.Bitmap, source.Size);
Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, image)); Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, image, true));
} }
else else
{ {
var size = new Commands.QueryFileSize(_repo.FullPath, _file, _revision.SHA).Result(); var size = new Commands.QueryFileSize(_repo.FullPath, _file, _revision.SHA).Result();
var binaryFile = new Models.RevisionBinaryFile() { Size = size }; var binaryFile = new Models.RevisionBinaryFile() { Size = size };
Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, binaryFile)); Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, binaryFile, true));
} }
return; return;
@ -101,18 +119,18 @@ namespace SourceGit.ViewModels
if (imgDecoder != Models.ImageDecoder.None) if (imgDecoder != Models.ImageDecoder.None)
{ {
var combined = new RevisionLFSImage(_repo.FullPath, _file, lfs, imgDecoder); var combined = new RevisionLFSImage(_repo.FullPath, _file, lfs, imgDecoder);
Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, combined)); Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, combined, true));
} }
else else
{ {
var rlfs = new Models.RevisionLFSObject() { Object = lfs }; var rlfs = new Models.RevisionLFSObject() { Object = lfs };
Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, rlfs)); Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, rlfs, true));
} }
} }
else else
{ {
var txt = new Models.RevisionTextFile() { FileName = obj.Path, Content = content }; var txt = new Models.RevisionTextFile() { FileName = obj.Path, Content = content };
Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, txt)); Dispatcher.UIThread.Invoke(() => ViewContent = new FileHistoriesRevisionFile(_file, txt, true));
} }
}); });
break; break;
@ -132,7 +150,7 @@ namespace SourceGit.ViewModels
}); });
break; break;
default: default:
ViewContent = new FileHistoriesRevisionFile(_file, null); ViewContent = new FileHistoriesRevisionFile(_file);
break; break;
} }
} }

View file

@ -14,11 +14,6 @@ namespace SourceGit.ViewModels
{ {
public class Histories : ObservableObject, IDisposable public class Histories : ObservableObject, IDisposable
{ {
public Repository Repo
{
get => _repo;
}
public bool IsLoading public bool IsLoading
{ {
get => _isLoading; get => _isLoading;
@ -214,9 +209,56 @@ namespace SourceGit.ViewModels
} }
} }
public void DoubleTapped(Models.Commit commit) public bool CheckoutBranchByDecorator(Models.Decorator decorator)
{ {
if (commit == null || commit.IsCurrentHead) if (decorator == null)
return false;
if (decorator.Type == Models.DecoratorType.CurrentBranchHead ||
decorator.Type == Models.DecoratorType.CurrentCommitHead)
return true;
if (decorator.Type == Models.DecoratorType.LocalBranchHead)
{
var b = _repo.Branches.Find(x => x.Name == decorator.Name);
if (b == null)
return false;
_repo.CheckoutBranch(b);
return true;
}
if (decorator.Type == Models.DecoratorType.RemoteBranchHead)
{
var rb = _repo.Branches.Find(x => x.FriendlyName == decorator.Name);
if (rb == null)
return false;
var lb = _repo.Branches.Find(x => x.IsLocal && x.Upstream == rb.FullName);
if (lb == null || lb.TrackStatus.Ahead.Count > 0)
{
if (_repo.CanCreatePopup())
_repo.ShowPopup(new CreateBranch(_repo, rb));
}
else if (lb.TrackStatus.Behind.Count > 0)
{
if (_repo.CanCreatePopup())
_repo.ShowPopup(new CheckoutAndFastForward(_repo, lb, rb));
}
else if (!lb.IsCurrent)
{
_repo.CheckoutBranch(lb);
}
return true;
}
return false;
}
public void CheckoutBranchByCommit(Models.Commit commit)
{
if (commit.IsCurrentHead)
return; return;
var firstRemoteBranch = null as Models.Branch; var firstRemoteBranch = null as Models.Branch;
@ -224,29 +266,28 @@ namespace SourceGit.ViewModels
{ {
if (d.Type == Models.DecoratorType.LocalBranchHead) if (d.Type == Models.DecoratorType.LocalBranchHead)
{ {
var b = _repo.Branches.Find(x => x.FriendlyName == d.Name); var b = _repo.Branches.Find(x => x.Name == d.Name);
if (b != null) if (b == null)
{ continue;
_repo.CheckoutBranch(b);
return; _repo.CheckoutBranch(b);
} return;
} }
else if (d.Type == Models.DecoratorType.RemoteBranchHead) else if (d.Type == Models.DecoratorType.RemoteBranchHead)
{ {
var remoteBranch = _repo.Branches.Find(x => x.FriendlyName == d.Name); var rb = _repo.Branches.Find(x => x.FriendlyName == d.Name);
if (remoteBranch != null) if (rb == null)
continue;
var lb = _repo.Branches.Find(x => x.IsLocal && x.Upstream == rb.FullName);
if (lb is { TrackStatus.Ahead.Count: 0 })
{ {
var localBranch = _repo.Branches.Find(x => x.IsLocal && x.Upstream == remoteBranch.FullName); if (_repo.CanCreatePopup())
if (localBranch is { TrackStatus.Ahead.Count: 0 }) _repo.ShowPopup(new CheckoutAndFastForward(_repo, lb, rb));
{ return;
if (_repo.CanCreatePopup())
_repo.ShowPopup(new CheckoutAndFastForward(_repo, localBranch, remoteBranch));
return;
}
} }
if (firstRemoteBranch == null) firstRemoteBranch ??= rb;
firstRemoteBranch = remoteBranch;
} }
} }
@ -560,9 +601,7 @@ namespace SourceGit.ViewModels
var parents = new List<Models.Commit>(); var parents = new List<Models.Commit>();
foreach (var sha in commit.Parents) foreach (var sha in commit.Parents)
{ {
var parent = _commits.Find(x => x.SHA == sha); var parent = _commits.Find(x => x.SHA == sha) ?? new Commands.QuerySingleCommit(_repo.FullPath, sha).Result();
if (parent == null)
parent = new Commands.QuerySingleCommit(_repo.FullPath, sha).Result();
if (parent != null) if (parent != null)
parents.Add(parent); parents.Add(parent);
@ -627,6 +666,22 @@ namespace SourceGit.ViewModels
if (current.Head != commit.SHA) if (current.Head != commit.SHA)
{ {
if (current.TrackStatus.Ahead.Contains(commit.SHA))
{
var upstream = _repo.Branches.Find(x => x.FullName.Equals(current.Upstream, StringComparison.Ordinal));
var pushRevision = new MenuItem();
pushRevision.Header = App.Text("CommitCM.PushRevision", commit.SHA.Substring(0, 10), upstream.FriendlyName);
pushRevision.Icon = App.CreateMenuIcon("Icons.Push");
pushRevision.Click += (_, e) =>
{
if (_repo.CanCreatePopup())
_repo.ShowPopup(new PushRevision(_repo, commit, upstream));
e.Handled = true;
};
menu.Items.Add(pushRevision);
menu.Items.Add(new MenuItem() { Header = "-" });
}
var compareWithHead = new MenuItem(); var compareWithHead = new MenuItem();
compareWithHead.Header = App.Text("CommitCM.CompareWithHead"); compareWithHead.Header = App.Text("CommitCM.CompareWithHead");
compareWithHead.Icon = App.CreateMenuIcon("Icons.Compare"); compareWithHead.Icon = App.CreateMenuIcon("Icons.Compare");

View file

@ -89,7 +89,7 @@ namespace SourceGit.ViewModels
catch (Exception e) catch (Exception e)
{ {
Console.Out.WriteLine(e.Message); Console.Out.WriteLine(e.Message);
} }
} }
return new ImageSource(null, 0); return new ImageSource(null, 0);
@ -154,7 +154,7 @@ namespace SourceGit.ViewModels
return new ImageSource(bitmap, size); return new ImageSource(bitmap, size);
} }
} }
private static ImageSource DecodeWithTiff(Stream stream, long size) private static ImageSource DecodeWithTiff(Stream stream, long size)
{ {
using (var tiff = Tiff.ClientOpen($"{Guid.NewGuid()}.tif", "r", stream, new TiffStream())) using (var tiff = Tiff.ClientOpen($"{Guid.NewGuid()}.tif", "r", stream, new TiffStream()))
@ -166,7 +166,7 @@ namespace SourceGit.ViewModels
var height = tiff.GetField(TiffTag.IMAGELENGTH)[0].ToInt(); var height = tiff.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
var pixels = new int[width * height]; var pixels = new int[width * height];
// Currently only supports image when its `BITSPERSAMPLE` is one in [1,2,4,8,16] // Currently only supports image when its `BITSPERSAMPLE` is one in [1,2,4,8,16]
tiff.ReadRGBAImageOriented(width, height, pixels, Orientation.TOPLEFT); tiff.ReadRGBAImageOriented(width, height, pixels, Orientation.TOPLEFT);
var ptr = Marshal.UnsafeAddrOfPinnedArrayElement(pixels, 0); var ptr = Marshal.UnsafeAddrOfPinnedArrayElement(pixels, 0);

View file

@ -65,17 +65,14 @@ namespace SourceGit.ViewModels
var repos = ActiveWorkspace.Repositories.ToArray(); var repos = ActiveWorkspace.Repositories.ToArray();
foreach (var repo in repos) foreach (var repo in repos)
{ {
var node = pref.FindNode(repo); var node = pref.FindNode(repo) ??
if (node == null) new RepositoryNode
{
node = new RepositoryNode()
{ {
Id = repo, Id = repo,
Name = Path.GetFileName(repo), Name = Path.GetFileName(repo),
Bookmark = 0, Bookmark = 0,
IsRepository = true, IsRepository = true,
}; };
}
OpenRepositoryInTab(node, null); OpenRepositoryInTab(node, null);
} }
@ -184,17 +181,14 @@ namespace SourceGit.ViewModels
var repos = to.Repositories.ToArray(); var repos = to.Repositories.ToArray();
foreach (var repo in repos) foreach (var repo in repos)
{ {
var node = pref.FindNode(repo); var node = pref.FindNode(repo) ??
if (node == null) new RepositoryNode
{
node = new RepositoryNode()
{ {
Id = repo, Id = repo,
Name = Path.GetFileName(repo), Name = Path.GetFileName(repo),
Bookmark = 0, Bookmark = 0,
IsRepository = true, IsRepository = true,
}; };
}
OpenRepositoryInTab(node, null); OpenRepositoryInTab(node, null);
} }
@ -290,8 +284,7 @@ namespace SourceGit.ViewModels
return; return;
} }
if (page == null) page ??= _activePage;
page = _activePage;
var removeIdx = Pages.IndexOf(page); var removeIdx = Pages.IndexOf(page);
var activeIdx = Pages.IndexOf(_activePage); var activeIdx = Pages.IndexOf(_activePage);

View file

@ -87,7 +87,7 @@ namespace SourceGit.ViewModels
public bool CanCreatePopup() public bool CanCreatePopup()
{ {
return _popup == null || !_popup.InProgress; return _popup is not { InProgress: true };
} }
public void StartPopup(Popup popup) public void StartPopup(Popup popup)

View file

@ -21,6 +21,12 @@ namespace SourceGit.ViewModels
set; set;
} }
public bool Edit
{
get;
set;
} = false;
public Merge(Repository repo, Models.Branch source, string into, bool forceFastForward) public Merge(Repository repo, Models.Branch source, string into, bool forceFastForward)
{ {
_repo = repo; _repo = repo;
@ -62,7 +68,7 @@ namespace SourceGit.ViewModels
return Task.Run(() => return Task.Run(() =>
{ {
new Commands.Merge(_repo.FullPath, _sourceName, Mode.Arg).Use(log).Exec(); new Commands.Merge(_repo.FullPath, _sourceName, Mode.Arg, Edit).Use(log).Exec();
log.Complete(); log.Complete();
var head = new Commands.QueryRevisionByRefName(_repo.FullPath, "HEAD").Result(); var head = new Commands.QueryRevisionByRefName(_repo.FullPath, "HEAD").Result();

View file

@ -7,7 +7,7 @@ namespace SourceGit.ViewModels
public class Pull : Popup public class Pull : Popup
{ {
public List<Models.Remote> Remotes => _repo.Remotes; public List<Models.Remote> Remotes => _repo.Remotes;
public Models.Branch Current => _current; public Models.Branch Current { get; }
public bool HasSpecifiedRemoteBranch public bool HasSpecifiedRemoteBranch
{ {
@ -64,7 +64,7 @@ namespace SourceGit.ViewModels
public Pull(Repository repo, Models.Branch specifiedRemoteBranch) public Pull(Repository repo, Models.Branch specifiedRemoteBranch)
{ {
_repo = repo; _repo = repo;
_current = repo.CurrentBranch; Current = repo.CurrentBranch;
if (specifiedRemoteBranch != null) if (specifiedRemoteBranch != null)
{ {
@ -84,12 +84,12 @@ namespace SourceGit.ViewModels
else else
{ {
var autoSelectedRemote = null as Models.Remote; var autoSelectedRemote = null as Models.Remote;
if (!string.IsNullOrEmpty(_current.Upstream)) if (!string.IsNullOrEmpty(Current.Upstream))
{ {
var remoteNameEndIdx = _current.Upstream.IndexOf('/', 13); var remoteNameEndIdx = Current.Upstream.IndexOf('/', 13);
if (remoteNameEndIdx > 0) if (remoteNameEndIdx > 0)
{ {
var remoteName = _current.Upstream.Substring(13, remoteNameEndIdx - 13); var remoteName = Current.Upstream.Substring(13, remoteNameEndIdx - 13);
autoSelectedRemote = _repo.Remotes.Find(x => x.Name == remoteName); autoSelectedRemote = _repo.Remotes.Find(x => x.Name == remoteName);
} }
} }
@ -146,7 +146,7 @@ namespace SourceGit.ViewModels
bool rs = new Commands.Pull( bool rs = new Commands.Pull(
_repo.FullPath, _repo.FullPath,
_selectedRemote.Name, _selectedRemote.Name,
!string.IsNullOrEmpty(_current.Upstream) && _current.Upstream.Equals(_selectedBranch.FullName) ? string.Empty : _selectedBranch.Name, !string.IsNullOrEmpty(Current.Upstream) && Current.Upstream.Equals(_selectedBranch.FullName) ? string.Empty : _selectedBranch.Name,
UseRebase).Use(log).Exec(); UseRebase).Use(log).Exec();
if (rs) if (rs)
@ -188,12 +188,12 @@ namespace SourceGit.ViewModels
RemoteBranches = branches; RemoteBranches = branches;
var autoSelectedBranch = false; var autoSelectedBranch = false;
if (!string.IsNullOrEmpty(_current.Upstream) && if (!string.IsNullOrEmpty(Current.Upstream) &&
_current.Upstream.StartsWith($"refs/remotes/{remoteName}/", System.StringComparison.Ordinal)) Current.Upstream.StartsWith($"refs/remotes/{remoteName}/", System.StringComparison.Ordinal))
{ {
foreach (var branch in branches) foreach (var branch in branches)
{ {
if (_current.Upstream == branch.FullName) if (Current.Upstream == branch.FullName)
{ {
SelectedBranch = branch; SelectedBranch = branch;
autoSelectedBranch = true; autoSelectedBranch = true;
@ -206,7 +206,7 @@ namespace SourceGit.ViewModels
{ {
foreach (var branch in branches) foreach (var branch in branches)
{ {
if (_current.Name == branch.Name) if (Current.Name == branch.Name)
{ {
SelectedBranch = branch; SelectedBranch = branch;
autoSelectedBranch = true; autoSelectedBranch = true;
@ -220,7 +220,6 @@ namespace SourceGit.ViewModels
} }
private readonly Repository _repo = null; private readonly Repository _repo = null;
private readonly Models.Branch _current = null;
private Models.Remote _selectedRemote = null; private Models.Remote _selectedRemote = null;
private List<Models.Branch> _remoteBranches = null; private List<Models.Branch> _remoteBranches = null;
private Models.Branch _selectedBranch = null; private Models.Branch _selectedBranch = null;

View file

@ -0,0 +1,59 @@
using System.Threading.Tasks;
namespace SourceGit.ViewModels
{
public class PushRevision : Popup
{
public Models.Commit Revision
{
get;
}
public Models.Branch RemoteBranch
{
get;
}
public bool Force
{
get;
set;
}
public PushRevision(Repository repo, Models.Commit revision, Models.Branch remoteBranch)
{
_repo = repo;
Revision = revision;
RemoteBranch = remoteBranch;
Force = false;
}
public override Task<bool> Sure()
{
_repo.SetWatcherEnabled(false);
ProgressDescription = $"Push {Revision.SHA.Substring(0, 10)} -> {RemoteBranch.FriendlyName} ...";
var log = _repo.CreateLog("Push Revision");
Use(log);
return Task.Run(() =>
{
var succ = new Commands.Push(
_repo.FullPath,
Revision.SHA,
RemoteBranch.Remote,
RemoteBranch.Name,
false,
false,
false,
Force).Use(log).Exec();
log.Complete();
CallUIThread(() => _repo.SetWatcherEnabled(true));
return succ;
});
}
private readonly Repository _repo;
}
}

View file

@ -172,7 +172,7 @@ namespace SourceGit.ViewModels
private set private set
{ {
var oldHead = _currentBranch?.Head; var oldHead = _currentBranch?.Head;
if (SetProperty(ref _currentBranch, value)) if (SetProperty(ref _currentBranch, value) && value != null)
{ {
if (oldHead != _currentBranch.Head && _workingCopy is { UseAmend: true }) if (oldHead != _currentBranch.Head && _workingCopy is { UseAmend: true })
_workingCopy.UseAmend = false; _workingCopy.UseAmend = false;
@ -1090,6 +1090,7 @@ namespace SourceGit.ViewModels
var succ = new Commands.Bisect(_fullpath, subcmd).Use(log).Exec(); var succ = new Commands.Bisect(_fullpath, subcmd).Use(log).Exec();
log.Complete(); log.Complete();
var head = new Commands.QueryRevisionByRefName(_fullpath, "HEAD").Result();
Dispatcher.UIThread.Invoke(() => Dispatcher.UIThread.Invoke(() =>
{ {
if (!succ) if (!succ)
@ -1098,6 +1099,7 @@ namespace SourceGit.ViewModels
App.SendNotification(_fullpath, log.Content.Substring(log.Content.IndexOf('\n')).Trim()); App.SendNotification(_fullpath, log.Content.Substring(log.Content.IndexOf('\n')).Trim());
MarkBranchesDirtyManually(); MarkBranchesDirtyManually();
NavigateToCommit(head, true);
SetWatcherEnabled(true); SetWatcherEnabled(true);
IsBisectCommandRunning = false; IsBisectCommandRunning = false;
}); });
@ -1424,17 +1426,14 @@ namespace SourceGit.ViewModels
var root = Path.GetFullPath(Path.Combine(_fullpath, submodule)); var root = Path.GetFullPath(Path.Combine(_fullpath, submodule));
var normalizedPath = root.Replace('\\', '/').TrimEnd('/'); var normalizedPath = root.Replace('\\', '/').TrimEnd('/');
var node = Preferences.Instance.FindNode(normalizedPath); var node = Preferences.Instance.FindNode(normalizedPath) ??
if (node == null) new RepositoryNode
{
node = new RepositoryNode()
{ {
Id = normalizedPath, Id = normalizedPath,
Name = Path.GetFileName(normalizedPath), Name = Path.GetFileName(normalizedPath),
Bookmark = selfPage.Node.Bookmark, Bookmark = selfPage.Node.Bookmark,
IsRepository = true, IsRepository = true,
}; };
}
App.GetLauncher().OpenRepositoryInTab(node, null); App.GetLauncher().OpenRepositoryInTab(node, null);
} }
@ -1453,17 +1452,14 @@ namespace SourceGit.ViewModels
public void OpenWorktree(Models.Worktree worktree) public void OpenWorktree(Models.Worktree worktree)
{ {
var node = Preferences.Instance.FindNode(worktree.FullPath); var node = Preferences.Instance.FindNode(worktree.FullPath) ??
if (node == null) new RepositoryNode
{
node = new RepositoryNode()
{ {
Id = worktree.FullPath, Id = worktree.FullPath,
Name = Path.GetFileName(worktree.FullPath), Name = Path.GetFileName(worktree.FullPath),
Bookmark = 0, Bookmark = 0,
IsRepository = true, IsRepository = true,
}; };
}
App.GetLauncher()?.OpenRepositoryInTab(node, null); App.GetLauncher()?.OpenRepositoryInTab(node, null);
} }
@ -2244,7 +2240,7 @@ namespace SourceGit.ViewModels
} }
var compareWithHead = new MenuItem(); var compareWithHead = new MenuItem();
compareWithHead.Header = App.Text("BranchCM.CompareWithHead"); compareWithHead.Header = App.Text("BranchCM.CompareWithCurrent", _currentBranch.Name);
compareWithHead.Icon = App.CreateMenuIcon("Icons.Compare"); compareWithHead.Icon = App.CreateMenuIcon("Icons.Compare");
compareWithHead.Click += (_, _) => compareWithHead.Click += (_, _) =>
{ {

View file

@ -24,10 +24,7 @@ namespace SourceGit.ViewModels
private set => SetProperty(ref _endPoint, value); private set => SetProperty(ref _endPoint, value);
} }
public bool CanSaveAsPatch public bool CanSaveAsPatch { get; }
{
get => _canSaveAsPatch;
}
public List<Models.Change> VisibleChanges public List<Models.Change> VisibleChanges
{ {
@ -78,7 +75,7 @@ namespace SourceGit.ViewModels
_repo = repo; _repo = repo;
_startPoint = (object)startPoint ?? new Models.Null(); _startPoint = (object)startPoint ?? new Models.Null();
_endPoint = (object)endPoint ?? new Models.Null(); _endPoint = (object)endPoint ?? new Models.Null();
_canSaveAsPatch = startPoint != null && endPoint != null; CanSaveAsPatch = startPoint != null && endPoint != null;
Task.Run(Refresh); Task.Run(Refresh);
} }
@ -138,7 +135,7 @@ namespace SourceGit.ViewModels
public ContextMenu CreateChangeContextMenu() public ContextMenu CreateChangeContextMenu()
{ {
if (_selectedChanges == null || _selectedChanges.Count != 1) if (_selectedChanges is not { Count: 1 })
return null; return null;
var change = _selectedChanges[0]; var change = _selectedChanges[0];
@ -244,7 +241,6 @@ namespace SourceGit.ViewModels
private string _repo; private string _repo;
private object _startPoint = null; private object _startPoint = null;
private object _endPoint = null; private object _endPoint = null;
private bool _canSaveAsPatch = false;
private List<Models.Change> _changes = null; private List<Models.Change> _changes = null;
private List<Models.Change> _visibleChanges = null; private List<Models.Change> _visibleChanges = null;
private List<Models.Change> _selectedChanges = null; private List<Models.Change> _selectedChanges = null;

View file

@ -27,19 +27,20 @@ namespace SourceGit.ViewModels
public bool OnlyStaged public bool OnlyStaged
{ {
get => _repo.Settings.OnlyStagedWhenStash; get => _repo.Settings.OnlyStagedWhenStash;
set => _repo.Settings.OnlyStagedWhenStash = value; set
{
if (_repo.Settings.OnlyStagedWhenStash != value)
{
_repo.Settings.OnlyStagedWhenStash = value;
OnPropertyChanged();
}
}
} }
public bool KeepIndex public int ChangesAfterStashing
{ {
get => _repo.Settings.KeepIndexWhenStash; get => _repo.Settings.ChangesAfterStashing;
set => _repo.Settings.KeepIndexWhenStash = value; set => _repo.Settings.ChangesAfterStashing = value;
}
public bool AutoRestore
{
get => _repo.Settings.AutoRestoreAfterStash;
set => _repo.Settings.AutoRestoreAfterStash = value;
} }
public StashChanges(Repository repo, List<Models.Change> changes, bool hasSelectedFiles) public StashChanges(Repository repo, List<Models.Change> changes, bool hasSelectedFiles)
@ -59,6 +60,8 @@ namespace SourceGit.ViewModels
return Task.Run(() => return Task.Run(() =>
{ {
var mode = (DealWithChangesAfterStashing)ChangesAfterStashing;
var keepIndex = mode == DealWithChangesAfterStashing.KeepIndex;
var succ = false; var succ = false;
if (!HasSelectedFiles) if (!HasSelectedFiles)
@ -67,7 +70,7 @@ namespace SourceGit.ViewModels
{ {
if (Native.OS.GitVersion >= Models.GitVersions.STASH_PUSH_ONLY_STAGED) if (Native.OS.GitVersion >= Models.GitVersions.STASH_PUSH_ONLY_STAGED)
{ {
succ = new Commands.Stash(_repo.FullPath).Use(log).PushOnlyStaged(Message, KeepIndex); succ = new Commands.Stash(_repo.FullPath).Use(log).PushOnlyStaged(Message, keepIndex);
} }
else else
{ {
@ -78,20 +81,20 @@ namespace SourceGit.ViewModels
staged.Add(c); staged.Add(c);
} }
succ = StashWithChanges(staged, log); succ = StashWithChanges(staged, keepIndex, log);
} }
} }
else else
{ {
succ = new Commands.Stash(_repo.FullPath).Use(log).Push(Message, IncludeUntracked, KeepIndex); succ = new Commands.Stash(_repo.FullPath).Use(log).Push(Message, IncludeUntracked, keepIndex);
} }
} }
else else
{ {
succ = StashWithChanges(_changes, log); succ = StashWithChanges(_changes, keepIndex, log);
} }
if (AutoRestore && succ) if (mode == DealWithChangesAfterStashing.KeepAll && succ)
succ = new Commands.Stash(_repo.FullPath).Use(log).Apply("stash@{0}", true); succ = new Commands.Stash(_repo.FullPath).Use(log).Apply("stash@{0}", true);
log.Complete(); log.Complete();
@ -105,7 +108,7 @@ namespace SourceGit.ViewModels
}); });
} }
private bool StashWithChanges(List<Models.Change> changes, CommandLog log) private bool StashWithChanges(List<Models.Change> changes, bool keepIndex, CommandLog log)
{ {
if (changes.Count == 0) if (changes.Count == 0)
return true; return true;
@ -119,7 +122,7 @@ namespace SourceGit.ViewModels
var pathSpecFile = Path.GetTempFileName(); var pathSpecFile = Path.GetTempFileName();
File.WriteAllLines(pathSpecFile, paths); File.WriteAllLines(pathSpecFile, paths);
succ = new Commands.Stash(_repo.FullPath).Use(log).Push(Message, pathSpecFile, KeepIndex); succ = new Commands.Stash(_repo.FullPath).Use(log).Push(Message, pathSpecFile, keepIndex);
File.Delete(pathSpecFile); File.Delete(pathSpecFile);
} }
else else
@ -128,7 +131,7 @@ namespace SourceGit.ViewModels
{ {
var count = Math.Min(32, changes.Count - i); var count = Math.Min(32, changes.Count - i);
var step = changes.GetRange(i, count); var step = changes.GetRange(i, count);
succ = new Commands.Stash(_repo.FullPath).Use(log).Push(Message, step, KeepIndex); succ = new Commands.Stash(_repo.FullPath).Use(log).Push(Message, step, keepIndex);
if (!succ) if (!succ)
break; break;
} }
@ -137,6 +140,13 @@ namespace SourceGit.ViewModels
return succ; return succ;
} }
private enum DealWithChangesAfterStashing
{
Discard = 0,
KeepIndex,
KeepAll,
}
private readonly Repository _repo = null; private readonly Repository _repo = null;
private readonly List<Models.Change> _changes = null; private readonly List<Models.Change> _changes = null;
} }

View file

@ -142,6 +142,7 @@ namespace SourceGit.ViewModels
var apply = new MenuItem(); var apply = new MenuItem();
apply.Header = App.Text("StashCM.Apply"); apply.Header = App.Text("StashCM.Apply");
apply.Icon = App.CreateMenuIcon("Icons.CheckCircled");
apply.Click += (_, ev) => apply.Click += (_, ev) =>
{ {
if (_repo.CanCreatePopup()) if (_repo.CanCreatePopup())
@ -152,6 +153,7 @@ namespace SourceGit.ViewModels
var drop = new MenuItem(); var drop = new MenuItem();
drop.Header = App.Text("StashCM.Drop"); drop.Header = App.Text("StashCM.Drop");
drop.Icon = App.CreateMenuIcon("Icons.Clear");
drop.Click += (_, ev) => drop.Click += (_, ev) =>
{ {
if (_repo.CanCreatePopup()) if (_repo.CanCreatePopup())
@ -194,11 +196,22 @@ namespace SourceGit.ViewModels
e.Handled = true; e.Handled = true;
}; };
var copy = new MenuItem();
copy.Header = App.Text("StashCM.CopyMessage");
copy.Icon = App.CreateMenuIcon("Icons.Copy");
copy.Click += (_, ev) =>
{
App.CopyText(stash.Message);
ev.Handled = true;
};
var menu = new ContextMenu(); var menu = new ContextMenu();
menu.Items.Add(apply); menu.Items.Add(apply);
menu.Items.Add(drop); menu.Items.Add(drop);
menu.Items.Add(new MenuItem { Header = "-" }); menu.Items.Add(new MenuItem { Header = "-" });
menu.Items.Add(patch); menu.Items.Add(patch);
menu.Items.Add(new MenuItem { Header = "-" });
menu.Items.Add(copy);
return menu; return menu;
} }

View file

@ -11,7 +11,7 @@ namespace SourceGit.ViewModels
{ {
public class Welcome : ObservableObject public class Welcome : ObservableObject
{ {
public static Welcome Instance => _instance; public static Welcome Instance { get; } = new();
public AvaloniaList<RepositoryNode> Rows public AvaloniaList<RepositoryNode> Rows
{ {
@ -354,7 +354,6 @@ namespace SourceGit.ViewModels
} }
} }
private static Welcome _instance = new Welcome();
private string _searchFilter = string.Empty; private string _searchFilter = string.Empty;
} }
} }

View file

@ -581,7 +581,7 @@ namespace SourceGit.ViewModels
DoCommit(false, true); DoCommit(false, true);
} }
public ContextMenu CreateContextMenuForUnstagedChanges() public ContextMenu CreateContextMenuForUnstagedChanges(string selectedSingleFolder)
{ {
if (_selectedUnstaged == null || _selectedUnstaged.Count == 0) if (_selectedUnstaged == null || _selectedUnstaged.Count == 0)
return null; return null;
@ -761,52 +761,76 @@ namespace SourceGit.ViewModels
var hasExtra = false; var hasExtra = false;
if (change.WorkTree == Models.ChangeState.Untracked) if (change.WorkTree == Models.ChangeState.Untracked)
{ {
var isRooted = change.Path.IndexOf('/', StringComparison.Ordinal) <= 0;
var addToIgnore = new MenuItem(); var addToIgnore = new MenuItem();
addToIgnore.Header = App.Text("WorkingCopy.AddToGitIgnore"); addToIgnore.Header = App.Text("WorkingCopy.AddToGitIgnore");
addToIgnore.Icon = App.CreateMenuIcon("Icons.GitIgnore"); addToIgnore.Icon = App.CreateMenuIcon("Icons.GitIgnore");
var singleFile = new MenuItem(); if (!string.IsNullOrEmpty(selectedSingleFolder))
singleFile.Header = App.Text("WorkingCopy.AddToGitIgnore.SingleFile");
singleFile.Click += (_, e) =>
{ {
Commands.GitIgnore.Add(_repo.FullPath, change.Path); var ignoreFolder = new MenuItem();
e.Handled = true; ignoreFolder.Header = App.Text("WorkingCopy.AddToGitIgnore.InFolder");
}; ignoreFolder.Click += (_, e) =>
addToIgnore.Items.Add(singleFile);
var byParentFolder = new MenuItem();
byParentFolder.Header = App.Text("WorkingCopy.AddToGitIgnore.InSameFolder");
byParentFolder.IsVisible = !isRooted;
byParentFolder.Click += (_, e) =>
{
var dir = Path.GetDirectoryName(change.Path)!.Replace('\\', '/').TrimEnd('/');
Commands.GitIgnore.Add(_repo.FullPath, dir + "/");
e.Handled = true;
};
addToIgnore.Items.Add(byParentFolder);
if (!string.IsNullOrEmpty(extension))
{
var byExtension = new MenuItem();
byExtension.Header = App.Text("WorkingCopy.AddToGitIgnore.Extension", extension);
byExtension.Click += (_, e) =>
{ {
Commands.GitIgnore.Add(_repo.FullPath, $"*{extension}"); Commands.GitIgnore.Add(_repo.FullPath, $"{selectedSingleFolder}/");
e.Handled = true; e.Handled = true;
}; };
addToIgnore.Items.Add(byExtension); addToIgnore.Items.Add(ignoreFolder);
}
var byExtensionInSameFolder = new MenuItem(); else
byExtensionInSameFolder.Header = App.Text("WorkingCopy.AddToGitIgnore.ExtensionInSameFolder", extension); {
byExtensionInSameFolder.IsVisible = !isRooted; var isRooted = change.Path.IndexOf('/', StringComparison.Ordinal) <= 0;
byExtensionInSameFolder.Click += (_, e) => var singleFile = new MenuItem();
singleFile.Header = App.Text("WorkingCopy.AddToGitIgnore.SingleFile");
singleFile.Click += (_, e) =>
{ {
var dir = Path.GetDirectoryName(change.Path)!.Replace('\\', '/').TrimEnd('/'); Commands.GitIgnore.Add(_repo.FullPath, change.Path);
Commands.GitIgnore.Add(_repo.FullPath, $"{dir}/*{extension}");
e.Handled = true; e.Handled = true;
}; };
addToIgnore.Items.Add(byExtensionInSameFolder); addToIgnore.Items.Add(singleFile);
if (!string.IsNullOrEmpty(extension))
{
var byExtension = new MenuItem();
byExtension.Header = App.Text("WorkingCopy.AddToGitIgnore.Extension", extension);
byExtension.Click += (_, e) =>
{
Commands.GitIgnore.Add(_repo.FullPath, $"*{extension}");
e.Handled = true;
};
addToIgnore.Items.Add(byExtension);
var byExtensionInSameFolder = new MenuItem();
byExtensionInSameFolder.Header = App.Text("WorkingCopy.AddToGitIgnore.ExtensionInSameFolder", extension);
byExtensionInSameFolder.IsVisible = !isRooted;
byExtensionInSameFolder.Click += (_, e) =>
{
var dir = Path.GetDirectoryName(change.Path)!.Replace('\\', '/').TrimEnd('/');
Commands.GitIgnore.Add(_repo.FullPath, $"{dir}/*{extension}");
e.Handled = true;
};
addToIgnore.Items.Add(byExtensionInSameFolder);
}
}
menu.Items.Add(addToIgnore);
hasExtra = true;
}
else if (!string.IsNullOrEmpty(selectedSingleFolder))
{
var addToIgnore = new MenuItem();
addToIgnore.Header = App.Text("WorkingCopy.AddToGitIgnore");
addToIgnore.Icon = App.CreateMenuIcon("Icons.GitIgnore");
if (!string.IsNullOrEmpty(selectedSingleFolder))
{
var ignoreFolder = new MenuItem();
ignoreFolder.Header = App.Text("WorkingCopy.AddToGitIgnore.InFolder");
ignoreFolder.Click += (_, e) =>
{
Commands.GitIgnore.Add(_repo.FullPath, $"{selectedSingleFolder}/");
e.Handled = true;
};
addToIgnore.Items.Add(ignoreFolder);
} }
menu.Items.Add(addToIgnore); menu.Items.Add(addToIgnore);
@ -1028,6 +1052,22 @@ namespace SourceGit.ViewModels
return menu; return menu;
} }
if (!string.IsNullOrEmpty(selectedSingleFolder))
{
var dir = Path.Combine(_repo.FullPath, selectedSingleFolder);
var explore = new MenuItem();
explore.Header = App.Text("RevealFile");
explore.Icon = App.CreateMenuIcon("Icons.Explore");
explore.IsEnabled = Directory.Exists(dir);
explore.Click += (_, e) =>
{
Native.OS.OpenInFileManager(dir, true);
e.Handled = true;
};
menu.Items.Add(explore);
menu.Items.Add(new MenuItem() { Header = "-" });
}
var stage = new MenuItem(); var stage = new MenuItem();
stage.Header = App.Text("FileCM.StageMulti", _selectedUnstaged.Count); stage.Header = App.Text("FileCM.StageMulti", _selectedUnstaged.Count);
stage.Icon = App.CreateMenuIcon("Icons.File.Add"); stage.Icon = App.CreateMenuIcon("Icons.File.Add");
@ -1086,12 +1126,31 @@ namespace SourceGit.ViewModels
menu.Items.Add(discard); menu.Items.Add(discard);
menu.Items.Add(stash); menu.Items.Add(stash);
menu.Items.Add(patch); menu.Items.Add(patch);
if (!string.IsNullOrEmpty(selectedSingleFolder))
{
var ignoreFolder = new MenuItem();
ignoreFolder.Header = App.Text("WorkingCopy.AddToGitIgnore.InFolder");
ignoreFolder.Click += (_, e) =>
{
Commands.GitIgnore.Add(_repo.FullPath, $"{selectedSingleFolder}/");
e.Handled = true;
};
var addToIgnore = new MenuItem();
addToIgnore.Header = App.Text("WorkingCopy.AddToGitIgnore");
addToIgnore.Icon = App.CreateMenuIcon("Icons.GitIgnore");
addToIgnore.Items.Add(ignoreFolder);
menu.Items.Add(new MenuItem() { Header = "-" });
menu.Items.Add(addToIgnore);
}
} }
return menu; return menu;
} }
public ContextMenu CreateContextMenuForStagedChanges() public ContextMenu CreateContextMenuForStagedChanges(string selectedSingleFolder)
{ {
if (_selectedStaged == null || _selectedStaged.Count == 0) if (_selectedStaged == null || _selectedStaged.Count == 0)
return null; return null;
@ -1340,6 +1399,23 @@ namespace SourceGit.ViewModels
} }
else else
{ {
if (!string.IsNullOrEmpty(selectedSingleFolder))
{
var dir = Path.Combine(_repo.FullPath, selectedSingleFolder);
var explore = new MenuItem();
explore.IsEnabled = Directory.Exists(dir);
explore.Header = App.Text("RevealFile");
explore.Icon = App.CreateMenuIcon("Icons.Explore");
explore.Click += (_, e) =>
{
Native.OS.OpenInFileManager(dir, true);
e.Handled = true;
};
menu.Items.Add(explore);
menu.Items.Add(new MenuItem() { Header = "-" });
}
var unstage = new MenuItem(); var unstage = new MenuItem();
unstage.Header = App.Text("FileCM.UnstageMulti", _selectedStaged.Count); unstage.Header = App.Text("FileCM.UnstageMulti", _selectedStaged.Count);
unstage.Icon = App.CreateMenuIcon("Icons.File.Remove"); unstage.Icon = App.CreateMenuIcon("Icons.File.Remove");

View file

@ -26,7 +26,7 @@ namespace SourceGit.Views
{ {
var folder = selected[0]; var folder = selected[0];
var folderPath = folder is { Path: { IsAbsoluteUri: true } path } ? path.LocalPath : folder?.Path.ToString(); var folderPath = folder is { Path: { IsAbsoluteUri: true } path } ? path.LocalPath : folder?.Path.ToString();
TxtLocation.Text = folderPath; TxtLocation.Text = folderPath.TrimEnd(['\\', '/']);
} }
} }
catch (Exception exception) catch (Exception exception)

View file

@ -3,7 +3,6 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.ApplyStash" x:Class="SourceGit.Views.ApplyStash"
x:DataType="vm:ApplyStash"> x:DataType="vm:ApplyStash">
@ -16,14 +15,16 @@
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{DynamicResource Text.ApplyStash.Stash}"/> Text="{DynamicResource Text.ApplyStash.Stash}"/>
<StackPanel Grid.Row="0" Grid.Column="1" Orientation="Horizontal"> <Grid Grid.Row="0" Grid.Column="1" ColumnDefinitions="Auto,Auto,*">
<Path Width="12" Height="12" Margin="2,0,8,0" <Path Grid.Column="0"
Width="12" Height="12"
Margin="2,0,8,0"
HorizontalAlignment="Left" VerticalAlignment="Center" HorizontalAlignment="Left" VerticalAlignment="Center"
Data="{StaticResource Icons.Stashes}"/> Data="{StaticResource Icons.Stashes}"/>
<TextBlock VerticalAlignment="Center" Classes="primary" Text="{Binding Stash.SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange"/> <TextBlock Grid.Column="1" VerticalAlignment="Center" Classes="primary" Text="{Binding Stash.Name}" Foreground="DarkOrange"/>
<TextBlock VerticalAlignment="Center" Text="{Binding Stash.Message}" Margin="8,0,0,0"/> <TextBlock Grid.Column="2" VerticalAlignment="Center" Text="{Binding Stash.Subject}" TextTrimming="CharacterEllipsis" Margin="4,0,0,0"/>
</StackPanel> </Grid>
<CheckBox Grid.Row="1" Grid.Column="1" <CheckBox Grid.Row="1" Grid.Column="1"
Content="{DynamicResource Text.ApplyStash.RestoreIndex}" Content="{DynamicResource Text.ApplyStash.RestoreIndex}"

View file

@ -12,13 +12,7 @@
Icon="/App.ico" Icon="/App.ico"
Title="{DynamicResource Text.Blame}" Title="{DynamicResource Text.Blame}"
MinWidth="1280" MinHeight="720"> MinWidth="1280" MinHeight="720">
<Grid> <Grid RowDefinitions="Auto,24,*">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="24"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- TitleBar --> <!-- TitleBar -->
<Grid Grid.Row="0" Height="28" IsVisible="{Binding !#ThisControl.UseSystemWindowFrame}"> <Grid Grid.Row="0" Height="28" IsVisible="{Binding !#ThisControl.UseSystemWindowFrame}">
<!-- Bottom border --> <!-- Bottom border -->

View file

@ -306,7 +306,7 @@ namespace SourceGit.Views
return; return;
var view = TextArea.TextView; var view = TextArea.TextView;
if (view == null || !view.VisualLinesValid) if (view is not { VisualLinesValid: true })
return; return;
var color = (Color)this.FindResource("SystemAccentColor")!; var color = (Color)this.FindResource("SystemAccentColor")!;

View file

@ -13,13 +13,7 @@
Title="{DynamicResource Text.BranchCompare}" Title="{DynamicResource Text.BranchCompare}"
MinWidth="1280" MinHeight="720" MinWidth="1280" MinHeight="720"
WindowStartupLocation="CenterOwner"> WindowStartupLocation="CenterOwner">
<Grid> <Grid RowDefinitions="Auto,64,*">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="64"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- TitleBar --> <!-- TitleBar -->
<Grid Grid.Row="0" Height="28" IsVisible="{Binding !#ThisControl.UseSystemWindowFrame}"> <Grid Grid.Row="0" Height="28" IsVisible="{Binding !#ThisControl.UseSystemWindowFrame}">
<!-- Bottom border --> <!-- Bottom border -->

View file

@ -4,57 +4,24 @@ using System.Globalization;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Styling;
namespace SourceGit.Views namespace SourceGit.Views
{ {
public class ChangeStatusIcon : Control public class ChangeStatusIcon : Control
{ {
private static readonly string[] INDICATOR = ["?", "±", "T", "+", "", "➜", "❏", "★", "!"]; private static readonly string[] INDICATOR = ["?", "±", "T", "+", "", "➜", "❏", "★", "!"];
private static readonly IBrush[] BACKGROUNDS = [ private static readonly Color[] COLOR =
Brushes.Transparent, [
new LinearGradientBrush Colors.Transparent,
{ Colors.Goldenrod,
GradientStops = new GradientStops() { new GradientStop(Color.FromRgb(238, 160, 14), 0), new GradientStop(Color.FromRgb(228, 172, 67), 1) }, Colors.Goldenrod,
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative), Colors.LimeGreen,
EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative), Colors.Tomato,
}, Colors.Orchid,
new LinearGradientBrush Colors.Goldenrod,
{ Colors.LimeGreen,
GradientStops = new GradientStops() { new GradientStop(Color.FromRgb(238, 160, 14), 0), new GradientStop(Color.FromRgb(228, 172, 67), 1) }, Colors.OrangeRed,
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative),
},
new LinearGradientBrush
{
GradientStops = new GradientStops() { new GradientStop(Color.FromRgb(47, 185, 47), 0), new GradientStop(Color.FromRgb(75, 189, 75), 1) },
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative),
},
new LinearGradientBrush
{
GradientStops = new GradientStops() { new GradientStop(Colors.Tomato, 0), new GradientStop(Color.FromRgb(252, 165, 150), 1) },
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative),
},
new LinearGradientBrush
{
GradientStops = new GradientStops() { new GradientStop(Colors.Orchid, 0), new GradientStop(Color.FromRgb(248, 161, 245), 1) },
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative),
},
new LinearGradientBrush
{
GradientStops = new GradientStops() { new GradientStop(Color.FromRgb(238, 160, 14), 0), new GradientStop(Color.FromRgb(228, 172, 67), 1) },
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative),
},
new LinearGradientBrush
{
GradientStops = new GradientStops() { new GradientStop(Color.FromRgb(47, 185, 47), 0), new GradientStop(Color.FromRgb(75, 189, 75), 1) },
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative),
},
Brushes.OrangeRed,
]; ];
public static readonly StyledProperty<bool> IsUnstagedChangeProperty = public static readonly StyledProperty<bool> IsUnstagedChangeProperty =
@ -82,18 +49,20 @@ namespace SourceGit.Views
var typeface = new Typeface("fonts:SourceGit#JetBrains Mono"); var typeface = new Typeface("fonts:SourceGit#JetBrains Mono");
IBrush background; var idx = (int)(IsUnstagedChange ? Change.WorkTree : Change.Index);
string indicator; var indicator = INDICATOR[idx];
if (IsUnstagedChange) var color = COLOR[idx];
var hsl = color.ToHsl();
var color2 = ActualThemeVariant == ThemeVariant.Dark
? new HslColor(hsl.A, hsl.H, hsl.S, hsl.L - 0.1).ToRgb()
: new HslColor(hsl.A, hsl.H, hsl.S, hsl.L + 0.1).ToRgb();
var background = new LinearGradientBrush
{ {
background = BACKGROUNDS[(int)Change.WorkTree]; GradientStops = [new GradientStop(color, 0), new GradientStop(color2, 1)],
indicator = INDICATOR[(int)Change.WorkTree]; StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
} EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative),
else };
{
background = BACKGROUNDS[(int)Change.Index];
indicator = INDICATOR[(int)Change.Index];
}
var txt = new FormattedText( var txt = new FormattedText(
indicator, indicator,
@ -113,7 +82,9 @@ namespace SourceGit.Views
{ {
base.OnPropertyChanged(change); base.OnPropertyChanged(change);
if (change.Property == IsUnstagedChangeProperty || change.Property == ChangeProperty) if (change.Property == IsUnstagedChangeProperty ||
change.Property == ChangeProperty ||
(change.Property.Name == "ActualThemeVariant" && change.NewValue != null))
InvalidateVisual(); InvalidateVisual();
} }
} }

View file

@ -10,7 +10,7 @@ namespace SourceGit.Views
public class ColorPicker : Control public class ColorPicker : Control
{ {
public static readonly StyledProperty<uint> ValueProperty = public static readonly StyledProperty<uint> ValueProperty =
AvaloniaProperty.Register<ColorPicker, uint>(nameof(Value), 0); AvaloniaProperty.Register<ColorPicker, uint>(nameof(Value));
public uint Value public uint Value
{ {

View file

@ -11,7 +11,7 @@ namespace SourceGit.Views
public class CommandLogTime : TextBlock public class CommandLogTime : TextBlock
{ {
public static readonly StyledProperty<ViewModels.CommandLog> LogProperty = public static readonly StyledProperty<ViewModels.CommandLog> LogProperty =
AvaloniaProperty.Register<CommandLogTime, ViewModels.CommandLog>(nameof(Log), null); AvaloniaProperty.Register<CommandLogTime, ViewModels.CommandLog>(nameof(Log));
public ViewModels.CommandLog Log public ViewModels.CommandLog Log
{ {

View file

@ -58,7 +58,7 @@
<Run Text="{Binding IndexDesc, Mode=OneWay}" Foreground="Gray"/> <Run Text="{Binding IndexDesc, Mode=OneWay}" Foreground="Gray"/>
</TextBlock> </TextBlock>
</ToolTip.Tip> </ToolTip.Tip>
<v:ChangeStatusIcon Grid.Column="0" <v:ChangeStatusIcon Grid.Column="0"
Width="14" Height="14" Width="14" Height="14"
HorizontalAlignment="Left" HorizontalAlignment="Left"

View file

@ -4,7 +4,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.StandaloneCommitMessageEditor" x:Class="SourceGit.Views.CommitMessageEditor"
x:Name="ThisControl" x:Name="ThisControl"
Icon="/App.ico" Icon="/App.ico"
Title="{DynamicResource Text.CodeEditor}" Title="{DynamicResource Text.CodeEditor}"

View file

@ -0,0 +1,69 @@
using System;
using System.IO;
using Avalonia.Interactivity;
namespace SourceGit.Views
{
public partial class CommitMessageEditor : ChromelessWindow
{
public CommitMessageEditor()
{
InitializeComponent();
}
public void AsStandalone(string file)
{
_onSave = msg => File.WriteAllText(file, msg);
_shouldExitApp = true;
var content = File.ReadAllText(file).ReplaceLineEndings("\n").Trim();
var firstLineEnd = content.IndexOf('\n', StringComparison.Ordinal);
if (firstLineEnd == -1)
{
Editor.SubjectEditor.Text = content;
}
else
{
Editor.SubjectEditor.Text = content.Substring(0, firstLineEnd);
Editor.DescriptionEditor.Text = content.Substring(firstLineEnd + 1).Trim();
}
}
public void AsBuiltin(string msg, Action<string> onSave)
{
_onSave = onSave;
_shouldExitApp = false;
var firstLineEnd = msg.IndexOf('\n', StringComparison.Ordinal);
if (firstLineEnd == -1)
{
Editor.SubjectEditor.Text = msg;
}
else
{
Editor.SubjectEditor.Text = msg.Substring(0, firstLineEnd);
Editor.DescriptionEditor.Text = msg.Substring(firstLineEnd + 1).Trim();
}
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
if (_shouldExitApp)
App.Quit(_exitCode);
}
private void SaveAndClose(object _1, RoutedEventArgs _2)
{
_onSave?.Invoke(Editor.Text);
_exitCode = 0;
Close();
}
private Action<string> _onSave = null;
private bool _shouldExitApp = true;
private int _exitCode = -1;
}
}

View file

@ -57,7 +57,7 @@ namespace SourceGit.Views
} }
public static readonly StyledProperty<bool> ShowAdvancedOptionsProperty = public static readonly StyledProperty<bool> ShowAdvancedOptionsProperty =
AvaloniaProperty.Register<CommitMessageTextBox, bool>(nameof(ShowAdvancedOptions), false); AvaloniaProperty.Register<CommitMessageTextBox, bool>(nameof(ShowAdvancedOptions));
public static readonly StyledProperty<string> TextProperty = public static readonly StyledProperty<string> TextProperty =
AvaloniaProperty.Register<CommitMessageTextBox, string>(nameof(Text), string.Empty); AvaloniaProperty.Register<CommitMessageTextBox, string>(nameof(Text), string.Empty);
@ -182,7 +182,7 @@ namespace SourceGit.Views
{ {
var menu = vm.CreateContextMenuForCommitMessages(); var menu = vm.CreateContextMenuForCommitMessages();
menu.Placement = PlacementMode.TopEdgeAlignedLeft; menu.Placement = PlacementMode.TopEdgeAlignedLeft;
menu?.Open(button); menu.Open(button);
} }
e.Handled = true; e.Handled = true;
@ -201,7 +201,14 @@ namespace SourceGit.Views
private void OnOpenConventionalCommitHelper(object _, RoutedEventArgs e) private void OnOpenConventionalCommitHelper(object _, RoutedEventArgs e)
{ {
App.ShowWindow(new ViewModels.ConventionalCommitMessageBuilder(text => Text = text), true); var toplevel = TopLevel.GetTopLevel(this);
if (toplevel is Window owner)
{
var vm = new ViewModels.ConventionalCommitMessageBuilder(text => Text = text);
var builder = new ConventionalCommitMessageBuilder() { DataContext = vm };
builder.ShowDialog(owner);
}
e.Handled = true; e.Handled = true;
} }

View file

@ -17,6 +17,7 @@ namespace SourceGit.Views
public IBrush Brush { get; set; } = null; public IBrush Brush { get; set; } = null;
public bool IsHead { get; set; } = false; public bool IsHead { get; set; } = false;
public double Width { get; set; } = 0.0; public double Width { get; set; } = 0.0;
public Models.Decorator Decorator { get; set; } = null;
} }
public static readonly StyledProperty<FontFamily> FontFamilyProperty = public static readonly StyledProperty<FontFamily> FontFamilyProperty =
@ -93,6 +94,19 @@ namespace SourceGit.Views
ShowTagsProperty); ShowTagsProperty);
} }
public Models.Decorator DecoratorAt(Point point)
{
var x = 0.0;
foreach (var item in _items)
{
x += item.Width;
if (point.X < x)
return item.Decorator;
}
return null;
}
public override void Render(DrawingContext context) public override void Render(DrawingContext context)
{ {
if (_items.Count == 0) if (_items.Count == 0)
@ -198,7 +212,8 @@ namespace SourceGit.Views
{ {
Label = label, Label = label,
Brush = normalBG, Brush = normalBG,
IsHead = isHead IsHead = isHead,
Decorator = decorator,
}; };
StreamGeometry geo; StreamGeometry geo;

View file

@ -19,7 +19,7 @@ namespace SourceGit.Views
} }
public static readonly StyledProperty<int> DateTimeFormatProperty = public static readonly StyledProperty<int> DateTimeFormatProperty =
AvaloniaProperty.Register<CommitTimeTextBlock, int>(nameof(DateTimeFormat), 0); AvaloniaProperty.Register<CommitTimeTextBlock, int>(nameof(DateTimeFormat));
public int DateTimeFormat public int DateTimeFormat
{ {

View file

@ -112,7 +112,7 @@
</Grid> </Grid>
</Border> </Border>
<StackPanel Margin="0,8,0,0" Orientation="Horizontal" HorizontalAlignment="Center"> <StackPanel Margin="0,8,0,0" Orientation="Horizontal" HorizontalAlignment="Center">
<Button Classes="flat" Margin="0,0,0,0" Command="{Binding UseTheirs}"> <Button Classes="flat" Margin="0,0,0,0" Command="{Binding UseTheirs}">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<Path Width="12" Height="12" Data="{StaticResource Icons.Incoming}"/> <Path Width="12" Height="12" Data="{StaticResource Icons.Incoming}"/>

View file

@ -264,7 +264,7 @@
<Border Height="16" HorizontalAlignment="Center" Background="Red" CornerRadius="8" IsVisible="{Binding New, Converter={x:Static ObjectConverters.IsNull}}"> <Border Height="16" HorizontalAlignment="Center" Background="Red" CornerRadius="8" IsVisible="{Binding New, Converter={x:Static ObjectConverters.IsNull}}">
<TextBlock Classes="primary" Text="{DynamicResource Text.Diff.Submodule.Deleted}" Margin="8,0" FontSize="10" Foreground="White"/> <TextBlock Classes="primary" Text="{DynamicResource Text.Diff.Submodule.Deleted}" Margin="8,0" FontSize="10" Foreground="White"/>
</Border> </Border>
<Border Margin="0,8,0,0" IsVisible="{Binding Old, Converter={x:Static ObjectConverters.IsNotNull}}"> <Border Margin="0,8,0,0" IsVisible="{Binding Old, Converter={x:Static ObjectConverters.IsNotNull}}">
<ContentControl Content="{Binding Old}"> <ContentControl Content="{Binding Old}">
<ContentControl.DataTemplates> <ContentControl.DataTemplates>

View file

@ -3,7 +3,6 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
x:Class="SourceGit.Views.DropStash" x:Class="SourceGit.Views.DropStash"
x:DataType="vm:DropStash"> x:DataType="vm:DropStash">
@ -16,14 +15,16 @@
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0" Margin="0,0,8,0"
Text="{DynamicResource Text.StashDropConfirm.Label}"/> Text="{DynamicResource Text.StashDropConfirm.Label}"/>
<StackPanel Grid.Column="1" Orientation="Horizontal"> <Grid Grid.Column="1" ColumnDefinitions="Auto,Auto,*">
<Path Width="12" Height="12" Margin="0,0,8,0" <Path Grid.Column="0"
Width="12" Height="12"
Margin="0,0,8,0"
HorizontalAlignment="Left" VerticalAlignment="Center" HorizontalAlignment="Left" VerticalAlignment="Center"
Data="{StaticResource Icons.Stashes}"/> Data="{StaticResource Icons.Stashes}"/>
<TextBlock VerticalAlignment="Center" Classes="primary" Text="{Binding Stash.SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange"/> <TextBlock Grid.Column="1" VerticalAlignment="Center" Classes="primary" Text="{Binding Stash.Name}" Foreground="DarkOrange"/>
<TextBlock VerticalAlignment="Center" Text="{Binding Stash.Message}" Margin="8,0,0,0"/> <TextBlock Grid.Column="2" VerticalAlignment="Center" Text="{Binding Stash.Subject}" TextTrimming="CharacterEllipsis" Margin="4,0,0,0"/>
</StackPanel> </Grid>
</Grid> </Grid>
</StackPanel> </StackPanel>
</UserControl> </UserControl>

View file

@ -13,12 +13,7 @@
Icon="/App.ico" Icon="/App.ico"
Title="{DynamicResource Text.FileHistory}" Title="{DynamicResource Text.FileHistory}"
MinWidth="1280" MinHeight="720"> MinWidth="1280" MinHeight="720">
<Grid> <Grid RowDefinitions="Auto,*">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- TitleBar --> <!-- TitleBar -->
<Grid Grid.Row="0" Height="28" IsVisible="{Binding !#ThisControl.UseSystemWindowFrame}"> <Grid Grid.Row="0" Height="28" IsVisible="{Binding !#ThisControl.UseSystemWindowFrame}">
<!-- Bottom border --> <!-- Bottom border -->
@ -139,7 +134,7 @@
<Border Grid.Row="0" <Border Grid.Row="0"
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border2}"
Background="{DynamicResource Brush.Window}"> Background="{DynamicResource Brush.Window}">
<Grid ColumnDefinitions="Auto,*,Auto"> <Grid ColumnDefinitions="Auto,*,Auto,Auto">
<Path Grid.Column="0" Width="12" Height="12" Data="{StaticResource Icons.File}" Margin="8,0,0,0"/> <Path Grid.Column="0" Width="12" Height="12" Data="{StaticResource Icons.File}" Margin="8,0,0,0"/>
<TextBlock Grid.Column="1" <TextBlock Grid.Column="1"
Classes="primary" Classes="primary"
@ -161,6 +156,15 @@
</ToggleButton.IsVisible> </ToggleButton.IsVisible>
<Path Width="13" Height="13" Data="{StaticResource Icons.SyntaxHighlight}" Margin="0,3,0,0"/> <Path Width="13" Height="13" Data="{StaticResource Icons.SyntaxHighlight}" Margin="0,3,0,0"/>
</ToggleButton> </ToggleButton>
<Button Grid.Column="3"
Classes="icon_button"
Width="28"
Background="Transparent"
Click="OnOpenFileWithDefaultEditor"
IsVisible="{Binding CanOpenWithDefaultEditor, Mode=OneWay}"
ToolTip.Tip="{DynamicResource Text.OpenWith}">
<Path Width="12" Height="12" Data="{StaticResource Icons.OpenWith}"/>
</Button>
</Grid> </Grid>
</Border> </Border>

View file

@ -76,5 +76,13 @@ namespace SourceGit.Views
ToolTip.SetTip(border, vm.GetCommitFullMessage(commit)); ToolTip.SetTip(border, vm.GetCommitFullMessage(commit));
} }
} }
private async void OnOpenFileWithDefaultEditor(object sender, RoutedEventArgs e)
{
if (DataContext is ViewModels.FileHistories { ViewContent: ViewModels.FileHistoriesSingleRevision revision })
await revision.OpenWithDefaultEditor();
e.Handled = true;
}
} }
} }

View file

@ -34,7 +34,7 @@
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
<ColumnDefinition Width="3"/> <ColumnDefinition Width="3"/>
<ColumnDefinition Width="{Binding #ThisControl.AuthorNameColumnWidth, Mode=TwoWay}" MinWidth="80"/> <ColumnDefinition SharedSizeGroup="AuthorName" Width="{Binding Source={x:Static vm:Preferences.Instance}, Path=Layout.HistoriesAuthorColumnWidth, Mode=TwoWay}" MinWidth="80"/>
<ColumnDefinition SharedSizeGroup="SHA" MinWidth="100"/> <ColumnDefinition SharedSizeGroup="SHA" MinWidth="100"/>
<ColumnDefinition SharedSizeGroup="Time" MinWidth="160"/> <ColumnDefinition SharedSizeGroup="Time" MinWidth="160"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
@ -70,7 +70,6 @@
LayoutUpdated="OnCommitListLayoutUpdated" LayoutUpdated="OnCommitListLayoutUpdated"
SelectionChanged="OnCommitListSelectionChanged" SelectionChanged="OnCommitListSelectionChanged"
ContextRequested="OnCommitListContextRequested" ContextRequested="OnCommitListContextRequested"
DoubleTapped="OnCommitListDoubleTapped"
KeyDown="OnCommitListKeyDown"> KeyDown="OnCommitListKeyDown">
<ListBox.Styles> <ListBox.Styles>
<Style Selector="ListBoxItem"> <Style Selector="ListBoxItem">
@ -117,10 +116,10 @@
<ListBox.ItemTemplate> <ListBox.ItemTemplate>
<DataTemplate DataType="m:Commit"> <DataTemplate DataType="m:Commit">
<Grid Height="26"> <Grid Height="26" Background="Transparent" DoubleTapped="OnCommitListItemDoubleTapped">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
<ColumnDefinition Width="{Binding #ThisControl.AuthorNameColumnWidth, Mode=OneWay}"/> <ColumnDefinition SharedSizeGroup="AuthorName" Width="Auto"/>
<ColumnDefinition SharedSizeGroup="SHA" Width="Auto"/> <ColumnDefinition SharedSizeGroup="SHA" Width="Auto"/>
<ColumnDefinition SharedSizeGroup="Time" Width="Auto"/> <ColumnDefinition SharedSizeGroup="Time" Width="Auto"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>

View file

@ -12,7 +12,7 @@ namespace SourceGit.Views
public class HistoriesLayout : Grid public class HistoriesLayout : Grid
{ {
public static readonly StyledProperty<bool> UseHorizontalProperty = public static readonly StyledProperty<bool> UseHorizontalProperty =
AvaloniaProperty.Register<HistoriesLayout, bool>(nameof(UseHorizontal), false); AvaloniaProperty.Register<HistoriesLayout, bool>(nameof(UseHorizontal));
public bool UseHorizontal public bool UseHorizontal
{ {
@ -73,15 +73,6 @@ namespace SourceGit.Views
public partial class Histories : UserControl public partial class Histories : UserControl
{ {
public static readonly StyledProperty<GridLength> AuthorNameColumnWidthProperty =
AvaloniaProperty.Register<Histories, GridLength>(nameof(AuthorNameColumnWidth), new GridLength(120));
public GridLength AuthorNameColumnWidth
{
get => GetValue(AuthorNameColumnWidthProperty);
set => SetValue(AuthorNameColumnWidthProperty, value);
}
public static readonly StyledProperty<Models.Branch> CurrentBranchProperty = public static readonly StyledProperty<Models.Branch> CurrentBranchProperty =
AvaloniaProperty.Register<Histories, Models.Branch>(nameof(CurrentBranch)); AvaloniaProperty.Register<Histories, Models.Branch>(nameof(CurrentBranch));
@ -150,7 +141,7 @@ namespace SourceGit.Views
private void OnCommitListLayoutUpdated(object _1, EventArgs _2) private void OnCommitListLayoutUpdated(object _1, EventArgs _2)
{ {
var y = CommitListContainer.Scroll?.Offset.Y ?? 0; var y = CommitListContainer.Scroll?.Offset.Y ?? 0;
var authorNameColumnWidth = AuthorNameColumnWidth.Value; var authorNameColumnWidth = ViewModels.Preferences.Instance.Layout.HistoriesAuthorColumnWidth.Value;
if (y != _lastScrollY || authorNameColumnWidth != _lastAuthorNameColumnWidth) if (y != _lastScrollY || authorNameColumnWidth != _lastAuthorNameColumnWidth)
{ {
_lastScrollY = y; _lastScrollY = y;
@ -178,18 +169,6 @@ namespace SourceGit.Views
e.Handled = true; e.Handled = true;
} }
private void OnCommitListDoubleTapped(object sender, TappedEventArgs e)
{
if (DataContext is ViewModels.Histories histories && sender is ListBox { SelectedItems.Count: 1 })
{
var source = e.Source as Control;
var item = source.FindAncestorOfType<ListBoxItem>();
if (item is { DataContext: Models.Commit commit })
histories.DoubleTapped(commit);
}
e.Handled = true;
}
private void OnCommitListKeyDown(object sender, KeyEventArgs e) private void OnCommitListKeyDown(object sender, KeyEventArgs e)
{ {
if (!e.KeyModifiers.HasFlag(OperatingSystem.IsMacOS() ? KeyModifiers.Meta : KeyModifiers.Control)) if (!e.KeyModifiers.HasFlag(OperatingSystem.IsMacOS() ? KeyModifiers.Meta : KeyModifiers.Control))
@ -233,6 +212,25 @@ namespace SourceGit.Views
} }
} }
private void OnCommitListItemDoubleTapped(object sender, TappedEventArgs e)
{
e.Handled = true;
if (DataContext is ViewModels.Histories histories &&
CommitListContainer.SelectedItems is { Count: 1 } &&
sender is Grid { DataContext: Models.Commit commit })
{
if (e.Source is CommitRefsPresenter crp)
{
var decorator = crp.DecoratorAt(e.GetPosition(crp));
if (histories.CheckoutBranchByDecorator(decorator))
return;
}
histories.CheckoutBranchByCommit(commit);
}
}
private double _lastScrollY = 0; private double _lastScrollY = 0;
private double _lastAuthorNameColumnWidth = 0; private double _lastAuthorNameColumnWidth = 0;
} }

View file

@ -189,14 +189,11 @@
<!-- Subject --> <!-- Subject -->
<Grid Grid.Column="2" ColumnDefinitions="Auto,*" ClipToBounds="True"> <Grid Grid.Column="2" ColumnDefinitions="Auto,*" ClipToBounds="True">
<Button Grid.Column="0" Classes="icon_button" Margin="0,0,8,0" IsVisible="{Binding Action, Converter={x:Static c:InteractiveRebaseActionConverters.CanEditMessage}}"> <Button Grid.Column="0"
<Button.Flyout> Classes="icon_button"
<Flyout Placement="BottomEdgeAlignedLeft"> Margin="0,0,8,0"
<Panel Width="600" Height="120"> IsVisible="{Binding Action, Converter={x:Static c:InteractiveRebaseActionConverters.CanEditMessage}}"
<v:CommitMessageTextBox Text="{Binding FullMessage, Mode=TwoWay}"/> Click="OnOpenCommitMessageEditor">
</Panel>
</Flyout>
</Button.Flyout>
<Path Width="14" Height="14" Margin="0,4,0,0" Data="{StaticResource Icons.Edit}"/> <Path Width="14" Height="14" Margin="0,4,0,0" Data="{StaticResource Icons.Edit}"/>
</Button> </Button>
<TextBlock Grid.Column="1" Classes="primary" Margin="0,0,4,0" Text="{Binding Subject}"/> <TextBlock Grid.Column="1" Classes="primary" Margin="0,0,4,0" Text="{Binding Subject}"/>

View file

@ -167,6 +167,18 @@ namespace SourceGit.Views
e.Handled = true; e.Handled = true;
} }
private void OnOpenCommitMessageEditor(object sender, RoutedEventArgs e)
{
if (sender is Button { DataContext: ViewModels.InteractiveRebaseItem item })
{
var dialog = new CommitMessageEditor();
dialog.AsBuiltin(item.FullMessage, msg => item.FullMessage = msg);
dialog.ShowDialog(this);
}
e.Handled = true;
}
private async void OnStartJobs(object _1, RoutedEventArgs _2) private async void OnStartJobs(object _1, RoutedEventArgs _2)
{ {
var vm = DataContext as ViewModels.InteractiveRebase; var vm = DataContext as ViewModels.InteractiveRebase;

View file

@ -55,7 +55,7 @@ namespace SourceGit.Views
{ {
if (sender is ContentPresenter presenter) if (sender is ContentPresenter presenter)
{ {
if (presenter.DataContext == null || presenter.DataContext is not ViewModels.Popup) if (presenter.DataContext is not ViewModels.Popup)
{ {
presenter.Content = null; presenter.Content = null;
return; return;

View file

@ -84,7 +84,7 @@ namespace SourceGit.Views
return; return;
var geo = new StreamGeometry(); var geo = new StreamGeometry();
var angle = Math.PI / 2; const double angle = Math.PI / 2;
var y = height + 0.5; var y = height + 0.5;
using (var ctx = geo.Open()) using (var ctx = geo.Open())
{ {

View file

@ -1,12 +1,11 @@
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Data;
namespace SourceGit.Views namespace SourceGit.Views
{ {
public class MenuItemExtension : AvaloniaObject public class MenuItemExtension : AvaloniaObject
{ {
public static readonly AttachedProperty<string> CommandProperty = public static readonly AttachedProperty<string> CommandProperty =
AvaloniaProperty.RegisterAttached<MenuItemExtension, MenuItem, string>("Command", string.Empty, false, BindingMode.OneWay); AvaloniaProperty.RegisterAttached<MenuItemExtension, MenuItem, string>("Command", string.Empty);
} }
} }

View file

@ -12,7 +12,7 @@
<TextBlock FontSize="18" <TextBlock FontSize="18"
Classes="bold" Classes="bold"
Text="{DynamicResource Text.Merge}"/> Text="{DynamicResource Text.Merge}"/>
<Grid Margin="0,16,0,0" RowDefinitions="32,32,32" ColumnDefinitions="130,*"> <Grid Margin="0,16,0,0" RowDefinitions="32,32,32,32" ColumnDefinitions="130,*">
<TextBlock Grid.Row="0" Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0" Margin="0,0,8,0"
@ -87,6 +87,12 @@
</DataTemplate> </DataTemplate>
</ComboBox.SelectionBoxItemTemplate> </ComboBox.SelectionBoxItemTemplate>
</ComboBox> </ComboBox>
<CheckBox Grid.Row="3" Grid.Column="1"
Height="32"
Content="{DynamicResource Text.Merge.Edit}"
IsChecked="{Binding Edit, Mode=TwoWay}"
ToolTip.Tip="--edit"/>
</Grid> </Grid>
</StackPanel> </StackPanel>
</UserControl> </UserControl>

View file

@ -0,0 +1,51 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels"
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.PushRevision"
x:DataType="vm:PushRevision">
<StackPanel Orientation="Vertical" Margin="8,0">
<TextBlock FontSize="18"
Classes="bold"
Text="{DynamicResource Text.Push.Revision.Title}"/>
<Grid Margin="0,16,0,0" RowDefinitions="32,32,32" ColumnDefinitions="130,*">
<TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0"
Text="{DynamicResource Text.Push.Revision}"/>
<Grid Grid.Row="0" Grid.Column="1" ColumnDefinitions="Auto,Auto,*">
<Path Grid.Column="0" Width="14" Height="14" Data="{StaticResource Icons.Commit}"/>
<TextBlock Grid.Column="1"
Classes="primary"
VerticalAlignment="Center"
Text="{Binding Revision.SHA, Converter={x:Static c:StringConverters.ToShortSHA}}"
Foreground="DarkOrange"
Margin="8,0,0,0"/>
<TextBlock Grid.Column="2"
VerticalAlignment="Center"
Text="{Binding Revision.Subject}"
Margin="4,0,0,0"
TextTrimming="CharacterEllipsis"/>
</Grid>
<TextBlock Grid.Row="1" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0"
Text="{DynamicResource Text.Push.To}"/>
<StackPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal">
<Path Width="14" Height="14" Data="{StaticResource Icons.Branch}"/>
<TextBlock VerticalAlignment="Center" Text="{Binding RemoteBranch.FriendlyName}" Margin="8,0,0,0"/>
</StackPanel>
<CheckBox Grid.Row="2" Grid.Column="1"
Content="{DynamicResource Text.Push.Force}"
IsChecked="{Binding Force, Mode=TwoWay}"
ToolTip.Tip="--force-with-lease"/>
</Grid>
</StackPanel>
</UserControl>

View file

@ -0,0 +1,12 @@
using Avalonia.Controls;
namespace SourceGit.Views
{
public partial class PushRevision : UserControl
{
public PushRevision()
{
InitializeComponent();
}
}
}

View file

@ -829,11 +829,10 @@
<ContentControl Grid.Row="3" Content="{Binding SelectedView}"> <ContentControl Grid.Row="3" Content="{Binding SelectedView}">
<ContentControl.DataTemplates> <ContentControl.DataTemplates>
<DataTemplate DataType="vm:Histories"> <DataTemplate DataType="vm:Histories">
<v:Histories CurrentBranch="{Binding Repo.CurrentBranch}" <v:Histories CurrentBranch="{Binding $parent[v:Repository].((vm:Repository)DataContext).CurrentBranch}"
Bisect="{Binding Bisect}" Bisect="{Binding Bisect}"
AuthorNameColumnWidth="{Binding Source={x:Static vm:Preferences.Instance}, Path=Layout.HistoriesAuthorColumnWidth, Mode=TwoWay}" IssueTrackerRules="{Binding $parent[v:Repository].((vm:Repository)DataContext).Settings.IssueTrackerRules}"
IssueTrackerRules="{Binding Repo.Settings.IssueTrackerRules}" OnlyHighlightCurrentBranch="{Binding $parent[v:Repository].((vm:Repository)DataContext).OnlyHighlightCurrentBranchInHistories}"
OnlyHighlightCurrentBranch="{Binding Repo.OnlyHighlightCurrentBranchInHistories}"
NavigationId="{Binding NavigationId}"/> NavigationId="{Binding NavigationId}"/>
</DataTemplate> </DataTemplate>

View file

@ -12,7 +12,7 @@ namespace SourceGit.Views
public class CounterPresenter : Control public class CounterPresenter : Control
{ {
public static readonly StyledProperty<int> CountProperty = public static readonly StyledProperty<int> CountProperty =
AvaloniaProperty.Register<CounterPresenter, int>(nameof(Count), 0); AvaloniaProperty.Register<CounterPresenter, int>(nameof(Count));
public int Count public int Count
{ {

View file

@ -155,7 +155,7 @@ namespace SourceGit.Views
private void NavigateToHead(object sender, RoutedEventArgs e) private void NavigateToHead(object sender, RoutedEventArgs e)
{ {
if (DataContext is ViewModels.Repository { CurrentBranch: { } } repo) if (DataContext is ViewModels.Repository { CurrentBranch: not null } repo)
{ {
repo.NavigateToCommit(repo.CurrentBranch.Head); repo.NavigateToCommit(repo.CurrentBranch.Head);
e.Handled = true; e.Handled = true;

View file

@ -136,8 +136,7 @@ namespace SourceGit.Views
{ {
if (UseSyntaxHighlighting) if (UseSyntaxHighlighting)
{ {
if (_textMate == null) _textMate ??= Models.TextMateHelper.CreateForEditor(this);
_textMate = Models.TextMateHelper.CreateForEditor(this);
if (DataContext is Models.RevisionTextFile file) if (DataContext is Models.RevisionTextFile file)
Models.TextMateHelper.SetGrammarByFileName(_textMate, file.FileName); Models.TextMateHelper.SetGrammarByFileName(_textMate, file.FileName);

View file

@ -134,10 +134,7 @@ namespace SourceGit.Views
set => SetValue(RevisionProperty, value); set => SetValue(RevisionProperty, value);
} }
public AvaloniaList<ViewModels.RevisionFileTreeNode> Rows public AvaloniaList<ViewModels.RevisionFileTreeNode> Rows { get; } = [];
{
get => _rows;
}
public RevisionFileTreeView() public RevisionFileTreeView()
{ {
@ -146,7 +143,7 @@ namespace SourceGit.Views
public void SetSearchResult(string file) public void SetSearchResult(string file)
{ {
_rows.Clear(); Rows.Clear();
_searchResult.Clear(); _searchResult.Clear();
var rows = new List<ViewModels.RevisionFileTreeNode>(); var rows = new List<ViewModels.RevisionFileTreeNode>();
@ -161,10 +158,10 @@ namespace SourceGit.Views
return; return;
var objects = vm.GetRevisionFilesUnderFolder(file); var objects = vm.GetRevisionFilesUnderFolder(file);
if (objects == null || objects.Count != 1) if (objects is not { Count: 1 })
return; return;
var routes = file.Split('/', StringSplitOptions.None); var routes = file.Split('/');
if (routes.Length == 1) if (routes.Length == 1)
{ {
_searchResult.Add(new ViewModels.RevisionFileTreeNode _searchResult.Add(new ViewModels.RevisionFileTreeNode
@ -202,7 +199,7 @@ namespace SourceGit.Views
MakeRows(rows, _searchResult, 0); MakeRows(rows, _searchResult, 0);
} }
_rows.AddRange(rows); Rows.AddRange(rows);
GC.Collect(); GC.Collect();
} }
@ -212,7 +209,7 @@ namespace SourceGit.Views
node.IsExpanded = !node.IsExpanded; node.IsExpanded = !node.IsExpanded;
var depth = node.Depth; var depth = node.Depth;
var idx = _rows.IndexOf(node); var idx = Rows.IndexOf(node);
if (idx == -1) if (idx == -1)
return; return;
@ -223,21 +220,21 @@ namespace SourceGit.Views
{ {
var subrows = new List<ViewModels.RevisionFileTreeNode>(); var subrows = new List<ViewModels.RevisionFileTreeNode>();
MakeRows(subrows, subtree, depth + 1); MakeRows(subrows, subtree, depth + 1);
_rows.InsertRange(idx + 1, subrows); Rows.InsertRange(idx + 1, subrows);
} }
} }
else else
{ {
var removeCount = 0; var removeCount = 0;
for (int i = idx + 1; i < _rows.Count; i++) for (int i = idx + 1; i < Rows.Count; i++)
{ {
var row = _rows[i]; var row = Rows[i];
if (row.Depth <= depth) if (row.Depth <= depth)
break; break;
removeCount++; removeCount++;
} }
_rows.RemoveRange(idx + 1, removeCount); Rows.RemoveRange(idx + 1, removeCount);
} }
_disableSelectionChangingEvent = false; _disableSelectionChangingEvent = false;
@ -250,7 +247,7 @@ namespace SourceGit.Views
if (change.Property == RevisionProperty) if (change.Property == RevisionProperty)
{ {
_tree.Clear(); _tree.Clear();
_rows.Clear(); Rows.Clear();
_searchResult.Clear(); _searchResult.Clear();
var vm = DataContext as ViewModels.CommitDetail; var vm = DataContext as ViewModels.CommitDetail;
@ -274,7 +271,7 @@ namespace SourceGit.Views
var topTree = new List<ViewModels.RevisionFileTreeNode>(); var topTree = new List<ViewModels.RevisionFileTreeNode>();
MakeRows(topTree, _tree, 0); MakeRows(topTree, _tree, 0);
_rows.AddRange(topTree); Rows.AddRange(topTree);
GC.Collect(); GC.Collect();
} }
} }
@ -365,7 +362,6 @@ namespace SourceGit.Views
} }
private List<ViewModels.RevisionFileTreeNode> _tree = []; private List<ViewModels.RevisionFileTreeNode> _tree = [];
private AvaloniaList<ViewModels.RevisionFileTreeNode> _rows = [];
private bool _disableSelectionChangingEvent = false; private bool _disableSelectionChangingEvent = false;
private List<ViewModels.RevisionFileTreeNode> _searchResult = []; private List<ViewModels.RevisionFileTreeNode> _searchResult = [];
} }

View file

@ -119,7 +119,7 @@
Height="26" Height="26"
BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="0,0,0,1"
IsVisible="{Binding ViewRevisionFilePath, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"> IsVisible="{Binding ViewRevisionFilePath, Converter={x:Static StringConverters.IsNotNullOrEmpty}}">
<Grid ColumnDefinitions="Auto,*,Auto"> <Grid ColumnDefinitions="Auto,*,Auto,Auto">
<Path Grid.Column="0" Width="12" Height="12" Data="{StaticResource Icons.File}" Margin="8,0,0,0"/> <Path Grid.Column="0" Width="12" Height="12" Data="{StaticResource Icons.File}" Margin="8,0,0,0"/>
<TextBlock Grid.Column="1" <TextBlock Grid.Column="1"
Classes="primary" Classes="primary"
@ -140,8 +140,18 @@
Converter="{x:Static c:ObjectConverters.IsTypeOf}" Converter="{x:Static c:ObjectConverters.IsTypeOf}"
ConverterParameter="{x:Type m:RevisionTextFile}"/> ConverterParameter="{x:Type m:RevisionTextFile}"/>
</ToggleButton.IsVisible> </ToggleButton.IsVisible>
<Path Width="13" Height="13" Data="{StaticResource Icons.SyntaxHighlight}" Margin="0,3,0,0"/> <Path Width="13" Height="13" Data="{StaticResource Icons.SyntaxHighlight}" Margin="0,2,0,0"/>
</ToggleButton> </ToggleButton>
<Button Grid.Column="3"
Classes="icon_button"
Width="28"
Background="Transparent"
Click="OnOpenFileWithDefaultEditor"
IsVisible="{Binding CanOpenRevisionFileWithDefaultEditor, Mode=OneWay}"
ToolTip.Tip="{DynamicResource Text.OpenWith}">
<Path Width="12" Height="12" Data="{StaticResource Icons.OpenWith}"/>
</Button>
</Grid> </Grid>
</Border> </Border>

View file

@ -1,5 +1,6 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Interactivity;
namespace SourceGit.Views namespace SourceGit.Views
{ {
@ -80,5 +81,13 @@ namespace SourceGit.Views
e.Handled = true; e.Handled = true;
} }
private async void OnOpenFileWithDefaultEditor(object sender, RoutedEventArgs e)
{
if (DataContext is ViewModels.CommitDetail { CanOpenRevisionFileWithDefaultEditor: true } vm)
await vm.OpenRevisionFileWithDefaultEditor(vm.ViewRevisionFilePath);
e.Handled = true;
}
} }
} }

View file

@ -21,7 +21,7 @@
<v:CommitMessageTextBox Height="120" Margin="8,5,8,0" Text="{Binding Message, Mode=TwoWay}"/> <v:CommitMessageTextBox Height="120" Margin="8,5,8,0" Text="{Binding Message, Mode=TwoWay}"/>
<TextBlock Margin="8" <TextBlock Margin="8"
Text="{DynamicResource Text.Reword.Tip}" Text="{DynamicResource Text.PopupEnterKeyTip}"
TextWrapping="Wrap" TextWrapping="Wrap"
Foreground="{DynamicResource Brush.FG2}"/> Foreground="{DynamicResource Brush.FG2}"/>
</StackPanel> </StackPanel>

View file

@ -31,7 +31,7 @@
<v:CommitMessageTextBox Height="120" Margin="0,4,0,0" Text="{Binding Message, Mode=TwoWay}"/> <v:CommitMessageTextBox Height="120" Margin="0,4,0,0" Text="{Binding Message, Mode=TwoWay}"/>
<TextBlock Margin="0,6,0,0" <TextBlock Margin="0,6,0,0"
Text="{DynamicResource Text.Reword.Tip}" Text="{DynamicResource Text.PopupEnterKeyTip}"
TextWrapping="Wrap" TextWrapping="Wrap"
Foreground="{DynamicResource Brush.FG2}"/> Foreground="{DynamicResource Brush.FG2}"/>
</StackPanel> </StackPanel>

View file

@ -1,52 +0,0 @@
using System;
using System.IO;
using Avalonia.Interactivity;
namespace SourceGit.Views
{
public partial class StandaloneCommitMessageEditor : ChromelessWindow
{
public StandaloneCommitMessageEditor()
{
InitializeComponent();
}
public void SetFile(string file)
{
_file = file;
var content = File.ReadAllText(file).ReplaceLineEndings("\n").Trim();
var firstLineEnd = content.IndexOf('\n');
if (firstLineEnd == -1)
{
Editor.SubjectEditor.Text = content;
}
else
{
Editor.SubjectEditor.Text = content.Substring(0, firstLineEnd);
Editor.DescriptionEditor.Text = content.Substring(firstLineEnd + 1).Trim();
}
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
App.Quit(_exitCode);
}
private void SaveAndClose(object _1, RoutedEventArgs _2)
{
if (!string.IsNullOrEmpty(_file))
{
File.WriteAllText(_file, Editor.Text);
_exitCode = 0;
}
Close();
}
private string _file = string.Empty;
private int _exitCode = -1;
}
}

View file

@ -2,6 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
xmlns:vm="using:SourceGit.ViewModels" xmlns:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
@ -11,45 +12,77 @@
<TextBlock FontSize="18" <TextBlock FontSize="18"
Classes="bold" Classes="bold"
Text="{DynamicResource Text.Stash.Title}"/> Text="{DynamicResource Text.Stash.Title}"/>
<Grid Margin="8,16,0,0" RowDefinitions="32,Auto,Auto,32,Auto,Auto" ColumnDefinitions="120,*"> <Grid Margin="8,20,0,0" RowDefinitions="32,Auto,Auto,Auto,Auto,Auto" ColumnDefinitions="100,356">
<TextBlock Grid.Row="0" Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" HorizontalAlignment="Right"
Margin="8,0" Margin="8,0"
Text="{DynamicResource Text.Stash.Mode}"/>
<ComboBox Grid.Row="0" Grid.Column="1"
MinHeight="28"
Padding="8,0"
ItemsSource="{Binding Source={x:Static m:DealWithChangesAfterStashing.Supported}}"
SelectedIndex="{Binding ChangesAfterStashing, Mode=TwoWay}"
HorizontalAlignment="Stretch">
<ComboBox.ItemTemplate>
<DataTemplate DataType="m:DealWithChangesAfterStashing">
<Grid Height="20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Label}"/>
<TextBlock Grid.Column="1" Text="{Binding Desc}" Margin="8,0" FontSize="11" Foreground="{DynamicResource Brush.FG2}"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Grid.Row="1" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Top"
Margin="0,8,8,0"
Text="{DynamicResource Text.Stash.Message}"/> Text="{DynamicResource Text.Stash.Message}"/>
<TextBox Grid.Row="0" Grid.Column="1" <TextBox Grid.Row="1" Grid.Column="1"
Height="26" Height="100"
Margin="0,4,0,0"
CornerRadius="3" CornerRadius="3"
Text="{Binding Message, Mode=TwoWay}" Text="{Binding Message, Mode=TwoWay}"
Watermark="{DynamicResource Text.Stash.Message.Placeholder}" Watermark="{DynamicResource Text.Stash.Message.Placeholder}"
AcceptsReturn="True"
AcceptsTab="True"
VerticalContentAlignment="Top"
Padding="4"
v:AutoFocusBehaviour.IsEnabled="True"/> v:AutoFocusBehaviour.IsEnabled="True"/>
<CheckBox Grid.Row="1" Grid.Column="1" <TextBlock Grid.Row="2" Grid.Column="1"
Height="32" Classes="small"
Content="{DynamicResource Text.Stash.IncludeUntracked}" Margin="0,2,4,4"
IsChecked="{Binding IncludeUntracked, Mode=TwoWay}" Text="{DynamicResource Text.PopupEnterKeyTip}"
IsVisible="{Binding !HasSelectedFiles}" TextWrapping="Wrap"
ToolTip.Tip="--include-untracked"/> Foreground="{DynamicResource Brush.FG2}"/>
<CheckBox Grid.Row="2" Grid.Column="1" <CheckBox Grid.Row="3" Grid.Column="1"
Height="32" Height="32"
Content="{DynamicResource Text.Stash.OnlyStagedChanges}" Content="{DynamicResource Text.Stash.OnlyStagedChanges}"
IsChecked="{Binding OnlyStaged, Mode=TwoWay}" IsChecked="{Binding OnlyStaged, Mode=TwoWay}"
IsVisible="{Binding !HasSelectedFiles}" IsVisible="{Binding !HasSelectedFiles}"
ToolTip.Tip="--staged"/> ToolTip.Tip="--staged"/>
<CheckBox Grid.Row="3" Grid.Column="1"
Height="32"
Content="{DynamicResource Text.Stash.KeepIndex}"
IsChecked="{Binding KeepIndex, Mode=TwoWay}"
ToolTip.Tip="--keep-index"/>
<CheckBox Grid.Row="4" Grid.Column="1" <CheckBox Grid.Row="4" Grid.Column="1"
Height="32" Height="32"
Content="{DynamicResource Text.Stash.AutoRestore}" Content="{DynamicResource Text.Stash.IncludeUntracked}"
IsChecked="{Binding AutoRestore, Mode=TwoWay}" IsChecked="{Binding IncludeUntracked, Mode=TwoWay}"
ToolTip.Tip="{DynamicResource Text.Stash.AutoRestore.Tip}"/> ToolTip.Tip="--include-untracked">
<CheckBox.IsVisible>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Path="HasSelectedFiles" Converter="{x:Static BoolConverters.Not}"/>
<Binding Path="OnlyStaged" Converter="{x:Static BoolConverters.Not}"/>
</MultiBinding>
</CheckBox.IsVisible>
</CheckBox>
<TextBlock Grid.Row="5" Grid.Column="1" <TextBlock Grid.Row="5" Grid.Column="1"
Classes="small"
Margin="0,4,0,0" Margin="0,4,0,0"
Text="{DynamicResource Text.Stash.TipForSelectedFiles}" Text="{DynamicResource Text.Stash.TipForSelectedFiles}"
TextWrapping="Wrap" TextWrapping="Wrap"

View file

@ -0,0 +1,132 @@
using System;
using System.Globalization;
using System.Text.RegularExpressions;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Media;
namespace SourceGit.Views
{
public partial class StashSubjectPresenter : Control
{
public static readonly StyledProperty<FontFamily> FontFamilyProperty =
AvaloniaProperty.Register<StashSubjectPresenter, FontFamily>(nameof(FontFamily));
public FontFamily FontFamily
{
get => GetValue(FontFamilyProperty);
set => SetValue(FontFamilyProperty, value);
}
public static readonly StyledProperty<double> FontSizeProperty =
AvaloniaProperty.Register<StashSubjectPresenter, double>(nameof(FontSize), 13);
public double FontSize
{
get => GetValue(FontSizeProperty);
set => SetValue(FontSizeProperty, value);
}
public static readonly StyledProperty<IBrush> ForegroundProperty =
AvaloniaProperty.Register<StashSubjectPresenter, IBrush>(nameof(Foreground), Brushes.White);
public IBrush Foreground
{
get => GetValue(ForegroundProperty);
set => SetValue(ForegroundProperty, value);
}
public static readonly StyledProperty<IBrush> PrefixBackgroundProperty =
AvaloniaProperty.Register<StashSubjectPresenter, IBrush>(nameof(PrefixBackground), Brushes.Transparent);
public IBrush PrefixBackground
{
get => GetValue(PrefixBackgroundProperty);
set => SetValue(PrefixBackgroundProperty, value);
}
public static readonly StyledProperty<string> SubjectProperty =
AvaloniaProperty.Register<StashSubjectPresenter, string>(nameof(Subject));
public string Subject
{
get => GetValue(SubjectProperty);
set => SetValue(SubjectProperty, value);
}
public override void Render(DrawingContext context)
{
base.Render(context);
var subject = Subject;
if (string.IsNullOrEmpty(subject))
return;
var typeface = new Typeface(FontFamily, FontStyle.Normal, FontWeight.Normal);
var foreground = Foreground;
var x = 0.0;
var h = Bounds.Height;
var prefix = null as FormattedText;
var match = REG_KEYWORD_ON().Match(subject);
if (match.Success)
{
prefix = new FormattedText(match.Groups[1].Value, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, 11, foreground);
subject = subject.Substring(match.Length);
}
else
{
match = REG_KEYWORD_WIP().Match(subject);
if (match.Success)
{
prefix = new FormattedText($"WIP | {match.Groups[1].Value}", CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, 11, foreground);
subject = subject.Substring(match.Length);
}
}
if (prefix != null)
{
var pw = prefix.WidthIncludingTrailingWhitespace;
var ph = prefix.Height;
var bh = ph + 4;
var bw = pw + 12;
context.DrawRectangle(PrefixBackground, null, new RoundedRect(new Rect(0, (h - bh) * 0.5, bw, bh), new CornerRadius(bh * 0.5)));
context.DrawText(prefix, new Point(6, (h - ph) * 0.5));
x = bw + 4;
}
var body = new FormattedText(subject, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, FontSize, foreground);
context.DrawText(body, new Point(x, (h - body.Height) * 0.5));
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property == SubjectProperty ||
change.Property == FontFamilyProperty ||
change.Property == FontSizeProperty ||
change.Property == ForegroundProperty ||
change.Property == PrefixBackgroundProperty)
{
InvalidateVisual();
}
}
protected override Size MeasureOverride(Size availableSize)
{
var typeface = new Typeface(FontFamily, FontStyle.Normal, FontWeight.Normal);
var test = new FormattedText("fgl|", CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, FontSize, Brushes.White);
var h = Math.Max(18, test.Height);
return new Size(availableSize.Width, h);
}
[GeneratedRegex(@"^On ([^\s]+)\: ")]
private static partial Regex REG_KEYWORD_ON();
[GeneratedRegex(@"^WIP on ([^\s]+)\: ([a-f0-9]{6,40}) ")]
private static partial Regex REG_KEYWORD_WIP();
}
}

View file

@ -84,14 +84,23 @@
<ListBox.ItemTemplate> <ListBox.ItemTemplate>
<DataTemplate DataType="m:Stash"> <DataTemplate DataType="m:Stash">
<Border BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="0,0,0,1" Padding="4" Background="Transparent" ContextRequested="OnStashContextRequested"> <Border Background="Transparent"
BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="0,0,0,1"
Padding="4"
ContextRequested="OnStashContextRequested"
ToolTip.Tip="{Binding Message}">
<Grid RowDefinitions="Auto,*" > <Grid RowDefinitions="Auto,*" >
<Grid Grid.Row="0" ColumnDefinitions="*,Auto"> <Grid Grid.Row="0" ColumnDefinitions="*,Auto">
<TextBlock Grid.Column="0" Classes="primary" Text="{Binding Name}" Foreground="DarkOrange"/> <TextBlock Grid.Column="0" Classes="primary" Text="{Binding Name}" Foreground="DarkOrange"/>
<TextBlock Grid.Column="1" Classes="primary" Text="{Binding TimeStr}" Foreground="{DynamicResource Brush.FG2}" Margin="8,0,0,0"/> <TextBlock Grid.Column="1" Classes="primary" Text="{Binding TimeStr}" Foreground="{DynamicResource Brush.FG2}" Margin="8,0,0,0"/>
</Grid> </Grid>
<TextBlock Grid.Row="1" Classes="primary" Text="{Binding Message}" VerticalAlignment="Bottom"/> <v:StashSubjectPresenter Grid.Row="1"
Subject="{Binding Subject}"
Foreground="{DynamicResource Brush.FG1}"
FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=DefaultFontSize}"
PrefixBackground="{DynamicResource Brush.InlineCode}"
VerticalAlignment="Bottom"/>
</Grid> </Grid>
</Border> </Border>
</DataTemplate> </DataTemplate>

View file

@ -348,16 +348,11 @@ namespace SourceGit.Views
private ThemedTextDiffPresenter _presenter = null; private ThemedTextDiffPresenter _presenter = null;
} }
public class LineStyleTransformer : DocumentColorizingTransformer public class LineStyleTransformer(ThemedTextDiffPresenter presenter) : DocumentColorizingTransformer
{ {
public LineStyleTransformer(ThemedTextDiffPresenter presenter)
{
_presenter = presenter;
}
protected override void ColorizeLine(DocumentLine line) protected override void ColorizeLine(DocumentLine line)
{ {
var lines = _presenter.GetLines(); var lines = presenter.GetLines();
var idx = line.LineNumber; var idx = line.LineNumber;
if (idx > lines.Count) if (idx > lines.Count)
return; return;
@ -367,13 +362,11 @@ namespace SourceGit.Views
{ {
ChangeLinePart(line.Offset, line.EndOffset, v => ChangeLinePart(line.Offset, line.EndOffset, v =>
{ {
v.TextRunProperties.SetForegroundBrush(_presenter.IndicatorForeground); v.TextRunProperties.SetForegroundBrush(presenter.IndicatorForeground);
v.TextRunProperties.SetTypeface(new Typeface(_presenter.FontFamily, FontStyle.Italic)); v.TextRunProperties.SetTypeface(new Typeface(presenter.FontFamily, FontStyle.Italic));
}); });
} }
} }
private readonly ThemedTextDiffPresenter _presenter;
} }
public static readonly StyledProperty<string> FileNameProperty = public static readonly StyledProperty<string> FileNameProperty =

View file

@ -1,6 +1,7 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.VisualTree;
namespace SourceGit.Views namespace SourceGit.Views
{ {
@ -29,7 +30,12 @@ namespace SourceGit.Views
{ {
if (DataContext is ViewModels.WorkingCopy vm && sender is Control control) if (DataContext is ViewModels.WorkingCopy vm && sender is Control control)
{ {
var menu = vm.CreateContextMenuForUnstagedChanges(); var container = control.FindDescendantOfType<ChangeCollectionContainer>();
var selectedSingleFolder = string.Empty;
if (container is { SelectedItems: { Count: 1 }, SelectedItem: ViewModels.ChangeTreeNode { IsFolder: true } node })
selectedSingleFolder = node.FullPath;
var menu = vm.CreateContextMenuForUnstagedChanges(selectedSingleFolder);
menu?.Open(control); menu?.Open(control);
e.Handled = true; e.Handled = true;
} }
@ -39,7 +45,12 @@ namespace SourceGit.Views
{ {
if (DataContext is ViewModels.WorkingCopy vm && sender is Control control) if (DataContext is ViewModels.WorkingCopy vm && sender is Control control)
{ {
var menu = vm.CreateContextMenuForStagedChanges(); var container = control.FindDescendantOfType<ChangeCollectionContainer>();
var selectedSingleFolder = string.Empty;
if (container is { SelectedItems: { Count: 1 }, SelectedItem: ViewModels.ChangeTreeNode { IsFolder: true } node })
selectedSingleFolder = node.FullPath;
var menu = vm.CreateContextMenuForStagedChanges(selectedSingleFolder);
menu?.Open(control); menu?.Open(control);
e.Handled = true; e.Handled = true;
} }