Merge branch 'release/v2025.19'

This commit is contained in:
leo 2025-05-26 09:45:48 +08:00
commit 4887252870
No known key found for this signature in database
95 changed files with 1336 additions and 838 deletions

View file

@ -6,11 +6,18 @@ 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-98.23%25-yellow) ### ![de__DE](https://img.shields.io/badge/de__DE-96.75%25-yellow)
<details> <details>
<summary>Missing keys in de_DE.axaml</summary> <summary>Missing keys in de_DE.axaml</summary>
- Text.BranchCM.ResetToSelectedCommit
- Text.CommitDetail.Changes.Count
- Text.CreateBranch.OverwriteExisting
- Text.DeinitSubmodule
- Text.DeinitSubmodule.Force
- Text.DeinitSubmodule.Path
- Text.Diff.Submodule.Deleted
- Text.GitFlow.FinishWithPush - Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash - Text.GitFlow.FinishWithSquash
- Text.Hotkeys.Global.SwitchWorkspace - Text.Hotkeys.Global.SwitchWorkspace
@ -18,7 +25,12 @@ 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.Pull.RecurseSubmodules
- Text.Repository.ShowSubmodulesAsTree - Text.Repository.ShowSubmodulesAsTree
- Text.ResetWithoutCheckout
- Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target
- Text.Submodule.Deinit
- Text.Submodule.Status - Text.Submodule.Status
- Text.Submodule.Status.Modified - Text.Submodule.Status.Modified
- Text.Submodule.Status.NotInited - Text.Submodule.Status.NotInited
@ -28,19 +40,16 @@ This document shows the translation status of each locale file in the repository
</details> </details>
### ![es__ES](https://img.shields.io/badge/es__ES-99.49%25-yellow) ### ![es__ES](https://img.shields.io/badge/es__ES-99.87%25-yellow)
<details> <details>
<summary>Missing keys in es_ES.axaml</summary> <summary>Missing keys in es_ES.axaml</summary>
- Text.Hotkeys.Global.SwitchWorkspace - Text.CreateBranch.OverwriteExisting
- Text.Hotkeys.Global.SwitchTab
- Text.Launcher.Workspaces
- Text.Launcher.Pages
</details> </details>
### ![fr__FR](https://img.shields.io/badge/fr__FR-94.05%25-yellow) ### ![fr__FR](https://img.shields.io/badge/fr__FR-92.62%25-yellow)
<details> <details>
<summary>Missing keys in fr_FR.axaml</summary> <summary>Missing keys in fr_FR.axaml</summary>
@ -52,16 +61,23 @@ This document shows the translation status of each locale file in the repository
- Text.Bisect.Good - Text.Bisect.Good
- Text.Bisect.Skip - Text.Bisect.Skip
- Text.Bisect.WaitingForRange - Text.Bisect.WaitingForRange
- Text.BranchCM.ResetToSelectedCommit
- Text.Checkout.RecurseSubmodules - Text.Checkout.RecurseSubmodules
- Text.CommitCM.CopyAuthor - Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter - Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject - Text.CommitCM.CopySubject
- Text.CommitDetail.Changes.Count
- Text.CommitMessageTextBox.SubjectCount - Text.CommitMessageTextBox.SubjectCount
- Text.Configure.Git.PreferredMergeMode - Text.Configure.Git.PreferredMergeMode
- Text.ConfirmEmptyCommit.Continue - Text.ConfirmEmptyCommit.Continue
- Text.ConfirmEmptyCommit.NoLocalChanges - Text.ConfirmEmptyCommit.NoLocalChanges
- Text.ConfirmEmptyCommit.StageAllThenCommit - Text.ConfirmEmptyCommit.StageAllThenCommit
- Text.ConfirmEmptyCommit.WithLocalChanges - Text.ConfirmEmptyCommit.WithLocalChanges
- Text.CreateBranch.OverwriteExisting
- Text.DeinitSubmodule
- Text.DeinitSubmodule.Force
- Text.DeinitSubmodule.Path
- Text.Diff.Submodule.Deleted
- Text.GitFlow.FinishWithPush - Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash - Text.GitFlow.FinishWithSquash
- Text.Hotkeys.Global.SwitchWorkspace - Text.Hotkeys.Global.SwitchWorkspace
@ -70,6 +86,7 @@ This document shows the translation status of each locale file in the repository
- Text.Launcher.Workspaces - Text.Launcher.Workspaces
- Text.Launcher.Pages - Text.Launcher.Pages
- Text.Preferences.Git.IgnoreCRAtEOLInDiff - Text.Preferences.Git.IgnoreCRAtEOLInDiff
- Text.Pull.RecurseSubmodules
- Text.Repository.BranchSort - Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate - Text.Repository.BranchSort.ByCommitterDate
- Text.Repository.BranchSort.ByName - Text.Repository.BranchSort.ByName
@ -77,6 +94,10 @@ This document shows the translation status of each locale file in the repository
- Text.Repository.ShowSubmodulesAsTree - Text.Repository.ShowSubmodulesAsTree
- Text.Repository.ViewLogs - Text.Repository.ViewLogs
- Text.Repository.Visit - Text.Repository.Visit
- Text.ResetWithoutCheckout
- Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target
- Text.Submodule.Deinit
- Text.Submodule.Status - Text.Submodule.Status
- Text.Submodule.Status.Modified - Text.Submodule.Status.Modified
- Text.Submodule.Status.NotInited - Text.Submodule.Status.NotInited
@ -95,19 +116,31 @@ This document shows the translation status of each locale file in the repository
</details> </details>
### ![it__IT](https://img.shields.io/badge/it__IT-99.49%25-yellow) ### ![it__IT](https://img.shields.io/badge/it__IT-98.00%25-yellow)
<details> <details>
<summary>Missing keys in it_IT.axaml</summary> <summary>Missing keys in it_IT.axaml</summary>
- Text.BranchCM.ResetToSelectedCommit
- Text.CommitDetail.Changes.Count
- Text.CreateBranch.OverwriteExisting
- Text.DeinitSubmodule
- Text.DeinitSubmodule.Force
- Text.DeinitSubmodule.Path
- Text.Diff.Submodule.Deleted
- Text.Hotkeys.Global.SwitchWorkspace - Text.Hotkeys.Global.SwitchWorkspace
- Text.Hotkeys.Global.SwitchTab - Text.Hotkeys.Global.SwitchTab
- Text.Launcher.Workspaces - Text.Launcher.Workspaces
- Text.Launcher.Pages - Text.Launcher.Pages
- Text.Pull.RecurseSubmodules
- Text.ResetWithoutCheckout
- Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target
- Text.Submodule.Deinit
</details> </details>
### ![ja__JP](https://img.shields.io/badge/ja__JP-93.80%25-yellow) ### ![ja__JP](https://img.shields.io/badge/ja__JP-92.37%25-yellow)
<details> <details>
<summary>Missing keys in ja_JP.axaml</summary> <summary>Missing keys in ja_JP.axaml</summary>
@ -119,16 +152,23 @@ This document shows the translation status of each locale file in the repository
- Text.Bisect.Good - Text.Bisect.Good
- Text.Bisect.Skip - Text.Bisect.Skip
- Text.Bisect.WaitingForRange - Text.Bisect.WaitingForRange
- Text.BranchCM.ResetToSelectedCommit
- Text.Checkout.RecurseSubmodules - Text.Checkout.RecurseSubmodules
- Text.CommitCM.CopyAuthor - Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter - Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject - Text.CommitCM.CopySubject
- Text.CommitDetail.Changes.Count
- Text.CommitMessageTextBox.SubjectCount - Text.CommitMessageTextBox.SubjectCount
- Text.Configure.Git.PreferredMergeMode - Text.Configure.Git.PreferredMergeMode
- Text.ConfirmEmptyCommit.Continue - Text.ConfirmEmptyCommit.Continue
- Text.ConfirmEmptyCommit.NoLocalChanges - Text.ConfirmEmptyCommit.NoLocalChanges
- Text.ConfirmEmptyCommit.StageAllThenCommit - Text.ConfirmEmptyCommit.StageAllThenCommit
- Text.ConfirmEmptyCommit.WithLocalChanges - Text.ConfirmEmptyCommit.WithLocalChanges
- Text.CreateBranch.OverwriteExisting
- Text.DeinitSubmodule
- Text.DeinitSubmodule.Force
- Text.DeinitSubmodule.Path
- Text.Diff.Submodule.Deleted
- Text.GitFlow.FinishWithPush - Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash - Text.GitFlow.FinishWithSquash
- Text.Hotkeys.Global.SwitchWorkspace - Text.Hotkeys.Global.SwitchWorkspace
@ -137,6 +177,7 @@ This document shows the translation status of each locale file in the repository
- Text.Launcher.Workspaces - Text.Launcher.Workspaces
- Text.Launcher.Pages - Text.Launcher.Pages
- Text.Preferences.Git.IgnoreCRAtEOLInDiff - Text.Preferences.Git.IgnoreCRAtEOLInDiff
- Text.Pull.RecurseSubmodules
- Text.Repository.BranchSort - Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate - Text.Repository.BranchSort.ByCommitterDate
- Text.Repository.BranchSort.ByName - Text.Repository.BranchSort.ByName
@ -146,6 +187,10 @@ This document shows the translation status of each locale file in the repository
- Text.Repository.Tags.OrderByNameDes - Text.Repository.Tags.OrderByNameDes
- Text.Repository.ViewLogs - Text.Repository.ViewLogs
- Text.Repository.Visit - Text.Repository.Visit
- Text.ResetWithoutCheckout
- Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target
- Text.Submodule.Deinit
- Text.Submodule.Status - Text.Submodule.Status
- Text.Submodule.Status.Modified - Text.Submodule.Status.Modified
- Text.Submodule.Status.NotInited - Text.Submodule.Status.NotInited
@ -164,7 +209,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-85.57%25-yellow) ### ![pt__BR](https://img.shields.io/badge/pt__BR-84.23%25-yellow)
<details> <details>
<summary>Missing keys in pt_BR.axaml</summary> <summary>Missing keys in pt_BR.axaml</summary>
@ -184,6 +229,7 @@ This document shows the translation status of each locale file in the repository
- Text.Bisect.WaitingForRange - Text.Bisect.WaitingForRange
- Text.BranchCM.CustomAction - Text.BranchCM.CustomAction
- Text.BranchCM.MergeMultiBranches - Text.BranchCM.MergeMultiBranches
- Text.BranchCM.ResetToSelectedCommit
- Text.BranchUpstreamInvalid - Text.BranchUpstreamInvalid
- Text.Checkout.RecurseSubmodules - Text.Checkout.RecurseSubmodules
- Text.Clone.RecurseSubmodules - Text.Clone.RecurseSubmodules
@ -192,6 +238,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.CommitDetail.Changes.Count
- Text.CommitDetail.Files.Search - Text.CommitDetail.Files.Search
- Text.CommitDetail.Info.Children - Text.CommitDetail.Info.Children
- Text.CommitMessageTextBox.SubjectCount - Text.CommitMessageTextBox.SubjectCount
@ -206,11 +253,16 @@ This document shows the translation status of each locale file in the repository
- Text.ConfirmEmptyCommit.WithLocalChanges - Text.ConfirmEmptyCommit.WithLocalChanges
- Text.CopyFullPath - Text.CopyFullPath
- Text.CreateBranch.Name.WarnSpace - Text.CreateBranch.Name.WarnSpace
- Text.CreateBranch.OverwriteExisting
- Text.DeinitSubmodule
- Text.DeinitSubmodule.Force
- Text.DeinitSubmodule.Path
- Text.DeleteRepositoryNode.Path - Text.DeleteRepositoryNode.Path
- Text.DeleteRepositoryNode.TipForGroup - Text.DeleteRepositoryNode.TipForGroup
- Text.DeleteRepositoryNode.TipForRepository - Text.DeleteRepositoryNode.TipForRepository
- Text.Diff.First - Text.Diff.First
- Text.Diff.Last - Text.Diff.Last
- Text.Diff.Submodule.Deleted
- Text.Diff.UseBlockNavigation - Text.Diff.UseBlockNavigation
- Text.Fetch.Force - Text.Fetch.Force
- Text.FileCM.ResolveUsing - Text.FileCM.ResolveUsing
@ -238,6 +290,7 @@ This document shows the translation status of each locale file in the repository
- Text.Preferences.General.ShowTagsInGraph - Text.Preferences.General.ShowTagsInGraph
- Text.Preferences.Git.IgnoreCRAtEOLInDiff - Text.Preferences.Git.IgnoreCRAtEOLInDiff
- Text.Preferences.Git.SSLVerify - Text.Preferences.Git.SSLVerify
- Text.Pull.RecurseSubmodules
- Text.Repository.BranchSort - Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate - Text.Repository.BranchSort.ByCommitterDate
- Text.Repository.BranchSort.ByName - Text.Repository.BranchSort.ByName
@ -258,6 +311,9 @@ This document shows the translation status of each locale file in the repository
- Text.Repository.UseRelativeTimeInHistories - Text.Repository.UseRelativeTimeInHistories
- Text.Repository.ViewLogs - Text.Repository.ViewLogs
- Text.Repository.Visit - Text.Repository.Visit
- Text.ResetWithoutCheckout
- Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target
- Text.SetUpstream - Text.SetUpstream
- Text.SetUpstream.Local - Text.SetUpstream.Local
- Text.SetUpstream.Unset - Text.SetUpstream.Unset
@ -266,6 +322,7 @@ This document shows the translation status of each locale file in the repository
- Text.Stash.AutoRestore - Text.Stash.AutoRestore
- Text.Stash.AutoRestore.Tip - Text.Stash.AutoRestore.Tip
- Text.StashCM.SaveAsPatch - Text.StashCM.SaveAsPatch
- Text.Submodule.Deinit
- Text.Submodule.Status - Text.Submodule.Status
- Text.Submodule.Status.Modified - Text.Submodule.Status.Modified
- Text.Submodule.Status.NotInited - Text.Submodule.Status.NotInited
@ -286,17 +343,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-92.62%25-yellow)
<summary>Missing keys in ru_RU.axaml</summary>
- Text.Hotkeys.Global.SwitchTab
- Text.Launcher.Pages
</details>
### ![ta__IN](https://img.shields.io/badge/ta__IN-94.05%25-yellow)
<details> <details>
<summary>Missing keys in ta_IN.axaml</summary> <summary>Missing keys in ta_IN.axaml</summary>
@ -308,16 +357,23 @@ This document shows the translation status of each locale file in the repository
- Text.Bisect.Good - Text.Bisect.Good
- Text.Bisect.Skip - Text.Bisect.Skip
- Text.Bisect.WaitingForRange - Text.Bisect.WaitingForRange
- Text.BranchCM.ResetToSelectedCommit
- Text.Checkout.RecurseSubmodules - Text.Checkout.RecurseSubmodules
- Text.CommitCM.CopyAuthor - Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter - Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject - Text.CommitCM.CopySubject
- Text.CommitDetail.Changes.Count
- Text.CommitMessageTextBox.SubjectCount - Text.CommitMessageTextBox.SubjectCount
- Text.Configure.Git.PreferredMergeMode - Text.Configure.Git.PreferredMergeMode
- Text.ConfirmEmptyCommit.Continue - Text.ConfirmEmptyCommit.Continue
- Text.ConfirmEmptyCommit.NoLocalChanges - Text.ConfirmEmptyCommit.NoLocalChanges
- Text.ConfirmEmptyCommit.StageAllThenCommit - Text.ConfirmEmptyCommit.StageAllThenCommit
- Text.ConfirmEmptyCommit.WithLocalChanges - Text.ConfirmEmptyCommit.WithLocalChanges
- Text.CreateBranch.OverwriteExisting
- Text.DeinitSubmodule
- Text.DeinitSubmodule.Force
- Text.DeinitSubmodule.Path
- Text.Diff.Submodule.Deleted
- Text.GitFlow.FinishWithPush - Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash - Text.GitFlow.FinishWithSquash
- Text.Hotkeys.Global.SwitchWorkspace - Text.Hotkeys.Global.SwitchWorkspace
@ -326,6 +382,7 @@ This document shows the translation status of each locale file in the repository
- Text.Launcher.Workspaces - Text.Launcher.Workspaces
- Text.Launcher.Pages - Text.Launcher.Pages
- Text.Preferences.Git.IgnoreCRAtEOLInDiff - Text.Preferences.Git.IgnoreCRAtEOLInDiff
- Text.Pull.RecurseSubmodules
- Text.Repository.BranchSort - Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate - Text.Repository.BranchSort.ByCommitterDate
- Text.Repository.BranchSort.ByName - Text.Repository.BranchSort.ByName
@ -333,6 +390,10 @@ This document shows the translation status of each locale file in the repository
- Text.Repository.ShowSubmodulesAsTree - Text.Repository.ShowSubmodulesAsTree
- Text.Repository.ViewLogs - Text.Repository.ViewLogs
- Text.Repository.Visit - Text.Repository.Visit
- Text.ResetWithoutCheckout
- Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target
- Text.Submodule.Deinit
- Text.Submodule.Status - Text.Submodule.Status
- Text.Submodule.Status.Modified - Text.Submodule.Status.Modified
- Text.Submodule.Status.NotInited - Text.Submodule.Status.NotInited
@ -351,7 +412,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-95.19%25-yellow) ### ![uk__UA](https://img.shields.io/badge/uk__UA-93.74%25-yellow)
<details> <details>
<summary>Missing keys in uk_UA.axaml</summary> <summary>Missing keys in uk_UA.axaml</summary>
@ -363,12 +424,19 @@ This document shows the translation status of each locale file in the repository
- Text.Bisect.Good - Text.Bisect.Good
- Text.Bisect.Skip - Text.Bisect.Skip
- Text.Bisect.WaitingForRange - Text.Bisect.WaitingForRange
- Text.BranchCM.ResetToSelectedCommit
- Text.Checkout.RecurseSubmodules - Text.Checkout.RecurseSubmodules
- Text.CommitCM.CopyAuthor - Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter - Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject - Text.CommitCM.CopySubject
- Text.CommitDetail.Changes.Count
- Text.CommitMessageTextBox.SubjectCount - Text.CommitMessageTextBox.SubjectCount
- Text.ConfigureWorkspace.Name - Text.ConfigureWorkspace.Name
- Text.CreateBranch.OverwriteExisting
- Text.DeinitSubmodule
- Text.DeinitSubmodule.Force
- Text.DeinitSubmodule.Path
- Text.Diff.Submodule.Deleted
- Text.GitFlow.FinishWithPush - Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash - Text.GitFlow.FinishWithSquash
- Text.Hotkeys.Global.SwitchWorkspace - Text.Hotkeys.Global.SwitchWorkspace
@ -377,6 +445,7 @@ This document shows the translation status of each locale file in the repository
- Text.Launcher.Workspaces - Text.Launcher.Workspaces
- Text.Launcher.Pages - Text.Launcher.Pages
- Text.Preferences.Git.IgnoreCRAtEOLInDiff - Text.Preferences.Git.IgnoreCRAtEOLInDiff
- Text.Pull.RecurseSubmodules
- Text.Repository.BranchSort - Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate - Text.Repository.BranchSort.ByCommitterDate
- Text.Repository.BranchSort.ByName - Text.Repository.BranchSort.ByName
@ -384,6 +453,10 @@ This document shows the translation status of each locale file in the repository
- Text.Repository.ShowSubmodulesAsTree - Text.Repository.ShowSubmodulesAsTree
- Text.Repository.ViewLogs - Text.Repository.ViewLogs
- Text.Repository.Visit - Text.Repository.Visit
- Text.ResetWithoutCheckout
- Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target
- Text.Submodule.Deinit
- Text.Submodule.Status - Text.Submodule.Status
- Text.Submodule.Status.Modified - Text.Submodule.Status.Modified
- Text.Submodule.Status.NotInited - Text.Submodule.Status.NotInited

View file

@ -1 +1 @@
2025.18 2025.19

View file

@ -548,7 +548,7 @@ namespace SourceGit
private void TryLaunchAsNormal(IClassicDesktopStyleApplicationLifetime desktop) private void TryLaunchAsNormal(IClassicDesktopStyleApplicationLifetime desktop)
{ {
Native.OS.SetupEnternalTools(); Native.OS.SetupExternalTools();
Models.AvatarManager.Instance.Start(); Models.AvatarManager.Instance.Start();
string startupRepo = null; string startupRepo = null;
@ -671,7 +671,16 @@ namespace SourceGit
prevChar = c; prevChar = c;
} }
trimmed.Add(sb.ToString()); var name = sb.ToString();
var idx = name.IndexOf('#');
if (idx >= 0)
{
if (!name.Equals("fonts:Inter#Inter", StringComparison.Ordinal) &&
!name.Equals("fonts:SourceGit#JetBrains Mono", StringComparison.Ordinal))
continue;
}
trimmed.Add(name);
} }
return trimmed.Count > 0 ? string.Join(',', trimmed) : string.Empty; return trimmed.Count > 0 ? string.Join(',', trimmed) : string.Empty;

View file

@ -1,4 +1,6 @@
namespace SourceGit.Commands using System.Text;
namespace SourceGit.Commands
{ {
public static class Branch public static class Branch
{ {
@ -11,12 +13,20 @@
return cmd.ReadToEnd().StdOut.Trim(); return cmd.ReadToEnd().StdOut.Trim();
} }
public static bool Create(string repo, string name, string basedOn, Models.ICommandLog log) public static bool Create(string repo, string name, string basedOn, bool force, Models.ICommandLog log)
{ {
var builder = new StringBuilder();
builder.Append("branch ");
if (force)
builder.Append("-f ");
builder.Append(name);
builder.Append(" ");
builder.Append(basedOn);
var cmd = new Command(); var cmd = new Command();
cmd.WorkingDirectory = repo; cmd.WorkingDirectory = repo;
cmd.Context = repo; cmd.Context = repo;
cmd.Args = $"branch {name} {basedOn}"; cmd.Args = builder.ToString();
cmd.Log = log; cmd.Log = log;
return cmd.Exec(); return cmd.Exec();
} }

View file

@ -13,15 +13,28 @@ namespace SourceGit.Commands
public bool Branch(string branch, bool force) public bool Branch(string branch, bool force)
{ {
var option = force ? "--force" : string.Empty; var builder = new StringBuilder();
Args = $"checkout {option} --progress {branch}"; builder.Append("checkout --progress ");
if (force)
builder.Append("--force ");
builder.Append(branch);
Args = builder.ToString();
return Exec(); return Exec();
} }
public bool Branch(string branch, string basedOn, bool force) public bool Branch(string branch, string basedOn, bool force, bool allowOverwrite)
{ {
var option = force ? "--force" : string.Empty; var builder = new StringBuilder();
Args = $"checkout --progress -b {branch} {basedOn}"; builder.Append("checkout --progress ");
builder.Append(allowOverwrite ? "-B " : "-b ");
if (force)
builder.Append("--force ");
builder.Append(branch);
builder.Append(" ");
builder.Append(basedOn);
Args = builder.ToString();
return Exec(); return Exec();
} }

View file

@ -36,44 +36,14 @@ namespace SourceGit.Commands
public bool Exec() public bool Exec()
{ {
Log?.AppendLine($"$ git {Args}\n");
var start = CreateGitStartInfo(); var start = CreateGitStartInfo();
var errs = new List<string>(); var errs = new List<string>();
var proc = new Process() { StartInfo = start }; var proc = new Process() { StartInfo = start };
Log?.AppendLine($"$ git {Args}\n"); proc.OutputDataReceived += (_, e) => HandleOutput(e.Data, errs);
proc.ErrorDataReceived += (_, e) => HandleOutput(e.Data, errs);
proc.OutputDataReceived += (_, e) =>
{
if (e.Data == null)
return;
Log?.AppendLine(e.Data);
};
proc.ErrorDataReceived += (_, e) =>
{
if (string.IsNullOrEmpty(e.Data))
{
errs.Add(string.Empty);
return;
}
Log?.AppendLine(e.Data);
// Ignore progress messages
if (e.Data.StartsWith("remote: Enumerating objects:", StringComparison.Ordinal))
return;
if (e.Data.StartsWith("remote: Counting objects:", StringComparison.Ordinal))
return;
if (e.Data.StartsWith("remote: Compressing objects:", StringComparison.Ordinal))
return;
if (e.Data.StartsWith("Filtering content:", StringComparison.Ordinal))
return;
if (REG_PROGRESS().IsMatch(e.Data))
return;
errs.Add(e.Data);
};
var dummy = null as Process; var dummy = null as Process;
var dummyProcLock = new object(); var dummyProcLock = new object();
@ -222,6 +192,28 @@ namespace SourceGit.Commands
return start; return start;
} }
private void HandleOutput(string line, List<string> errs)
{
line = line ?? string.Empty;
Log?.AppendLine(line);
// Lines to hide in error message.
if (line.Length > 0)
{
if (line.StartsWith("remote: Enumerating objects:", StringComparison.Ordinal) ||
line.StartsWith("remote: Counting objects:", StringComparison.Ordinal) ||
line.StartsWith("remote: Compressing objects:", StringComparison.Ordinal) ||
line.StartsWith("Filtering content:", StringComparison.Ordinal) ||
line.StartsWith("hint:", StringComparison.Ordinal))
return;
if (REG_PROGRESS().IsMatch(line))
return;
}
errs.Add(line);
}
[GeneratedRegex(@"\d+%")] [GeneratedRegex(@"\d+%")]
private static partial Regex REG_PROGRESS(); private static partial Regex REG_PROGRESS();
} }

View file

@ -27,7 +27,7 @@ namespace SourceGit.Commands
} }
} }
public static void RunAndWait(string repo, string file, string args, Action<string> outputHandler) public static void RunAndWait(string repo, string file, string args, Models.ICommandLog log)
{ {
var start = new ProcessStartInfo(); var start = new ProcessStartInfo();
start.FileName = file; start.FileName = file;
@ -40,20 +40,22 @@ namespace SourceGit.Commands
start.StandardErrorEncoding = Encoding.UTF8; start.StandardErrorEncoding = Encoding.UTF8;
start.WorkingDirectory = repo; start.WorkingDirectory = repo;
log?.AppendLine($"$ {file} {args}\n");
var proc = new Process() { StartInfo = start }; var proc = new Process() { StartInfo = start };
var builder = new StringBuilder(); var builder = new StringBuilder();
proc.OutputDataReceived += (_, e) => proc.OutputDataReceived += (_, e) =>
{ {
if (e.Data != null) if (e.Data != null)
outputHandler?.Invoke(e.Data); log?.AppendLine(e.Data);
}; };
proc.ErrorDataReceived += (_, e) => proc.ErrorDataReceived += (_, e) =>
{ {
if (e.Data != null) if (e.Data != null)
{ {
outputHandler?.Invoke(e.Data); log?.AppendLine(e.Data);
builder.AppendLine(e.Data); builder.AppendLine(e.Data);
} }
}; };

View file

@ -1,53 +1,12 @@
using System; using System.Text;
using System.Collections.Generic;
using System.Text;
using Avalonia.Threading; using Avalonia.Threading;
namespace SourceGit.Commands namespace SourceGit.Commands
{ {
public static class GitFlow public static class GitFlow
{ {
public class BranchDetectResult public static bool Init(string repo, string master, string develop, string feature, string release, string hotfix, string version, Models.ICommandLog log)
{ {
public bool IsGitFlowBranch { get; set; } = false;
public string Type { get; set; } = string.Empty;
public string Prefix { get; set; } = string.Empty;
}
public static bool IsEnabled(string repo, List<Models.Branch> branches)
{
var localBrancheNames = new HashSet<string>();
foreach (var branch in branches)
{
if (branch.IsLocal)
localBrancheNames.Add(branch.Name);
}
var config = new Config(repo).ListAll();
if (!config.TryGetValue("gitflow.branch.master", out string master) || !localBrancheNames.Contains(master))
return false;
if (!config.TryGetValue("gitflow.branch.develop", out string develop) || !localBrancheNames.Contains(develop))
return false;
return config.ContainsKey("gitflow.prefix.feature") &&
config.ContainsKey("gitflow.prefix.release") &&
config.ContainsKey("gitflow.prefix.hotfix");
}
public static bool Init(string repo, List<Models.Branch> branches, string master, string develop, string feature, string release, string hotfix, string version, Models.ICommandLog log)
{
var current = branches.Find(x => x.IsCurrent);
var masterBranch = branches.Find(x => x.Name == master);
if (masterBranch == null && current != null)
Branch.Create(repo, master, current.Head, log);
var devBranch = branches.Find(x => x.Name == develop);
if (devBranch == null && current != null)
Branch.Create(repo, develop, current.Head, log);
var config = new Config(repo); var config = new Config(repo);
config.Set("gitflow.branch.master", master); config.Set("gitflow.branch.master", master);
config.Set("gitflow.branch.develop", develop); config.Set("gitflow.branch.develop", develop);
@ -66,90 +25,53 @@ namespace SourceGit.Commands
return init.Exec(); return init.Exec();
} }
public static string GetPrefix(string repo, string type) public static bool Start(string repo, Models.GitFlowBranchType type, string name, Models.ICommandLog log)
{ {
return new Config(repo).Get($"gitflow.prefix.{type}");
}
public static BranchDetectResult DetectType(string repo, List<Models.Branch> branches, string branch)
{
var rs = new BranchDetectResult();
var localBrancheNames = new HashSet<string>();
foreach (var b in branches)
{
if (b.IsLocal)
localBrancheNames.Add(b.Name);
}
var config = new Config(repo).ListAll();
if (!config.TryGetValue("gitflow.branch.master", out string master) || !localBrancheNames.Contains(master))
return rs;
if (!config.TryGetValue("gitflow.branch.develop", out string develop) || !localBrancheNames.Contains(develop))
return rs;
if (!config.TryGetValue("gitflow.prefix.feature", out var feature) ||
!config.TryGetValue("gitflow.prefix.release", out var release) ||
!config.TryGetValue("gitflow.prefix.hotfix", out var hotfix))
return rs;
if (branch.StartsWith(feature, StringComparison.Ordinal))
{
rs.IsGitFlowBranch = true;
rs.Type = "feature";
rs.Prefix = feature;
}
else if (branch.StartsWith(release, StringComparison.Ordinal))
{
rs.IsGitFlowBranch = true;
rs.Type = "release";
rs.Prefix = release;
}
else if (branch.StartsWith(hotfix, StringComparison.Ordinal))
{
rs.IsGitFlowBranch = true;
rs.Type = "hotfix";
rs.Prefix = hotfix;
}
return rs;
}
public static bool Start(string repo, string type, string name, Models.ICommandLog log)
{
if (!SUPPORTED_BRANCH_TYPES.Contains(type))
{
Dispatcher.UIThread.Post(() =>
{
App.RaiseException(repo, "Bad branch type!!!");
});
return false;
}
var start = new Command(); var start = new Command();
start.WorkingDirectory = repo; start.WorkingDirectory = repo;
start.Context = repo; start.Context = repo;
start.Args = $"flow {type} start {name}";
switch (type)
{
case Models.GitFlowBranchType.Feature:
start.Args = $"flow feature start {name}";
break;
case Models.GitFlowBranchType.Release:
start.Args = $"flow release start {name}";
break;
case Models.GitFlowBranchType.Hotfix:
start.Args = $"flow hotfix start {name}";
break;
default:
Dispatcher.UIThread.Invoke(() => App.RaiseException(repo, "Bad git-flow branch type!!!"));
return false;
}
start.Log = log; start.Log = log;
return start.Exec(); return start.Exec();
} }
public static bool Finish(string repo, string type, string name, bool squash, bool push, bool keepBranch, Models.ICommandLog log) public static bool Finish(string repo, Models.GitFlowBranchType type, string name, bool squash, bool push, bool keepBranch, Models.ICommandLog log)
{ {
if (!SUPPORTED_BRANCH_TYPES.Contains(type)) var builder = new StringBuilder();
{ builder.Append("flow ");
Dispatcher.UIThread.Post(() =>
{
App.RaiseException(repo, "Bad branch type!!!");
});
switch (type)
{
case Models.GitFlowBranchType.Feature:
builder.Append("feature");
break;
case Models.GitFlowBranchType.Release:
builder.Append("release");
break;
case Models.GitFlowBranchType.Hotfix:
builder.Append("hotfix");
break;
default:
Dispatcher.UIThread.Invoke(() => App.RaiseException(repo, "Bad git-flow branch type!!!"));
return false; return false;
} }
var builder = new StringBuilder();
builder.Append("flow ");
builder.Append(type);
builder.Append(" finish "); builder.Append(" finish ");
if (squash) if (squash)
builder.Append("--squash "); builder.Append("--squash ");
@ -166,14 +88,5 @@ namespace SourceGit.Commands
finish.Log = log; finish.Log = log;
return finish.Exec(); return finish.Exec();
} }
private static readonly List<string> SUPPORTED_BRANCH_TYPES = new List<string>()
{
"feature",
"release",
"bugfix",
"hotfix",
"support",
};
} }
} }

View file

@ -11,7 +11,7 @@ namespace SourceGit.Commands
{ {
WorkingDirectory = repo; WorkingDirectory = repo;
Context = repo; Context = repo;
Args = $"diff 4b825dc642cb6eb9a060e54bf8d69288fbee4904 {commit} --numstat -- \"{path}\""; Args = $"diff {Models.Commit.EmptyTreeSHA1} {commit} --numstat -- \"{path}\"";
RaiseError = false; RaiseError = false;
} }

View file

@ -2,7 +2,7 @@
{ {
public class Pull : Command public class Pull : Command
{ {
public Pull(string repo, string remote, string branch, bool useRebase, bool noTags) public Pull(string repo, string remote, string branch, bool useRebase)
{ {
WorkingDirectory = repo; WorkingDirectory = repo;
Context = repo; Context = repo;
@ -12,9 +12,6 @@
if (useRebase) if (useRebase)
Args += "--rebase=true "; Args += "--rebase=true ";
if (noTags)
Args += "--no-tags ";
Args += $"{remote} {branch}"; Args += $"{remote} {branch}";
} }
} }

View file

@ -27,7 +27,7 @@ namespace SourceGit.Commands
return branches; return branches;
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries); var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
var remoteBranches = new HashSet<string>(); var remoteHeads = new Dictionary<string, string>();
foreach (var line in lines) foreach (var line in lines)
{ {
var b = ParseLine(line); var b = ParseLine(line);
@ -35,7 +35,7 @@ namespace SourceGit.Commands
{ {
branches.Add(b); branches.Add(b);
if (!b.IsLocal) if (!b.IsLocal)
remoteBranches.Add(b.FullName); remoteHeads.Add(b.FullName, b.Head);
else else
localBranchesCount++; localBranchesCount++;
} }
@ -44,7 +44,22 @@ namespace SourceGit.Commands
foreach (var b in branches) foreach (var b in branches)
{ {
if (b.IsLocal && !string.IsNullOrEmpty(b.Upstream)) if (b.IsLocal && !string.IsNullOrEmpty(b.Upstream))
b.IsUpstreamGone = !remoteBranches.Contains(b.Upstream); {
if (remoteHeads.TryGetValue(b.Upstream, out var upstreamHead))
{
b.IsUpstreamGone = false;
if (b.TrackStatus == null)
b.TrackStatus = new QueryTrackStatus(WorkingDirectory, b.Head, upstreamHead).Result();
}
else
{
b.IsUpstreamGone = true;
if (b.TrackStatus == null)
b.TrackStatus = new Models.BranchTrackStatus();
}
}
} }
return branches; return branches;
@ -93,9 +108,10 @@ namespace SourceGit.Commands
branch.Upstream = parts[4]; branch.Upstream = parts[4];
branch.IsUpstreamGone = false; branch.IsUpstreamGone = false;
if (branch.IsLocal && !string.IsNullOrEmpty(parts[5]) && !parts[5].Equals("=", StringComparison.Ordinal)) if (!branch.IsLocal ||
branch.TrackStatus = new QueryTrackStatus(WorkingDirectory, branch.Name, branch.Upstream).Result(); string.IsNullOrEmpty(branch.Upstream) ||
else string.IsNullOrEmpty(parts[5]) ||
parts[5].Equals("=", StringComparison.Ordinal))
branch.TrackStatus = new Models.BranchTrackStatus(); branch.TrackStatus = new Models.BranchTrackStatus();
return branch; return branch;

View file

@ -128,30 +128,16 @@ namespace SourceGit.Commands
change.Set(Models.ChangeState.Deleted, Models.ChangeState.Copied); change.Set(Models.ChangeState.Deleted, Models.ChangeState.Copied);
break; break;
case "DD": case "DD":
change.Set(Models.ChangeState.Deleted, Models.ChangeState.Deleted);
break;
case "AU": case "AU":
change.Set(Models.ChangeState.Added, Models.ChangeState.Unmerged);
break;
case "UD": case "UD":
change.Set(Models.ChangeState.Unmerged, Models.ChangeState.Deleted);
break;
case "UA": case "UA":
change.Set(Models.ChangeState.Unmerged, Models.ChangeState.Added);
break;
case "DU": case "DU":
change.Set(Models.ChangeState.Deleted, Models.ChangeState.Unmerged);
break;
case "AA": case "AA":
change.Set(Models.ChangeState.Added, Models.ChangeState.Added);
break;
case "UU": case "UU":
change.Set(Models.ChangeState.Unmerged, Models.ChangeState.Unmerged); change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
break; break;
case "??": case "??":
change.Set(Models.ChangeState.Untracked, Models.ChangeState.Untracked); change.Set(Models.ChangeState.None, Models.ChangeState.Untracked);
break;
default:
break; break;
} }

View file

@ -6,7 +6,7 @@ namespace SourceGit.Commands
{ {
public partial class QueryStagedChangesWithAmend : Command public partial class QueryStagedChangesWithAmend : Command
{ {
[GeneratedRegex(@"^:[\d]{6} ([\d]{6}) ([0-9a-f]{40}) [0-9a-f]{40} ([ACDMTUX])\d{0,6}\t(.*)$")] [GeneratedRegex(@"^:[\d]{6} ([\d]{6}) ([0-9a-f]{40}) [0-9a-f]{40} ([ACDMT])\d{0,6}\t(.*)$")]
private static partial Regex REG_FORMAT1(); private static partial Regex REG_FORMAT1();
[GeneratedRegex(@"^:[\d]{6} ([\d]{6}) ([0-9a-f]{40}) [0-9a-f]{40} R\d{0,6}\t(.*\t.*)$")] [GeneratedRegex(@"^:[\d]{6} ([\d]{6}) ([0-9a-f]{40}) [0-9a-f]{40} R\d{0,6}\t(.*\t.*)$")]
private static partial Regex REG_FORMAT2(); private static partial Regex REG_FORMAT2();
@ -22,8 +22,9 @@ namespace SourceGit.Commands
public List<Models.Change> Result() public List<Models.Change> Result()
{ {
var rs = ReadToEnd(); var rs = ReadToEnd();
if (rs.IsSuccess) if (!rs.IsSuccess)
{ return [];
var changes = new List<Models.Change>(); var changes = new List<Models.Change>();
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries); var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines) foreach (var line in lines)
@ -78,9 +79,6 @@ namespace SourceGit.Commands
case "T": case "T":
change.Set(Models.ChangeState.TypeChanged); change.Set(Models.ChangeState.TypeChanged);
break; break;
case "U":
change.Set(Models.ChangeState.Unmerged);
break;
} }
changes.Add(change); changes.Add(change);
} }
@ -89,9 +87,6 @@ namespace SourceGit.Commands
return changes; return changes;
} }
return []; private readonly string _parent;
}
private string _parent = string.Empty;
} }
} }

View file

@ -112,7 +112,7 @@ namespace SourceGit.Commands
} }
} }
Args = $"--no-optional-locks status -uno --porcelain -- {builder}"; Args = $"--no-optional-locks status --porcelain -- {builder}";
rs = ReadToEnd(); rs = ReadToEnd();
if (!rs.IsSuccess) if (!rs.IsSuccess)
return submodules; return submodules;

View file

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace SourceGit.Commands
{
public partial class QueryUpdatableSubmodules : Command
{
[GeneratedRegex(@"^([U\-\+ ])([0-9a-f]+)\s(.*?)(\s\(.*\))?$")]
private static partial Regex REG_FORMAT_STATUS();
public QueryUpdatableSubmodules(string repo)
{
WorkingDirectory = repo;
Context = repo;
Args = "submodule status";
}
public List<string> Result()
{
var submodules = new List<string>();
var rs = ReadToEnd();
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
var match = REG_FORMAT_STATUS().Match(line);
if (match.Success)
{
var stat = match.Groups[1].Value;
var path = match.Groups[3].Value;
if (!stat.StartsWith(' '))
submodules.Add(path);
}
}
return submodules;
}
}
}

View file

@ -13,7 +13,7 @@ namespace SourceGit.Commands
public bool Add(string url, string relativePath, bool recursive) public bool Add(string url, string relativePath, bool recursive)
{ {
Args = $"submodule add {url} \"{relativePath}\""; Args = $"-c protocol.file.allow=always submodule add \"{url}\" \"{relativePath}\"";
if (!Exec()) if (!Exec())
return false; return false;
@ -29,23 +29,7 @@ namespace SourceGit.Commands
} }
} }
public bool Update(string module, bool init, bool recursive, bool useRemote) public bool Update(List<string> modules, bool init, bool recursive, bool useRemote = false)
{
Args = "submodule update";
if (init)
Args += " --init";
if (recursive)
Args += " --recursive";
if (useRemote)
Args += " --remote";
if (!string.IsNullOrEmpty(module))
Args += $" -- \"{module}\"";
return Exec();
}
public bool Update(List<Models.Submodule> modules, bool init, bool recursive, bool useRemote)
{ {
var builder = new StringBuilder(); var builder = new StringBuilder();
builder.Append("submodule update"); builder.Append("submodule update");
@ -60,20 +44,22 @@ namespace SourceGit.Commands
{ {
builder.Append(" --"); builder.Append(" --");
foreach (var module in modules) foreach (var module in modules)
builder.Append($" \"{module.Path}\""); builder.Append($" \"{module}\"");
} }
Args = builder.ToString(); Args = builder.ToString();
return Exec(); return Exec();
} }
public bool Delete(string relativePath) public bool Deinit(string module, bool force)
{ {
Args = $"submodule deinit -f \"{relativePath}\""; Args = force ? $"submodule deinit -f -- \"{module}\"" : $"submodule deinit -- \"{module}\"";
if (!Exec()) return Exec();
return false; }
Args = $"rm -rf \"{relativePath}\""; public bool Delete(string module)
{
Args = $"rm -rf \"{module}\"";
return Exec(); return Exec();
} }
} }

View file

@ -1,12 +0,0 @@
namespace SourceGit.Commands
{
public class UpdateRef : Command
{
public UpdateRef(string repo, string refName, string toRevision)
{
WorkingDirectory = repo;
Context = repo;
Args = $"update-ref {refName} {toRevision}";
}
}
}

View file

@ -7,6 +7,9 @@ namespace SourceGit.Converters
{ {
public static class ListConverters public static class ListConverters
{ {
public static readonly FuncValueConverter<IList, string> Count =
new FuncValueConverter<IList, string>(v => v == null ? "0" : $"{v.Count}");
public static readonly FuncValueConverter<IList, string> ToCount = public static readonly FuncValueConverter<IList, string> ToCount =
new FuncValueConverter<IList, string>(v => v == null ? "(0)" : $"({v.Count})"); new FuncValueConverter<IList, string>(v => v == null ? "(0)" : $"({v.Count})");

View file

@ -18,8 +18,8 @@ namespace SourceGit.Models
Deleted, Deleted,
Renamed, Renamed,
Copied, Copied,
Unmerged, Untracked,
Untracked Conflicted,
} }
public class ChangeDataForAmend public class ChangeDataForAmend
@ -36,20 +36,7 @@ namespace SourceGit.Models
public string Path { get; set; } = ""; public string Path { get; set; } = "";
public string OriginalPath { get; set; } = ""; public string OriginalPath { get; set; } = "";
public ChangeDataForAmend DataForAmend { get; set; } = null; public ChangeDataForAmend DataForAmend { get; set; } = null;
public bool IsConflicted => WorkTree == ChangeState.Conflicted;
public bool IsConflict
{
get
{
if (Index == ChangeState.Unmerged || WorkTree == ChangeState.Unmerged)
return true;
if (Index == ChangeState.Added && WorkTree == ChangeState.Added)
return true;
if (Index == ChangeState.Deleted && WorkTree == ChangeState.Deleted)
return true;
return false;
}
}
public void Set(ChangeState index, ChangeState workTree = ChangeState.None) public void Set(ChangeState index, ChangeState workTree = ChangeState.None)
{ {
@ -77,6 +64,7 @@ namespace SourceGit.Models
if (Path[0] == '"') if (Path[0] == '"')
Path = Path.Substring(1, Path.Length - 2); Path = Path.Substring(1, Path.Length - 2);
if (!string.IsNullOrEmpty(OriginalPath) && OriginalPath[0] == '"') if (!string.IsNullOrEmpty(OriginalPath) && OriginalPath[0] == '"')
OriginalPath = OriginalPath.Substring(1, OriginalPath.Length - 2); OriginalPath = OriginalPath.Substring(1, OriginalPath.Length - 2);
} }

View file

@ -18,6 +18,9 @@ namespace SourceGit.Models
public class Commit public class Commit
{ {
// As retrieved by: git mktree </dev/null
public static readonly string EmptyTreeSHA1 = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
public static double OpacityForNotMerged public static double OpacityForNotMerged
{ {
get; get;

19
src/Models/Count.cs Normal file
View file

@ -0,0 +1,19 @@
using System;
namespace SourceGit.Models
{
public class Count : IDisposable
{
public int Value { get; set; } = 0;
public Count(int value)
{
Value = value;
}
public void Dispose()
{
// Ignore
}
}
}

View file

@ -65,7 +65,7 @@ namespace SourceGit.Models
/// <param name="change"></param> /// <param name="change"></param>
public DiffOption(Commit commit, Change change) public DiffOption(Commit commit, Change change)
{ {
var baseRevision = commit.Parents.Count == 0 ? "4b825dc642cb6eb9a060e54bf8d69288fbee4904" : $"{commit.SHA}^"; var baseRevision = commit.Parents.Count == 0 ? Commit.EmptyTreeSHA1 : $"{commit.SHA}^";
_revisions.Add(baseRevision); _revisions.Add(baseRevision);
_revisions.Add(commit.SHA); _revisions.Add(commit.SHA);
_path = change.Path; _path = change.Path;
@ -79,7 +79,7 @@ namespace SourceGit.Models
/// <param name="file"></param> /// <param name="file"></param>
public DiffOption(Commit commit, string file) public DiffOption(Commit commit, string file)
{ {
var baseRevision = commit.Parents.Count == 0 ? "4b825dc642cb6eb9a060e54bf8d69288fbee4904" : $"{commit.SHA}^"; var baseRevision = commit.Parents.Count == 0 ? Commit.EmptyTreeSHA1 : $"{commit.SHA}^";
_revisions.Add(baseRevision); _revisions.Add(baseRevision);
_revisions.Add(commit.SHA); _revisions.Add(commit.SHA);
_path = file; _path = file;
@ -124,6 +124,6 @@ namespace SourceGit.Models
private readonly string _path; private readonly string _path;
private readonly string _orgPath = string.Empty; private readonly string _orgPath = string.Empty;
private readonly string _extra = string.Empty; private readonly string _extra = string.Empty;
private readonly List<string> _revisions = new List<string>(); private readonly List<string> _revisions = [];
} }
} }

46
src/Models/GitFlow.cs Normal file
View file

@ -0,0 +1,46 @@
namespace SourceGit.Models
{
public enum GitFlowBranchType
{
None = 0,
Feature,
Release,
Hotfix,
}
public class GitFlow
{
public string Master { get; set; } = string.Empty;
public string Develop { get; set; } = string.Empty;
public string FeaturePrefix { get; set; } = string.Empty;
public string ReleasePrefix { get; set; } = string.Empty;
public string HotfixPrefix { get; set; } = string.Empty;
public bool IsValid
{
get
{
return !string.IsNullOrEmpty(Master) &&
!string.IsNullOrEmpty(Develop) &&
!string.IsNullOrEmpty(FeaturePrefix) &&
!string.IsNullOrEmpty(ReleasePrefix) &&
!string.IsNullOrEmpty(HotfixPrefix);
}
}
public string GetPrefix(GitFlowBranchType type)
{
switch (type)
{
case GitFlowBranchType.Feature:
return FeaturePrefix;
case GitFlowBranchType.Release:
return ReleasePrefix;
case GitFlowBranchType.Hotfix:
return HotfixPrefix;
default:
return string.Empty;
}
}
}
}

View file

@ -2,6 +2,8 @@
{ {
public interface IRepository public interface IRepository
{ {
bool MayHaveSubmodules();
void RefreshBranches(); void RefreshBranches();
void RefreshWorktrees(); void RefreshWorktrees();
void RefreshTags(); void RefreshTags();

View file

@ -6,8 +6,10 @@ namespace SourceGit.Models
{ {
public partial class Remote public partial class Remote
{ {
[GeneratedRegex(@"^https?://([-a-zA-Z0-9:%._\+~#=]+@)?[-a-zA-Z0-9:%._\+~#=]{1,256}(\.[a-zA-Z0-9()]{1,6})?(:[0-9]{1,5})?\b(/[-a-zA-Z0-9()@:%_\+.~#?&=]+)+(\.git)?$")] [GeneratedRegex(@"^https?://[^/]+/.+[^/\.]$")]
private static partial Regex REG_HTTPS(); private static partial Regex REG_HTTPS();
[GeneratedRegex(@"^git://[^/]+/.+[^/\.]$")]
private static partial Regex REG_GIT();
[GeneratedRegex(@"^[\w\-]+@[\w\.\-]+(\:[0-9]+)?:([a-zA-z0-9~%][\w\-\./~%]*)?[a-zA-Z0-9](\.git)?$")] [GeneratedRegex(@"^[\w\-]+@[\w\.\-]+(\:[0-9]+)?:([a-zA-z0-9~%][\w\-\./~%]*)?[a-zA-Z0-9](\.git)?$")]
private static partial Regex REG_SSH1(); private static partial Regex REG_SSH1();
[GeneratedRegex(@"^ssh://([\w\-]+@)?[\w\.\-]+(\:[0-9]+)?/([a-zA-z0-9~%][\w\-\./~%]*)?[a-zA-Z0-9](\.git)?$")] [GeneratedRegex(@"^ssh://([\w\-]+@)?[\w\.\-]+(\:[0-9]+)?/([a-zA-z0-9~%][\w\-\./~%]*)?[a-zA-Z0-9](\.git)?$")]
@ -18,6 +20,7 @@ namespace SourceGit.Models
private static readonly Regex[] URL_FORMATS = [ private static readonly Regex[] URL_FORMATS = [
REG_HTTPS(), REG_HTTPS(),
REG_GIT(),
REG_SSH1(), REG_SSH1(),
REG_SSH2(), REG_SSH2(),
]; ];
@ -30,13 +33,10 @@ namespace SourceGit.Models
if (string.IsNullOrWhiteSpace(url)) if (string.IsNullOrWhiteSpace(url))
return false; return false;
for (int i = 1; i < URL_FORMATS.Length; i++) if (REG_SSH1().IsMatch(url))
{
if (URL_FORMATS[i].IsMatch(url))
return true; return true;
}
return false; return REG_SSH2().IsMatch(url);
} }
public static bool IsValidURL(string url) public static bool IsValidURL(string url)
@ -50,7 +50,10 @@ namespace SourceGit.Models
return true; return true;
} }
return url.EndsWith(".git", StringComparison.Ordinal) && Directory.Exists(url); return url.StartsWith("file://", StringComparison.Ordinal) ||
url.StartsWith("./", StringComparison.Ordinal) ||
url.StartsWith("../", StringComparison.Ordinal) ||
Directory.Exists(url);
} }
public bool TryGetVisitURL(out string url) public bool TryGetVisitURL(out string url)

View file

@ -80,18 +80,6 @@ namespace SourceGit.Models
set; set;
} = true; } = true;
public bool FetchWithoutTagsOnPull
{
get;
set;
} = false;
public bool FetchAllBranchesOnPull
{
get;
set;
} = true;
public bool CheckSubmodulesOnPush public bool CheckSubmodulesOnPush
{ {
get; get;
@ -417,6 +405,7 @@ namespace SourceGit.Models
public void PushCommitMessage(string message) public void PushCommitMessage(string message)
{ {
message = message.Trim().ReplaceLineEndings("\n");
var existIdx = CommitMessages.IndexOf(message); var existIdx = CommitMessages.IndexOf(message);
if (existIdx == 0) if (existIdx == 0)
return; return;

View file

@ -107,7 +107,6 @@ namespace SourceGit.Models
{ {
_updateBranch = 0; _updateBranch = 0;
_updateWC = 0; _updateWC = 0;
_updateSubmodules = 0;
if (_updateTags > 0) if (_updateTags > 0)
{ {
@ -115,10 +114,15 @@ namespace SourceGit.Models
Task.Run(_repo.RefreshTags); Task.Run(_repo.RefreshTags);
} }
if (_updateSubmodules > 0 || _repo.MayHaveSubmodules())
{
_updateSubmodules = 0;
Task.Run(_repo.RefreshSubmodules);
}
Task.Run(_repo.RefreshBranches); Task.Run(_repo.RefreshBranches);
Task.Run(_repo.RefreshCommits); Task.Run(_repo.RefreshCommits);
Task.Run(_repo.RefreshWorkingCopyChanges); Task.Run(_repo.RefreshWorkingCopyChanges);
Task.Run(_repo.RefreshSubmodules);
Task.Run(_repo.RefreshWorktrees); Task.Run(_repo.RefreshWorktrees);
} }
@ -150,15 +154,30 @@ namespace SourceGit.Models
private void OnRepositoryChanged(object o, FileSystemEventArgs e) private void OnRepositoryChanged(object o, FileSystemEventArgs e)
{ {
if (string.IsNullOrEmpty(e.Name) || e.Name.EndsWith(".lock", StringComparison.Ordinal)) if (string.IsNullOrEmpty(e.Name))
return; return;
var name = e.Name.Replace("\\", "/"); var name = e.Name.Replace("\\", "/");
if (name.StartsWith("modules", StringComparison.Ordinal) && name.EndsWith("HEAD", StringComparison.Ordinal)) if (name.Contains("fsmonitor--daemon/", StringComparison.Ordinal) ||
name.EndsWith(".lock", StringComparison.Ordinal) ||
name.StartsWith("lfs/", StringComparison.Ordinal))
return;
if (name.StartsWith("modules", StringComparison.Ordinal))
{
if (name.EndsWith("/HEAD", StringComparison.Ordinal) ||
name.EndsWith("/ORIG_HEAD", StringComparison.Ordinal))
{ {
_updateSubmodules = DateTime.Now.AddSeconds(1).ToFileTime(); _updateSubmodules = DateTime.Now.AddSeconds(1).ToFileTime();
_updateWC = DateTime.Now.AddSeconds(1).ToFileTime(); _updateWC = DateTime.Now.AddSeconds(1).ToFileTime();
} }
}
else if (name.Equals("MERGE_HEAD", StringComparison.Ordinal) ||
name.Equals("AUTO_MERGE", StringComparison.Ordinal))
{
if (_repo.MayHaveSubmodules())
_updateSubmodules = DateTime.Now.AddSeconds(1).ToFileTime();
}
else if (name.StartsWith("refs/tags", StringComparison.Ordinal)) else if (name.StartsWith("refs/tags", StringComparison.Ordinal))
{ {
_updateTags = DateTime.Now.AddSeconds(.5).ToFileTime(); _updateTags = DateTime.Now.AddSeconds(.5).ToFileTime();
@ -187,9 +206,20 @@ namespace SourceGit.Models
return; return;
var name = e.Name.Replace("\\", "/"); var name = e.Name.Replace("\\", "/");
if (name == ".git" || name.StartsWith(".git/", StringComparison.Ordinal)) if (name.Equals(".git", StringComparison.Ordinal) ||
name.StartsWith(".git/", StringComparison.Ordinal) ||
name.EndsWith("/.git", StringComparison.Ordinal))
return; return;
if (name.StartsWith(".vs/", StringComparison.Ordinal))
return;
if (name.Equals(".gitmodules", StringComparison.Ordinal))
{
_updateSubmodules = DateTime.Now.AddSeconds(1).ToFileTime();
return;
}
lock (_lockSubmodule) lock (_lockSubmodule)
{ {
foreach (var submodule in _submodules) foreach (var submodule in _submodules)

View file

@ -124,7 +124,7 @@ namespace SourceGit.Native
Directory.CreateDirectory(DataDir); Directory.CreateDirectory(DataDir);
} }
public static void SetupEnternalTools() public static void SetupExternalTools()
{ {
ExternalTools = _backend.FindExternalTools(); ExternalTools = _backend.FindExternalTools();
} }

View file

@ -292,7 +292,6 @@
<x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">Ausgewähltes Repository bearbeiten</x:String> <x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">Ausgewähltes Repository bearbeiten</x:String>
<x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">Führe benutzerdefinierte Aktion aus</x:String> <x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">Führe benutzerdefinierte Aktion aus</x:String>
<x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">Name der Aktion:</x:String> <x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">Name der Aktion:</x:String>
<x:String x:Key="Text.FastForwardWithoutCheck" xml:space="preserve">Fast-Forward (ohne Auschecken)</x:String>
<x:String x:Key="Text.Fetch" xml:space="preserve">Fetch</x:String> <x:String x:Key="Text.Fetch" xml:space="preserve">Fetch</x:String>
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Alle Remotes fetchen</x:String> <x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Alle Remotes fetchen</x:String>
<x:String x:Key="Text.Fetch.Force" xml:space="preserve">Aktiviere '--force' Option</x:String> <x:String x:Key="Text.Fetch.Force" xml:space="preserve">Aktiviere '--force' Option</x:String>
@ -527,12 +526,10 @@
<x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">Worktree Informationen in `$GIT_COMMON_DIR/worktrees` löschen</x:String> <x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">Worktree Informationen in `$GIT_COMMON_DIR/worktrees` löschen</x:String>
<x:String x:Key="Text.Pull" xml:space="preserve">Pull</x:String> <x:String x:Key="Text.Pull" xml:space="preserve">Pull</x:String>
<x:String x:Key="Text.Pull.Branch" xml:space="preserve">Remote-Branch:</x:String> <x:String x:Key="Text.Pull.Branch" xml:space="preserve">Remote-Branch:</x:String>
<x:String x:Key="Text.Pull.FetchAllBranches" xml:space="preserve">Alle Branches fetchen</x:String>
<x:String x:Key="Text.Pull.Into" xml:space="preserve">Lokaler Branch:</x:String> <x:String x:Key="Text.Pull.Into" xml:space="preserve">Lokaler Branch:</x:String>
<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.NoTags" xml:space="preserve">Ohne Tags fetchen</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>

View file

@ -63,6 +63,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}$ on ${1}$...</x:String> <x:String x:Key="Text.BranchCM.Rebase" xml:space="preserve">Rebase ${0}$ on ${1}$...</x:String>
<x:String x:Key="Text.BranchCM.Rename" xml:space="preserve">Rename ${0}$...</x:String> <x:String x:Key="Text.BranchCM.Rename" xml:space="preserve">Rename ${0}$...</x:String>
<x:String x:Key="Text.BranchCM.ResetToSelectedCommit" xml:space="preserve">Reset ${0}$ to ${1}$...</x:String>
<x:String x:Key="Text.BranchCM.Tracking" xml:space="preserve">Set Tracking Branch...</x:String> <x:String x:Key="Text.BranchCM.Tracking" xml:space="preserve">Set Tracking Branch...</x:String>
<x:String x:Key="Text.BranchCompare" xml:space="preserve">Branch Compare</x:String> <x:String x:Key="Text.BranchCompare" xml:space="preserve">Branch Compare</x:String>
<x:String x:Key="Text.BranchUpstreamInvalid" xml:space="preserve">Invalid upstream!</x:String> <x:String x:Key="Text.BranchUpstreamInvalid" xml:space="preserve">Invalid upstream!</x:String>
@ -124,6 +125,7 @@
<x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">Squash into Parent</x:String> <x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">Squash into Parent</x:String>
<x:String x:Key="Text.CommitCM.SquashCommitsSinceThis" xml:space="preserve">Squash Children into Here</x:String> <x:String x:Key="Text.CommitCM.SquashCommitsSinceThis" xml:space="preserve">Squash Children into Here</x:String>
<x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">CHANGES</x:String> <x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">CHANGES</x:String>
<x:String x:Key="Text.CommitDetail.Changes.Count" xml:space="preserve">changed file(s)</x:String>
<x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">Search Changes...</x:String> <x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">Search Changes...</x:String>
<x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">FILES</x:String> <x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">FILES</x:String>
<x:String x:Key="Text.CommitDetail.Files.LFS" xml:space="preserve">LFS File</x:String> <x:String x:Key="Text.CommitDetail.Files.LFS" xml:space="preserve">LFS File</x:String>
@ -215,6 +217,7 @@
<x:String x:Key="Text.CreateBranch.Name.Placeholder" xml:space="preserve">Enter branch name.</x:String> <x:String x:Key="Text.CreateBranch.Name.Placeholder" xml:space="preserve">Enter branch name.</x:String>
<x:String x:Key="Text.CreateBranch.Name.WarnSpace" xml:space="preserve">Spaces will be replaced with dashes.</x:String> <x:String x:Key="Text.CreateBranch.Name.WarnSpace" xml:space="preserve">Spaces will be replaced with dashes.</x:String>
<x:String x:Key="Text.CreateBranch.Title" xml:space="preserve">Create Local Branch</x:String> <x:String x:Key="Text.CreateBranch.Title" xml:space="preserve">Create Local Branch</x:String>
<x:String x:Key="Text.CreateBranch.OverwriteExisting" xml:space="preserve">Overwrite existing branch</x:String>
<x:String x:Key="Text.CreateTag" xml:space="preserve">Create Tag...</x:String> <x:String x:Key="Text.CreateTag" xml:space="preserve">Create Tag...</x:String>
<x:String x:Key="Text.CreateTag.BasedOn" xml:space="preserve">New Tag At:</x:String> <x:String x:Key="Text.CreateTag.BasedOn" xml:space="preserve">New Tag At:</x:String>
<x:String x:Key="Text.CreateTag.GPGSign" xml:space="preserve">GPG signing</x:String> <x:String x:Key="Text.CreateTag.GPGSign" xml:space="preserve">GPG signing</x:String>
@ -229,6 +232,9 @@
<x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">lightweight</x:String> <x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">lightweight</x:String>
<x:String x:Key="Text.CtrlClickTip" xml:space="preserve">Hold Ctrl to start directly</x:String> <x:String x:Key="Text.CtrlClickTip" xml:space="preserve">Hold Ctrl to start directly</x:String>
<x:String x:Key="Text.Cut" xml:space="preserve">Cut</x:String> <x:String x:Key="Text.Cut" xml:space="preserve">Cut</x:String>
<x:String x:Key="Text.DeinitSubmodule" xml:space="preserve">De-initialize Submodule</x:String>
<x:String x:Key="Text.DeinitSubmodule.Force" xml:space="preserve">Force de-init even if it contains local changes.</x:String>
<x:String x:Key="Text.DeinitSubmodule.Path" xml:space="preserve">Submodule:</x:String>
<x:String x:Key="Text.DeleteBranch" xml:space="preserve">Delete Branch</x:String> <x:String x:Key="Text.DeleteBranch" xml:space="preserve">Delete Branch</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">You are about to delete a remote branch!!!</x:String> <x:String x:Key="Text.DeleteBranch.IsRemoteTip" xml:space="preserve">You are about to delete a remote branch!!!</x:String>
@ -264,6 +270,7 @@
<x:String x:Key="Text.Diff.ShowHiddenSymbols" xml:space="preserve">Show hidden symbols</x:String> <x:String x:Key="Text.Diff.ShowHiddenSymbols" xml:space="preserve">Show hidden symbols</x:String>
<x:String x:Key="Text.Diff.SideBySide" xml:space="preserve">Side-By-Side Diff</x:String> <x:String x:Key="Text.Diff.SideBySide" xml:space="preserve">Side-By-Side Diff</x:String>
<x:String x:Key="Text.Diff.Submodule" xml:space="preserve">SUBMODULE</x:String> <x:String x:Key="Text.Diff.Submodule" xml:space="preserve">SUBMODULE</x:String>
<x:String x:Key="Text.Diff.Submodule.Deleted" xml:space="preserve">DELETED</x:String>
<x:String x:Key="Text.Diff.Submodule.New" xml:space="preserve">NEW</x:String> <x:String x:Key="Text.Diff.Submodule.New" xml:space="preserve">NEW</x:String>
<x:String x:Key="Text.Diff.SwapCommits" xml:space="preserve">Swap</x:String> <x:String x:Key="Text.Diff.SwapCommits" xml:space="preserve">Swap</x:String>
<x:String x:Key="Text.Diff.SyntaxHighlight" xml:space="preserve">Syntax Highlighting</x:String> <x:String x:Key="Text.Diff.SyntaxHighlight" xml:space="preserve">Syntax Highlighting</x:String>
@ -288,7 +295,6 @@
<x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">Edit Selected Repository</x:String> <x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">Edit Selected Repository</x:String>
<x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">Run Custom Action</x:String> <x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">Run Custom Action</x:String>
<x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">Action Name:</x:String> <x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">Action Name:</x:String>
<x:String x:Key="Text.FastForwardWithoutCheck" xml:space="preserve">Fast-Forward (without checkout)</x:String>
<x:String x:Key="Text.Fetch" xml:space="preserve">Fetch</x:String> <x:String x:Key="Text.Fetch" xml:space="preserve">Fetch</x:String>
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Fetch all remotes</x:String> <x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Fetch all remotes</x:String>
<x:String x:Key="Text.Fetch.Force" xml:space="preserve">Force override local refs</x:String> <x:String x:Key="Text.Fetch.Force" xml:space="preserve">Force override local refs</x:String>
@ -530,12 +536,11 @@
<x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">Prune worktree information in `$GIT_COMMON_DIR/worktrees`</x:String> <x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">Prune worktree information in `$GIT_COMMON_DIR/worktrees`</x:String>
<x:String x:Key="Text.Pull" xml:space="preserve">Pull</x:String> <x:String x:Key="Text.Pull" xml:space="preserve">Pull</x:String>
<x:String x:Key="Text.Pull.Branch" xml:space="preserve">Remote Branch:</x:String> <x:String x:Key="Text.Pull.Branch" xml:space="preserve">Remote Branch:</x:String>
<x:String x:Key="Text.Pull.FetchAllBranches" xml:space="preserve">Fetch all branches</x:String>
<x:String x:Key="Text.Pull.Into" xml:space="preserve">Into:</x:String> <x:String x:Key="Text.Pull.Into" xml:space="preserve">Into:</x:String>
<x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">Local Changes:</x:String> <x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">Local Changes:</x:String>
<x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">Discard</x:String> <x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">Discard</x:String>
<x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">Stash &amp; Reapply</x:String> <x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">Stash &amp; Reapply</x:String>
<x:String x:Key="Text.Pull.NoTags" xml:space="preserve">Fetch without tags</x:String> <x:String x:Key="Text.Pull.RecurseSubmodules" xml:space="preserve">Update all submodules</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">Use rebase instead of merge</x:String> <x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">Use rebase instead of merge</x:String>
@ -646,6 +651,9 @@
<x:String x:Key="Text.Reset.Mode" xml:space="preserve">Reset Mode:</x:String> <x:String x:Key="Text.Reset.Mode" xml:space="preserve">Reset Mode:</x:String>
<x:String x:Key="Text.Reset.MoveTo" xml:space="preserve">Move To:</x:String> <x:String x:Key="Text.Reset.MoveTo" xml:space="preserve">Move To:</x:String>
<x:String x:Key="Text.Reset.Target" xml:space="preserve">Current Branch:</x:String> <x:String x:Key="Text.Reset.Target" xml:space="preserve">Current Branch:</x:String>
<x:String x:Key="Text.ResetWithoutCheckout" xml:space="preserve">Reset Branch (Without Checkout)</x:String>
<x:String x:Key="Text.ResetWithoutCheckout.MoveTo" xml:space="preserve">Move To:</x:String>
<x:String x:Key="Text.ResetWithoutCheckout.Target" xml:space="preserve">Branch:</x:String>
<x:String x:Key="Text.RevealFile" xml:space="preserve">Reveal in File Explorer</x:String> <x:String x:Key="Text.RevealFile" xml:space="preserve">Reveal in File Explorer</x:String>
<x:String x:Key="Text.Revert" xml:space="preserve">Revert Commit</x:String> <x:String x:Key="Text.Revert" xml:space="preserve">Revert Commit</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>
@ -705,6 +713,7 @@
<x:String x:Key="Text.Submodule" xml:space="preserve">SUBMODULES</x:String> <x:String x:Key="Text.Submodule" xml:space="preserve">SUBMODULES</x:String>
<x:String x:Key="Text.Submodule.Add" xml:space="preserve">Add Submodule</x:String> <x:String x:Key="Text.Submodule.Add" xml:space="preserve">Add Submodule</x:String>
<x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">Copy Relative Path</x:String> <x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">Copy Relative Path</x:String>
<x:String x:Key="Text.Submodule.Deinit" xml:space="preserve">De-initialize Submodule</x:String>
<x:String x:Key="Text.Submodule.FetchNested" xml:space="preserve">Fetch nested submodules</x:String> <x:String x:Key="Text.Submodule.FetchNested" xml:space="preserve">Fetch nested submodules</x:String>
<x:String x:Key="Text.Submodule.Open" xml:space="preserve">Open Submodule Repository</x:String> <x:String x:Key="Text.Submodule.Open" xml:space="preserve">Open Submodule Repository</x:String>
<x:String x:Key="Text.Submodule.RelativePath" xml:space="preserve">Relative Path:</x:String> <x:String x:Key="Text.Submodule.RelativePath" xml:space="preserve">Relative Path:</x:String>

View file

@ -67,6 +67,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}$ en ${1}$...</x:String> <x:String x:Key="Text.BranchCM.Rebase" xml:space="preserve">Rebase ${0}$ en ${1}$...</x:String>
<x:String x:Key="Text.BranchCM.Rename" xml:space="preserve">Renombrar ${0}$...</x:String> <x:String x:Key="Text.BranchCM.Rename" xml:space="preserve">Renombrar ${0}$...</x:String>
<x:String x:Key="Text.BranchCM.ResetToSelectedCommit" xml:space="preserve">Resetear ${0}$ a ${1}$...</x:String>
<x:String x:Key="Text.BranchCM.Tracking" xml:space="preserve">Establecer Rama de Seguimiento...</x:String> <x:String x:Key="Text.BranchCM.Tracking" xml:space="preserve">Establecer Rama de Seguimiento...</x:String>
<x:String x:Key="Text.BranchCompare" xml:space="preserve">Comparar Ramas</x:String> <x:String x:Key="Text.BranchCompare" xml:space="preserve">Comparar Ramas</x:String>
<x:String x:Key="Text.BranchUpstreamInvalid" xml:space="preserve">¡Upstream inválido!</x:String> <x:String x:Key="Text.BranchUpstreamInvalid" xml:space="preserve">¡Upstream inválido!</x:String>
@ -128,6 +129,7 @@
<x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">Squash en Parent</x:String> <x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">Squash en Parent</x:String>
<x:String x:Key="Text.CommitCM.SquashCommitsSinceThis" xml:space="preserve">Squash Commits Hijos hasta Aquí</x:String> <x:String x:Key="Text.CommitCM.SquashCommitsSinceThis" xml:space="preserve">Squash Commits Hijos hasta Aquí</x:String>
<x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">CAMBIOS</x:String> <x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">CAMBIOS</x:String>
<x:String x:Key="Text.CommitDetail.Changes.Count" xml:space="preserve">archivo(s) modificado(s)</x:String>
<x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">Buscar Cambios...</x:String> <x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">Buscar Cambios...</x:String>
<x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">ARCHIVOS</x:String> <x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">ARCHIVOS</x:String>
<x:String x:Key="Text.CommitDetail.Files.LFS" xml:space="preserve">Archivo LFS</x:String> <x:String x:Key="Text.CommitDetail.Files.LFS" xml:space="preserve">Archivo LFS</x:String>
@ -233,6 +235,9 @@
<x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">ligera</x:String> <x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">ligera</x:String>
<x:String x:Key="Text.CtrlClickTip" xml:space="preserve">Mantenga Ctrl para iniciar directamente</x:String> <x:String x:Key="Text.CtrlClickTip" xml:space="preserve">Mantenga Ctrl para iniciar directamente</x:String>
<x:String x:Key="Text.Cut" xml:space="preserve">Cortar</x:String> <x:String x:Key="Text.Cut" xml:space="preserve">Cortar</x:String>
<x:String x:Key="Text.DeinitSubmodule" xml:space="preserve">Desinicializar Submódulo</x:String>
<x:String x:Key="Text.DeinitSubmodule.Force" xml:space="preserve">Forzar desinicialización incluso si contiene cambios locales.</x:String>
<x:String x:Key="Text.DeinitSubmodule.Path" xml:space="preserve">Submódulo:</x:String>
<x:String x:Key="Text.DeleteBranch" xml:space="preserve">Eliminar Rama</x:String> <x:String x:Key="Text.DeleteBranch" xml:space="preserve">Eliminar Rama</x:String>
<x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">Rama:</x:String> <x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">Rama:</x:String>
<x:String x:Key="Text.DeleteBranch.IsRemoteTip" xml:space="preserve">¡Estás a punto de eliminar una rama remota!</x:String> <x:String x:Key="Text.DeleteBranch.IsRemoteTip" xml:space="preserve">¡Estás a punto de eliminar una rama remota!</x:String>
@ -268,6 +273,7 @@
<x:String x:Key="Text.Diff.ShowHiddenSymbols" xml:space="preserve">Mostrar símbolos ocultos</x:String> <x:String x:Key="Text.Diff.ShowHiddenSymbols" xml:space="preserve">Mostrar símbolos ocultos</x:String>
<x:String x:Key="Text.Diff.SideBySide" xml:space="preserve">Diferencia Lado a Lado</x:String> <x:String x:Key="Text.Diff.SideBySide" xml:space="preserve">Diferencia Lado a Lado</x:String>
<x:String x:Key="Text.Diff.Submodule" xml:space="preserve">SUBMÓDULO</x:String> <x:String x:Key="Text.Diff.Submodule" xml:space="preserve">SUBMÓDULO</x:String>
<x:String x:Key="Text.Diff.Submodule.Deleted" xml:space="preserve">BORRADO</x:String>
<x:String x:Key="Text.Diff.Submodule.New" xml:space="preserve">NUEVO</x:String> <x:String x:Key="Text.Diff.Submodule.New" xml:space="preserve">NUEVO</x:String>
<x:String x:Key="Text.Diff.SwapCommits" xml:space="preserve">Intercambiar</x:String> <x:String x:Key="Text.Diff.SwapCommits" xml:space="preserve">Intercambiar</x:String>
<x:String x:Key="Text.Diff.SyntaxHighlight" xml:space="preserve">Resaltado de Sintaxis</x:String> <x:String x:Key="Text.Diff.SyntaxHighlight" xml:space="preserve">Resaltado de Sintaxis</x:String>
@ -292,7 +298,6 @@
<x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">Editar Repositorio Seleccionado</x:String> <x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">Editar Repositorio Seleccionado</x:String>
<x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">Ejecutar Acción Personalizada</x:String> <x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">Ejecutar Acción Personalizada</x:String>
<x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">Nombre de la Acción:</x:String> <x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">Nombre de la Acción:</x:String>
<x:String x:Key="Text.FastForwardWithoutCheck" xml:space="preserve">Fast-Forward (sin checkout)</x:String>
<x:String x:Key="Text.Fetch" xml:space="preserve">Fetch</x:String> <x:String x:Key="Text.Fetch" xml:space="preserve">Fetch</x:String>
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Fetch todos los remotos</x:String> <x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Fetch todos los remotos</x:String>
<x:String x:Key="Text.Fetch.Force" xml:space="preserve">Utilizar opción '--force'</x:String> <x:String x:Key="Text.Fetch.Force" xml:space="preserve">Utilizar opción '--force'</x:String>
@ -390,6 +395,8 @@
<x:String x:Key="Text.Hotkeys.Global.GotoPrevTab" xml:space="preserve">Ir a la página anterior</x:String> <x:String x:Key="Text.Hotkeys.Global.GotoPrevTab" xml:space="preserve">Ir a la página anterior</x:String>
<x:String x:Key="Text.Hotkeys.Global.NewTab" xml:space="preserve">Crear nueva página</x:String> <x:String x:Key="Text.Hotkeys.Global.NewTab" xml:space="preserve">Crear nueva página</x:String>
<x:String x:Key="Text.Hotkeys.Global.OpenPreferences" xml:space="preserve">Abrir diálogo de preferencias</x:String> <x:String x:Key="Text.Hotkeys.Global.OpenPreferences" xml:space="preserve">Abrir diálogo de preferencias</x:String>
<x:String x:Key="Text.Hotkeys.Global.SwitchWorkspace" xml:space="preserve">Cambiar espacio de trabajo activo</x:String>
<x:String x:Key="Text.Hotkeys.Global.SwitchTab" xml:space="preserve">Cambiar página activa</x:String>
<x:String x:Key="Text.Hotkeys.Repo" xml:space="preserve">REPOSITORIO</x:String> <x:String x:Key="Text.Hotkeys.Repo" xml:space="preserve">REPOSITORIO</x:String>
<x:String x:Key="Text.Hotkeys.Repo.Commit" xml:space="preserve">Commit cambios staged</x:String> <x:String x:Key="Text.Hotkeys.Repo.Commit" xml:space="preserve">Commit cambios staged</x:String>
<x:String x:Key="Text.Hotkeys.Repo.CommitAndPush" xml:space="preserve">Commit y push cambios staged</x:String> <x:String x:Key="Text.Hotkeys.Repo.CommitAndPush" xml:space="preserve">Commit y push cambios staged</x:String>
@ -432,6 +439,8 @@
<x:String x:Key="Text.IssueLinkCM.OpenInBrowser" xml:space="preserve">Abrir en el Navegador</x:String> <x:String x:Key="Text.IssueLinkCM.OpenInBrowser" xml:space="preserve">Abrir en el Navegador</x:String>
<x:String x:Key="Text.Launcher.Error" xml:space="preserve">ERROR</x:String> <x:String x:Key="Text.Launcher.Error" xml:space="preserve">ERROR</x:String>
<x:String x:Key="Text.Launcher.Info" xml:space="preserve">AVISO</x:String> <x:String x:Key="Text.Launcher.Info" xml:space="preserve">AVISO</x:String>
<x:String x:Key="Text.Launcher.Workspaces" xml:space="preserve">Espacios de trabajo</x:String>
<x:String x:Key="Text.Launcher.Pages" xml:space="preserve">Páginas</x:String>
<x:String x:Key="Text.Merge" xml:space="preserve">Merge Rama</x:String> <x:String x:Key="Text.Merge" xml:space="preserve">Merge Rama</x:String>
<x:String x:Key="Text.Merge.Into" xml:space="preserve">En:</x:String> <x:String x:Key="Text.Merge.Into" xml:space="preserve">En:</x:String>
<x:String x:Key="Text.Merge.Mode" xml:space="preserve">Opción de Merge:</x:String> <x:String x:Key="Text.Merge.Mode" xml:space="preserve">Opción de Merge:</x:String>
@ -530,12 +539,11 @@
<x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">Podar información de worktree en `$GIT_COMMON_DIR/worktrees`</x:String> <x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">Podar información de worktree en `$GIT_COMMON_DIR/worktrees`</x:String>
<x:String x:Key="Text.Pull" xml:space="preserve">Pull</x:String> <x:String x:Key="Text.Pull" xml:space="preserve">Pull</x:String>
<x:String x:Key="Text.Pull.Branch" xml:space="preserve">Rama Remota:</x:String> <x:String x:Key="Text.Pull.Branch" xml:space="preserve">Rama Remota:</x:String>
<x:String x:Key="Text.Pull.FetchAllBranches" xml:space="preserve">Fetch todas las ramas</x:String>
<x:String x:Key="Text.Pull.Into" xml:space="preserve">En:</x:String> <x:String x:Key="Text.Pull.Into" xml:space="preserve">En:</x:String>
<x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">Cambios Locales:</x:String> <x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">Cambios Locales:</x:String>
<x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">Descartar</x:String> <x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">Descartar</x:String>
<x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">Stash &amp; Reaplicar</x:String> <x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">Stash &amp; Reaplicar</x:String>
<x:String x:Key="Text.Pull.NoTags" xml:space="preserve">Fetch sin etiquetas</x:String> <x:String x:Key="Text.Pull.RecurseSubmodules" xml:space="preserve">Actualizar todos los submódulos</x:String>
<x:String x:Key="Text.Pull.Remote" xml:space="preserve">Remoto:</x:String> <x:String x:Key="Text.Pull.Remote" xml:space="preserve">Remoto:</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">Usar rebase en lugar de merge</x:String> <x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">Usar rebase en lugar de merge</x:String>
@ -646,6 +654,9 @@
<x:String x:Key="Text.Reset.Mode" xml:space="preserve">Modo de Reset:</x:String> <x:String x:Key="Text.Reset.Mode" xml:space="preserve">Modo de Reset:</x:String>
<x:String x:Key="Text.Reset.MoveTo" xml:space="preserve">Mover a:</x:String> <x:String x:Key="Text.Reset.MoveTo" xml:space="preserve">Mover a:</x:String>
<x:String x:Key="Text.Reset.Target" xml:space="preserve">Rama Actual:</x:String> <x:String x:Key="Text.Reset.Target" xml:space="preserve">Rama Actual:</x:String>
<x:String x:Key="Text.ResetWithoutCheckout" xml:space="preserve">Resetear Rama (Sin hacer Checkout)</x:String>
<x:String x:Key="Text.ResetWithoutCheckout.MoveTo" xml:space="preserve">Mover A:</x:String>
<x:String x:Key="Text.ResetWithoutCheckout.Target" xml:space="preserve">Rama:</x:String>
<x:String x:Key="Text.RevealFile" xml:space="preserve">Revelar en el Explorador de Archivos</x:String> <x:String x:Key="Text.RevealFile" xml:space="preserve">Revelar en el Explorador de Archivos</x:String>
<x:String x:Key="Text.Revert" xml:space="preserve">Revertir Commit</x:String> <x:String x:Key="Text.Revert" xml:space="preserve">Revertir Commit</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>
@ -705,6 +716,7 @@
<x:String x:Key="Text.Submodule" xml:space="preserve">SUBMÓDULOS</x:String> <x:String x:Key="Text.Submodule" xml:space="preserve">SUBMÓDULOS</x:String>
<x:String x:Key="Text.Submodule.Add" xml:space="preserve">Añadir Submódulo</x:String> <x:String x:Key="Text.Submodule.Add" xml:space="preserve">Añadir Submódulo</x:String>
<x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">Copiar Ruta Relativa</x:String> <x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">Copiar Ruta Relativa</x:String>
<x:String x:Key="Text.Submodule.Deinit" xml:space="preserve">Desinicializar Submódulo</x:String>
<x:String x:Key="Text.Submodule.FetchNested" xml:space="preserve">Fetch submódulos anidados</x:String> <x:String x:Key="Text.Submodule.FetchNested" xml:space="preserve">Fetch submódulos anidados</x:String>
<x:String x:Key="Text.Submodule.Open" xml:space="preserve">Abrir Repositorio del Submódulo</x:String> <x:String x:Key="Text.Submodule.Open" xml:space="preserve">Abrir Repositorio del Submódulo</x:String>
<x:String x:Key="Text.Submodule.RelativePath" xml:space="preserve">Ruta Relativa:</x:String> <x:String x:Key="Text.Submodule.RelativePath" xml:space="preserve">Ruta Relativa:</x:String>

View file

@ -275,7 +275,6 @@
<x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">Éditer le dépôt sélectionné</x:String> <x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">Éditer le dépôt sélectionné</x:String>
<x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">Lancer action personnalisée</x:String> <x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">Lancer action personnalisée</x:String>
<x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">Nom de l'action :</x:String> <x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">Nom de l'action :</x:String>
<x:String x:Key="Text.FastForwardWithoutCheck" xml:space="preserve">Fast-Forward (sans récupération)</x:String>
<x:String x:Key="Text.Fetch" xml:space="preserve">Fetch</x:String> <x:String x:Key="Text.Fetch" xml:space="preserve">Fetch</x:String>
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Fetch toutes les branches distantes</x:String> <x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Fetch toutes les branches distantes</x:String>
<x:String x:Key="Text.Fetch.Force" xml:space="preserve">Outrepasser les vérifications de refs</x:String> <x:String x:Key="Text.Fetch.Force" xml:space="preserve">Outrepasser les vérifications de refs</x:String>
@ -509,12 +508,10 @@
<x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve"> Élaguer les information de worktree dans `$GIT_COMMON_DIR/worktrees`</x:String> <x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve"> Élaguer les information de worktree dans `$GIT_COMMON_DIR/worktrees`</x:String>
<x:String x:Key="Text.Pull" xml:space="preserve">Pull</x:String> <x:String x:Key="Text.Pull" xml:space="preserve">Pull</x:String>
<x:String x:Key="Text.Pull.Branch" xml:space="preserve">Branche distante :</x:String> <x:String x:Key="Text.Pull.Branch" xml:space="preserve">Branche distante :</x:String>
<x:String x:Key="Text.Pull.FetchAllBranches" xml:space="preserve">Fetch toutes les branches</x:String>
<x:String x:Key="Text.Pull.Into" xml:space="preserve">Dans :</x:String> <x:String x:Key="Text.Pull.Into" xml:space="preserve">Dans :</x:String>
<x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">Changements locaux :</x:String> <x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">Changements locaux :</x:String>
<x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">Rejeter</x:String> <x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">Rejeter</x:String>
<x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">Stash &amp; Réappliquer</x:String> <x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">Stash &amp; Réappliquer</x:String>
<x:String x:Key="Text.Pull.NoTags" xml:space="preserve">Fetch sans les tags</x:String>
<x:String x:Key="Text.Pull.Remote" xml:space="preserve">Dépôt distant :</x:String> <x:String x:Key="Text.Pull.Remote" xml:space="preserve">Dépôt distant :</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">Utiliser rebase au lieu de merge</x:String> <x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">Utiliser rebase au lieu de merge</x:String>

View file

@ -292,7 +292,6 @@
<x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">Modifica Repository Selezionato</x:String> <x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">Modifica Repository Selezionato</x:String>
<x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">Esegui Azione Personalizzata</x:String> <x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">Esegui Azione Personalizzata</x:String>
<x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">Nome Azione:</x:String> <x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">Nome Azione:</x:String>
<x:String x:Key="Text.FastForwardWithoutCheck" xml:space="preserve">Avanzamento Veloce (senza verifica)</x:String>
<x:String x:Key="Text.Fetch" xml:space="preserve">Recupera</x:String> <x:String x:Key="Text.Fetch" xml:space="preserve">Recupera</x:String>
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Recupera da tutti i remoti</x:String> <x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Recupera da tutti i remoti</x:String>
<x:String x:Key="Text.Fetch.Force" xml:space="preserve">Forza la sovrascrittura dei riferimenti locali</x:String> <x:String x:Key="Text.Fetch.Force" xml:space="preserve">Forza la sovrascrittura dei riferimenti locali</x:String>
@ -530,12 +529,10 @@
<x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">Potatura delle informazioni di worktree in `$GIT_COMMON_DIR/worktrees`</x:String> <x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">Potatura delle informazioni di worktree in `$GIT_COMMON_DIR/worktrees`</x:String>
<x:String x:Key="Text.Pull" xml:space="preserve">Scarica</x:String> <x:String x:Key="Text.Pull" xml:space="preserve">Scarica</x:String>
<x:String x:Key="Text.Pull.Branch" xml:space="preserve">Branch Remoto:</x:String> <x:String x:Key="Text.Pull.Branch" xml:space="preserve">Branch Remoto:</x:String>
<x:String x:Key="Text.Pull.FetchAllBranches" xml:space="preserve">Recupera tutti i branch</x:String>
<x:String x:Key="Text.Pull.Into" xml:space="preserve">In:</x:String> <x:String x:Key="Text.Pull.Into" xml:space="preserve">In:</x:String>
<x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">Modifiche Locali:</x:String> <x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">Modifiche Locali:</x:String>
<x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">Scarta</x:String> <x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">Scarta</x:String>
<x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">Stasha e Riapplica</x:String> <x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">Stasha e Riapplica</x:String>
<x:String x:Key="Text.Pull.NoTags" xml:space="preserve">Recupera senza tag</x:String>
<x:String x:Key="Text.Pull.Remote" xml:space="preserve">Remoto:</x:String> <x:String x:Key="Text.Pull.Remote" xml:space="preserve">Remoto:</x:String>
<x:String x:Key="Text.Pull.Title" xml:space="preserve">Scarica (Recupera e Unisci)</x:String> <x:String x:Key="Text.Pull.Title" xml:space="preserve">Scarica (Recupera e Unisci)</x:String>
<x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">Riallineare anziché unire</x:String> <x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">Riallineare anziché unire</x:String>

View file

@ -275,7 +275,6 @@
<x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">選択中のリポジトリを編集</x:String> <x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">選択中のリポジトリを編集</x:String>
<x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">カスタムアクションを実行</x:String> <x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">カスタムアクションを実行</x:String>
<x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">アクション名:</x:String> <x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">アクション名:</x:String>
<x:String x:Key="Text.FastForwardWithoutCheck" xml:space="preserve">(チェックアウトせずに)ブランチを早送りする</x:String>
<x:String x:Key="Text.Fetch" xml:space="preserve">フェッチ</x:String> <x:String x:Key="Text.Fetch" xml:space="preserve">フェッチ</x:String>
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">すべてのリモートをフェッチ</x:String> <x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">すべてのリモートをフェッチ</x:String>
<x:String x:Key="Text.Fetch.Force" xml:space="preserve">ローカル参照を強制的に上書き</x:String> <x:String x:Key="Text.Fetch.Force" xml:space="preserve">ローカル参照を強制的に上書き</x:String>
@ -509,12 +508,10 @@
<x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">`$GIT_DIR/worktrees` の作業ツリー情報を削除</x:String> <x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">`$GIT_DIR/worktrees` の作業ツリー情報を削除</x:String>
<x:String x:Key="Text.Pull" xml:space="preserve">プル</x:String> <x:String x:Key="Text.Pull" xml:space="preserve">プル</x:String>
<x:String x:Key="Text.Pull.Branch" xml:space="preserve">ブランチ:</x:String> <x:String x:Key="Text.Pull.Branch" xml:space="preserve">ブランチ:</x:String>
<x:String x:Key="Text.Pull.FetchAllBranches" xml:space="preserve">すべてのブランチをフェッチ</x:String>
<x:String x:Key="Text.Pull.Into" xml:space="preserve">宛先:</x:String> <x:String x:Key="Text.Pull.Into" xml:space="preserve">宛先:</x:String>
<x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">ローカルの変更:</x:String> <x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">ローカルの変更:</x:String>
<x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">破棄</x:String> <x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">破棄</x:String>
<x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">スタッシュして再適用</x:String> <x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">スタッシュして再適用</x:String>
<x:String x:Key="Text.Pull.NoTags" xml:space="preserve">タグなしでフェッチ</x:String>
<x:String x:Key="Text.Pull.Remote" xml:space="preserve">リモート:</x:String> <x:String x:Key="Text.Pull.Remote" xml:space="preserve">リモート:</x:String>
<x:String x:Key="Text.Pull.Title" xml:space="preserve">プル (フェッチ &amp; マージ)</x:String> <x:String x:Key="Text.Pull.Title" xml:space="preserve">プル (フェッチ &amp; マージ)</x:String>
<x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">マージの代わりにリベースを使用</x:String> <x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">マージの代わりにリベースを使用</x:String>

View file

@ -249,7 +249,6 @@
<x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">Editar Repositório Selecionado</x:String> <x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">Editar Repositório Selecionado</x:String>
<x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">Executar ação customizada</x:String> <x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">Executar ação customizada</x:String>
<x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">Nome da ação:</x:String> <x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">Nome da ação:</x:String>
<x:String x:Key="Text.FastForwardWithoutCheck" xml:space="preserve">Fast-Forward (sem checkout)</x:String>
<x:String x:Key="Text.Fetch" xml:space="preserve">Buscar</x:String> <x:String x:Key="Text.Fetch" xml:space="preserve">Buscar</x:String>
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Buscar todos os remotos</x:String> <x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Buscar todos os remotos</x:String>
<x:String x:Key="Text.Fetch.NoTags" xml:space="preserve">Buscar sem tags</x:String> <x:String x:Key="Text.Fetch.NoTags" xml:space="preserve">Buscar sem tags</x:String>
@ -465,12 +464,10 @@
<x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">Podar informações de worktree em `$GIT_COMMON_DIR/worktrees`</x:String> <x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">Podar informações de worktree em `$GIT_COMMON_DIR/worktrees`</x:String>
<x:String x:Key="Text.Pull" xml:space="preserve">Puxar</x:String> <x:String x:Key="Text.Pull" xml:space="preserve">Puxar</x:String>
<x:String x:Key="Text.Pull.Branch" xml:space="preserve">Branch Remoto:</x:String> <x:String x:Key="Text.Pull.Branch" xml:space="preserve">Branch Remoto:</x:String>
<x:String x:Key="Text.Pull.FetchAllBranches" xml:space="preserve">Buscar todos os branches</x:String>
<x:String x:Key="Text.Pull.Into" xml:space="preserve">Para:</x:String> <x:String x:Key="Text.Pull.Into" xml:space="preserve">Para:</x:String>
<x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">Alterações Locais:</x:String> <x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">Alterações Locais:</x:String>
<x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">Descartar</x:String> <x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">Descartar</x:String>
<x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">Guardar &amp; Reaplicar</x:String> <x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">Guardar &amp; Reaplicar</x:String>
<x:String x:Key="Text.Pull.NoTags" xml:space="preserve">Buscar sem tags</x:String>
<x:String x:Key="Text.Pull.Remote" xml:space="preserve">Remoto:</x:String> <x:String x:Key="Text.Pull.Remote" xml:space="preserve">Remoto:</x:String>
<x:String x:Key="Text.Pull.Title" xml:space="preserve">Puxar (Buscar &amp; Mesclar)</x:String> <x:String x:Key="Text.Pull.Title" xml:space="preserve">Puxar (Buscar &amp; Mesclar)</x:String>
<x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">Usar rebase em vez de merge</x:String> <x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">Usar rebase em vez de merge</x:String>

View file

@ -67,6 +67,7 @@
<x:String x:Key="Text.BranchCM.Push" xml:space="preserve">Выложить ${0}$</x:String> <x:String x:Key="Text.BranchCM.Push" xml:space="preserve">Выложить ${0}$</x:String>
<x:String x:Key="Text.BranchCM.Rebase" xml:space="preserve">Переместить ${0}$ на ${1}$...</x:String> <x:String x:Key="Text.BranchCM.Rebase" xml:space="preserve">Переместить ${0}$ на ${1}$...</x:String>
<x:String x:Key="Text.BranchCM.Rename" xml:space="preserve">Переименовать ${0}$...</x:String> <x:String x:Key="Text.BranchCM.Rename" xml:space="preserve">Переименовать ${0}$...</x:String>
<x:String x:Key="Text.BranchCM.ResetToSelectedCommit" xml:space="preserve">Сбросить ${0}$ к ${1}$...</x:String>
<x:String x:Key="Text.BranchCM.Tracking" xml:space="preserve">Отслеживать ветку...</x:String> <x:String x:Key="Text.BranchCM.Tracking" xml:space="preserve">Отслеживать ветку...</x:String>
<x:String x:Key="Text.BranchCompare" xml:space="preserve">Сравнение веток</x:String> <x:String x:Key="Text.BranchCompare" xml:space="preserve">Сравнение веток</x:String>
<x:String x:Key="Text.BranchUpstreamInvalid" xml:space="preserve">Недопустимая основная ветка!</x:String> <x:String x:Key="Text.BranchUpstreamInvalid" xml:space="preserve">Недопустимая основная ветка!</x:String>
@ -128,6 +129,7 @@
<x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">Объединить с предыдущей ревизией</x:String> <x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">Объединить с предыдущей ревизией</x:String>
<x:String x:Key="Text.CommitCM.SquashCommitsSinceThis" xml:space="preserve">Объединить все следующие ревизии с этим</x:String> <x:String x:Key="Text.CommitCM.SquashCommitsSinceThis" xml:space="preserve">Объединить все следующие ревизии с этим</x:String>
<x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">ИЗМЕНЕНИЯ</x:String> <x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">ИЗМЕНЕНИЯ</x:String>
<x:String x:Key="Text.CommitDetail.Changes.Count" xml:space="preserve">изменённый(х) файл(ов)</x:String>
<x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">Найти изменения....</x:String> <x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">Найти изменения....</x:String>
<x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">ФАЙЛЫ</x:String> <x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">ФАЙЛЫ</x:String>
<x:String x:Key="Text.CommitDetail.Files.LFS" xml:space="preserve">Файл LFS</x:String> <x:String x:Key="Text.CommitDetail.Files.LFS" xml:space="preserve">Файл LFS</x:String>
@ -219,6 +221,7 @@
<x:String x:Key="Text.CreateBranch.Name.Placeholder" xml:space="preserve">Введите имя ветки.</x:String> <x:String x:Key="Text.CreateBranch.Name.Placeholder" xml:space="preserve">Введите имя ветки.</x:String>
<x:String x:Key="Text.CreateBranch.Name.WarnSpace" xml:space="preserve">Пробелы будут заменены на тире.</x:String> <x:String x:Key="Text.CreateBranch.Name.WarnSpace" xml:space="preserve">Пробелы будут заменены на тире.</x:String>
<x:String x:Key="Text.CreateBranch.Title" xml:space="preserve">Создать локальную ветку</x:String> <x:String x:Key="Text.CreateBranch.Title" xml:space="preserve">Создать локальную ветку</x:String>
<x:String x:Key="Text.CreateBranch.OverwriteExisting" xml:space="preserve">Перезаписать существующую ветку</x:String>
<x:String x:Key="Text.CreateTag" xml:space="preserve">Создать метку...</x:String> <x:String x:Key="Text.CreateTag" xml:space="preserve">Создать метку...</x:String>
<x:String x:Key="Text.CreateTag.BasedOn" xml:space="preserve">Новая метка у:</x:String> <x:String x:Key="Text.CreateTag.BasedOn" xml:space="preserve">Новая метка у:</x:String>
<x:String x:Key="Text.CreateTag.GPGSign" xml:space="preserve">GPG подпись</x:String> <x:String x:Key="Text.CreateTag.GPGSign" xml:space="preserve">GPG подпись</x:String>
@ -233,6 +236,9 @@
<x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">Простой</x:String> <x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">Простой</x:String>
<x:String x:Key="Text.CtrlClickTip" xml:space="preserve">Удерживайте Ctrl, чтобы сразу начать</x:String> <x:String x:Key="Text.CtrlClickTip" xml:space="preserve">Удерживайте Ctrl, чтобы сразу начать</x:String>
<x:String x:Key="Text.Cut" xml:space="preserve">Вырезать</x:String> <x:String x:Key="Text.Cut" xml:space="preserve">Вырезать</x:String>
<x:String x:Key="Text.DeinitSubmodule" xml:space="preserve">Удалить подмодуль</x:String>
<x:String x:Key="Text.DeinitSubmodule.Force" xml:space="preserve">Принудительно удалить даже если содержит локальные изменения.</x:String>
<x:String x:Key="Text.DeinitSubmodule.Path" xml:space="preserve">Подмодуль:</x:String>
<x:String x:Key="Text.DeleteBranch" xml:space="preserve">Удалить ветку</x:String> <x:String x:Key="Text.DeleteBranch" xml:space="preserve">Удалить ветку</x:String>
<x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">Ветка:</x:String> <x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">Ветка:</x:String>
<x:String x:Key="Text.DeleteBranch.IsRemoteTip" xml:space="preserve">Вы собираетесь удалить внешнюю ветку!!!</x:String> <x:String x:Key="Text.DeleteBranch.IsRemoteTip" xml:space="preserve">Вы собираетесь удалить внешнюю ветку!!!</x:String>
@ -268,6 +274,7 @@
<x:String x:Key="Text.Diff.ShowHiddenSymbols" xml:space="preserve">Показывать скрытые символы</x:String> <x:String x:Key="Text.Diff.ShowHiddenSymbols" xml:space="preserve">Показывать скрытые символы</x:String>
<x:String x:Key="Text.Diff.SideBySide" xml:space="preserve">Сравнение рядом</x:String> <x:String x:Key="Text.Diff.SideBySide" xml:space="preserve">Сравнение рядом</x:String>
<x:String x:Key="Text.Diff.Submodule" xml:space="preserve">ПОДМОДУЛЬ</x:String> <x:String x:Key="Text.Diff.Submodule" xml:space="preserve">ПОДМОДУЛЬ</x:String>
<x:String x:Key="Text.Diff.Submodule.Deleted" xml:space="preserve">УДАЛЁН</x:String>
<x:String x:Key="Text.Diff.Submodule.New" xml:space="preserve">НОВЫЙ</x:String> <x:String x:Key="Text.Diff.Submodule.New" xml:space="preserve">НОВЫЙ</x:String>
<x:String x:Key="Text.Diff.SwapCommits" xml:space="preserve">Обмен</x:String> <x:String x:Key="Text.Diff.SwapCommits" xml:space="preserve">Обмен</x:String>
<x:String x:Key="Text.Diff.SyntaxHighlight" xml:space="preserve">Подсветка синтаксиса </x:String> <x:String x:Key="Text.Diff.SyntaxHighlight" xml:space="preserve">Подсветка синтаксиса </x:String>
@ -292,7 +299,6 @@
<x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">Редактировать выбранный репозиторий</x:String> <x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">Редактировать выбранный репозиторий</x:String>
<x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">Выполнить пользовательское действие</x:String> <x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">Выполнить пользовательское действие</x:String>
<x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">Имя действия:</x:String> <x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">Имя действия:</x:String>
<x:String x:Key="Text.FastForwardWithoutCheck" xml:space="preserve">Быстрая перемотка вперёд (без проверки)</x:String>
<x:String x:Key="Text.Fetch" xml:space="preserve">Извлечь</x:String> <x:String x:Key="Text.Fetch" xml:space="preserve">Извлечь</x:String>
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Извлечь все внешние репозитории</x:String> <x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Извлечь все внешние репозитории</x:String>
<x:String x:Key="Text.Fetch.Force" xml:space="preserve">Разрешить опцию (--force)</x:String> <x:String x:Key="Text.Fetch.Force" xml:space="preserve">Разрешить опцию (--force)</x:String>
@ -391,6 +397,7 @@
<x:String x:Key="Text.Hotkeys.Global.NewTab" xml:space="preserve">Создать новую вкладку</x:String> <x:String x:Key="Text.Hotkeys.Global.NewTab" xml:space="preserve">Создать новую вкладку</x:String>
<x:String x:Key="Text.Hotkeys.Global.OpenPreferences" xml:space="preserve">Открыть диалоговое окно настроек</x:String> <x:String x:Key="Text.Hotkeys.Global.OpenPreferences" xml:space="preserve">Открыть диалоговое окно настроек</x:String>
<x:String x:Key="Text.Hotkeys.Global.SwitchWorkspace" xml:space="preserve">Переключить активное рабочее место</x:String> <x:String x:Key="Text.Hotkeys.Global.SwitchWorkspace" xml:space="preserve">Переключить активное рабочее место</x:String>
<x:String x:Key="Text.Hotkeys.Global.SwitchTab" xml:space="preserve">Переключить активную страницу</x:String>
<x:String x:Key="Text.Hotkeys.Repo" xml:space="preserve">РЕПОЗИТОРИЙ</x:String> <x:String x:Key="Text.Hotkeys.Repo" xml:space="preserve">РЕПОЗИТОРИЙ</x:String>
<x:String x:Key="Text.Hotkeys.Repo.Commit" xml:space="preserve">Зафиксировать сформированные изменения</x:String> <x:String x:Key="Text.Hotkeys.Repo.Commit" xml:space="preserve">Зафиксировать сформированные изменения</x:String>
<x:String x:Key="Text.Hotkeys.Repo.CommitAndPush" xml:space="preserve">Зафиксировать и выложить сформированные изменения</x:String> <x:String x:Key="Text.Hotkeys.Repo.CommitAndPush" xml:space="preserve">Зафиксировать и выложить сформированные изменения</x:String>
@ -434,6 +441,7 @@
<x:String x:Key="Text.Launcher.Error" xml:space="preserve">ОШИБКА</x:String> <x:String x:Key="Text.Launcher.Error" xml:space="preserve">ОШИБКА</x:String>
<x:String x:Key="Text.Launcher.Info" xml:space="preserve">УВЕДОМЛЕНИЕ</x:String> <x:String x:Key="Text.Launcher.Info" xml:space="preserve">УВЕДОМЛЕНИЕ</x:String>
<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.Merge" xml:space="preserve">Влить ветку</x:String> <x:String x:Key="Text.Merge" 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>
@ -532,12 +540,11 @@
<x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">Информация об обрезке рабочего каталога в «$GIT_COMMON_DIR/worktrees»</x:String> <x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">Информация об обрезке рабочего каталога в «$GIT_COMMON_DIR/worktrees»</x:String>
<x:String x:Key="Text.Pull" xml:space="preserve">Загрузить</x:String> <x:String x:Key="Text.Pull" xml:space="preserve">Загрузить</x:String>
<x:String x:Key="Text.Pull.Branch" xml:space="preserve">Ветка внешнего репозитория:</x:String> <x:String x:Key="Text.Pull.Branch" xml:space="preserve">Ветка внешнего репозитория:</x:String>
<x:String x:Key="Text.Pull.FetchAllBranches" xml:space="preserve">Извлечь все ветки</x:String>
<x:String x:Key="Text.Pull.Into" xml:space="preserve">В:</x:String> <x:String x:Key="Text.Pull.Into" xml:space="preserve">В:</x:String>
<x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">Локальные изменения:</x:String> <x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">Локальные изменения:</x:String>
<x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">Отклонить</x:String> <x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">Отклонить</x:String>
<x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">Отложить и применить повторно</x:String> <x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">Отложить и применить повторно</x:String>
<x:String x:Key="Text.Pull.NoTags" xml:space="preserve">Загрузить без меток</x:String> <x:String x:Key="Text.Pull.RecurseSubmodules" xml:space="preserve">Обновить все подмодули</x:String>
<x:String x:Key="Text.Pull.Remote" xml:space="preserve">Внешний репозиторий:</x:String> <x:String x:Key="Text.Pull.Remote" xml:space="preserve">Внешний репозиторий:</x:String>
<x:String x:Key="Text.Pull.Title" xml:space="preserve">Загрузить (Получить и слить)</x:String> <x:String x:Key="Text.Pull.Title" xml:space="preserve">Загрузить (Получить и слить)</x:String>
<x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">Использовать перемещение вместо слияния</x:String> <x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">Использовать перемещение вместо слияния</x:String>
@ -648,6 +655,9 @@
<x:String x:Key="Text.Reset.Mode" xml:space="preserve">Режим сброса:</x:String> <x:String x:Key="Text.Reset.Mode" xml:space="preserve">Режим сброса:</x:String>
<x:String x:Key="Text.Reset.MoveTo" xml:space="preserve">Переместить в:</x:String> <x:String x:Key="Text.Reset.MoveTo" xml:space="preserve">Переместить в:</x:String>
<x:String x:Key="Text.Reset.Target" xml:space="preserve">Текущая ветка:</x:String> <x:String x:Key="Text.Reset.Target" xml:space="preserve">Текущая ветка:</x:String>
<x:String x:Key="Text.ResetWithoutCheckout" xml:space="preserve">Сброс ветки (без переключения)</x:String>
<x:String x:Key="Text.ResetWithoutCheckout.MoveTo" xml:space="preserve">Переместить в:</x:String>
<x:String x:Key="Text.ResetWithoutCheckout.Target" xml:space="preserve">Ветка:</x:String>
<x:String x:Key="Text.RevealFile" xml:space="preserve">Открыть в файловом менеджере</x:String> <x:String x:Key="Text.RevealFile" xml:space="preserve">Открыть в файловом менеджере</x:String>
<x:String x:Key="Text.Revert" xml:space="preserve">Отменить ревизию</x:String> <x:String x:Key="Text.Revert" xml:space="preserve">Отменить ревизию</x:String>
<x:String x:Key="Text.Revert.Commit" xml:space="preserve">Ревизия:</x:String> <x:String x:Key="Text.Revert.Commit" xml:space="preserve">Ревизия:</x:String>
@ -707,6 +717,7 @@
<x:String x:Key="Text.Submodule" xml:space="preserve">ПОДМОДУЛИ</x:String> <x:String x:Key="Text.Submodule" xml:space="preserve">ПОДМОДУЛИ</x:String>
<x:String x:Key="Text.Submodule.Add" xml:space="preserve">Добавить подмодули</x:String> <x:String x:Key="Text.Submodule.Add" xml:space="preserve">Добавить подмодули</x:String>
<x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">Копировать относительный путь</x:String> <x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">Копировать относительный путь</x:String>
<x:String x:Key="Text.Submodule.Deinit" xml:space="preserve">Удалить подмодуль</x:String>
<x:String x:Key="Text.Submodule.FetchNested" xml:space="preserve">Извлечение вложенных подмодулей</x:String> <x:String x:Key="Text.Submodule.FetchNested" xml:space="preserve">Извлечение вложенных подмодулей</x:String>
<x:String x:Key="Text.Submodule.Open" xml:space="preserve">Открыть подмодуль репозитория</x:String> <x:String x:Key="Text.Submodule.Open" xml:space="preserve">Открыть подмодуль репозитория</x:String>
<x:String x:Key="Text.Submodule.RelativePath" xml:space="preserve">Каталог:</x:String> <x:String x:Key="Text.Submodule.RelativePath" xml:space="preserve">Каталог:</x:String>

View file

@ -275,7 +275,6 @@
<x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">தேர்ந்தெடுக்கப்பட்ட களஞ்சியத்தைத் திருத்து</x:String> <x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">தேர்ந்தெடுக்கப்பட்ட களஞ்சியத்தைத் திருத்து</x:String>
<x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">தனிப்பயன் செயலை இயக்கு</x:String> <x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">தனிப்பயன் செயலை இயக்கு</x:String>
<x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">செயல் பெயர்:</x:String> <x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">செயல் பெயர்:</x:String>
<x:String x:Key="Text.FastForwardWithoutCheck" xml:space="preserve">வேகமாக முன்னோக்கி (சரிபார்க்காமல்)</x:String>
<x:String x:Key="Text.Fetch" xml:space="preserve">பெறு</x:String> <x:String x:Key="Text.Fetch" xml:space="preserve">பெறு</x:String>
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">எல்லா தொலைகளையும் பெறு</x:String> <x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">எல்லா தொலைகளையும் பெறு</x:String>
<x:String x:Key="Text.Fetch.Force" xml:space="preserve">உள்ளக குறிப்புகளை கட்டாயமாக மீறு</x:String> <x:String x:Key="Text.Fetch.Force" xml:space="preserve">உள்ளக குறிப்புகளை கட்டாயமாக மீறு</x:String>
@ -509,12 +508,10 @@
<x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">`$GIT_COMMON_DIR/பணிமரங்கள்` இதில் பணிமரம் தகவலை கத்தரி</x:String> <x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">`$GIT_COMMON_DIR/பணிமரங்கள்` இதில் பணிமரம் தகவலை கத்தரி</x:String>
<x:String x:Key="Text.Pull" xml:space="preserve">இழு</x:String> <x:String x:Key="Text.Pull" xml:space="preserve">இழு</x:String>
<x:String x:Key="Text.Pull.Branch" xml:space="preserve">தொலை கிளை:</x:String> <x:String x:Key="Text.Pull.Branch" xml:space="preserve">தொலை கிளை:</x:String>
<x:String x:Key="Text.Pull.FetchAllBranches" xml:space="preserve">எல்லா கிளைகளையும் எடு</x:String>
<x:String x:Key="Text.Pull.Into" xml:space="preserve">இதனுள்:</x:String> <x:String x:Key="Text.Pull.Into" xml:space="preserve">இதனுள்:</x:String>
<x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">உள்ளக மாற்றங்கள்:</x:String> <x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">உள்ளக மாற்றங்கள்:</x:String>
<x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">நிராகரி</x:String> <x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">நிராகரி</x:String>
<x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">பதுக்கிவை &amp; மீண்டும் இடு</x:String> <x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">பதுக்கிவை &amp; மீண்டும் இடு</x:String>
<x:String x:Key="Text.Pull.NoTags" xml:space="preserve">குறிச்சொற்கள் இல்லாமல் பெறு</x:String>
<x:String x:Key="Text.Pull.Remote" xml:space="preserve">தொலை:</x:String> <x:String x:Key="Text.Pull.Remote" xml:space="preserve">தொலை:</x:String>
<x:String x:Key="Text.Pull.Title" xml:space="preserve">இழு (எடுத்து ஒன்றிணை)</x:String> <x:String x:Key="Text.Pull.Title" xml:space="preserve">இழு (எடுத்து ஒன்றிணை)</x:String>
<x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">ஒன்றிணை என்பதற்குப் பதிலாக மறுதளத்தைப் பயன்படுத்து</x:String> <x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">ஒன்றிணை என்பதற்குப் பதிலாக மறுதளத்தைப் பயன்படுத்து</x:String>

View file

@ -279,7 +279,6 @@
<x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">Редагувати вибраний репозиторій</x:String> <x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">Редагувати вибраний репозиторій</x:String>
<x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">Виконати спеціальну дію</x:String> <x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">Виконати спеціальну дію</x:String>
<x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">Ім'я дії:</x:String> <x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">Ім'я дії:</x:String>
<x:String x:Key="Text.FastForwardWithoutCheck" xml:space="preserve">Перемотати (без перемкнуття)</x:String>
<x:String x:Key="Text.Fetch" xml:space="preserve">Витягти</x:String> <x:String x:Key="Text.Fetch" xml:space="preserve">Витягти</x:String>
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Витягти всі віддалені сховища</x:String> <x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Витягти всі віддалені сховища</x:String>
<x:String x:Key="Text.Fetch.Force" xml:space="preserve">Примусово перезаписати локальні refs</x:String> <x:String x:Key="Text.Fetch.Force" xml:space="preserve">Примусово перезаписати локальні refs</x:String>
@ -513,12 +512,10 @@
<x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">Видалити застарілу інформацію про робочі дерева в `$GIT_COMMON_DIR/worktrees`</x:String> <x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">Видалити застарілу інформацію про робочі дерева в `$GIT_COMMON_DIR/worktrees`</x:String>
<x:String x:Key="Text.Pull" xml:space="preserve">Pull (Витягти)</x:String> <x:String x:Key="Text.Pull" xml:space="preserve">Pull (Витягти)</x:String>
<x:String x:Key="Text.Pull.Branch" xml:space="preserve">Віддалена гілка:</x:String> <x:String x:Key="Text.Pull.Branch" xml:space="preserve">Віддалена гілка:</x:String>
<x:String x:Key="Text.Pull.FetchAllBranches" xml:space="preserve">Отримати всі гілки</x:String>
<x:String x:Key="Text.Pull.Into" xml:space="preserve">В:</x:String> <x:String x:Key="Text.Pull.Into" xml:space="preserve">В:</x:String>
<x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">Локальні зміни:</x:String> <x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">Локальні зміни:</x:String>
<x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">Скасувати</x:String> <x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">Скасувати</x:String>
<x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">Сховати та Застосувати</x:String> <x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">Сховати та Застосувати</x:String>
<x:String x:Key="Text.Pull.NoTags" xml:space="preserve">Отримати без тегів</x:String>
<x:String x:Key="Text.Pull.Remote" xml:space="preserve">Віддалене сховище:</x:String> <x:String x:Key="Text.Pull.Remote" xml:space="preserve">Віддалене сховище:</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 замість merge</x:String> <x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">Використовувати rebase замість merge</x:String>

View file

@ -65,8 +65,9 @@
<x:String x:Key="Text.BranchCM.Pull" xml:space="preserve">拉回(pull) ${0}$</x:String> <x:String x:Key="Text.BranchCM.Pull" xml:space="preserve">拉回(pull) ${0}$</x:String>
<x:String x:Key="Text.BranchCM.PullInto" xml:space="preserve">拉回(pull) ${0}$ 内容至 ${1}$...</x:String> <x:String x:Key="Text.BranchCM.PullInto" xml:space="preserve">拉回(pull) ${0}$ 内容至 ${1}$...</x:String>
<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}$ 分支至 ${1}$...</x:String> <x:String x:Key="Text.BranchCM.Rebase" xml:space="preserve">变基(rebase) ${0}$ 至 ${1}$...</x:String>
<x:String x:Key="Text.BranchCM.Rename" xml:space="preserve">重命名 ${0}$...</x:String> <x:String x:Key="Text.BranchCM.Rename" xml:space="preserve">重命名 ${0}$...</x:String>
<x:String x:Key="Text.BranchCM.ResetToSelectedCommit" xml:space="preserve">重置 ${0}$ 到 ${1}$...</x:String>
<x:String x:Key="Text.BranchCM.Tracking" xml:space="preserve">切换上游分支 ...</x:String> <x:String x:Key="Text.BranchCM.Tracking" xml:space="preserve">切换上游分支 ...</x:String>
<x:String x:Key="Text.BranchCompare" xml:space="preserve">分支比较</x:String> <x:String x:Key="Text.BranchCompare" xml:space="preserve">分支比较</x:String>
<x:String x:Key="Text.BranchUpstreamInvalid" xml:space="preserve">跟踪的上游分支不存在或已删除!</x:String> <x:String x:Key="Text.BranchUpstreamInvalid" xml:space="preserve">跟踪的上游分支不存在或已删除!</x:String>
@ -128,6 +129,7 @@
<x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">合并此提交到上一个提交</x:String> <x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">合并此提交到上一个提交</x:String>
<x:String x:Key="Text.CommitCM.SquashCommitsSinceThis" xml:space="preserve">合并之后的提交到此处</x:String> <x:String x:Key="Text.CommitCM.SquashCommitsSinceThis" xml:space="preserve">合并之后的提交到此处</x:String>
<x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">变更对比</x:String> <x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">变更对比</x:String>
<x:String x:Key="Text.CommitDetail.Changes.Count" xml:space="preserve">个文件发生变更</x:String>
<x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">查找变更...</x:String> <x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">查找变更...</x:String>
<x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">文件列表</x:String> <x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">文件列表</x:String>
<x:String x:Key="Text.CommitDetail.Files.LFS" xml:space="preserve">LFS文件</x:String> <x:String x:Key="Text.CommitDetail.Files.LFS" xml:space="preserve">LFS文件</x:String>
@ -219,6 +221,7 @@
<x:String x:Key="Text.CreateBranch.Name.Placeholder" xml:space="preserve">填写分支名称。</x:String> <x:String x:Key="Text.CreateBranch.Name.Placeholder" xml:space="preserve">填写分支名称。</x:String>
<x:String x:Key="Text.CreateBranch.Name.WarnSpace" xml:space="preserve">空格将被替换为'-'符号</x:String> <x:String x:Key="Text.CreateBranch.Name.WarnSpace" xml:space="preserve">空格将被替换为'-'符号</x:String>
<x:String x:Key="Text.CreateBranch.Title" xml:space="preserve">创建本地分支</x:String> <x:String x:Key="Text.CreateBranch.Title" xml:space="preserve">创建本地分支</x:String>
<x:String x:Key="Text.CreateBranch.OverwriteExisting" xml:space="preserve">允许重置已存在的分支</x:String>
<x:String x:Key="Text.CreateTag" xml:space="preserve">新建标签 ...</x:String> <x:String x:Key="Text.CreateTag" xml:space="preserve">新建标签 ...</x:String>
<x:String x:Key="Text.CreateTag.BasedOn" xml:space="preserve">标签位于 </x:String> <x:String x:Key="Text.CreateTag.BasedOn" xml:space="preserve">标签位于 </x:String>
<x:String x:Key="Text.CreateTag.GPGSign" xml:space="preserve">使用GPG签名</x:String> <x:String x:Key="Text.CreateTag.GPGSign" xml:space="preserve">使用GPG签名</x:String>
@ -233,6 +236,9 @@
<x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">轻量标签</x:String> <x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">轻量标签</x:String>
<x:String x:Key="Text.CtrlClickTip" xml:space="preserve">按住Ctrl键点击将以默认参数运行</x:String> <x:String x:Key="Text.CtrlClickTip" xml:space="preserve">按住Ctrl键点击将以默认参数运行</x:String>
<x:String x:Key="Text.Cut" xml:space="preserve">剪切</x:String> <x:String x:Key="Text.Cut" xml:space="preserve">剪切</x:String>
<x:String x:Key="Text.DeinitSubmodule" xml:space="preserve">取消初始化子模块</x:String>
<x:String x:Key="Text.DeinitSubmodule.Force" xml:space="preserve">强制取消,即使包含本地变更</x:String>
<x:String x:Key="Text.DeinitSubmodule.Path" xml:space="preserve">子模块 </x:String>
<x:String x:Key="Text.DeleteBranch" xml:space="preserve">删除分支确认</x:String> <x:String x:Key="Text.DeleteBranch" xml:space="preserve">删除分支确认</x:String>
<x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">分支名 </x:String> <x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">分支名 </x:String>
<x:String x:Key="Text.DeleteBranch.IsRemoteTip" xml:space="preserve">您正在删除远程上的分支,请务必小心!!!</x:String> <x:String x:Key="Text.DeleteBranch.IsRemoteTip" xml:space="preserve">您正在删除远程上的分支,请务必小心!!!</x:String>
@ -268,6 +274,7 @@
<x:String x:Key="Text.Diff.ShowHiddenSymbols" xml:space="preserve">显示隐藏符号</x:String> <x:String x:Key="Text.Diff.ShowHiddenSymbols" xml:space="preserve">显示隐藏符号</x:String>
<x:String x:Key="Text.Diff.SideBySide" xml:space="preserve">分列对比</x:String> <x:String x:Key="Text.Diff.SideBySide" xml:space="preserve">分列对比</x:String>
<x:String x:Key="Text.Diff.Submodule" xml:space="preserve">子模块</x:String> <x:String x:Key="Text.Diff.Submodule" xml:space="preserve">子模块</x:String>
<x:String x:Key="Text.Diff.Submodule.Deleted" xml:space="preserve">删除</x:String>
<x:String x:Key="Text.Diff.Submodule.New" xml:space="preserve">新增</x:String> <x:String x:Key="Text.Diff.Submodule.New" xml:space="preserve">新增</x:String>
<x:String x:Key="Text.Diff.SwapCommits" xml:space="preserve">交换比对双方</x:String> <x:String x:Key="Text.Diff.SwapCommits" xml:space="preserve">交换比对双方</x:String>
<x:String x:Key="Text.Diff.SyntaxHighlight" xml:space="preserve">语法高亮</x:String> <x:String x:Key="Text.Diff.SyntaxHighlight" xml:space="preserve">语法高亮</x:String>
@ -292,7 +299,6 @@
<x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">编辑仓库</x:String> <x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">编辑仓库</x:String>
<x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">执行自定义操作</x:String> <x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">执行自定义操作</x:String>
<x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">自定义操作 </x:String> <x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">自定义操作 </x:String>
<x:String x:Key="Text.FastForwardWithoutCheck" xml:space="preserve">快进(fast-forward无需checkout)</x:String>
<x:String x:Key="Text.Fetch" xml:space="preserve">拉取(fetch)</x:String> <x:String x:Key="Text.Fetch" xml:space="preserve">拉取(fetch)</x:String>
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">拉取所有的远程仓库</x:String> <x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">拉取所有的远程仓库</x:String>
<x:String x:Key="Text.Fetch.Force" xml:space="preserve">强制覆盖本地REFs</x:String> <x:String x:Key="Text.Fetch.Force" xml:space="preserve">强制覆盖本地REFs</x:String>
@ -534,12 +540,11 @@
<x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">清理在`$GIT_COMMON_DIR/worktrees`中的无效工作树信息</x:String> <x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">清理在`$GIT_COMMON_DIR/worktrees`中的无效工作树信息</x:String>
<x:String x:Key="Text.Pull" xml:space="preserve">拉回(pull)</x:String> <x:String x:Key="Text.Pull" xml:space="preserve">拉回(pull)</x:String>
<x:String x:Key="Text.Pull.Branch" xml:space="preserve">拉取分支 </x:String> <x:String x:Key="Text.Pull.Branch" xml:space="preserve">拉取分支 </x:String>
<x:String x:Key="Text.Pull.FetchAllBranches" xml:space="preserve">拉取远程中的所有分支变更</x:String>
<x:String x:Key="Text.Pull.Into" xml:space="preserve">本地分支 </x:String> <x:String x:Key="Text.Pull.Into" xml:space="preserve">本地分支 </x:String>
<x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">未提交更改 </x:String> <x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">未提交更改 </x:String>
<x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">丢弃更改</x:String> <x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">丢弃更改</x:String>
<x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">贮藏并自动恢复</x:String> <x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">贮藏并自动恢复</x:String>
<x:String x:Key="Text.Pull.NoTags" xml:space="preserve">不拉取远程标签</x:String> <x:String x:Key="Text.Pull.RecurseSubmodules" xml:space="preserve">同时更新所有子模块</x:String>
<x:String x:Key="Text.Pull.Remote" xml:space="preserve">远程 </x:String> <x:String x:Key="Text.Pull.Remote" xml:space="preserve">远程 </x:String>
<x:String x:Key="Text.Pull.Title" xml:space="preserve">拉回(拉取并合并)</x:String> <x:String x:Key="Text.Pull.Title" xml:space="preserve">拉回(拉取并合并)</x:String>
<x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">使用变基方式合并分支</x:String> <x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">使用变基方式合并分支</x:String>
@ -650,6 +655,9 @@
<x:String x:Key="Text.Reset.Mode" xml:space="preserve">重置模式 </x:String> <x:String x:Key="Text.Reset.Mode" xml:space="preserve">重置模式 </x:String>
<x:String x:Key="Text.Reset.MoveTo" xml:space="preserve">提交 </x:String> <x:String x:Key="Text.Reset.MoveTo" xml:space="preserve">提交 </x:String>
<x:String x:Key="Text.Reset.Target" xml:space="preserve">当前分支 </x:String> <x:String x:Key="Text.Reset.Target" xml:space="preserve">当前分支 </x:String>
<x:String x:Key="Text.ResetWithoutCheckout" xml:space="preserve">重置所选分支(非当前分支)</x:String>
<x:String x:Key="Text.ResetWithoutCheckout.MoveTo" xml:space="preserve">重置点 </x:String>
<x:String x:Key="Text.ResetWithoutCheckout.Target" xml:space="preserve">操作分支 </x:String>
<x:String x:Key="Text.RevealFile" xml:space="preserve">在文件浏览器中查看</x:String> <x:String x:Key="Text.RevealFile" xml:space="preserve">在文件浏览器中查看</x:String>
<x:String x:Key="Text.Revert" xml:space="preserve">回滚操作确认</x:String> <x:String x:Key="Text.Revert" xml:space="preserve">回滚操作确认</x:String>
<x:String x:Key="Text.Revert.Commit" xml:space="preserve">目标提交 </x:String> <x:String x:Key="Text.Revert.Commit" xml:space="preserve">目标提交 </x:String>
@ -709,6 +717,7 @@
<x:String x:Key="Text.Submodule" xml:space="preserve">子模块</x:String> <x:String x:Key="Text.Submodule" xml:space="preserve">子模块</x:String>
<x:String x:Key="Text.Submodule.Add" xml:space="preserve">添加子模块</x:String> <x:String x:Key="Text.Submodule.Add" xml:space="preserve">添加子模块</x:String>
<x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">复制路径</x:String> <x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">复制路径</x:String>
<x:String x:Key="Text.Submodule.Deinit" xml:space="preserve">取消初始化</x:String>
<x:String x:Key="Text.Submodule.FetchNested" xml:space="preserve">拉取子孙模块</x:String> <x:String x:Key="Text.Submodule.FetchNested" xml:space="preserve">拉取子孙模块</x:String>
<x:String x:Key="Text.Submodule.Open" xml:space="preserve">打开仓库</x:String> <x:String x:Key="Text.Submodule.Open" xml:space="preserve">打开仓库</x:String>
<x:String x:Key="Text.Submodule.RelativePath" xml:space="preserve">相对仓库路径 </x:String> <x:String x:Key="Text.Submodule.RelativePath" xml:space="preserve">相对仓库路径 </x:String>

View file

@ -67,6 +67,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}$ 分支至 ${1}$...</x:String> <x:String x:Key="Text.BranchCM.Rebase" xml:space="preserve">重定基底 (rebase) ${0}$ 分支至 ${1}$...</x:String>
<x:String x:Key="Text.BranchCM.Rename" xml:space="preserve">重新命名 ${0}$...</x:String> <x:String x:Key="Text.BranchCM.Rename" xml:space="preserve">重新命名 ${0}$...</x:String>
<x:String x:Key="Text.BranchCM.ResetToSelectedCommit" xml:space="preserve">重設 ${0}$ 至 ${1}$...</x:String>
<x:String x:Key="Text.BranchCM.Tracking" xml:space="preserve">切換上游分支...</x:String> <x:String x:Key="Text.BranchCM.Tracking" xml:space="preserve">切換上游分支...</x:String>
<x:String x:Key="Text.BranchCompare" xml:space="preserve">分支比較</x:String> <x:String x:Key="Text.BranchCompare" xml:space="preserve">分支比較</x:String>
<x:String x:Key="Text.BranchUpstreamInvalid" xml:space="preserve">追蹤上游分支不存在或已刪除!</x:String> <x:String x:Key="Text.BranchUpstreamInvalid" xml:space="preserve">追蹤上游分支不存在或已刪除!</x:String>
@ -128,6 +129,7 @@
<x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">合併此提交到上一個提交</x:String> <x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">合併此提交到上一個提交</x:String>
<x:String x:Key="Text.CommitCM.SquashCommitsSinceThis" xml:space="preserve">合併之後的提交到此處</x:String> <x:String x:Key="Text.CommitCM.SquashCommitsSinceThis" xml:space="preserve">合併之後的提交到此處</x:String>
<x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">變更對比</x:String> <x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">變更對比</x:String>
<x:String x:Key="Text.CommitDetail.Changes.Count" xml:space="preserve">個檔案已變更</x:String>
<x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">搜尋變更...</x:String> <x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">搜尋變更...</x:String>
<x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">檔案列表</x:String> <x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">檔案列表</x:String>
<x:String x:Key="Text.CommitDetail.Files.LFS" xml:space="preserve">LFS 檔案</x:String> <x:String x:Key="Text.CommitDetail.Files.LFS" xml:space="preserve">LFS 檔案</x:String>
@ -219,6 +221,7 @@
<x:String x:Key="Text.CreateBranch.Name.Placeholder" xml:space="preserve">輸入分支名稱。</x:String> <x:String x:Key="Text.CreateBranch.Name.Placeholder" xml:space="preserve">輸入分支名稱。</x:String>
<x:String x:Key="Text.CreateBranch.Name.WarnSpace" xml:space="preserve">空格將以英文破折號取代</x:String> <x:String x:Key="Text.CreateBranch.Name.WarnSpace" xml:space="preserve">空格將以英文破折號取代</x:String>
<x:String x:Key="Text.CreateBranch.Title" xml:space="preserve">建立本機分支</x:String> <x:String x:Key="Text.CreateBranch.Title" xml:space="preserve">建立本機分支</x:String>
<x:String x:Key="Text.CreateBranch.OverwriteExisting" xml:space="preserve">允許覆寫現有分支</x:String>
<x:String x:Key="Text.CreateTag" xml:space="preserve">新增標籤...</x:String> <x:String x:Key="Text.CreateTag" xml:space="preserve">新增標籤...</x:String>
<x:String x:Key="Text.CreateTag.BasedOn" xml:space="preserve">標籤位於:</x:String> <x:String x:Key="Text.CreateTag.BasedOn" xml:space="preserve">標籤位於:</x:String>
<x:String x:Key="Text.CreateTag.GPGSign" xml:space="preserve">使用 GPG 簽章</x:String> <x:String x:Key="Text.CreateTag.GPGSign" xml:space="preserve">使用 GPG 簽章</x:String>
@ -233,6 +236,9 @@
<x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">輕量標籤</x:String> <x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">輕量標籤</x:String>
<x:String x:Key="Text.CtrlClickTip" xml:space="preserve">按住 Ctrl 鍵將直接以預設參數執行</x:String> <x:String x:Key="Text.CtrlClickTip" xml:space="preserve">按住 Ctrl 鍵將直接以預設參數執行</x:String>
<x:String x:Key="Text.Cut" xml:space="preserve">剪下</x:String> <x:String x:Key="Text.Cut" xml:space="preserve">剪下</x:String>
<x:String x:Key="Text.DeinitSubmodule" xml:space="preserve">取消初始化子模組</x:String>
<x:String x:Key="Text.DeinitSubmodule.Force" xml:space="preserve">強制取消,即使它包含本地變更</x:String>
<x:String x:Key="Text.DeinitSubmodule.Path" xml:space="preserve">子模組 </x:String>
<x:String x:Key="Text.DeleteBranch" xml:space="preserve">刪除分支確認</x:String> <x:String x:Key="Text.DeleteBranch" xml:space="preserve">刪除分支確認</x:String>
<x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">分支名稱:</x:String> <x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">分支名稱:</x:String>
<x:String x:Key="Text.DeleteBranch.IsRemoteTip" xml:space="preserve">您正在刪除遠端上的分支,請務必小心!</x:String> <x:String x:Key="Text.DeleteBranch.IsRemoteTip" xml:space="preserve">您正在刪除遠端上的分支,請務必小心!</x:String>
@ -268,6 +274,7 @@
<x:String x:Key="Text.Diff.ShowHiddenSymbols" xml:space="preserve">顯示隱藏符號</x:String> <x:String x:Key="Text.Diff.ShowHiddenSymbols" xml:space="preserve">顯示隱藏符號</x:String>
<x:String x:Key="Text.Diff.SideBySide" xml:space="preserve">並排對比</x:String> <x:String x:Key="Text.Diff.SideBySide" xml:space="preserve">並排對比</x:String>
<x:String x:Key="Text.Diff.Submodule" xml:space="preserve">子模組</x:String> <x:String x:Key="Text.Diff.Submodule" xml:space="preserve">子模組</x:String>
<x:String x:Key="Text.Diff.Submodule.Deleted" xml:space="preserve">已刪除</x:String>
<x:String x:Key="Text.Diff.Submodule.New" xml:space="preserve">新增</x:String> <x:String x:Key="Text.Diff.Submodule.New" xml:space="preserve">新增</x:String>
<x:String x:Key="Text.Diff.SwapCommits" xml:space="preserve">交換比對雙方</x:String> <x:String x:Key="Text.Diff.SwapCommits" xml:space="preserve">交換比對雙方</x:String>
<x:String x:Key="Text.Diff.SyntaxHighlight" xml:space="preserve">語法上色</x:String> <x:String x:Key="Text.Diff.SyntaxHighlight" xml:space="preserve">語法上色</x:String>
@ -292,7 +299,6 @@
<x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">編輯存放庫</x:String> <x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">編輯存放庫</x:String>
<x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">執行自訂動作</x:String> <x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">執行自訂動作</x:String>
<x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">自訂動作:</x:String> <x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">自訂動作:</x:String>
<x:String x:Key="Text.FastForwardWithoutCheck" xml:space="preserve">快進 (fast-forward無需 checkout)</x:String>
<x:String x:Key="Text.Fetch" xml:space="preserve">提取 (fetch)</x:String> <x:String x:Key="Text.Fetch" xml:space="preserve">提取 (fetch)</x:String>
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">提取所有的遠端存放庫</x:String> <x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">提取所有的遠端存放庫</x:String>
<x:String x:Key="Text.Fetch.Force" xml:space="preserve">強制覆寫本機 REFs</x:String> <x:String x:Key="Text.Fetch.Force" xml:space="preserve">強制覆寫本機 REFs</x:String>
@ -534,12 +540,11 @@
<x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">清理在 `$GIT_COMMON_DIR/worktrees` 中的無效工作區資訊</x:String> <x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">清理在 `$GIT_COMMON_DIR/worktrees` 中的無效工作區資訊</x:String>
<x:String x:Key="Text.Pull" xml:space="preserve">拉取 (pull)</x:String> <x:String x:Key="Text.Pull" xml:space="preserve">拉取 (pull)</x:String>
<x:String x:Key="Text.Pull.Branch" xml:space="preserve">拉取分支:</x:String> <x:String x:Key="Text.Pull.Branch" xml:space="preserve">拉取分支:</x:String>
<x:String x:Key="Text.Pull.FetchAllBranches" xml:space="preserve">拉取遠端中的所有分支</x:String>
<x:String x:Key="Text.Pull.Into" xml:space="preserve">本機分支:</x:String> <x:String x:Key="Text.Pull.Into" xml:space="preserve">本機分支:</x:String>
<x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">未提交變更:</x:String> <x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">未提交變更:</x:String>
<x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">捨棄變更</x:String> <x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">捨棄變更</x:String>
<x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">擱置變更並自動復原</x:String> <x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">擱置變更並自動復原</x:String>
<x:String x:Key="Text.Pull.NoTags" xml:space="preserve">不拉取遠端標籤</x:String> <x:String x:Key="Text.Pull.RecurseSubmodules" xml:space="preserve">同時更新所有子模組</x:String>
<x:String x:Key="Text.Pull.Remote" xml:space="preserve">遠端:</x:String> <x:String x:Key="Text.Pull.Remote" xml:space="preserve">遠端:</x:String>
<x:String x:Key="Text.Pull.Title" xml:space="preserve">拉取 (提取並合併)</x:String> <x:String x:Key="Text.Pull.Title" xml:space="preserve">拉取 (提取並合併)</x:String>
<x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">使用重定基底 (rebase) 合併分支</x:String> <x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">使用重定基底 (rebase) 合併分支</x:String>
@ -650,6 +655,9 @@
<x:String x:Key="Text.Reset.Mode" xml:space="preserve">重設模式:</x:String> <x:String x:Key="Text.Reset.Mode" xml:space="preserve">重設模式:</x:String>
<x:String x:Key="Text.Reset.MoveTo" xml:space="preserve">移至提交:</x:String> <x:String x:Key="Text.Reset.MoveTo" xml:space="preserve">移至提交:</x:String>
<x:String x:Key="Text.Reset.Target" xml:space="preserve">目前分支:</x:String> <x:String x:Key="Text.Reset.Target" xml:space="preserve">目前分支:</x:String>
<x:String x:Key="Text.ResetWithoutCheckout" xml:space="preserve">重設選取的分支(非目前分支)</x:String>
<x:String x:Key="Text.ResetWithoutCheckout.MoveTo" xml:space="preserve">重設位置 </x:String>
<x:String x:Key="Text.ResetWithoutCheckout.Target" xml:space="preserve">選取分支 </x:String>
<x:String x:Key="Text.RevealFile" xml:space="preserve">在檔案瀏覽器中檢視</x:String> <x:String x:Key="Text.RevealFile" xml:space="preserve">在檔案瀏覽器中檢視</x:String>
<x:String x:Key="Text.Revert" xml:space="preserve">復原操作確認</x:String> <x:String x:Key="Text.Revert" xml:space="preserve">復原操作確認</x:String>
<x:String x:Key="Text.Revert.Commit" xml:space="preserve">目標提交:</x:String> <x:String x:Key="Text.Revert.Commit" xml:space="preserve">目標提交:</x:String>
@ -709,6 +717,7 @@
<x:String x:Key="Text.Submodule" xml:space="preserve">子模組</x:String> <x:String x:Key="Text.Submodule" xml:space="preserve">子模組</x:String>
<x:String x:Key="Text.Submodule.Add" xml:space="preserve">新增子模組</x:String> <x:String x:Key="Text.Submodule.Add" xml:space="preserve">新增子模組</x:String>
<x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">複製路徑</x:String> <x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">複製路徑</x:String>
<x:String x:Key="Text.Submodule.Deinit" xml:space="preserve">取消初始化</x:String>
<x:String x:Key="Text.Submodule.FetchNested" xml:space="preserve">提取子模組</x:String> <x:String x:Key="Text.Submodule.FetchNested" xml:space="preserve">提取子模組</x:String>
<x:String x:Key="Text.Submodule.Open" xml:space="preserve">開啟存放庫</x:String> <x:String x:Key="Text.Submodule.Open" xml:space="preserve">開啟存放庫</x:String>
<x:String x:Key="Text.Submodule.RelativePath" xml:space="preserve">相對存放庫路徑:</x:String> <x:String x:Key="Text.Submodule.RelativePath" xml:space="preserve">相對存放庫路徑:</x:String>

View file

@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations; using System;
using System.ComponentModel.DataAnnotations;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -14,12 +15,10 @@ namespace SourceGit.ViewModels
set => SetProperty(ref _url, value, true); set => SetProperty(ref _url, value, true);
} }
[Required(ErrorMessage = "Reletive path is required!!!")]
[CustomValidation(typeof(AddSubmodule), nameof(ValidateRelativePath))]
public string RelativePath public string RelativePath
{ {
get => _relativePath; get => _relativePath;
set => SetProperty(ref _relativePath, value, true); set => SetProperty(ref _relativePath, value);
} }
public bool Recursive public bool Recursive
@ -37,20 +36,6 @@ namespace SourceGit.ViewModels
{ {
if (!Models.Remote.IsValidURL(url)) if (!Models.Remote.IsValidURL(url))
return new ValidationResult("Invalid repository URL format"); return new ValidationResult("Invalid repository URL format");
return ValidationResult.Success;
}
public static ValidationResult ValidateRelativePath(string path, ValidationContext ctx)
{
if (Path.Exists(path))
{
return new ValidationResult("Give path is exists already!");
}
if (Path.IsPathRooted(path))
{
return new ValidationResult("Path must be relative to this repository!");
}
return ValidationResult.Success; return ValidationResult.Success;
} }
@ -63,9 +48,20 @@ namespace SourceGit.ViewModels
var log = _repo.CreateLog("Add Submodule"); var log = _repo.CreateLog("Add Submodule");
Use(log); Use(log);
var relativePath = _relativePath;
if (string.IsNullOrEmpty(relativePath))
{
if (_url.EndsWith("/.git", StringComparison.Ordinal))
relativePath = Path.GetFileName(Path.GetDirectoryName(_url));
else if (_url.EndsWith(".git", StringComparison.Ordinal))
relativePath = Path.GetFileNameWithoutExtension(_url);
else
relativePath = Path.GetFileName(_url);
}
return Task.Run(() => return Task.Run(() =>
{ {
var succ = new Commands.Submodule(_repo.FullPath).Use(log).Add(_url, _relativePath, Recursive); var succ = new Commands.Submodule(_repo.FullPath).Use(log).Add(_url, relativePath, Recursive);
log.Complete(); log.Complete();
CallUIThread(() => _repo.SetWatcherEnabled(true)); CallUIThread(() => _repo.SetWatcherEnabled(true));

View file

@ -17,8 +17,7 @@ namespace SourceGit.ViewModels
public bool IsRecurseSubmoduleVisible public bool IsRecurseSubmoduleVisible
{ {
get; get => _repo.Submodules.Count > 0;
private set;
} }
public bool RecurseSubmodules public bool RecurseSubmodules
@ -32,7 +31,6 @@ namespace SourceGit.ViewModels
_repo = repo; _repo = repo;
Branch = branch; Branch = branch;
DiscardLocalChanges = false; DiscardLocalChanges = false;
IsRecurseSubmoduleVisible = repo.Submodules.Count > 0;
} }
public override Task<bool> Sure() public override Task<bool> Sure()
@ -76,9 +74,9 @@ namespace SourceGit.ViewModels
{ {
if (updateSubmodules) if (updateSubmodules)
{ {
var submodules = new Commands.QuerySubmodules(_repo.FullPath).Result(); var submodules = new Commands.QueryUpdatableSubmodules(_repo.FullPath).Result();
if (submodules.Count > 0) if (submodules.Count > 0)
new Commands.Submodule(_repo.FullPath).Use(log).Update(submodules, true, true, false); new Commands.Submodule(_repo.FullPath).Use(log).Update(submodules, true, true);
} }
if (needPopStash) if (needPopStash)

View file

@ -17,8 +17,7 @@ namespace SourceGit.ViewModels
public bool IsRecurseSubmoduleVisible public bool IsRecurseSubmoduleVisible
{ {
get; get => _repo.Submodules.Count > 0;
private set;
} }
public bool RecurseSubmodules public bool RecurseSubmodules
@ -32,7 +31,6 @@ namespace SourceGit.ViewModels
_repo = repo; _repo = repo;
Commit = commit; Commit = commit;
DiscardLocalChanges = false; DiscardLocalChanges = false;
IsRecurseSubmoduleVisible = repo.Submodules.Count > 0;
} }
public override Task<bool> Sure() public override Task<bool> Sure()
@ -76,9 +74,9 @@ namespace SourceGit.ViewModels
{ {
if (updateSubmodules) if (updateSubmodules)
{ {
var submodules = new Commands.QuerySubmodules(_repo.FullPath).Result(); var submodules = new Commands.QueryUpdatableSubmodules(_repo.FullPath).Result();
if (submodules.Count > 0) if (submodules.Count > 0)
new Commands.Submodule(_repo.FullPath).Use(log).Update(submodules, true, true, false); new Commands.Submodule(_repo.FullPath).Use(log).Update(submodules, true, true);
} }
if (needPop) if (needPop)

View file

@ -140,9 +140,9 @@ namespace SourceGit.ViewModels
if (InitAndUpdateSubmodules) if (InitAndUpdateSubmodules)
{ {
var submodules = new Commands.QuerySubmodules(path).Result(); var submodules = new Commands.QueryUpdatableSubmodules(path).Result();
if (submodules.Count > 0) if (submodules.Count > 0)
new Commands.Submodule(path).Use(log).Update(submodules, true, true, false); new Commands.Submodule(path).Use(log).Update(submodules, true, true);
} }
log.Complete(); log.Complete();

View file

@ -15,7 +15,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.ViewModels namespace SourceGit.ViewModels
{ {
public partial class CommitDetail : ObservableObject public partial class CommitDetail : ObservableObject, IDisposable
{ {
public int ActivePageIndex public int ActivePageIndex
{ {
@ -137,7 +137,7 @@ namespace SourceGit.ViewModels
WebLinks = Models.CommitLink.Get(repo.Remotes); WebLinks = Models.CommitLink.Get(repo.Remotes);
} }
public void Cleanup() public void Dispose()
{ {
_repo = null; _repo = null;
_commit = null; _commit = null;
@ -149,6 +149,7 @@ namespace SourceGit.ViewModels
_diffContext = null; _diffContext = null;
_viewRevisionFileContent = null; _viewRevisionFileContent = null;
_cancellationSource = null; _cancellationSource = null;
_requestingRevisionFiles = false;
_revisionFiles = null; _revisionFiles = null;
_revisionFileSearchSuggestion = null; _revisionFileSearchSuggestion = null;
} }
@ -335,7 +336,7 @@ namespace SourceGit.ViewModels
options.DefaultExtension = ".patch"; options.DefaultExtension = ".patch";
options.FileTypeChoices = [new FilePickerFileType("Patch File") { Patterns = ["*.patch"] }]; options.FileTypeChoices = [new FilePickerFileType("Patch File") { Patterns = ["*.patch"] }];
var baseRevision = _commit.Parents.Count == 0 ? "4b825dc642cb6eb9a060e54bf8d69288fbee4904" : _commit.Parents[0]; var baseRevision = _commit.Parents.Count == 0 ? Models.Commit.EmptyTreeSHA1 : _commit.Parents[0];
var storageFile = await storageProvider.SaveFilePickerAsync(options); var storageFile = await storageProvider.SaveFilePickerAsync(options);
if (storageFile != null) if (storageFile != null)
{ {
@ -546,6 +547,7 @@ namespace SourceGit.ViewModels
private void Refresh() private void Refresh()
{ {
_changes = null; _changes = null;
_requestingRevisionFiles = false;
_revisionFiles = null; _revisionFiles = null;
SignInfo = null; SignInfo = null;
@ -593,7 +595,7 @@ namespace SourceGit.ViewModels
Task.Run(() => Task.Run(() =>
{ {
var parent = _commit.Parents.Count == 0 ? "4b825dc642cb6eb9a060e54bf8d69288fbee4904" : _commit.Parents[0]; var parent = _commit.Parents.Count == 0 ? Models.Commit.EmptyTreeSHA1 : _commit.Parents[0];
var cmd = new Commands.CompareRevisions(_repo.FullPath, parent, _commit.SHA) { CancellationToken = token }; var cmd = new Commands.CompareRevisions(_repo.FullPath, parent, _commit.SHA) { CancellationToken = token };
var changes = cmd.Result(); var changes = cmd.Result();
var visible = changes; var visible = changes;
@ -812,16 +814,22 @@ namespace SourceGit.ViewModels
{ {
if (_revisionFiles == null) if (_revisionFiles == null)
{ {
if (_requestingRevisionFiles)
return;
var sha = Commit.SHA; var sha = Commit.SHA;
_requestingRevisionFiles = true;
Task.Run(() => Task.Run(() =>
{ {
var files = new Commands.QueryRevisionFileNames(_repo.FullPath, sha).Result(); var files = new Commands.QueryRevisionFileNames(_repo.FullPath, sha).Result();
Dispatcher.UIThread.Invoke(() => Dispatcher.UIThread.Invoke(() =>
{ {
if (sha == Commit.SHA) if (sha == Commit.SHA && _requestingRevisionFiles)
{ {
_revisionFiles = files; _revisionFiles = files;
_requestingRevisionFiles = false;
if (!string.IsNullOrEmpty(_revisionFileSearchFilter)) if (!string.IsNullOrEmpty(_revisionFileSearchFilter))
CalcRevisionFileSearchSuggestion(); CalcRevisionFileSearchSuggestion();
} }
@ -907,6 +915,7 @@ namespace SourceGit.ViewModels
private DiffContext _diffContext = null; private DiffContext _diffContext = null;
private object _viewRevisionFileContent = null; private object _viewRevisionFileContent = null;
private CancellationTokenSource _cancellationSource = null; private CancellationTokenSource _cancellationSource = null;
private bool _requestingRevisionFiles = false;
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;

View file

@ -1,4 +1,6 @@
namespace SourceGit.ViewModels using System;
namespace SourceGit.ViewModels
{ {
public class ConflictSourceBranch public class ConflictSourceBranch
{ {
@ -46,7 +48,8 @@
_wc = wc; _wc = wc;
_change = change; _change = change;
IsResolved = new Commands.IsConflictResolved(repo.FullPath, change).Result(); var isSubmodule = repo.Submodules.Find(x => x.Path.Equals(change.Path, StringComparison.Ordinal)) != null;
IsResolved = !isSubmodule && new Commands.IsConflictResolved(repo.FullPath, change).Result();
var context = wc.InProgressContext; var context = wc.InProgressContext;
if (context is CherryPickInProgress cherryPick) if (context is CherryPickInProgress cherryPick)

View file

@ -43,10 +43,19 @@ namespace SourceGit.ViewModels
get => _repo.IsBare; get => _repo.IsBare;
} }
public bool AllowOverwrite
{
get => _allowOverwrite;
set
{
if (SetProperty(ref _allowOverwrite, value))
ValidateProperty(_name, nameof(Name));
}
}
public bool IsRecurseSubmoduleVisible public bool IsRecurseSubmoduleVisible
{ {
get; get => _repo.Submodules.Count > 0;
private set;
} }
public bool RecurseSubmodules public bool RecurseSubmodules
@ -67,7 +76,6 @@ namespace SourceGit.ViewModels
BasedOn = branch; BasedOn = branch;
DiscardLocalChanges = false; DiscardLocalChanges = false;
IsRecurseSubmoduleVisible = repo.Submodules.Count > 0;
} }
public CreateBranch(Repository repo, Models.Commit commit) public CreateBranch(Repository repo, Models.Commit commit)
@ -77,7 +85,6 @@ namespace SourceGit.ViewModels
BasedOn = commit; BasedOn = commit;
DiscardLocalChanges = false; DiscardLocalChanges = false;
IsRecurseSubmoduleVisible = repo.Submodules.Count > 0;
} }
public CreateBranch(Repository repo, Models.Tag tag) public CreateBranch(Repository repo, Models.Tag tag)
@ -87,24 +94,29 @@ namespace SourceGit.ViewModels
BasedOn = tag; BasedOn = tag;
DiscardLocalChanges = false; DiscardLocalChanges = false;
IsRecurseSubmoduleVisible = repo.Submodules.Count > 0;
} }
public static ValidationResult ValidateBranchName(string name, ValidationContext ctx) public static ValidationResult ValidateBranchName(string name, ValidationContext ctx)
{ {
var creator = ctx.ObjectInstance as CreateBranch; if (ctx.ObjectInstance is CreateBranch creator)
if (creator == null) {
return new ValidationResult("Missing runtime context to create branch!"); if (!creator._allowOverwrite)
{
var fixedName = creator.FixName(name); var fixedName = creator.FixName(name);
foreach (var b in creator._repo.Branches) foreach (var b in creator._repo.Branches)
{ {
if (b.FriendlyName == fixedName) if (b.FriendlyName == fixedName)
return new ValidationResult("A branch with same name already exists!"); return new ValidationResult("A branch with same name already exists!");
} }
}
return ValidationResult.Success; return ValidationResult.Success;
} }
else
{
return new ValidationResult("Missing runtime context to create branch!");
}
}
public override Task<bool> Sure() public override Task<bool> Sure()
{ {
@ -123,7 +135,7 @@ namespace SourceGit.ViewModels
var needPopStash = false; var needPopStash = false;
if (DiscardLocalChanges) if (DiscardLocalChanges)
{ {
succ = new Commands.Checkout(_repo.FullPath).Use(log).Branch(fixedName, _baseOnRevision, true); succ = new Commands.Checkout(_repo.FullPath).Use(log).Branch(fixedName, _baseOnRevision, true, _allowOverwrite);
} }
else else
{ {
@ -141,16 +153,16 @@ namespace SourceGit.ViewModels
needPopStash = true; needPopStash = true;
} }
succ = new Commands.Checkout(_repo.FullPath).Use(log).Branch(fixedName, _baseOnRevision, false); succ = new Commands.Checkout(_repo.FullPath).Use(log).Branch(fixedName, _baseOnRevision, false, _allowOverwrite);
} }
if (succ) if (succ)
{ {
if (updateSubmodules) if (updateSubmodules)
{ {
var submodules = new Commands.QuerySubmodules(_repo.FullPath).Result(); var submodules = new Commands.QueryUpdatableSubmodules(_repo.FullPath).Result();
if (submodules.Count > 0) if (submodules.Count > 0)
new Commands.Submodule(_repo.FullPath).Use(log).Update(submodules, true, true, false); new Commands.Submodule(_repo.FullPath).Use(log).Update(submodules, true, true);
} }
if (needPopStash) if (needPopStash)
@ -159,7 +171,7 @@ namespace SourceGit.ViewModels
} }
else else
{ {
succ = Commands.Branch.Create(_repo.FullPath, fixedName, _baseOnRevision, log); succ = Commands.Branch.Create(_repo.FullPath, fixedName, _baseOnRevision, _allowOverwrite, log);
} }
log.Complete(); log.Complete();
@ -205,5 +217,6 @@ namespace SourceGit.ViewModels
private readonly Repository _repo = null; private readonly Repository _repo = null;
private string _name = null; private string _name = null;
private readonly string _baseOnRevision = null; private readonly string _baseOnRevision = null;
private bool _allowOverwrite = false;
} }
} }

View file

@ -0,0 +1,45 @@
using System.Threading.Tasks;
namespace SourceGit.ViewModels
{
public class DeinitSubmodule : Popup
{
public string Submodule
{
get;
private set;
}
public bool Force
{
get;
set;
}
public DeinitSubmodule(Repository repo, string submodule)
{
_repo = repo;
Submodule = submodule;
Force = false;
}
public override Task<bool> Sure()
{
_repo.SetWatcherEnabled(false);
ProgressDescription = "De-initialize Submodule";
var log = _repo.CreateLog("De-initialize Submodule");
Use(log);
return Task.Run(() =>
{
var succ = new Commands.Submodule(_repo.FullPath).Use(log).Deinit(Submodule, false);
log.Complete();
CallUIThread(() => _repo.SetWatcherEnabled(true));
return succ;
});
}
private Repository _repo;
}
}

View file

@ -36,13 +36,17 @@ namespace SourceGit.ViewModels
_repo.SetWatcherEnabled(false); _repo.SetWatcherEnabled(false);
ProgressDescription = "Run custom action ..."; ProgressDescription = "Run custom action ...";
var log = _repo.CreateLog(CustomAction.Name);
Use(log);
return Task.Run(() => return Task.Run(() =>
{ {
if (CustomAction.WaitForExit) if (CustomAction.WaitForExit)
Commands.ExecuteCustomAction.RunAndWait(_repo.FullPath, CustomAction.Executable, _args, output => CallUIThread(() => ProgressDescription = output)); Commands.ExecuteCustomAction.RunAndWait(_repo.FullPath, CustomAction.Executable, _args, log);
else else
Commands.ExecuteCustomAction.Run(_repo.FullPath, CustomAction.Executable, _args); Commands.ExecuteCustomAction.Run(_repo.FullPath, CustomAction.Executable, _args);
log.Complete();
CallUIThread(() => _repo.SetWatcherEnabled(true)); CallUIThread(() => _repo.SetWatcherEnabled(true));
return true; return true;
}); });

View file

@ -1,47 +0,0 @@
using System.Threading.Tasks;
namespace SourceGit.ViewModels
{
public class FastForwardWithoutCheckout : Popup
{
public Models.Branch Local
{
get;
}
public Models.Branch To
{
get;
}
public FastForwardWithoutCheckout(Repository repo, Models.Branch local, Models.Branch upstream)
{
_repo = repo;
Local = local;
To = upstream;
}
public override Task<bool> Sure()
{
_repo.SetWatcherEnabled(false);
ProgressDescription = "Fast-Forward ...";
var log = _repo.CreateLog("Fast-Forward (No checkout)");
Use(log);
return Task.Run(() =>
{
new Commands.UpdateRef(_repo.FullPath, Local.FullName, To.FullName).Use(log).Exec();
log.Complete();
CallUIThread(() =>
{
_repo.NavigateToCommit(To.Head);
_repo.SetWatcherEnabled(true);
});
return true;
});
}
private readonly Repository _repo = null;
}
}

View file

@ -80,9 +80,16 @@ namespace SourceGit.ViewModels
log.Complete(); log.Complete();
var upstream = _repo.CurrentBranch?.Upstream;
var upstreamHead = string.Empty;
if (!string.IsNullOrEmpty(upstream))
upstreamHead = new Commands.QueryRevisionByRefName(_repo.FullPath, upstream.Substring(13)).Result();
CallUIThread(() => CallUIThread(() =>
{ {
_repo.NavigateToBranchDelayed(_repo.CurrentBranch?.Upstream); if (!string.IsNullOrEmpty(upstreamHead))
_repo.NavigateToCommitDelayed(upstreamHead);
_repo.MarkFetched(); _repo.MarkFetched();
_repo.SetWatcherEnabled(true); _repo.SetWatcherEnabled(true);
}); });

View file

@ -33,11 +33,14 @@ namespace SourceGit.ViewModels
{ {
new Commands.Fetch(_repo.FullPath, Local, Upstream).Use(log).Exec(); new Commands.Fetch(_repo.FullPath, Local, Upstream).Use(log).Exec();
log.Complete(); log.Complete();
var changedLocalBranchHead = new Commands.QueryRevisionByRefName(_repo.FullPath, Local.Name).Result();
CallUIThread(() => CallUIThread(() =>
{ {
_repo.NavigateToBranchDelayed(Upstream.FullName); _repo.NavigateToCommitDelayed(changedLocalBranchHead);
_repo.SetWatcherEnabled(true); _repo.SetWatcherEnabled(true);
}); });
return true; return true;
}); });
} }

View file

@ -9,9 +9,11 @@ namespace SourceGit.ViewModels
get; get;
} }
public bool IsFeature => _type == "feature"; public Models.GitFlowBranchType Type
public bool IsRelease => _type == "release"; {
public bool IsHotfix => _type == "hotfix"; get;
private set;
}
public bool Squash public bool Squash
{ {
@ -31,27 +33,27 @@ namespace SourceGit.ViewModels
set; set;
} = false; } = false;
public GitFlowFinish(Repository repo, Models.Branch branch, string type, string prefix) public GitFlowFinish(Repository repo, Models.Branch branch, Models.GitFlowBranchType type)
{ {
_repo = repo; _repo = repo;
_type = type;
_prefix = prefix;
Branch = branch; Branch = branch;
Type = type;
} }
public override Task<bool> Sure() public override Task<bool> Sure()
{ {
_repo.SetWatcherEnabled(false); _repo.SetWatcherEnabled(false);
ProgressDescription = $"Git Flow - Finish {Branch.Name} ...";
var name = Branch.Name.StartsWith(_prefix) ? Branch.Name.Substring(_prefix.Length) : Branch.Name; var log = _repo.CreateLog("GitFlow - Finish");
ProgressDescription = $"Git Flow - finishing {_type} {name} ...";
var log = _repo.CreateLog("Gitflow - Finish");
Use(log); Use(log);
var prefix = _repo.GitFlow.GetPrefix(Type);
var name = Branch.Name.StartsWith(prefix) ? Branch.Name.Substring(prefix.Length) : Branch.Name;
return Task.Run(() => return Task.Run(() =>
{ {
var succ = Commands.GitFlow.Finish(_repo.FullPath, _type, name, Squash, AutoPush, KeepBranch, log); var succ = Commands.GitFlow.Finish(_repo.FullPath, Type, name, Squash, AutoPush, KeepBranch, log);
log.Complete(); log.Complete();
CallUIThread(() => _repo.SetWatcherEnabled(true)); CallUIThread(() => _repo.SetWatcherEnabled(true));
return succ; return succ;
@ -59,7 +61,5 @@ namespace SourceGit.ViewModels
} }
private readonly Repository _repo; private readonly Repository _repo;
private readonly string _type;
private readonly string _prefix;
} }
} }

View file

@ -5,6 +5,18 @@ namespace SourceGit.ViewModels
{ {
public class GitFlowStart : Popup public class GitFlowStart : Popup
{ {
public Models.GitFlowBranchType Type
{
get;
private set;
}
public string Prefix
{
get;
private set;
}
[Required(ErrorMessage = "Name is required!!!")] [Required(ErrorMessage = "Name is required!!!")]
[RegularExpression(@"^[\w\-/\.#]+$", ErrorMessage = "Bad branch name format!")] [RegularExpression(@"^[\w\-/\.#]+$", ErrorMessage = "Bad branch name format!")]
[CustomValidation(typeof(GitFlowStart), nameof(ValidateBranchName))] [CustomValidation(typeof(GitFlowStart), nameof(ValidateBranchName))]
@ -14,27 +26,19 @@ namespace SourceGit.ViewModels
set => SetProperty(ref _name, value, true); set => SetProperty(ref _name, value, true);
} }
public string Prefix public GitFlowStart(Repository repo, Models.GitFlowBranchType type)
{
get => _prefix;
}
public bool IsFeature => _type == "feature";
public bool IsRelease => _type == "release";
public bool IsHotfix => _type == "hotfix";
public GitFlowStart(Repository repo, string type)
{ {
_repo = repo; _repo = repo;
_type = type;
_prefix = Commands.GitFlow.GetPrefix(repo.FullPath, type); Type = type;
Prefix = _repo.GitFlow.GetPrefix(type);
} }
public static ValidationResult ValidateBranchName(string name, ValidationContext ctx) public static ValidationResult ValidateBranchName(string name, ValidationContext ctx)
{ {
if (ctx.ObjectInstance is GitFlowStart starter) if (ctx.ObjectInstance is GitFlowStart starter)
{ {
var check = $"{starter._prefix}{name}"; var check = $"{starter.Prefix}{name}";
foreach (var b in starter._repo.Branches) foreach (var b in starter._repo.Branches)
{ {
if (b.FriendlyName == check) if (b.FriendlyName == check)
@ -48,14 +52,14 @@ namespace SourceGit.ViewModels
public override Task<bool> Sure() public override Task<bool> Sure()
{ {
_repo.SetWatcherEnabled(false); _repo.SetWatcherEnabled(false);
ProgressDescription = $"Git Flow - starting {_type} {_name} ..."; ProgressDescription = $"Git Flow - Start {Prefix}{_name} ...";
var log = _repo.CreateLog("Gitflow - Start"); var log = _repo.CreateLog("GitFlow - Start");
Use(log); Use(log);
return Task.Run(() => return Task.Run(() =>
{ {
var succ = Commands.GitFlow.Start(_repo.FullPath, _type, _name, log); var succ = Commands.GitFlow.Start(_repo.FullPath, Type, _name, log);
log.Complete(); log.Complete();
CallUIThread(() => _repo.SetWatcherEnabled(true)); CallUIThread(() => _repo.SetWatcherEnabled(true));
return succ; return succ;
@ -63,8 +67,6 @@ namespace SourceGit.ViewModels
} }
private readonly Repository _repo; private readonly Repository _repo;
private readonly string _type;
private readonly string _prefix;
private string _name = null; private string _name = null;
} }
} }

View file

@ -12,7 +12,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.ViewModels namespace SourceGit.ViewModels
{ {
public class Histories : ObservableObject public class Histories : ObservableObject, IDisposable
{ {
public Repository Repo public Repository Repo
{ {
@ -57,7 +57,7 @@ namespace SourceGit.ViewModels
private set => SetProperty(ref _navigationId, value); private set => SetProperty(ref _navigationId, value);
} }
public object DetailContext public IDisposable DetailContext
{ {
get => _detailContext; get => _detailContext;
set => SetProperty(ref _detailContext, value); set => SetProperty(ref _detailContext, value);
@ -98,23 +98,13 @@ namespace SourceGit.ViewModels
_repo = repo; _repo = repo;
} }
public void Cleanup() public void Dispose()
{ {
Commits = new List<Models.Commit>(); Commits = [];
_repo = null; _repo = null;
_graph = null; _graph = null;
_autoSelectedCommit = null; _autoSelectedCommit = null;
_detailContext?.Dispose();
if (_detailContext is CommitDetail cd)
{
cd.Cleanup();
}
else if (_detailContext is RevisionCompare rc)
{
rc.Cleanup();
}
_detailContext = null; _detailContext = null;
} }
@ -220,7 +210,7 @@ namespace SourceGit.ViewModels
else else
{ {
_repo.SelectedSearchedCommit = null; _repo.SelectedSearchedCommit = null;
DetailContext = commits.Count; DetailContext = new Models.Count(commits.Count);
} }
} }
@ -985,8 +975,8 @@ namespace SourceGit.ViewModels
if (!_repo.IsBare) if (!_repo.IsBare)
{ {
var detect = Commands.GitFlow.DetectType(_repo.FullPath, _repo.Branches, current.Name); var type = _repo.GetGitFlowType(current);
if (detect.IsGitFlowBranch) if (type != Models.GitFlowBranchType.None)
{ {
var finish = new MenuItem(); var finish = new MenuItem();
finish.Header = App.Text("BranchCM.Finish", current.Name); finish.Header = App.Text("BranchCM.Finish", current.Name);
@ -994,7 +984,7 @@ namespace SourceGit.ViewModels
finish.Click += (_, e) => finish.Click += (_, e) =>
{ {
if (_repo.CanCreatePopup()) if (_repo.CanCreatePopup())
_repo.ShowPopup(new GitFlowFinish(_repo, current, detect.Type, detect.Prefix)); _repo.ShowPopup(new GitFlowFinish(_repo, current, type));
e.Handled = true; e.Handled = true;
}; };
submenu.Items.Add(finish); submenu.Items.Add(finish);
@ -1073,8 +1063,8 @@ namespace SourceGit.ViewModels
if (!_repo.IsBare) if (!_repo.IsBare)
{ {
var detect = Commands.GitFlow.DetectType(_repo.FullPath, _repo.Branches, branch.Name); var type = _repo.GetGitFlowType(branch);
if (detect.IsGitFlowBranch) if (type != Models.GitFlowBranchType.None)
{ {
var finish = new MenuItem(); var finish = new MenuItem();
finish.Header = App.Text("BranchCM.Finish", branch.Name); finish.Header = App.Text("BranchCM.Finish", branch.Name);
@ -1082,7 +1072,7 @@ namespace SourceGit.ViewModels
finish.Click += (_, e) => finish.Click += (_, e) =>
{ {
if (_repo.CanCreatePopup()) if (_repo.CanCreatePopup())
_repo.ShowPopup(new GitFlowFinish(_repo, branch, detect.Type, detect.Prefix)); _repo.ShowPopup(new GitFlowFinish(_repo, branch, type));
e.Handled = true; e.Handled = true;
}; };
submenu.Items.Add(finish); submenu.Items.Add(finish);
@ -1256,7 +1246,7 @@ namespace SourceGit.ViewModels
private Models.CommitGraph _graph = null; private Models.CommitGraph _graph = null;
private Models.Commit _autoSelectedCommit = null; private Models.Commit _autoSelectedCommit = null;
private long _navigationId = 0; private long _navigationId = 0;
private object _detailContext = null; private IDisposable _detailContext = null;
private Models.Bisect _bisect = null; private Models.Bisect _bisect = null;

View file

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -109,9 +110,35 @@ namespace SourceGit.ViewModels
return Task.Run(() => return Task.Run(() =>
{ {
var succ = Commands.GitFlow.Init( var succ = false;
var current = _repo.CurrentBranch;
var masterBranch = _repo.Branches.Find(x => x.IsLocal && x.Name.Equals(_master, StringComparison.Ordinal));
if (masterBranch == null)
{
succ = Commands.Branch.Create(_repo.FullPath, _master, current.Head, true, log);
if (!succ)
{
log.Complete();
CallUIThread(() => _repo.SetWatcherEnabled(true));
return false;
}
}
var developBranch = _repo.Branches.Find(x => x.IsLocal && x.Name.Equals(_develop, StringComparison.Ordinal));
if (developBranch == null)
{
succ = Commands.Branch.Create(_repo.FullPath, _develop, current.Head, true, log);
if (!succ)
{
log.Complete();
CallUIThread(() => _repo.SetWatcherEnabled(true));
return false;
}
}
succ = Commands.GitFlow.Init(
_repo.FullPath, _repo.FullPath,
_repo.Branches,
_master, _master,
_develop, _develop,
_featurePrefix, _featurePrefix,
@ -121,7 +148,23 @@ namespace SourceGit.ViewModels
log); log);
log.Complete(); log.Complete();
CallUIThread(() => _repo.SetWatcherEnabled(true));
CallUIThread(() =>
{
if (succ)
{
var gitflow = new Models.GitFlow();
gitflow.Master = _master;
gitflow.Develop = _develop;
gitflow.FeaturePrefix = _featurePrefix;
gitflow.ReleasePrefix = _releasePrefix;
gitflow.HotfixPrefix = _hotfixPrefix;
_repo.GitFlow = gitflow;
}
_repo.SetWatcherEnabled(true);
});
return succ; return succ;
}); });
} }

View file

@ -19,10 +19,23 @@ namespace SourceGit.ViewModels
private set; private set;
} }
public bool CanSquashOrFixup
{
get => _canSquashOrFixup;
set
{
if (SetProperty(ref _canSquashOrFixup, value))
{
if (_action == Models.InteractiveRebaseAction.Squash || _action == Models.InteractiveRebaseAction.Fixup)
Action = Models.InteractiveRebaseAction.Pick;
}
}
}
public Models.InteractiveRebaseAction Action public Models.InteractiveRebaseAction Action
{ {
get => _action; get => _action;
private set => SetProperty(ref _action, value); set => SetProperty(ref _action, value);
} }
public string Subject public string Subject
@ -48,20 +61,17 @@ namespace SourceGit.ViewModels
} }
} }
public InteractiveRebaseItem(Models.Commit c, string message) public InteractiveRebaseItem(Models.Commit c, string message, bool canSquashOrFixup)
{ {
Commit = c; Commit = c;
FullMessage = message; FullMessage = message;
} CanSquashOrFixup = canSquashOrFixup;
public void SetAction(object param)
{
Action = (Models.InteractiveRebaseAction)param;
} }
private Models.InteractiveRebaseAction _action = Models.InteractiveRebaseAction.Pick; private Models.InteractiveRebaseAction _action = Models.InteractiveRebaseAction.Pick;
private string _subject; private string _subject;
private string _fullMessage; private string _fullMessage;
private bool _canSquashOrFixup = true;
} }
public class InteractiveRebase : ObservableObject public class InteractiveRebase : ObservableObject
@ -88,7 +98,7 @@ namespace SourceGit.ViewModels
{ {
get; get;
private set; private set;
} = new AvaloniaList<InteractiveRebaseItem>(); } = [];
public InteractiveRebaseItem SelectedItem public InteractiveRebaseItem SelectedItem
{ {
@ -121,8 +131,11 @@ namespace SourceGit.ViewModels
var commits = new Commands.QueryCommitsForInteractiveRebase(repoPath, on.SHA).Result(); var commits = new Commands.QueryCommitsForInteractiveRebase(repoPath, on.SHA).Result();
var list = new List<InteractiveRebaseItem>(); var list = new List<InteractiveRebaseItem>();
foreach (var c in commits) for (var i = 0; i < commits.Count; i++)
list.Add(new InteractiveRebaseItem(c.Commit, c.Message)); {
var c = commits[i];
list.Add(new InteractiveRebaseItem(c.Commit, c.Message, i < commits.Count - 1));
}
Dispatcher.UIThread.Invoke(() => Dispatcher.UIThread.Invoke(() =>
{ {
@ -141,6 +154,7 @@ namespace SourceGit.ViewModels
Items.RemoveAt(idx - 1); Items.RemoveAt(idx - 1);
Items.Insert(idx, prev); Items.Insert(idx, prev);
SelectedItem = item; SelectedItem = item;
UpdateItems();
} }
} }
@ -153,9 +167,22 @@ namespace SourceGit.ViewModels
Items.RemoveAt(idx + 1); Items.RemoveAt(idx + 1);
Items.Insert(idx, next); Items.Insert(idx, next);
SelectedItem = item; SelectedItem = item;
UpdateItems();
} }
} }
public void ChangeAction(InteractiveRebaseItem item, Models.InteractiveRebaseAction action)
{
if (!item.CanSquashOrFixup)
{
if (action == Models.InteractiveRebaseAction.Squash || action == Models.InteractiveRebaseAction.Fixup)
return;
}
item.Action = action;
UpdateItems();
}
public Task<bool> Start() public Task<bool> Start()
{ {
_repo.SetWatcherEnabled(false); _repo.SetWatcherEnabled(false);
@ -186,6 +213,27 @@ namespace SourceGit.ViewModels
}); });
} }
private void UpdateItems()
{
if (Items.Count == 0)
return;
var hasValidParent = false;
for (var i = Items.Count - 1; i >= 0; i--)
{
var item = Items[i];
if (hasValidParent)
{
item.CanSquashOrFixup = true;
}
else
{
item.CanSquashOrFixup = false;
hasValidParent = item.Action != Models.InteractiveRebaseAction.Drop;
}
}
}
private Repository _repo = null; private Repository _repo = null;
private bool _isLoading = false; private bool _isLoading = false;
private InteractiveRebaseItem _selectedItem = null; private InteractiveRebaseItem _selectedItem = null;

View file

@ -64,9 +64,10 @@ namespace SourceGit.ViewModels
new Commands.Merge(_repo.FullPath, _sourceName, Mode.Arg).Use(log).Exec(); new Commands.Merge(_repo.FullPath, _sourceName, Mode.Arg).Use(log).Exec();
log.Complete(); log.Complete();
var head = new Commands.QueryRevisionByRefName(_repo.FullPath, "HEAD").Result();
CallUIThread(() => CallUIThread(() =>
{ {
_repo.NavigateToBranchDelayed(_repo.CurrentBranch?.FullName); _repo.NavigateToCommitDelayed(head);
_repo.SetWatcherEnabled(true); _repo.SetWatcherEnabled(true);
}); });
return true; return true;

View file

@ -48,7 +48,14 @@ namespace SourceGit.ViewModels
protected void Use(CommandLog log) protected void Use(CommandLog log)
{ {
log.Register(newline => ProgressDescription = newline.Trim()); log.Register(SetDescription);
}
private void SetDescription(string data)
{
var desc = data.Trim();
if (!string.IsNullOrEmpty(desc))
ProgressDescription = desc;
} }
private bool _inProgress = false; private bool _inProgress = false;

View file

@ -50,16 +50,15 @@ namespace SourceGit.ViewModels
set => _repo.Settings.PreferRebaseInsteadOfMerge = value; set => _repo.Settings.PreferRebaseInsteadOfMerge = value;
} }
public bool FetchAllBranches public bool IsRecurseSubmoduleVisible
{ {
get => _repo.Settings.FetchAllBranchesOnPull; get => _repo.Submodules.Count > 0;
set => _repo.Settings.FetchAllBranchesOnPull = value;
} }
public bool NoTags public bool RecurseSubmodules
{ {
get => _repo.Settings.FetchWithoutTagsOnPull; get => _repo.Settings.UpdateSubmodulesOnCheckoutBranch;
set => _repo.Settings.FetchWithoutTagsOnPull = value; set => _repo.Settings.UpdateSubmodulesOnCheckoutBranch = value;
} }
public Pull(Repository repo, Models.Branch specifiedRemoteBranch) public Pull(Repository repo, Models.Branch specifiedRemoteBranch)
@ -119,6 +118,7 @@ namespace SourceGit.ViewModels
var log = _repo.CreateLog("Pull"); var log = _repo.CreateLog("Pull");
Use(log); Use(log);
var updateSubmodules = IsRecurseSubmoduleVisible && RecurseSubmodules;
return Task.Run(() => return Task.Run(() =>
{ {
var changes = new Commands.CountLocalChangesWithoutUntracked(_repo.FullPath).Result(); var changes = new Commands.CountLocalChangesWithoutUntracked(_repo.FullPath).Result();
@ -143,47 +143,31 @@ namespace SourceGit.ViewModels
} }
} }
bool rs; bool rs = new Commands.Pull(
if (FetchAllBranches)
{
rs = new Commands.Fetch(
_repo.FullPath, _repo.FullPath,
_selectedRemote.Name, _selectedRemote.Name,
NoTags, !string.IsNullOrEmpty(_current.Upstream) && _current.Upstream.Equals(_selectedBranch.FullName) ? string.Empty : _selectedBranch.Name,
false).Use(log).Exec(); UseRebase).Use(log).Exec();
if (!rs)
if (rs)
{ {
log.Complete(); if (updateSubmodules)
CallUIThread(() => _repo.SetWatcherEnabled(true));
return false;
}
_repo.MarkFetched();
// Use merge/rebase instead of pull as fetch is done manually.
if (UseRebase)
rs = new Commands.Rebase(_repo.FullPath, _selectedBranch.FriendlyName, false).Use(log).Exec();
else
rs = new Commands.Merge(_repo.FullPath, _selectedBranch.FriendlyName, "").Use(log).Exec();
}
else
{ {
rs = new Commands.Pull( var submodules = new Commands.QueryUpdatableSubmodules(_repo.FullPath).Result();
_repo.FullPath, if (submodules.Count > 0)
_selectedRemote.Name, new Commands.Submodule(_repo.FullPath).Use(log).Update(submodules, true, true);
_selectedBranch.Name,
UseRebase,
NoTags).Use(log).Exec();
} }
if (rs && needPopStash) if (needPopStash)
rs = new Commands.Stash(_repo.FullPath).Use(log).Pop("stash@{0}"); new Commands.Stash(_repo.FullPath).Use(log).Pop("stash@{0}");
}
log.Complete(); log.Complete();
var head = new Commands.QueryRevisionByRefName(_repo.FullPath, "HEAD").Result();
CallUIThread(() => CallUIThread(() =>
{ {
_repo.NavigateToBranchDelayed(_repo.CurrentBranch?.FullName); _repo.NavigateToCommitDelayed(head);
_repo.SetWatcherEnabled(true); _repo.SetWatcherEnabled(true);
}); });

View file

@ -51,6 +51,12 @@ namespace SourceGit.ViewModels
get => _settings; get => _settings;
} }
public Models.GitFlow GitFlow
{
get;
set;
} = new Models.GitFlow();
public Models.FilterMode HistoriesFilterMode public Models.FilterMode HistoriesFilterMode
{ {
get => _historiesFilterMode; get => _historiesFilterMode;
@ -294,6 +300,7 @@ namespace SourceGit.ViewModels
SelectedSearchedCommit = null; SelectedSearchedCommit = null;
SearchCommitFilter = string.Empty; SearchCommitFilter = string.Empty;
MatchedFilesForSearching = null; MatchedFilesForSearching = null;
_requestingWorktreeFiles = false;
_worktreeFiles = null; _worktreeFiles = null;
} }
} }
@ -545,9 +552,9 @@ namespace SourceGit.ViewModels
_historiesFilterMode = Models.FilterMode.None; _historiesFilterMode = Models.FilterMode.None;
_watcher?.Dispose(); _watcher?.Dispose();
_histories.Cleanup(); _histories.Dispose();
_workingCopy.Cleanup(); _workingCopy.Dispose();
_stashesPage.Cleanup(); _stashesPage.Dispose();
_watcher = null; _watcher = null;
_histories = null; _histories = null;
@ -568,6 +575,7 @@ namespace SourceGit.ViewModels
_searchedCommits.Clear(); _searchedCommits.Clear();
_selectedSearchedCommit = null; _selectedSearchedCommit = null;
_requestingWorktreeFiles = false;
_worktreeFiles = null; _worktreeFiles = null;
_matchedFilesForSearching = null; _matchedFilesForSearching = null;
} }
@ -593,6 +601,28 @@ namespace SourceGit.ViewModels
GetOwnerPage()?.StartPopup(popup); GetOwnerPage()?.StartPopup(popup);
} }
public bool IsGitFlowEnabled()
{
return GitFlow is { IsValid: true } &&
_branches.Find(x => x.IsLocal && x.Name.Equals(GitFlow.Master, StringComparison.Ordinal)) != null &&
_branches.Find(x => x.IsLocal && x.Name.Equals(GitFlow.Develop, StringComparison.Ordinal)) != null;
}
public Models.GitFlowBranchType GetGitFlowType(Models.Branch b)
{
if (!IsGitFlowEnabled())
return Models.GitFlowBranchType.None;
var name = b.Name;
if (name.StartsWith(GitFlow.FeaturePrefix, StringComparison.Ordinal))
return Models.GitFlowBranchType.Feature;
if (name.StartsWith(GitFlow.ReleasePrefix, StringComparison.Ordinal))
return Models.GitFlowBranchType.Release;
if (name.StartsWith(GitFlow.HotfixPrefix, StringComparison.Ordinal))
return Models.GitFlowBranchType.Hotfix;
return Models.GitFlowBranchType.None;
}
public CommandLog CreateLog(string name) public CommandLog CreateLog(string name)
{ {
var log = new CommandLog(name); var log = new CommandLog(name);
@ -602,19 +632,30 @@ namespace SourceGit.ViewModels
public void RefreshAll() public void RefreshAll()
{ {
Task.Run(() => Task.Run(RefreshCommits);
{
var allowedSignersFile = new Commands.Config(_fullpath).Get("gpg.ssh.allowedSignersFile");
_hasAllowedSignersFile = !string.IsNullOrEmpty(allowedSignersFile);
});
Task.Run(RefreshBranches); Task.Run(RefreshBranches);
Task.Run(RefreshTags); Task.Run(RefreshTags);
Task.Run(RefreshCommits);
Task.Run(RefreshSubmodules); Task.Run(RefreshSubmodules);
Task.Run(RefreshWorktrees); Task.Run(RefreshWorktrees);
Task.Run(RefreshWorkingCopyChanges); Task.Run(RefreshWorkingCopyChanges);
Task.Run(RefreshStashes); Task.Run(RefreshStashes);
Task.Run(() =>
{
var config = new Commands.Config(_fullpath).ListAll();
_hasAllowedSignersFile = config.TryGetValue("gpg.ssh.allowedSignersFile", out var allowedSignersFile) && !string.IsNullOrEmpty(allowedSignersFile);
if (config.TryGetValue("gitflow.branch.master", out var masterName))
GitFlow.Master = masterName;
if (config.TryGetValue("gitflow.branch.develop", out var developName))
GitFlow.Develop = developName;
if (config.TryGetValue("gitflow.prefix.feature", out var featurePrefix))
GitFlow.FeaturePrefix = featurePrefix;
if (config.TryGetValue("gitflow.prefix.release", out var releasePrefix))
GitFlow.ReleasePrefix = releasePrefix;
if (config.TryGetValue("gitflow.prefix.hotfix", out var hotfixPrefix))
GitFlow.HotfixPrefix = hotfixPrefix;
});
} }
public ContextMenu CreateContextMenuForExternalTools() public ContextMenu CreateContextMenuForExternalTools()
@ -881,17 +922,17 @@ namespace SourceGit.ViewModels
} }
} }
public void NavigateToCommitDelayed(string sha)
{
_navigateToCommitDelayed = sha;
}
public void NavigateToCurrentHead() public void NavigateToCurrentHead()
{ {
if (_currentBranch != null) if (_currentBranch != null)
NavigateToCommit(_currentBranch.Head); NavigateToCommit(_currentBranch.Head);
} }
public void NavigateToBranchDelayed(string branch)
{
_navigateToBranchDelayed = branch;
}
public void ClearHistoriesFilter() public void ClearHistoriesFilter()
{ {
_settings.HistoriesFilters.Clear(); _settings.HistoriesFilters.Clear();
@ -1052,6 +1093,13 @@ namespace SourceGit.ViewModels
}); });
} }
public bool MayHaveSubmodules()
{
var modulesFile = Path.Combine(_fullpath, ".gitmodules");
var info = new FileInfo(modulesFile);
return info.Exists && info.Length > 20;
}
public void RefreshBranches() public void RefreshBranches()
{ {
var branches = new Commands.QueryBranches(_fullpath).Result(out var localBranchesCount); var branches = new Commands.QueryBranches(_fullpath).Result(out var localBranchesCount);
@ -1141,27 +1189,64 @@ namespace SourceGit.ViewModels
BisectState = _histories.UpdateBisectInfo(); BisectState = _histories.UpdateBisectInfo();
if (!string.IsNullOrEmpty(_navigateToBranchDelayed)) if (!string.IsNullOrEmpty(_navigateToCommitDelayed))
{ NavigateToCommit(_navigateToCommitDelayed);
var branch = _branches.Find(x => x.FullName == _navigateToBranchDelayed);
if (branch != null)
NavigateToCommit(branch.Head);
}
} }
_navigateToBranchDelayed = string.Empty; _navigateToCommitDelayed = string.Empty;
}); });
} }
public void RefreshSubmodules() public void RefreshSubmodules()
{ {
if (!MayHaveSubmodules())
{
if (_submodules.Count > 0)
{
Dispatcher.UIThread.Invoke(() =>
{
Submodules = [];
VisibleSubmodules = BuildVisibleSubmodules();
});
}
return;
}
var submodules = new Commands.QuerySubmodules(_fullpath).Result(); var submodules = new Commands.QuerySubmodules(_fullpath).Result();
_watcher?.SetSubmodules(submodules); _watcher?.SetSubmodules(submodules);
Dispatcher.UIThread.Invoke(() => Dispatcher.UIThread.Invoke(() =>
{
bool hasChanged = _submodules.Count != submodules.Count;
if (!hasChanged)
{
var old = new Dictionary<string, Models.Submodule>();
foreach (var module in _submodules)
old.Add(module.Path, module);
foreach (var module in submodules)
{
if (!old.TryGetValue(module.Path, out var exist))
{
hasChanged = true;
break;
}
hasChanged = !exist.SHA.Equals(module.SHA, StringComparison.Ordinal) ||
!exist.URL.Equals(module.URL, StringComparison.Ordinal) ||
exist.Status != module.Status;
if (hasChanged)
break;
}
}
if (hasChanged)
{ {
Submodules = submodules; Submodules = submodules;
VisibleSubmodules = BuildVisibleSubmodules(); VisibleSubmodules = BuildVisibleSubmodules();
}
}); });
} }
@ -1375,8 +1460,7 @@ namespace SourceGit.ViewModels
var menu = new ContextMenu(); var menu = new ContextMenu();
menu.Placement = PlacementMode.BottomEdgeAlignedLeft; menu.Placement = PlacementMode.BottomEdgeAlignedLeft;
var isGitFlowEnabled = Commands.GitFlow.IsEnabled(_fullpath, _branches); if (IsGitFlowEnabled())
if (isGitFlowEnabled)
{ {
var startFeature = new MenuItem(); var startFeature = new MenuItem();
startFeature.Header = App.Text("GitFlow.StartFeature"); startFeature.Header = App.Text("GitFlow.StartFeature");
@ -1384,7 +1468,7 @@ namespace SourceGit.ViewModels
startFeature.Click += (_, e) => startFeature.Click += (_, e) =>
{ {
if (CanCreatePopup()) if (CanCreatePopup())
ShowPopup(new GitFlowStart(this, "feature")); ShowPopup(new GitFlowStart(this, Models.GitFlowBranchType.Feature));
e.Handled = true; e.Handled = true;
}; };
@ -1394,7 +1478,7 @@ namespace SourceGit.ViewModels
startRelease.Click += (_, e) => startRelease.Click += (_, e) =>
{ {
if (CanCreatePopup()) if (CanCreatePopup())
ShowPopup(new GitFlowStart(this, "release")); ShowPopup(new GitFlowStart(this, Models.GitFlowBranchType.Release));
e.Handled = true; e.Handled = true;
}; };
@ -1404,7 +1488,7 @@ namespace SourceGit.ViewModels
startHotfix.Click += (_, e) => startHotfix.Click += (_, e) =>
{ {
if (CanCreatePopup()) if (CanCreatePopup())
ShowPopup(new GitFlowStart(this, "hotfix")); ShowPopup(new GitFlowStart(this, Models.GitFlowBranchType.Hotfix));
e.Handled = true; e.Handled = true;
}; };
@ -1419,8 +1503,15 @@ namespace SourceGit.ViewModels
init.Icon = App.CreateMenuIcon("Icons.Init"); init.Icon = App.CreateMenuIcon("Icons.Init");
init.Click += (_, e) => init.Click += (_, e) =>
{ {
if (CanCreatePopup()) if (_currentBranch == null)
{
App.RaiseException(_fullpath, "Git flow init failed: No branch found!!!");
}
else if (CanCreatePopup())
{
ShowPopup(new InitGitFlow(this)); ShowPopup(new InitGitFlow(this));
}
e.Handled = true; e.Handled = true;
}; };
menu.Items.Add(init); menu.Items.Add(init);
@ -1770,9 +1861,25 @@ namespace SourceGit.ViewModels
fastForward.Click += (_, e) => fastForward.Click += (_, e) =>
{ {
if (CanCreatePopup()) if (CanCreatePopup())
ShowAndStartPopup(new FastForwardWithoutCheckout(this, branch, upstream)); ShowAndStartPopup(new ResetWithoutCheckout(this, branch, upstream));
e.Handled = true; e.Handled = true;
}; };
menu.Items.Add(fastForward);
var selectedCommit = (_histories?.DetailContext as CommitDetail)?.Commit;
if (selectedCommit != null && !selectedCommit.SHA.Equals(branch.Head, StringComparison.Ordinal))
{
var move = new MenuItem();
move.Header = App.Text("BranchCM.ResetToSelectedCommit", branch.Name, selectedCommit.SHA.Substring(0, 10));
move.Icon = App.CreateMenuIcon("Icons.Reset");
move.Click += (_, e) =>
{
if (CanCreatePopup())
ShowPopup(new ResetWithoutCheckout(this, branch, selectedCommit));
e.Handled = true;
};
menu.Items.Add(move);
}
var fetchInto = new MenuItem(); var fetchInto = new MenuItem();
fetchInto.Header = App.Text("BranchCM.FetchInto", upstream.FriendlyName, branch.Name); fetchInto.Header = App.Text("BranchCM.FetchInto", upstream.FriendlyName, branch.Name);
@ -1785,7 +1892,6 @@ namespace SourceGit.ViewModels
e.Handled = true; e.Handled = true;
}; };
menu.Items.Add(fastForward);
menu.Items.Add(new MenuItem() { Header = "-" }); menu.Items.Add(new MenuItem() { Header = "-" });
menu.Items.Add(fetchInto); menu.Items.Add(fetchInto);
} }
@ -1850,8 +1956,8 @@ namespace SourceGit.ViewModels
if (!IsBare) if (!IsBare)
{ {
var detect = Commands.GitFlow.DetectType(_fullpath, _branches, branch.Name); var type = GetGitFlowType(branch);
if (detect.IsGitFlowBranch) if (type != Models.GitFlowBranchType.None)
{ {
var finish = new MenuItem(); var finish = new MenuItem();
finish.Header = App.Text("BranchCM.Finish", branch.Name); finish.Header = App.Text("BranchCM.Finish", branch.Name);
@ -1859,7 +1965,7 @@ namespace SourceGit.ViewModels
finish.Click += (_, e) => finish.Click += (_, e) =>
{ {
if (CanCreatePopup()) if (CanCreatePopup())
ShowPopup(new GitFlowFinish(this, branch, detect.Type, detect.Prefix)); ShowPopup(new GitFlowFinish(this, branch, type));
e.Handled = true; e.Handled = true;
}; };
menu.Items.Add(new MenuItem() { Header = "-" }); menu.Items.Add(new MenuItem() { Header = "-" });
@ -2370,12 +2476,14 @@ namespace SourceGit.ViewModels
ev.Handled = true; ev.Handled = true;
}; };
var copy = new MenuItem(); var deinit = new MenuItem();
copy.Header = App.Text("Submodule.CopyPath"); deinit.Header = App.Text("Submodule.Deinit");
copy.Icon = App.CreateMenuIcon("Icons.Copy"); deinit.Icon = App.CreateMenuIcon("Icons.Undo");
copy.Click += (_, ev) => deinit.IsEnabled = submodule.Status != Models.SubmoduleStatus.NotInited;
deinit.Click += (_, ev) =>
{ {
App.CopyText(submodule.Path); if (CanCreatePopup())
ShowPopup(new DeinitSubmodule(this, submodule.Path));
ev.Handled = true; ev.Handled = true;
}; };
@ -2389,10 +2497,22 @@ namespace SourceGit.ViewModels
ev.Handled = true; ev.Handled = true;
}; };
var copy = new MenuItem();
copy.Header = App.Text("Submodule.CopyPath");
copy.Icon = App.CreateMenuIcon("Icons.Copy");
copy.Click += (_, ev) =>
{
App.CopyText(submodule.Path);
ev.Handled = true;
};
var menu = new ContextMenu(); var menu = new ContextMenu();
menu.Items.Add(open); menu.Items.Add(open);
menu.Items.Add(copy); menu.Items.Add(new MenuItem() { Header = "-" });
menu.Items.Add(deinit);
menu.Items.Add(rm); menu.Items.Add(rm);
menu.Items.Add(new MenuItem() { Header = "-" });
menu.Items.Add(copy);
return menu; return menu;
} }
@ -2683,19 +2803,27 @@ namespace SourceGit.ViewModels
{ {
if (!IsSearchingCommitsByFilePath()) if (!IsSearchingCommitsByFilePath())
{ {
_requestingWorktreeFiles = false;
_worktreeFiles = null; _worktreeFiles = null;
MatchedFilesForSearching = null; MatchedFilesForSearching = null;
GC.Collect(); GC.Collect();
return; return;
} }
if (_requestingWorktreeFiles)
return;
_requestingWorktreeFiles = true;
Task.Run(() => Task.Run(() =>
{ {
_worktreeFiles = new Commands.QueryRevisionFileNames(_fullpath, "HEAD").Result(); _worktreeFiles = new Commands.QueryRevisionFileNames(_fullpath, "HEAD").Result();
Dispatcher.UIThread.Invoke(() => Dispatcher.UIThread.Invoke(() =>
{ {
if (IsSearchingCommitsByFilePath()) if (IsSearchingCommitsByFilePath() && _requestingWorktreeFiles)
CalcMatchedFilesForSearching(); CalcMatchedFilesForSearching();
_requestingWorktreeFiles = false;
}); });
}); });
} }
@ -2781,6 +2909,7 @@ namespace SourceGit.ViewModels
private string _searchCommitFilter = string.Empty; private string _searchCommitFilter = string.Empty;
private List<Models.Commit> _searchedCommits = new List<Models.Commit>(); private List<Models.Commit> _searchedCommits = new List<Models.Commit>();
private Models.Commit _selectedSearchedCommit = null; private Models.Commit _selectedSearchedCommit = null;
private bool _requestingWorktreeFiles = false;
private List<string> _worktreeFiles = null; private List<string> _worktreeFiles = null;
private List<string> _matchedFilesForSearching = null; private List<string> _matchedFilesForSearching = null;
@ -2804,6 +2933,6 @@ namespace SourceGit.ViewModels
private Models.BisectState _bisectState = Models.BisectState.None; private Models.BisectState _bisectState = Models.BisectState.None;
private bool _isBisectCommandRunning = false; private bool _isBisectCommandRunning = false;
private string _navigateToBranchDelayed = string.Empty; private string _navigateToCommitDelayed = string.Empty;
} }
} }

View file

@ -0,0 +1,53 @@
using System.Threading.Tasks;
namespace SourceGit.ViewModels
{
public class ResetWithoutCheckout : Popup
{
public Models.Branch Target
{
get;
}
public object To
{
get;
}
public ResetWithoutCheckout(Repository repo, Models.Branch target, Models.Branch to)
{
_repo = repo;
_revision = to.Head;
Target = target;
To = to;
}
public ResetWithoutCheckout(Repository repo, Models.Branch target, Models.Commit to)
{
_repo = repo;
_revision = to.SHA;
Target = target;
To = to;
}
public override Task<bool> Sure()
{
_repo.SetWatcherEnabled(false);
ProgressDescription = $"Reset {Target.Name} to {_revision} ...";
var log = _repo.CreateLog($"Reset '{Target.Name}' to '{_revision}'");
Use(log);
return Task.Run(() =>
{
var succ = Commands.Branch.Create(_repo.FullPath, Target.Name, _revision, true, log);
log.Complete();
CallUIThread(() => _repo.SetWatcherEnabled(true));
return succ;
});
}
private readonly Repository _repo = null;
private readonly string _revision = string.Empty;
}
}

View file

@ -10,7 +10,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.ViewModels namespace SourceGit.ViewModels
{ {
public class RevisionCompare : ObservableObject public class RevisionCompare : ObservableObject, IDisposable
{ {
public object StartPoint public object StartPoint
{ {
@ -83,7 +83,7 @@ namespace SourceGit.ViewModels
Task.Run(Refresh); Task.Run(Refresh);
} }
public void Cleanup() public void Dispose()
{ {
_repo = null; _repo = null;
_startPoint = null; _startPoint = null;

View file

@ -11,7 +11,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.ViewModels namespace SourceGit.ViewModels
{ {
public class StashesPage : ObservableObject public class StashesPage : ObservableObject, IDisposable
{ {
public List<Models.Stash> Stashes public List<Models.Stash> Stashes
{ {
@ -69,7 +69,7 @@ namespace SourceGit.ViewModels
changes = new Commands.CompareRevisions(_repo.FullPath, $"{value.SHA}^", value.SHA).Result(); changes = new Commands.CompareRevisions(_repo.FullPath, $"{value.SHA}^", value.SHA).Result();
if (value.Parents.Count == 3) if (value.Parents.Count == 3)
{ {
var untracked = new Commands.CompareRevisions(_repo.FullPath, "4b825dc642cb6eb9a060e54bf8d69288fbee4904", value.Parents[2]).Result(); var untracked = new Commands.CompareRevisions(_repo.FullPath, Models.Commit.EmptyTreeSHA1, value.Parents[2]).Result();
var needSort = changes.Count > 0; var needSort = changes.Count > 0;
foreach (var c in untracked) foreach (var c in untracked)
@ -107,7 +107,7 @@ namespace SourceGit.ViewModels
if (value == null) if (value == null)
DiffContext = null; DiffContext = null;
else if (value.Index == Models.ChangeState.Added && _selectedStash.Parents.Count == 3) else if (value.Index == Models.ChangeState.Added && _selectedStash.Parents.Count == 3)
DiffContext = new DiffContext(_repo.FullPath, new Models.DiffOption("4b825dc642cb6eb9a060e54bf8d69288fbee4904", _selectedStash.Parents[2], value), _diffContext); DiffContext = new DiffContext(_repo.FullPath, new Models.DiffOption(Models.Commit.EmptyTreeSHA1, _selectedStash.Parents[2], value), _diffContext);
else else
DiffContext = new DiffContext(_repo.FullPath, new Models.DiffOption(_selectedStash.Parents[0], _selectedStash.SHA, value), _diffContext); DiffContext = new DiffContext(_repo.FullPath, new Models.DiffOption(_selectedStash.Parents[0], _selectedStash.SHA, value), _diffContext);
} }
@ -125,14 +125,13 @@ namespace SourceGit.ViewModels
_repo = repo; _repo = repo;
} }
public void Cleanup() public void Dispose()
{ {
_stashes?.Clear();
_changes?.Clear();
_repo = null; _repo = null;
if (_stashes != null)
_stashes.Clear();
_selectedStash = null; _selectedStash = null;
if (_changes != null)
_changes.Clear();
_selectedChange = null; _selectedChange = null;
_diffContext = null; _diffContext = null;
} }
@ -183,7 +182,7 @@ namespace SourceGit.ViewModels
foreach (var c in _changes) foreach (var c in _changes)
{ {
if (c.Index == Models.ChangeState.Added && _selectedStash.Parents.Count == 3) if (c.Index == Models.ChangeState.Added && _selectedStash.Parents.Count == 3)
opts.Add(new Models.DiffOption("4b825dc642cb6eb9a060e54bf8d69288fbee4904", _selectedStash.Parents[2], c)); opts.Add(new Models.DiffOption(Models.Commit.EmptyTreeSHA1, _selectedStash.Parents[2], c));
else else
opts.Add(new Models.DiffOption(_selectedStash.Parents[0], _selectedStash.SHA, c)); opts.Add(new Models.DiffOption(_selectedStash.Parents[0], _selectedStash.SHA, c));
} }

View file

@ -9,7 +9,7 @@ namespace SourceGit.ViewModels
{ {
public class SubmoduleTreeNode : ObservableObject public class SubmoduleTreeNode : ObservableObject
{ {
public string FullPath { get; set; } = string.Empty; public string FullPath { get; private set; } = string.Empty;
public int Depth { get; private set; } = 0; public int Depth { get; private set; } = 0;
public Models.Submodule Module { get; private set; } = null; public Models.Submodule Module { get; private set; } = null;
public List<SubmoduleTreeNode> Children { get; private set; } = []; public List<SubmoduleTreeNode> Children { get; private set; } = [];

View file

@ -23,7 +23,7 @@ namespace SourceGit.ViewModels
public class TagTreeNode : ObservableObject public class TagTreeNode : ObservableObject
{ {
public string FullPath { get; set; } public string FullPath { get; private set; }
public int Depth { get; private set; } = 0; public int Depth { get; private set; } = 0;
public Models.Tag Tag { get; private set; } = null; public Models.Tag Tag { get; private set; } = null;
public TagTreeNodeToolTip ToolTip { get; private set; } = null; public TagTreeNodeToolTip ToolTip { get; private set; } = null;

View file

@ -65,14 +65,9 @@ namespace SourceGit.ViewModels
return Task.Run(() => return Task.Run(() =>
{ {
foreach (var submodule in targets) new Commands.Submodule(_repo.FullPath)
{ .Use(log)
new Commands.Submodule(_repo.FullPath).Use(log).Update( .Update(targets, EnableInit, EnableRecursive, EnableRemote);
submodule,
EnableInit,
EnableRecursive,
EnableRemote);
}
log.Complete(); log.Complete();
CallUIThread(() => _repo.SetWatcherEnabled(true)); CallUIThread(() => _repo.SetWatcherEnabled(true));

View file

@ -11,7 +11,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.ViewModels namespace SourceGit.ViewModels
{ {
public class WorkingCopy : ObservableObject public class WorkingCopy : ObservableObject, IDisposable
{ {
public bool IncludeUntracked public bool IncludeUntracked
{ {
@ -210,7 +210,7 @@ namespace SourceGit.ViewModels
_repo = repo; _repo = repo;
} }
public void Cleanup() public void Dispose()
{ {
_repo = null; _repo = null;
_inProgressContext = null; _inProgressContext = null;
@ -244,7 +244,7 @@ namespace SourceGit.ViewModels
// Just force refresh selected changes. // Just force refresh selected changes.
Dispatcher.UIThread.Invoke(() => Dispatcher.UIThread.Invoke(() =>
{ {
HasUnsolvedConflicts = _cached.Find(x => x.IsConflict) != null; HasUnsolvedConflicts = _cached.Find(x => x.IsConflicted) != null;
UpdateDetail(); UpdateDetail();
UpdateInProgressState(); UpdateInProgressState();
@ -276,7 +276,7 @@ namespace SourceGit.ViewModels
if (c.WorkTree != Models.ChangeState.None) if (c.WorkTree != Models.ChangeState.None)
{ {
unstaged.Add(c); unstaged.Add(c);
hasConflict |= c.IsConflict; hasConflict |= c.IsConflicted;
} }
} }
@ -378,7 +378,7 @@ namespace SourceGit.ViewModels
foreach (var change in changes) foreach (var change in changes)
{ {
if (!change.IsConflict) if (!change.IsConflicted)
continue; continue;
if (change.WorkTree == Models.ChangeState.Deleted) if (change.WorkTree == Models.ChangeState.Deleted)
@ -420,7 +420,7 @@ namespace SourceGit.ViewModels
foreach (var change in changes) foreach (var change in changes)
{ {
if (!change.IsConflict) if (!change.IsConflicted)
continue; continue;
if (change.Index == Models.ChangeState.Deleted) if (change.Index == Models.ChangeState.Deleted)
@ -547,17 +547,17 @@ namespace SourceGit.ViewModels
public void Commit() public void Commit()
{ {
DoCommit(false, false, false); DoCommit(false, false);
} }
public void CommitWithAutoStage() public void CommitWithAutoStage()
{ {
DoCommit(true, false, false); DoCommit(true, false);
} }
public void CommitWithPush() public void CommitWithPush()
{ {
DoCommit(false, true, false); DoCommit(false, true);
} }
public ContextMenu CreateContextMenuForUnstagedChanges() public ContextMenu CreateContextMenuForUnstagedChanges()
@ -594,7 +594,7 @@ namespace SourceGit.ViewModels
menu.Items.Add(openWith); menu.Items.Add(openWith);
menu.Items.Add(new MenuItem() { Header = "-" }); menu.Items.Add(new MenuItem() { Header = "-" });
if (change.IsConflict) if (change.IsConflicted)
{ {
var useTheirs = new MenuItem(); var useTheirs = new MenuItem();
useTheirs.Icon = App.CreateMenuIcon("Icons.Incoming"); useTheirs.Icon = App.CreateMenuIcon("Icons.Incoming");
@ -949,7 +949,7 @@ namespace SourceGit.ViewModels
var hasNonConflicts = false; var hasNonConflicts = false;
foreach (var change in _selectedUnstaged) foreach (var change in _selectedUnstaged)
{ {
if (change.IsConflict) if (change.IsConflicted)
hasConflicts = true; hasConflicts = true;
else else
hasNonConflicts = true; hasNonConflicts = true;
@ -1528,14 +1528,13 @@ namespace SourceGit.ViewModels
if (_useAmend) if (_useAmend)
{ {
var head = new Commands.QuerySingleCommit(_repo.FullPath, "HEAD").Result(); var head = new Commands.QuerySingleCommit(_repo.FullPath, "HEAD").Result();
return new Commands.QueryStagedChangesWithAmend(_repo.FullPath, head.Parents.Count == 0 ? "4b825dc642cb6eb9a060e54bf8d69288fbee4904" : $"{head.SHA}^").Result(); return new Commands.QueryStagedChangesWithAmend(_repo.FullPath, head.Parents.Count == 0 ? Models.Commit.EmptyTreeSHA1 : $"{head.SHA}^").Result();
} }
var rs = new List<Models.Change>(); var rs = new List<Models.Change>();
foreach (var c in _cached) foreach (var c in _cached)
{ {
if (c.Index != Models.ChangeState.None && if (c.Index != Models.ChangeState.None)
c.Index != Models.ChangeState.Untracked)
rs.Add(c); rs.Add(c);
} }
return rs; return rs;
@ -1681,7 +1680,7 @@ namespace SourceGit.ViewModels
if (change == null) if (change == null)
DetailContext = null; DetailContext = null;
else if (change.IsConflict && isUnstaged) else if (change.IsConflicted)
DetailContext = new Conflict(_repo, this, change); DetailContext = new Conflict(_repo, this, change);
else else
DetailContext = new DiffContext(_repo.FullPath, new Models.DiffOption(change, isUnstaged), _detailContext as DiffContext); DetailContext = new DiffContext(_repo.FullPath, new Models.DiffOption(change, isUnstaged), _detailContext as DiffContext);
@ -1764,13 +1763,16 @@ namespace SourceGit.ViewModels
if (old.Count != cur.Count) if (old.Count != cur.Count)
return true; return true;
var oldSet = new HashSet<string>(); var oldMap = new Dictionary<string, Models.Change>();
foreach (var c in old) foreach (var c in old)
oldSet.Add($"{c.Path}\n{c.WorkTree}\n{c.Index}"); oldMap.Add(c.Path, c);
foreach (var c in cur) foreach (var c in cur)
{ {
if (!oldSet.Contains($"{c.Path}\n{c.WorkTree}\n{c.Index}")) if (!oldMap.TryGetValue(c.Path, out var o))
return true;
if (o.Index != c.Index || o.WorkTree != c.WorkTree)
return true; return true;
} }

View file

@ -296,8 +296,6 @@ namespace SourceGit.Views
TextArea.LeftMargins.Add(new CommitInfoMargin(this) { Margin = new Thickness(8, 0) }); TextArea.LeftMargins.Add(new CommitInfoMargin(this) { Margin = new Thickness(8, 0) });
TextArea.LeftMargins.Add(new VerticalSeparatorMargin(this)); TextArea.LeftMargins.Add(new VerticalSeparatorMargin(this));
TextArea.Caret.PositionChanged += OnTextAreaCaretPositionChanged; TextArea.Caret.PositionChanged += OnTextAreaCaretPositionChanged;
TextArea.LayoutUpdated += OnTextAreaLayoutUpdated;
TextArea.PointerWheelChanged += OnTextAreaPointerWheelChanged;
TextArea.TextView.ContextRequested += OnTextViewContextRequested; TextArea.TextView.ContextRequested += OnTextViewContextRequested;
TextArea.TextView.VisualLinesChanged += OnTextViewVisualLinesChanged; TextArea.TextView.VisualLinesChanged += OnTextViewVisualLinesChanged;
TextArea.TextView.Margin = new Thickness(4, 0); TextArea.TextView.Margin = new Thickness(4, 0);
@ -341,8 +339,6 @@ namespace SourceGit.Views
TextArea.LeftMargins.Clear(); TextArea.LeftMargins.Clear();
TextArea.Caret.PositionChanged -= OnTextAreaCaretPositionChanged; TextArea.Caret.PositionChanged -= OnTextAreaCaretPositionChanged;
TextArea.LayoutUpdated -= OnTextAreaLayoutUpdated;
TextArea.PointerWheelChanged -= OnTextAreaPointerWheelChanged;
TextArea.TextView.ContextRequested -= OnTextViewContextRequested; TextArea.TextView.ContextRequested -= OnTextViewContextRequested;
TextArea.TextView.VisualLinesChanged -= OnTextViewVisualLinesChanged; TextArea.TextView.VisualLinesChanged -= OnTextViewVisualLinesChanged;
@ -392,42 +388,21 @@ namespace SourceGit.Views
InvalidateVisual(); InvalidateVisual();
} }
private void OnTextAreaLayoutUpdated(object sender, EventArgs e)
{
if (TextArea.IsFocused)
InvalidateVisual();
}
private void OnTextAreaPointerWheelChanged(object sender, PointerWheelEventArgs e)
{
if (!TextArea.IsFocused && !string.IsNullOrEmpty(_highlight))
Focus();
}
private void OnTextViewContextRequested(object sender, ContextRequestedEventArgs e) private void OnTextViewContextRequested(object sender, ContextRequestedEventArgs e)
{ {
var selected = SelectedText; var selected = SelectedText;
if (string.IsNullOrEmpty(selected)) if (string.IsNullOrEmpty(selected))
return; return;
var copy = new MenuItem() { Header = App.Text("Copy") }; var copy = new MenuItem();
copy.Header = App.Text("Copy");
copy.Icon = App.CreateMenuIcon("Icons.Copy");
copy.Click += (_, ev) => copy.Click += (_, ev) =>
{ {
App.CopyText(selected); App.CopyText(selected);
ev.Handled = true; ev.Handled = true;
}; };
if (this.FindResource("Icons.Copy") is StreamGeometry geo)
{
copy.Icon = new Avalonia.Controls.Shapes.Path()
{
Width = 10,
Height = 10,
Stretch = Stretch.Fill,
Data = geo,
};
}
var menu = new ContextMenu(); var menu = new ContextMenu();
menu.Items.Add(copy); menu.Items.Add(copy);
menu.Open(TextArea.TextView); menu.Open(TextArea.TextView);
@ -445,6 +420,8 @@ namespace SourceGit.Views
break; break;
} }
} }
InvalidateVisual();
} }
private TextMate.Installation _textMate = null; private TextMate.Installation _textMate = null;

View file

@ -30,7 +30,8 @@
<UserControl.DataTemplates> <UserControl.DataTemplates>
<DataTemplate DataType="vm:ChangeCollectionAsTree"> <DataTemplate DataType="vm:ChangeCollectionAsTree">
<v:ChangeCollectionContainer ItemsSource="{Binding Rows}" <v:ChangeCollectionContainer Focusable="True"
ItemsSource="{Binding Rows}"
SelectedItems="{Binding SelectedRows, Mode=TwoWay}" SelectedItems="{Binding SelectedRows, Mode=TwoWay}"
SelectionMode="{Binding #ThisControl.SelectionMode}" SelectionMode="{Binding #ThisControl.SelectionMode}"
SelectionChanged="OnRowSelectionChanged"> SelectionChanged="OnRowSelectionChanged">
@ -66,7 +67,8 @@
</DataTemplate> </DataTemplate>
<DataTemplate DataType="vm:ChangeCollectionAsGrid"> <DataTemplate DataType="vm:ChangeCollectionAsGrid">
<v:ChangeCollectionContainer ItemsSource="{Binding Changes}" <v:ChangeCollectionContainer Focusable="True"
ItemsSource="{Binding Changes}"
SelectedItems="{Binding SelectedChanges, Mode=TwoWay}" SelectedItems="{Binding SelectedChanges, Mode=TwoWay}"
SelectionMode="{Binding #ThisControl.SelectionMode}" SelectionMode="{Binding #ThisControl.SelectionMode}"
SelectionChanged="OnRowSelectionChanged"> SelectionChanged="OnRowSelectionChanged">
@ -98,7 +100,8 @@
</DataTemplate> </DataTemplate>
<DataTemplate DataType="vm:ChangeCollectionAsList"> <DataTemplate DataType="vm:ChangeCollectionAsList">
<v:ChangeCollectionContainer ItemsSource="{Binding Changes}" <v:ChangeCollectionContainer Focusable="True"
ItemsSource="{Binding Changes}"
SelectedItems="{Binding SelectedChanges, Mode=TwoWay}" SelectedItems="{Binding SelectedChanges, Mode=TwoWay}"
SelectionMode="{Binding #ThisControl.SelectionMode}" SelectionMode="{Binding #ThisControl.SelectionMode}"
SelectionChanged="OnRowSelectionChanged"> SelectionChanged="OnRowSelectionChanged">

View file

@ -145,6 +145,7 @@ namespace SourceGit.Views
removeCount++; removeCount++;
} }
tree.Rows.RemoveRange(idx + 1, removeCount); tree.Rows.RemoveRange(idx + 1, removeCount);
} }
} }
@ -209,6 +210,13 @@ namespace SourceGit.Views
return null; return null;
} }
public void TakeFocus()
{
var container = this.FindDescendantOfType<ChangeCollectionContainer>();
if (container is { IsFocused: false })
container.Focus();
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{ {
base.OnPropertyChanged(change); base.OnPropertyChanged(change);

View file

@ -48,21 +48,16 @@ namespace SourceGit.Views
EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative), EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative),
}, },
new LinearGradientBrush 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) }, 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), StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative), EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative),
}, },
Brushes.OrangeRed,
]; ];
private static readonly string[] INDICATOR = ["?", "±", "T", "+", "", "➜", "❏", "U", "★"]; private static readonly string[] INDICATOR = ["?", "±", "T", "+", "", "➜", "❏", "★", "!"];
private static readonly string[] TIPS = ["Unknown", "Modified", "Type Changed", "Added", "Deleted", "Renamed", "Copied", "Unmerged", "Untracked"]; private static readonly string[] TIPS = ["Unknown", "Modified", "Type Changed", "Added", "Deleted", "Renamed", "Copied", "Untracked", "Conflict"];
public static readonly StyledProperty<bool> IsUnstagedChangeProperty = public static readonly StyledProperty<bool> IsUnstagedChangeProperty =
AvaloniaProperty.Register<ChangeStatusIcon, bool>(nameof(IsUnstagedChange)); AvaloniaProperty.Register<ChangeStatusIcon, bool>(nameof(IsUnstagedChange));
@ -92,18 +87,10 @@ namespace SourceGit.Views
IBrush background; IBrush background;
string indicator; string indicator;
if (IsUnstagedChange) if (IsUnstagedChange)
{
if (Change.IsConflict)
{
background = Brushes.OrangeRed;
indicator = "!";
}
else
{ {
background = BACKGROUNDS[(int)Change.WorkTree]; background = BACKGROUNDS[(int)Change.WorkTree];
indicator = INDICATOR[(int)Change.WorkTree]; indicator = INDICATOR[(int)Change.WorkTree];
} }
}
else else
{ {
background = BACKGROUNDS[(int)Change.Index]; background = BACKGROUNDS[(int)Change.Index];
@ -139,7 +126,7 @@ namespace SourceGit.Views
} }
if (isUnstaged) if (isUnstaged)
ToolTip.SetTip(this, c.IsConflict ? "Conflict" : TIPS[(int)c.WorkTree]); ToolTip.SetTip(this, TIPS[(int)c.WorkTree]);
else else
ToolTip.SetTip(this, TIPS[(int)c.Index]); ToolTip.SetTip(this, TIPS[(int)c.Index]);

View file

@ -4,6 +4,7 @@
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:v="using:SourceGit.Views" xmlns:v="using:SourceGit.Views"
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.CommitChanges" x:Class="SourceGit.Views.CommitChanges"
x:DataType="vm:CommitDetail"> x:DataType="vm:CommitDetail">
@ -14,7 +15,7 @@
<ColumnDefinition Width="*" MinWidth="100"/> <ColumnDefinition Width="*" MinWidth="100"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Grid Grid.Column="0" RowDefinitions="26,*"> <Grid Grid.Column="0" RowDefinitions="26,*,26">
<!-- Search & Display Mode --> <!-- Search & Display Mode -->
<Grid Grid.Row="0" ColumnDefinitions="*,Auto"> <Grid Grid.Row="0" ColumnDefinitions="*,Auto">
<TextBox Grid.Column="0" <TextBox Grid.Column="0"
@ -52,6 +53,16 @@
AutoSelectFirstChange="True" AutoSelectFirstChange="True"
ContextRequested="OnChangeContextRequested"/> ContextRequested="OnChangeContextRequested"/>
</Border> </Border>
<!-- Summary -->
<Border Grid.Row="2" BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="1,0,1,1" Background="Transparent">
<TextBlock Margin="4,0,0,0"
Foreground="{DynamicResource Brush.FG2}"
HorizontalAlignment="Left" VerticalAlignment="Center">
<Run Text="{Binding Changes, Converter={x:Static c:ListConverters.Count}, Mode=OneWay}" FontWeight="Bold"/>
<Run Text="{DynamicResource Text.CommitDetail.Changes.Count}"/>
</TextBlock>
</Border>
</Grid> </Grid>
<GridSplitter Grid.Column="1" <GridSplitter Grid.Column="1"

View file

@ -14,7 +14,7 @@
<TextBlock FontSize="18" <TextBlock FontSize="18"
Classes="bold" Classes="bold"
Text="{DynamicResource Text.CreateBranch.Title}"/> Text="{DynamicResource Text.CreateBranch.Title}"/>
<Grid Margin="0,16,0,0" RowDefinitions="32,32,Auto,Auto,Auto,Auto" ColumnDefinitions="140,*"> <Grid Margin="0,16,0,0" RowDefinitions="32,32,Auto,32,Auto,Auto,Auto" ColumnDefinitions="140,*">
<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"
@ -80,11 +80,16 @@
</Border> </Border>
<CheckBox Grid.Row="4" Grid.Column="1" <CheckBox Grid.Row="4" Grid.Column="1"
Content="{DynamicResource Text.CreateBranch.OverwriteExisting}"
IsChecked="{Binding AllowOverwrite, Mode=TwoWay}"
ToolTip.Tip="checkout -B or branch -f"/>
<CheckBox Grid.Row="5" Grid.Column="1"
Content="{DynamicResource Text.CreateBranch.Checkout}" Content="{DynamicResource Text.CreateBranch.Checkout}"
IsChecked="{Binding CheckoutAfterCreated, Mode=TwoWay}" IsChecked="{Binding CheckoutAfterCreated, Mode=TwoWay}"
IsVisible="{Binding !IsBareRepository}"/> IsVisible="{Binding !IsBareRepository}"/>
<CheckBox Grid.Row="5" Grid.Column="1" <CheckBox Grid.Row="6" Grid.Column="1"
Content="{DynamicResource Text.Checkout.RecurseSubmodules}" Content="{DynamicResource Text.Checkout.RecurseSubmodules}"
IsChecked="{Binding RecurseSubmodules, Mode=TwoWay}" IsChecked="{Binding RecurseSubmodules, Mode=TwoWay}"
ToolTip.Tip="--recurse-submodules"> ToolTip.Tip="--recurse-submodules">

View file

@ -0,0 +1,28 @@
<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:vm="using:SourceGit.ViewModels"
xmlns:v="using:SourceGit.Views"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.DeinitSubmodule"
x:DataType="vm:DeinitSubmodule">
<StackPanel Orientation="Vertical" Margin="8,0">
<TextBlock FontSize="18"
Classes="bold"
Text="{DynamicResource Text.DeinitSubmodule}"/>
<Grid Margin="0,16,8,0" RowDefinitions="32,Auto" ColumnDefinitions="120,*">
<TextBlock Grid.Row="0" Grid.Column="0" HorizontalAlignment="Right" Text="{DynamicResource Text.DeinitSubmodule.Path}"/>
<StackPanel Grid.Row="0" Grid.Column="1" Orientation="Horizontal">
<Path Width="14" Height="14" Margin="8,0" Data="{StaticResource Icons.Submodule}"/>
<TextBlock Text="{Binding Submodule}"/>
</StackPanel>
<CheckBox Grid.Row="1" Grid.Column="1"
Content="{DynamicResource Text.DeinitSubmodule.Force}"
IsChecked="{Binding Force, Mode=TwoWay}"
ToolTip.Tip="--force"/>
</Grid>
</StackPanel>
</UserControl>

View file

@ -2,9 +2,9 @@ using Avalonia.Controls;
namespace SourceGit.Views namespace SourceGit.Views
{ {
public partial class FastForwardWithoutCheckout : UserControl public partial class DeinitSubmodule : UserControl
{ {
public FastForwardWithoutCheckout() public DeinitSubmodule()
{ {
InitializeComponent(); InitializeComponent();
} }

View file

@ -178,12 +178,12 @@
<Button Classes="icon_button" <Button Classes="icon_button"
Width="28" Width="28"
Command="{Binding OpenExternalMergeTool}" Command="{Binding OpenExternalMergeTool}"
HotKey="{OnPlatform Ctrl+D, macOS=⌘+D}"> HotKey="{OnPlatform Ctrl+Shift+D, macOS=⌘+Shift+D}">
<ToolTip.Tip> <ToolTip.Tip>
<TextBlock> <TextBlock>
<Run Text="{DynamicResource Text.Diff.UseMerger}"/> <Run Text="{DynamicResource Text.Diff.UseMerger}"/>
<Run Text=" "/> <Run Text=" "/>
<Run Text="{OnPlatform Ctrl+D, macOS=⌘+D}" Foreground="{DynamicResource Brush.FG2}"/> <Run Text="{OnPlatform Ctrl+Shift+D, macOS=⌘+⇧+D}" Foreground="{DynamicResource Brush.FG2}"/>
</TextBlock> </TextBlock>
</ToolTip.Tip> </ToolTip.Tip>
<Path Width="12" Height="12" Stretch="Uniform" Data="{StaticResource Icons.OpenWith}"/> <Path Width="12" Height="12" Stretch="Uniform" Data="{StaticResource Icons.OpenWith}"/>
@ -279,8 +279,18 @@
<Path Width="16" Height="16" Data="{StaticResource Icons.DoubleDown}" HorizontalAlignment="Center" IsVisible="{Binding Old, Converter={x:Static ObjectConverters.IsNotNull}}"/> <Path Width="16" Height="16" Data="{StaticResource Icons.DoubleDown}" HorizontalAlignment="Center" IsVisible="{Binding Old, Converter={x:Static ObjectConverters.IsNotNull}}"/>
<Border Margin="0,8,0,0" BorderThickness="1" BorderBrush="Green" Background="{DynamicResource Brush.Window}"> <Border Margin="0,8,0,0" BorderThickness="1" BorderBrush="Green" Background="{DynamicResource Brush.Window}" IsVisible="{Binding New, Converter={x:Static ObjectConverters.IsNotNull}}">
<v:CommitBaseInfo MaxHeight="256" Margin="0,0,0,4" Content="{Binding New.Commit}" FullMessage="{Binding New.FullMessage}"/> <ContentControl Content="{Binding New}">
<ContentControl.DataTemplates>
<DataTemplate DataType="m:RevisionSubmodule">
<v:CommitBaseInfo MaxHeight="256" Margin="0,0,0,4" Content="{Binding Commit}" FullMessage="{Binding FullMessage}"/>
</DataTemplate>
</ContentControl.DataTemplates>
</ContentControl>
</Border>
<Border Margin="0,8,0,0" 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"/>
</Border> </Border>
</StackPanel> </StackPanel>
</ScrollViewer> </ScrollViewer>

View file

@ -1,21 +0,0 @@
<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:vm="using:SourceGit.ViewModels"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
x:Class="SourceGit.Views.FastForwardWithoutCheckout"
x:DataType="vm:FastForwardWithoutCheckout">
<StackPanel Orientation="Vertical" Margin="8,0">
<TextBlock FontSize="18"
Classes="bold"
Text="{DynamicResource Text.FastForwardWithoutCheck}"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,16,0,0">
<Path Width="14" Height="14" Data="{StaticResource Icons.Branch}"/>
<TextBlock Text="{Binding Local.Name}" Margin="8,0,0,0"/>
<TextBlock Text="→" Margin="8,0"/>
<Path Width="14" Height="14" Data="{StaticResource Icons.Branch}"/>
<TextBlock Text="{Binding To.FriendlyName}" Margin="8,0,0,0"/>
</StackPanel>
</StackPanel>
</UserControl>

View file

@ -2,7 +2,9 @@
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: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.GitFlowFinish" x:Class="SourceGit.Views.GitFlowFinish"
x:DataType="vm:GitFlowFinish"> x:DataType="vm:GitFlowFinish">
@ -10,15 +12,15 @@
<TextBlock FontSize="18" <TextBlock FontSize="18"
Classes="bold" Classes="bold"
Text="{DynamicResource Text.GitFlow.FinishFeature}" Text="{DynamicResource Text.GitFlow.FinishFeature}"
IsVisible="{Binding IsFeature}"/> IsVisible="{Binding Type, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:GitFlowBranchType.Feature}}"/>
<TextBlock FontSize="18" <TextBlock FontSize="18"
Classes="bold" Classes="bold"
Text="{DynamicResource Text.GitFlow.FinishRelease}" Text="{DynamicResource Text.GitFlow.FinishRelease}"
IsVisible="{Binding IsRelease}"/> IsVisible="{Binding Type, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:GitFlowBranchType.Release}}"/>
<TextBlock FontSize="18" <TextBlock FontSize="18"
Classes="bold" Classes="bold"
Text="{DynamicResource Text.GitFlow.FinishHotfix}" Text="{DynamicResource Text.GitFlow.FinishHotfix}"
IsVisible="{Binding IsHotfix}"/> IsVisible="{Binding Type, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:GitFlowBranchType.Hotfix}}"/>
<Grid Margin="0,16,0,0" RowDefinitions="32,32,32,32" ColumnDefinitions="150,*"> <Grid Margin="0,16,0,0" RowDefinitions="32,32,32,32" ColumnDefinitions="150,*">
<TextBlock Grid.Row="0" Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"

View file

@ -2,8 +2,10 @@
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"
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.GitFlowStart" x:Class="SourceGit.Views.GitFlowStart"
x:DataType="vm:GitFlowStart"> x:DataType="vm:GitFlowStart">
@ -11,15 +13,15 @@
<TextBlock FontSize="18" <TextBlock FontSize="18"
Classes="bold" Classes="bold"
Text="{DynamicResource Text.GitFlow.StartFeatureTitle}" Text="{DynamicResource Text.GitFlow.StartFeatureTitle}"
IsVisible="{Binding IsFeature}"/> IsVisible="{Binding Type, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:GitFlowBranchType.Feature}}"/>
<TextBlock FontSize="18" <TextBlock FontSize="18"
Classes="bold" Classes="bold"
Text="{DynamicResource Text.GitFlow.StartReleaseTitle}" Text="{DynamicResource Text.GitFlow.StartReleaseTitle}"
IsVisible="{Binding IsRelease}"/> IsVisible="{Binding Type, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:GitFlowBranchType.Release}}"/>
<TextBlock FontSize="18" <TextBlock FontSize="18"
Classes="bold" Classes="bold"
Text="{DynamicResource Text.GitFlow.StartHotfixTitle}" Text="{DynamicResource Text.GitFlow.StartHotfixTitle}"
IsVisible="{Binding IsHotfix}"/> IsVisible="{Binding Type, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:GitFlowBranchType.Hotfix}}"/>
<Grid Margin="0,16,0,0" ColumnDefinitions="120,*"> <Grid Margin="0,16,0,0" ColumnDefinitions="120,*">
<TextBlock Grid.Column="0" <TextBlock Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"

View file

@ -257,7 +257,7 @@
<v:RevisionCompare/> <v:RevisionCompare/>
</DataTemplate> </DataTemplate>
<DataTemplate DataType="x:Int32"> <DataTemplate DataType="m:Count">
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center"> <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
<Path Width="128" Height="128" <Path Width="128" Height="128"
Data="{StaticResource Icons.Detail}" Data="{StaticResource Icons.Detail}"
@ -268,7 +268,7 @@
Margin="0,16" Margin="0,16"
FontSize="24" FontWeight="Bold" FontSize="24" FontWeight="Bold"
Foreground="{DynamicResource Brush.FG2}" Foreground="{DynamicResource Brush.FG2}"
Text="{Binding Converter={x:Static c:StringConverters.FormatByResourceKey}, ConverterParameter='Histories.Selected'}"/> Text="{Binding Value, Converter={x:Static c:StringConverters.FormatByResourceKey}, ConverterParameter='Histories.Selected'}"/>
</StackPanel> </StackPanel>
</DataTemplate> </DataTemplate>
</ContentControl.DataTemplates> </ContentControl.DataTemplates>

View file

@ -149,7 +149,7 @@
<TextBlock Grid.Row="3" Grid.Column="0" Classes="primary bold" Text="ESC"/> <TextBlock Grid.Row="3" Grid.Column="0" Classes="primary bold" Text="ESC"/>
<TextBlock Grid.Row="3" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.TextEditor.CloseSearch}" /> <TextBlock Grid.Row="3" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.TextEditor.CloseSearch}" />
<TextBlock Grid.Row="4" Grid.Column="0" Classes="primary bold" Text="{OnPlatform Ctrl+D, macOS=⌘+D}"/> <TextBlock Grid.Row="4" Grid.Column="0" Classes="primary bold" Text="{OnPlatform Ctrl+Shift+D, macOS=⌘+⇧+D}"/>
<TextBlock Grid.Row="4" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.TextEditor.OpenExternalMergeTool}" /> <TextBlock Grid.Row="4" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.TextEditor.OpenExternalMergeTool}" />
</Grid> </Grid>
</StackPanel> </StackPanel>

View file

@ -107,7 +107,7 @@
<Button Grid.Column="1" Opacity="1" Margin="4,0,0,0" Padding="8,2" Background="Transparent"> <Button Grid.Column="1" Opacity="1" Margin="4,0,0,0" Padding="8,2" Background="Transparent">
<Button.Flyout> <Button.Flyout>
<MenuFlyout Placement="BottomEdgeAlignedLeft" VerticalOffset="-4"> <MenuFlyout Placement="BottomEdgeAlignedLeft" VerticalOffset="-4">
<MenuItem InputGesture="P" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Pick}"> <MenuItem InputGesture="P" Click="OnChangeRebaseAction" Tag="{x:Static m:InteractiveRebaseAction.Pick}">
<MenuItem.Icon> <MenuItem.Icon>
<Ellipse Width="14" Height="14" Fill="Green"/> <Ellipse Width="14" Height="14" Fill="Green"/>
</MenuItem.Icon> </MenuItem.Icon>
@ -119,7 +119,7 @@
</MenuItem.Header> </MenuItem.Header>
</MenuItem> </MenuItem>
<MenuItem InputGesture="E" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Edit}"> <MenuItem InputGesture="E" Click="OnChangeRebaseAction" Tag="{x:Static m:InteractiveRebaseAction.Edit}">
<MenuItem.Icon> <MenuItem.Icon>
<Ellipse Width="14" Height="14" Fill="Orange"/> <Ellipse Width="14" Height="14" Fill="Orange"/>
</MenuItem.Icon> </MenuItem.Icon>
@ -131,7 +131,7 @@
</MenuItem.Header> </MenuItem.Header>
</MenuItem> </MenuItem>
<MenuItem InputGesture="R" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Reword}"> <MenuItem InputGesture="R" Click="OnChangeRebaseAction" Tag="{x:Static m:InteractiveRebaseAction.Reword}">
<MenuItem.Icon> <MenuItem.Icon>
<Ellipse Width="14" Height="14" Fill="Orange"/> <Ellipse Width="14" Height="14" Fill="Orange"/>
</MenuItem.Icon> </MenuItem.Icon>
@ -143,7 +143,7 @@
</MenuItem.Header> </MenuItem.Header>
</MenuItem> </MenuItem>
<MenuItem InputGesture="S" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Squash}"> <MenuItem InputGesture="S" Click="OnChangeRebaseAction" Tag="{x:Static m:InteractiveRebaseAction.Squash}" IsVisible="{Binding CanSquashOrFixup}">
<MenuItem.Icon> <MenuItem.Icon>
<Ellipse Width="14" Height="14" Fill="LightGray"/> <Ellipse Width="14" Height="14" Fill="LightGray"/>
</MenuItem.Icon> </MenuItem.Icon>
@ -155,7 +155,7 @@
</MenuItem.Header> </MenuItem.Header>
</MenuItem> </MenuItem>
<MenuItem InputGesture="F" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Fixup}"> <MenuItem InputGesture="F" Click="OnChangeRebaseAction" Tag="{x:Static m:InteractiveRebaseAction.Fixup}" IsVisible="{Binding CanSquashOrFixup}">
<MenuItem.Icon> <MenuItem.Icon>
<Ellipse Width="14" Height="14" Fill="LightGray"/> <Ellipse Width="14" Height="14" Fill="LightGray"/>
</MenuItem.Icon> </MenuItem.Icon>
@ -167,7 +167,7 @@
</MenuItem.Header> </MenuItem.Header>
</MenuItem> </MenuItem>
<MenuItem InputGesture="D" Command="{Binding SetAction}" CommandParameter="{x:Static m:InteractiveRebaseAction.Drop}"> <MenuItem InputGesture="D" Click="OnChangeRebaseAction" Tag="{x:Static m:InteractiveRebaseAction.Drop}">
<MenuItem.Icon> <MenuItem.Icon>
<Ellipse Width="14" Height="14" Fill="Red"/> <Ellipse Width="14" Height="14" Fill="Red"/>
</MenuItem.Icon> </MenuItem.Icon>
@ -280,7 +280,7 @@
Minimum="0" Minimum="0"
Maximum="100" Maximum="100"
IsVisible="False"/> IsVisible="False"/>
<Button Grid.Column="1" Classes="flat primary" MinWidth="80" Content="{DynamicResource Text.Start}" Click="StartJobs"/> <Button Grid.Column="1" Classes="flat primary" MinWidth="80" Content="{DynamicResource Text.Start}" Click="OnStartJobs"/>
<Button Grid.Column="2" Classes="flat" Margin="8,0,0,0" MinWidth="80" Content="{DynamicResource Text.Cancel}" Click="CloseWindow"/> <Button Grid.Column="2" Classes="flat" Margin="8,0,0,0" MinWidth="80" Content="{DynamicResource Text.Cancel}" Click="CloseWindow"/>
</Grid> </Grid>
</Grid> </Grid>

View file

@ -29,32 +29,32 @@ namespace SourceGit.Views
if (e.Key == Key.P) if (e.Key == Key.P)
{ {
item.SetAction(Models.InteractiveRebaseAction.Pick); vm.ChangeAction(item, Models.InteractiveRebaseAction.Pick);
e.Handled = true; e.Handled = true;
} }
else if (e.Key == Key.E) else if (e.Key == Key.E)
{ {
item.SetAction(Models.InteractiveRebaseAction.Edit); vm.ChangeAction(item, Models.InteractiveRebaseAction.Edit);
e.Handled = true; e.Handled = true;
} }
else if (e.Key == Key.R) else if (e.Key == Key.R)
{ {
item.SetAction(Models.InteractiveRebaseAction.Reword); vm.ChangeAction(item, Models.InteractiveRebaseAction.Reword);
e.Handled = true; e.Handled = true;
} }
else if (e.Key == Key.S) else if (e.Key == Key.S)
{ {
item.SetAction(Models.InteractiveRebaseAction.Squash); vm.ChangeAction(item, Models.InteractiveRebaseAction.Squash);
e.Handled = true; e.Handled = true;
} }
else if (e.Key == Key.F) else if (e.Key == Key.F)
{ {
item.SetAction(Models.InteractiveRebaseAction.Fixup); vm.ChangeAction(item, Models.InteractiveRebaseAction.Fixup);
e.Handled = true; e.Handled = true;
} }
else if (e.Key == Key.D) else if (e.Key == Key.D)
{ {
item.SetAction(Models.InteractiveRebaseAction.Drop); vm.ChangeAction(item, Models.InteractiveRebaseAction.Drop);
e.Handled = true; e.Handled = true;
} }
else if (e.KeyModifiers == KeyModifiers.Alt && e.Key == Key.Up) else if (e.KeyModifiers == KeyModifiers.Alt && e.Key == Key.Up)
@ -154,7 +154,20 @@ namespace SourceGit.Views
} }
} }
private async void StartJobs(object _1, RoutedEventArgs _2) private void OnChangeRebaseAction(object sender, RoutedEventArgs e)
{
if (DataContext is ViewModels.InteractiveRebase vm &&
sender is Control
{
DataContext: ViewModels.InteractiveRebaseItem item,
Tag: Models.InteractiveRebaseAction action
})
vm.ChangeAction(item, action);
e.Handled = true;
}
private async void OnStartJobs(object _1, RoutedEventArgs _2)
{ {
var vm = DataContext as ViewModels.InteractiveRebase; var vm = DataContext as ViewModels.InteractiveRebase;
if (vm == null) if (vm == null)

View file

@ -35,7 +35,7 @@
<Button Grid.Column="0" Classes="icon_button" VerticalAlignment="Bottom" Margin="6,0,2,3" IsVisible="{OnPlatform True, macOS=False}"> <Button Grid.Column="0" Classes="icon_button" VerticalAlignment="Bottom" Margin="6,0,2,3" IsVisible="{OnPlatform True, macOS=False}">
<Button.Flyout> <Button.Flyout>
<MenuFlyout Placement="BottomEdgeAlignedLeft" VerticalOffset="-8"> <MenuFlyout Placement="BottomEdgeAlignedLeft" VerticalOffset="-8">
<MenuItem Header="{DynamicResource Text.Preferences}" Command="{x:Static s:App.OpenPreferencesCommand}" InputGesture="Ctrl+Shift+P"> <MenuItem Header="{DynamicResource Text.Preferences}" Command="{x:Static s:App.OpenPreferencesCommand}" InputGesture="Ctrl+,">
<MenuItem.Icon> <MenuItem.Icon>
<Path Width="14" Height="14" Data="{StaticResource Icons.Settings}"/> <Path Width="14" Height="14" Data="{StaticResource Icons.Settings}"/>
</MenuItem.Icon> </MenuItem.Icon>

View file

@ -264,8 +264,11 @@ namespace SourceGit.Views
} }
else if (e.Key == Key.Escape) else if (e.Key == Key.Escape)
{ {
vm.ActivePage.CancelPopup(); if (vm.Switcher != null)
vm.CancelSwitcher(); vm.CancelSwitcher();
else
vm.ActivePage.CancelPopup();
e.Handled = true; e.Handled = true;
return; return;
} }

View file

@ -19,8 +19,7 @@
<RowDefinition Height="32"/> <RowDefinition Height="32"/>
<RowDefinition Height="Auto" MinHeight="32"/> <RowDefinition Height="Auto" MinHeight="32"/>
<RowDefinition Height="32"/> <RowDefinition Height="32"/>
<RowDefinition Height="32"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="32"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
@ -93,18 +92,16 @@
</WrapPanel> </WrapPanel>
<CheckBox Grid.Row="4" Grid.Column="1" <CheckBox Grid.Row="4" Grid.Column="1"
Content="{DynamicResource Text.Pull.FetchAllBranches}"
IsChecked="{Binding FetchAllBranches, Mode=TwoWay}"/>
<CheckBox Grid.Row="5" Grid.Column="1"
Content="{DynamicResource Text.Pull.NoTags}"
IsChecked="{Binding NoTags, Mode=TwoWay}"
ToolTip.Tip="--no-tags"/>
<CheckBox Grid.Row="6" Grid.Column="1"
Content="{DynamicResource Text.Pull.UseRebase}" Content="{DynamicResource Text.Pull.UseRebase}"
IsChecked="{Binding UseRebase, Mode=TwoWay}" IsChecked="{Binding UseRebase, Mode=TwoWay}"
ToolTip.Tip="--rebase"/> ToolTip.Tip="--rebase"/>
<CheckBox Grid.Row="5" Grid.Column="1"
Height="32"
Content="{DynamicResource Text.Pull.RecurseSubmodules}"
IsChecked="{Binding RecurseSubmodules, Mode=TwoWay}"
IsVisible="{Binding IsRecurseSubmoduleVisible}"
ToolTip.Tip="--recurse-submodules"/>
</Grid> </Grid>
</StackPanel> </StackPanel>
</UserControl> </UserControl>

View file

@ -206,7 +206,7 @@
<Path Grid.Column="0" Width="11" Height="11" HorizontalAlignment="Left" Data="{StaticResource Icons.Local}" Fill="{DynamicResource Brush.FG2}"/> <Path Grid.Column="0" Width="11" Height="11" HorizontalAlignment="Left" Data="{StaticResource Icons.Local}" Fill="{DynamicResource Brush.FG2}"/>
<TextBlock Grid.Column="1" Classes="group_header_label" Margin="0"> <TextBlock Grid.Column="1" Classes="group_header_label" Margin="0">
<Run Text="{DynamicResource Text.Repository.LocalBranches}"/> <Run Text="{DynamicResource Text.Repository.LocalBranches}"/>
<Run Text="{Binding LocalBranchesCount, StringFormat='({0})'}"/> <Run Text="{Binding LocalBranchesCount, StringFormat='({0})', Mode=OneWay}"/>
</TextBlock> </TextBlock>
<Button Grid.Column="2" <Button Grid.Column="2"
Classes="icon_button" Classes="icon_button"
@ -236,7 +236,7 @@
<Path Grid.Column="0" Width="12" Height="12" HorizontalAlignment="Left" Data="{StaticResource Icons.Remotes}" Fill="{DynamicResource Brush.FG2}"/> <Path Grid.Column="0" Width="12" Height="12" HorizontalAlignment="Left" Data="{StaticResource Icons.Remotes}" Fill="{DynamicResource Brush.FG2}"/>
<TextBlock Grid.Column="1" Classes="group_header_label" Margin="0"> <TextBlock Grid.Column="1" Classes="group_header_label" Margin="0">
<Run Text="{DynamicResource Text.Repository.Remotes}"/> <Run Text="{DynamicResource Text.Repository.Remotes}"/>
<Run Text="{Binding Remotes, Converter={x:Static c:ListConverters.ToCount}}"/> <Run Text="{Binding Remotes, Converter={x:Static c:ListConverters.ToCount}, Mode=OneWay}"/>
</TextBlock> </TextBlock>
<Button Grid.Column="2" <Button Grid.Column="2"
Classes="icon_button" Classes="icon_button"
@ -266,7 +266,7 @@
<Path Grid.Column="0" Width="11" Height="11" Margin="2,1,0,0" HorizontalAlignment="Left" Data="{StaticResource Icons.Tags}" Fill="{DynamicResource Brush.FG2}"/> <Path Grid.Column="0" Width="11" Height="11" Margin="2,1,0,0" HorizontalAlignment="Left" Data="{StaticResource Icons.Tags}" Fill="{DynamicResource Brush.FG2}"/>
<TextBlock Grid.Column="1" Classes="group_header_label" Margin="0"> <TextBlock Grid.Column="1" Classes="group_header_label" Margin="0">
<Run Text="{DynamicResource Text.Repository.Tags}"/> <Run Text="{DynamicResource Text.Repository.Tags}"/>
<Run Text="{Binding Tags, Converter={x:Static c:ListConverters.ToCount}}"/> <Run Text="{Binding Tags, Converter={x:Static c:ListConverters.ToCount}, Mode=OneWay}"/>
</TextBlock> </TextBlock>
<ToggleButton Grid.Column="2" <ToggleButton Grid.Column="2"
Classes="show_as_tree" Classes="show_as_tree"
@ -308,7 +308,7 @@
<Path Grid.Column="0" Width="10" Height="10" Margin="2,0,0,0" HorizontalAlignment="Left" Data="{StaticResource Icons.Submodules}" Fill="{DynamicResource Brush.FG2}"/> <Path Grid.Column="0" Width="10" Height="10" Margin="2,0,0,0" HorizontalAlignment="Left" Data="{StaticResource Icons.Submodules}" Fill="{DynamicResource Brush.FG2}"/>
<TextBlock Grid.Column="1" Classes="group_header_label" Margin="0"> <TextBlock Grid.Column="1" Classes="group_header_label" Margin="0">
<Run Text="{DynamicResource Text.Repository.Submodules}"/> <Run Text="{DynamicResource Text.Repository.Submodules}"/>
<Run Text="{Binding Submodules, Converter={x:Static c:ListConverters.ToCount}}"/> <Run Text="{Binding Submodules, Converter={x:Static c:ListConverters.ToCount}, Mode=OneWay}"/>
</TextBlock> </TextBlock>
<ToggleButton Grid.Column="2" <ToggleButton Grid.Column="2"
Classes="show_as_tree" Classes="show_as_tree"
@ -350,7 +350,7 @@
<Path Grid.Column="0" Width="11" Height="11" Margin="1,0,0,0" HorizontalAlignment="Left" Data="{StaticResource Icons.Worktrees}" Fill="{DynamicResource Brush.FG2}"/> <Path Grid.Column="0" Width="11" Height="11" Margin="1,0,0,0" HorizontalAlignment="Left" Data="{StaticResource Icons.Worktrees}" Fill="{DynamicResource Brush.FG2}"/>
<TextBlock Grid.Column="1" Classes="group_header_label" Margin="0"> <TextBlock Grid.Column="1" Classes="group_header_label" Margin="0">
<Run Text="{DynamicResource Text.Repository.Worktrees}"/> <Run Text="{DynamicResource Text.Repository.Worktrees}"/>
<Run Text="{Binding Worktrees, Converter={x:Static c:ListConverters.ToCount}}"/> <Run Text="{Binding Worktrees, Converter={x:Static c:ListConverters.ToCount}, Mode=OneWay}"/>
</TextBlock> </TextBlock>
<Button Grid.Column="2" <Button Grid.Column="2"
Classes="icon_button" Classes="icon_button"

View file

@ -0,0 +1,49 @@
<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="500" d:DesignHeight="450"
x:Class="SourceGit.Views.ResetWithoutCheckout"
x:DataType="vm:ResetWithoutCheckout">
<StackPanel Orientation="Vertical" Margin="8,0">
<TextBlock FontSize="18"
Classes="bold"
Text="{DynamicResource Text.ResetWithoutCheckout}"/>
<Grid Margin="0,16,0,0" RowDefinitions="32,32" ColumnDefinitions="120,*">
<TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0"
Text="{DynamicResource Text.ResetWithoutCheckout.Target}"/>
<StackPanel Grid.Row="0" Grid.Column="1" Orientation="Horizontal" Height="20" VerticalAlignment="Center">
<Path Margin="0,0,8,0" Width="14" Height="14" Fill="{DynamicResource Brush.FG1}" Data="{StaticResource Icons.Branch}"/>
<TextBlock Text="{Binding Target.Name}"/>
</StackPanel>
<TextBlock Grid.Row="1" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0"
Text="{DynamicResource Text.ResetWithoutCheckout.MoveTo}"/>
<ContentControl Grid.Row="1" Grid.Column="1" Content="{Binding To}">
<ContentControl.DataTemplates>
<DataTemplate DataType="m:Branch">
<StackPanel Orientation="Horizontal">
<Path Width="14" Height="14" Data="{StaticResource Icons.Branch}"/>
<SelectableTextBlock VerticalAlignment="Center" Text="{Binding FriendlyName}" Margin="8,0,0,0"/>
</StackPanel>
</DataTemplate>
<DataTemplate DataType="m:Commit">
<Grid 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 SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange" Margin="8,0,0,0"/>
<TextBlock Grid.Column="2" VerticalAlignment="Center" Text="{Binding Subject}" Margin="4,0,0,0" TextTrimming="CharacterEllipsis"/>
</Grid>
</DataTemplate>
</ContentControl.DataTemplates>
</ContentControl>
</Grid>
</StackPanel>
</UserControl>

View file

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

View file

@ -23,7 +23,7 @@
<Path Grid.Column="0" Margin="8,0,0,0" Width="14" Height="14" Fill="{DynamicResource Brush.FG2}" Data="{StaticResource Icons.Stashes}"/> <Path Grid.Column="0" Margin="8,0,0,0" Width="14" Height="14" Fill="{DynamicResource Brush.FG2}" Data="{StaticResource Icons.Stashes}"/>
<TextBlock Grid.Column="1" Foreground="{DynamicResource Brush.FG2}" FontWeight="Bold" Margin="4,0,0,0"> <TextBlock Grid.Column="1" Foreground="{DynamicResource Brush.FG2}" FontWeight="Bold" Margin="4,0,0,0">
<Run Text="{DynamicResource Text.Stashes.Stashes}"/> <Run Text="{DynamicResource Text.Stashes.Stashes}"/>
<Run Text="{Binding Stashes, Converter={x:Static c:ListConverters.ToCount}}"/> <Run Text="{Binding Stashes, Converter={x:Static c:ListConverters.ToCount}, Mode=OneWay}"/>
</TextBlock> </TextBlock>
<Button Grid.Column="2" <Button Grid.Column="2"
Classes="icon_button" Classes="icon_button"
@ -111,7 +111,7 @@
<Path Grid.Column="0" Margin="8,0,0,0" Width="14" Height="14" Fill="{DynamicResource Brush.FG2}" Data="{StaticResource Icons.Changes}"/> <Path Grid.Column="0" Margin="8,0,0,0" Width="14" Height="14" Fill="{DynamicResource Brush.FG2}" Data="{StaticResource Icons.Changes}"/>
<TextBlock Grid.Column="1" Foreground="{DynamicResource Brush.FG2}" FontWeight="Bold" Margin="4,0,0,0"> <TextBlock Grid.Column="1" Foreground="{DynamicResource Brush.FG2}" FontWeight="Bold" Margin="4,0,0,0">
<Run Text="{DynamicResource Text.Stashes.Changes}"/> <Run Text="{DynamicResource Text.Stashes.Changes}"/>
<Run Text="{Binding Changes, Converter={x:Static c:ListConverters.ToCount}}"/> <Run Text="{Binding Changes, Converter={x:Static c:ListConverters.ToCount}, Mode=OneWay}"/>
</TextBlock> </TextBlock>
</Grid> </Grid>
</Border> </Border>

View file

@ -108,7 +108,7 @@
Classes="primary" Classes="primary"
Margin="8,0,0,0" Margin="8,0,0,0"
TextTrimming="CharacterEllipsis"> TextTrimming="CharacterEllipsis">
<Run Text="{Binding FullPath, Converter={x:Static c:PathConverters.PureFileName}}"/> <Run Text="{Binding FullPath, Converter={x:Static c:PathConverters.PureFileName}, Mode=OneWay}"/>
<Run Text="{Binding ChildCounter}" Foreground="{DynamicResource Brush.FG2}"/> <Run Text="{Binding ChildCounter}" Foreground="{DynamicResource Brush.FG2}"/>
</TextBlock> </TextBlock>

View file

@ -65,7 +65,7 @@
<TextBlock Grid.Column="2" <TextBlock Grid.Column="2"
Classes="primary" Classes="primary"
Margin="8,0,0,0"> Margin="8,0,0,0">
<Run Text="{Binding FullPath, Converter={x:Static c:PathConverters.PureFileName}}"/> <Run Text="{Binding FullPath, Converter={x:Static c:PathConverters.PureFileName}, Mode=OneWay}"/>
<Run Text="{Binding TagsCount}" Foreground="{DynamicResource Brush.FG2}"/> <Run Text="{Binding TagsCount}" Foreground="{DynamicResource Brush.FG2}"/>
</TextBlock> </TextBlock>

View file

@ -65,7 +65,7 @@
<Path Grid.Column="0" Margin="8,0,0,0" Width="14" Height="14" Fill="{DynamicResource Brush.FG2}" Data="{StaticResource Icons.Changes}"/> <Path Grid.Column="0" Margin="8,0,0,0" Width="14" Height="14" Fill="{DynamicResource Brush.FG2}" Data="{StaticResource Icons.Changes}"/>
<TextBlock Grid.Column="1" Foreground="{DynamicResource Brush.FG2}" FontWeight="Bold" Margin="4,0,0,0"> <TextBlock Grid.Column="1" Foreground="{DynamicResource Brush.FG2}" FontWeight="Bold" Margin="4,0,0,0">
<Run Text="{DynamicResource Text.WorkingCopy.Unstaged}"/> <Run Text="{DynamicResource Text.WorkingCopy.Unstaged}"/>
<Run Text="{Binding Unstaged, Converter={x:Static c:ListConverters.ToCount}}"/> <Run Text="{Binding Unstaged, Converter={x:Static c:ListConverters.ToCount}, Mode=OneWay}"/>
</TextBlock> </TextBlock>
<v:LoadingIcon Grid.Column="2" Width="14" Height="14" Margin="8,0,0,0" IsVisible="{Binding IsStaging}"/> <v:LoadingIcon Grid.Column="2" Width="14" Height="14" Margin="8,0,0,0" IsVisible="{Binding IsStaging}"/>
@ -122,7 +122,6 @@
<!-- Unstaged Changes --> <!-- Unstaged Changes -->
<v:ChangeCollectionView Grid.Row="1" <v:ChangeCollectionView Grid.Row="1"
x:Name="UnstagedChangesView" x:Name="UnstagedChangesView"
Focusable="True"
IsUnstagedChange="True" IsUnstagedChange="True"
SelectionMode="Multiple" SelectionMode="Multiple"
Background="{DynamicResource Brush.Contents}" Background="{DynamicResource Brush.Contents}"
@ -148,7 +147,7 @@
<Path Grid.Column="0" Margin="8,0,0,0" Width="14" Height="14" Fill="{DynamicResource Brush.FG2}" Data="{StaticResource Icons.Changes}"/> <Path Grid.Column="0" Margin="8,0,0,0" Width="14" Height="14" Fill="{DynamicResource Brush.FG2}" Data="{StaticResource Icons.Changes}"/>
<TextBlock Grid.Column="1" Foreground="{DynamicResource Brush.FG2}" FontWeight="Bold" Margin="4,0,0,0"> <TextBlock Grid.Column="1" Foreground="{DynamicResource Brush.FG2}" FontWeight="Bold" Margin="4,0,0,0">
<Run Text="{DynamicResource Text.WorkingCopy.Staged}"/> <Run Text="{DynamicResource Text.WorkingCopy.Staged}"/>
<Run Text="{Binding Staged, Converter={x:Static c:ListConverters.ToCount}}"/> <Run Text="{Binding Staged, Converter={x:Static c:ListConverters.ToCount}, Mode=OneWay}"/>
</TextBlock> </TextBlock>
<v:LoadingIcon Grid.Column="2" Width="14" Height="14" Margin="8,0,0,0" IsVisible="{Binding IsUnstaging}"/> <v:LoadingIcon Grid.Column="2" Width="14" Height="14" Margin="8,0,0,0" IsVisible="{Binding IsUnstaging}"/>
<Button Grid.Column="4" Classes="icon_button" Width="26" Height="14" Padding="0" Click="OnUnstageSelectedButtonClicked"> <Button Grid.Column="4" Classes="icon_button" Width="26" Height="14" Padding="0" Click="OnUnstageSelectedButtonClicked">
@ -173,7 +172,6 @@
<!-- Staged Changes --> <!-- Staged Changes -->
<v:ChangeCollectionView Grid.Row="1" <v:ChangeCollectionView Grid.Row="1"
x:Name="StagedChangesView" x:Name="StagedChangesView"
Focusable="True"
IsUnstagedChange="False" IsUnstagedChange="False"
SelectionMode="Multiple" SelectionMode="Multiple"
Background="{DynamicResource Brush.Contents}" Background="{DynamicResource Brush.Contents}"

View file

@ -51,7 +51,7 @@ namespace SourceGit.Views
{ {
var next = UnstagedChangesView.GetNextChangeWithoutSelection(); var next = UnstagedChangesView.GetNextChangeWithoutSelection();
vm.StageSelected(next); vm.StageSelected(next);
UnstagedChangesView.Focus(); UnstagedChangesView.TakeFocus();
e.Handled = true; e.Handled = true;
} }
} }
@ -62,7 +62,7 @@ namespace SourceGit.Views
{ {
var next = StagedChangesView.GetNextChangeWithoutSelection(); var next = StagedChangesView.GetNextChangeWithoutSelection();
vm.UnstageSelected(next); vm.UnstageSelected(next);
StagedChangesView.Focus(); StagedChangesView.TakeFocus();
e.Handled = true; e.Handled = true;
} }
} }
@ -75,7 +75,7 @@ namespace SourceGit.Views
{ {
var next = UnstagedChangesView.GetNextChangeWithoutSelection(); var next = UnstagedChangesView.GetNextChangeWithoutSelection();
vm.StageSelected(next); vm.StageSelected(next);
UnstagedChangesView.Focus(); UnstagedChangesView.TakeFocus();
e.Handled = true; e.Handled = true;
return; return;
} }
@ -94,7 +94,7 @@ namespace SourceGit.Views
{ {
var next = StagedChangesView.GetNextChangeWithoutSelection(); var next = StagedChangesView.GetNextChangeWithoutSelection();
vm.UnstageSelected(next); vm.UnstageSelected(next);
StagedChangesView.Focus(); StagedChangesView.TakeFocus();
e.Handled = true; e.Handled = true;
} }
} }
@ -105,7 +105,7 @@ namespace SourceGit.Views
{ {
var next = UnstagedChangesView.GetNextChangeWithoutSelection(); var next = UnstagedChangesView.GetNextChangeWithoutSelection();
vm.StageSelected(next); vm.StageSelected(next);
UnstagedChangesView.Focus(); UnstagedChangesView.TakeFocus();
} }
e.Handled = true; e.Handled = true;
@ -117,7 +117,7 @@ namespace SourceGit.Views
{ {
var next = StagedChangesView.GetNextChangeWithoutSelection(); var next = StagedChangesView.GetNextChangeWithoutSelection();
vm.UnstageSelected(next); vm.UnstageSelected(next);
StagedChangesView.Focus(); StagedChangesView.TakeFocus();
} }
e.Handled = true; e.Handled = true;