Merge branch 'release/v2025.17'

This commit is contained in:
leo 2025-05-12 09:23:46 +08:00
commit 01625ada1a
No known key found for this signature in database
48 changed files with 887 additions and 352 deletions

View file

@ -6,55 +6,19 @@ 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-95.07%25-yellow) ### ![de__DE](https://img.shields.io/badge/de__DE-99.74%25-yellow)
<details> <details>
<summary>Missing keys in de_DE.axaml</summary> <summary>Missing keys in de_DE.axaml</summary>
- Text.Bisect - Text.GitFlow.FinishWithPush
- Text.Bisect.Abort - Text.GitFlow.FinishWithSquash
- Text.Bisect.Bad
- Text.Bisect.Detecting
- Text.Bisect.Good
- Text.Bisect.Skip
- Text.Bisect.WaitingForRange
- Text.BranchUpstreamInvalid
- Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject
- Text.CommitMessageTextBox.SubjectCount
- Text.Configure.CustomAction.WaitForExit
- Text.Configure.Git.PreferredMergeMode
- Text.Configure.IssueTracker.AddSampleAzure
- Text.ConfirmEmptyCommit.Continue
- Text.ConfirmEmptyCommit.NoLocalChanges
- Text.ConfirmEmptyCommit.StageAllThenCommit
- Text.ConfirmEmptyCommit.WithLocalChanges
- Text.CopyFullPath
- Text.Diff.First
- Text.Diff.Last
- Text.Preferences.AI.Streaming
- Text.Preferences.Appearance.EditorTabWidth
- Text.Preferences.General.ShowTagsInGraph
- Text.Preferences.Git.IgnoreCRAtEOLInDiff
- Text.Repository.Search.ByContent
- Text.Repository.ViewLogs
- Text.StashCM.SaveAsPatch
- Text.ViewLogs
- Text.ViewLogs.Clear
- Text.ViewLogs.CopyLog
- Text.ViewLogs.Delete
- Text.WorkingCopy.ConfirmCommitWithFilter
- Text.WorkingCopy.Conflicts.OpenExternalMergeTool
- Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts
- Text.WorkingCopy.Conflicts.UseMine
- Text.WorkingCopy.Conflicts.UseTheirs
</details> </details>
### ![es__ES](https://img.shields.io/badge/es__ES-%E2%88%9A-brightgreen) ### ![es__ES](https://img.shields.io/badge/es__ES-%E2%88%9A-brightgreen)
### ![fr__FR](https://img.shields.io/badge/fr__FR-96.37%25-yellow) ### ![fr__FR](https://img.shields.io/badge/fr__FR-95.50%25-yellow)
<details> <details>
<summary>Missing keys in fr_FR.axaml</summary> <summary>Missing keys in fr_FR.axaml</summary>
@ -66,6 +30,7 @@ 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.Checkout.RecurseSubmodules
- Text.CommitCM.CopyAuthor - Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter - Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject - Text.CommitCM.CopySubject
@ -75,9 +40,15 @@ This document shows the translation status of each locale file in the repository
- Text.ConfirmEmptyCommit.NoLocalChanges - Text.ConfirmEmptyCommit.NoLocalChanges
- Text.ConfirmEmptyCommit.StageAllThenCommit - Text.ConfirmEmptyCommit.StageAllThenCommit
- Text.ConfirmEmptyCommit.WithLocalChanges - Text.ConfirmEmptyCommit.WithLocalChanges
- Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash
- Text.Preferences.Git.IgnoreCRAtEOLInDiff - Text.Preferences.Git.IgnoreCRAtEOLInDiff
- Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate
- Text.Repository.BranchSort.ByName
- Text.Repository.Search.ByContent - Text.Repository.Search.ByContent
- Text.Repository.ViewLogs - Text.Repository.ViewLogs
- Text.Repository.Visit
- Text.ViewLogs - Text.ViewLogs
- Text.ViewLogs.Clear - Text.ViewLogs.Clear
- Text.ViewLogs.CopyLog - Text.ViewLogs.CopyLog
@ -90,7 +61,7 @@ This document shows the translation status of each locale file in the repository
</details> </details>
### ![it__IT](https://img.shields.io/badge/it__IT-96.11%25-yellow) ### ![it__IT](https://img.shields.io/badge/it__IT-95.24%25-yellow)
<details> <details>
<summary>Missing keys in it_IT.axaml</summary> <summary>Missing keys in it_IT.axaml</summary>
@ -102,6 +73,7 @@ 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.Checkout.RecurseSubmodules
- Text.CommitCM.CopyAuthor - Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter - Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject - Text.CommitCM.CopySubject
@ -112,10 +84,16 @@ This document shows the translation status of each locale file in the repository
- Text.ConfirmEmptyCommit.StageAllThenCommit - Text.ConfirmEmptyCommit.StageAllThenCommit
- Text.ConfirmEmptyCommit.WithLocalChanges - Text.ConfirmEmptyCommit.WithLocalChanges
- Text.CopyFullPath - Text.CopyFullPath
- Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash
- Text.Preferences.General.ShowTagsInGraph - Text.Preferences.General.ShowTagsInGraph
- Text.Preferences.Git.IgnoreCRAtEOLInDiff - Text.Preferences.Git.IgnoreCRAtEOLInDiff
- Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate
- Text.Repository.BranchSort.ByName
- Text.Repository.Search.ByContent - Text.Repository.Search.ByContent
- Text.Repository.ViewLogs - Text.Repository.ViewLogs
- Text.Repository.Visit
- Text.ViewLogs - Text.ViewLogs
- Text.ViewLogs.Clear - Text.ViewLogs.Clear
- Text.ViewLogs.CopyLog - Text.ViewLogs.CopyLog
@ -128,7 +106,7 @@ This document shows the translation status of each locale file in the repository
</details> </details>
### ![ja__JP](https://img.shields.io/badge/ja__JP-96.11%25-yellow) ### ![ja__JP](https://img.shields.io/badge/ja__JP-95.24%25-yellow)
<details> <details>
<summary>Missing keys in ja_JP.axaml</summary> <summary>Missing keys in ja_JP.axaml</summary>
@ -140,6 +118,7 @@ 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.Checkout.RecurseSubmodules
- Text.CommitCM.CopyAuthor - Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter - Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject - Text.CommitCM.CopySubject
@ -149,11 +128,17 @@ This document shows the translation status of each locale file in the repository
- Text.ConfirmEmptyCommit.NoLocalChanges - Text.ConfirmEmptyCommit.NoLocalChanges
- Text.ConfirmEmptyCommit.StageAllThenCommit - Text.ConfirmEmptyCommit.StageAllThenCommit
- Text.ConfirmEmptyCommit.WithLocalChanges - Text.ConfirmEmptyCommit.WithLocalChanges
- Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash
- Text.Preferences.Git.IgnoreCRAtEOLInDiff - Text.Preferences.Git.IgnoreCRAtEOLInDiff
- Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate
- Text.Repository.BranchSort.ByName
- Text.Repository.FilterCommits - Text.Repository.FilterCommits
- Text.Repository.Search.ByContent - Text.Repository.Search.ByContent
- Text.Repository.Tags.OrderByNameDes - Text.Repository.Tags.OrderByNameDes
- Text.Repository.ViewLogs - Text.Repository.ViewLogs
- Text.Repository.Visit
- Text.ViewLogs - Text.ViewLogs
- Text.ViewLogs.Clear - Text.ViewLogs.Clear
- Text.ViewLogs.CopyLog - Text.ViewLogs.CopyLog
@ -166,7 +151,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-87.68%25-yellow) ### ![pt__BR](https://img.shields.io/badge/pt__BR-86.89%25-yellow)
<details> <details>
<summary>Missing keys in pt_BR.axaml</summary> <summary>Missing keys in pt_BR.axaml</summary>
@ -187,6 +172,7 @@ This document shows the translation status of each locale file in the repository
- Text.BranchCM.CustomAction - Text.BranchCM.CustomAction
- Text.BranchCM.MergeMultiBranches - Text.BranchCM.MergeMultiBranches
- Text.BranchUpstreamInvalid - Text.BranchUpstreamInvalid
- Text.Checkout.RecurseSubmodules
- Text.Clone.RecurseSubmodules - Text.Clone.RecurseSubmodules
- Text.CommitCM.CopyAuthor - Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter - Text.CommitCM.CopyCommitter
@ -215,6 +201,8 @@ This document shows the translation status of each locale file in the repository
- Text.Diff.UseBlockNavigation - Text.Diff.UseBlockNavigation
- Text.Fetch.Force - Text.Fetch.Force
- Text.FileCM.ResolveUsing - Text.FileCM.ResolveUsing
- Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash
- Text.Hotkeys.Global.Clone - Text.Hotkeys.Global.Clone
- Text.InProgress.CherryPick.Head - Text.InProgress.CherryPick.Head
- Text.InProgress.Merge.Operating - Text.InProgress.Merge.Operating
@ -232,6 +220,9 @@ 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.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate
- Text.Repository.BranchSort.ByName
- Text.Repository.FilterCommits - Text.Repository.FilterCommits
- Text.Repository.HistoriesLayout - Text.Repository.HistoriesLayout
- Text.Repository.HistoriesLayout.Horizontal - Text.Repository.HistoriesLayout.Horizontal
@ -247,6 +238,7 @@ This document shows the translation status of each locale file in the repository
- Text.Repository.Tags.Sort - Text.Repository.Tags.Sort
- Text.Repository.UseRelativeTimeInHistories - Text.Repository.UseRelativeTimeInHistories
- Text.Repository.ViewLogs - Text.Repository.ViewLogs
- Text.Repository.Visit
- Text.SetUpstream - Text.SetUpstream
- Text.SetUpstream.Local - Text.SetUpstream.Local
- Text.SetUpstream.Unset - Text.SetUpstream.Unset
@ -271,7 +263,7 @@ This document shows the translation status of each locale file in the repository
### ![ru__RU](https://img.shields.io/badge/ru__RU-%E2%88%9A-brightgreen) ### ![ru__RU](https://img.shields.io/badge/ru__RU-%E2%88%9A-brightgreen)
### ![ta__IN](https://img.shields.io/badge/ta__IN-96.37%25-yellow) ### ![ta__IN](https://img.shields.io/badge/ta__IN-95.50%25-yellow)
<details> <details>
<summary>Missing keys in ta_IN.axaml</summary> <summary>Missing keys in ta_IN.axaml</summary>
@ -283,6 +275,7 @@ 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.Checkout.RecurseSubmodules
- Text.CommitCM.CopyAuthor - Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter - Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject - Text.CommitCM.CopySubject
@ -292,9 +285,15 @@ This document shows the translation status of each locale file in the repository
- Text.ConfirmEmptyCommit.NoLocalChanges - Text.ConfirmEmptyCommit.NoLocalChanges
- Text.ConfirmEmptyCommit.StageAllThenCommit - Text.ConfirmEmptyCommit.StageAllThenCommit
- Text.ConfirmEmptyCommit.WithLocalChanges - Text.ConfirmEmptyCommit.WithLocalChanges
- Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash
- Text.Preferences.Git.IgnoreCRAtEOLInDiff - Text.Preferences.Git.IgnoreCRAtEOLInDiff
- Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate
- Text.Repository.BranchSort.ByName
- Text.Repository.Search.ByContent - Text.Repository.Search.ByContent
- Text.Repository.ViewLogs - Text.Repository.ViewLogs
- Text.Repository.Visit
- Text.UpdateSubmodules.Target - Text.UpdateSubmodules.Target
- Text.ViewLogs - Text.ViewLogs
- Text.ViewLogs.Clear - Text.ViewLogs.Clear
@ -307,7 +306,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-97.54%25-yellow) ### ![uk__UA](https://img.shields.io/badge/uk__UA-96.66%25-yellow)
<details> <details>
<summary>Missing keys in uk_UA.axaml</summary> <summary>Missing keys in uk_UA.axaml</summary>
@ -319,14 +318,21 @@ 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.Checkout.RecurseSubmodules
- Text.CommitCM.CopyAuthor - Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter - Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject - Text.CommitCM.CopySubject
- Text.CommitMessageTextBox.SubjectCount - Text.CommitMessageTextBox.SubjectCount
- Text.ConfigureWorkspace.Name - Text.ConfigureWorkspace.Name
- Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash
- Text.Preferences.Git.IgnoreCRAtEOLInDiff - Text.Preferences.Git.IgnoreCRAtEOLInDiff
- Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate
- Text.Repository.BranchSort.ByName
- Text.Repository.Search.ByContent - Text.Repository.Search.ByContent
- Text.Repository.ViewLogs - Text.Repository.ViewLogs
- Text.Repository.Visit
- Text.ViewLogs - Text.ViewLogs
- Text.ViewLogs.Clear - Text.ViewLogs.Clear
- Text.ViewLogs.CopyLog - Text.ViewLogs.CopyLog

View file

@ -1 +1 @@
2025.16 2025.17

View file

@ -78,7 +78,7 @@ namespace SourceGit
return builder; return builder;
} }
private static void LogException(Exception ex) public static void LogException(Exception ex)
{ {
if (ex == null) if (ex == null)
return; return;

View file

@ -11,15 +11,24 @@ namespace SourceGit.Commands
Context = repo; Context = repo;
} }
public bool Branch(string branch) public bool Branch(string branch, bool force)
{ {
Args = $"checkout --recurse-submodules --progress {branch}"; var option = force ? "--force" : string.Empty;
Args = $"checkout {option} --progress {branch}";
return Exec(); return Exec();
} }
public bool Branch(string branch, string basedOn) public bool Branch(string branch, string basedOn, bool force)
{ {
Args = $"checkout --recurse-submodules --progress -b {branch} {basedOn}"; var option = force ? "--force" : string.Empty;
Args = $"checkout --progress -b {branch} {basedOn}";
return Exec();
}
public bool Commit(string commitId, bool force)
{
var option = force ? "--force" : string.Empty;
Args = $"checkout {option} --detach --progress {commitId}";
return Exec(); return Exec();
} }
@ -56,11 +65,5 @@ namespace SourceGit.Commands
Args = $"checkout --no-overlay {revision} -- \"{file}\""; Args = $"checkout --no-overlay {revision} -- \"{file}\"";
return Exec(); return Exec();
} }
public bool Commit(string commitId)
{
Args = $"checkout --detach --progress {commitId}";
return Exec();
}
} }
} }

View file

@ -1,31 +1,12 @@
using System.Collections.Generic; namespace SourceGit.Commands
using System.Text;
namespace SourceGit.Commands
{ {
public class Clean : Command public class Clean : Command
{ {
public Clean(string repo, bool includeIgnored) public Clean(string repo)
{ {
WorkingDirectory = repo; WorkingDirectory = repo;
Context = repo; Context = repo;
Args = includeIgnored ? "clean -qfdx" : "clean -qfd"; Args = "clean -qfdx";
}
public Clean(string repo, List<string> files)
{
var builder = new StringBuilder();
builder.Append("clean -qfd --");
foreach (var f in files)
{
builder.Append(" \"");
builder.Append(f);
builder.Append("\"");
}
WorkingDirectory = repo;
Context = repo;
Args = builder.ToString();
} }
} }
} }

View file

@ -28,11 +28,11 @@ namespace SourceGit.Commands
Context = repo; Context = repo;
if (ignoreWhitespace) if (ignoreWhitespace)
Args = $"-c core.autocrlf=false diff --no-ext-diff --patch --ignore-all-space --unified={unified} {opt}"; Args = $"diff --no-ext-diff --patch --ignore-all-space --unified={unified} {opt}";
else if (Models.DiffOption.IgnoreCRAtEOL) else if (Models.DiffOption.IgnoreCRAtEOL)
Args = $"-c core.autocrlf=false diff --no-ext-diff --patch --ignore-cr-at-eol --unified={unified} {opt}"; Args = $"diff --no-ext-diff --patch --ignore-cr-at-eol --unified={unified} {opt}";
else else
Args = $"-c core.autocrlf=false diff --no-ext-diff --patch --unified={unified} {opt}"; Args = $"diff --no-ext-diff --patch --unified={unified} {opt}";
} }
public Models.DiffResult Result() public Models.DiffResult Result()

View file

@ -1,5 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using Avalonia.Threading;
namespace SourceGit.Commands namespace SourceGit.Commands
{ {
@ -7,33 +10,71 @@ namespace SourceGit.Commands
{ {
public static void All(string repo, bool includeIgnored, Models.ICommandLog log) public static void All(string repo, bool includeIgnored, Models.ICommandLog log)
{ {
var changes = new QueryLocalChanges(repo).Result();
try
{
foreach (var c in changes)
{
if (c.WorkTree == Models.ChangeState.Untracked ||
c.WorkTree == Models.ChangeState.Added ||
c.Index == Models.ChangeState.Added ||
c.Index == Models.ChangeState.Renamed)
{
var fullPath = Path.Combine(repo, c.Path);
if (Directory.Exists(fullPath))
Directory.Delete(fullPath, true);
else
File.Delete(fullPath);
}
}
}
catch (Exception e)
{
Dispatcher.UIThread.Invoke(() =>
{
App.RaiseException(repo, $"Failed to discard changes. Reason: {e.Message}");
});
}
new Restore(repo) { Log = log }.Exec(); new Restore(repo) { Log = log }.Exec();
new Clean(repo, includeIgnored) { Log = log }.Exec(); if (includeIgnored)
new Clean(repo) { Log = log }.Exec();
} }
public static void Changes(string repo, List<Models.Change> changes, Models.ICommandLog log) public static void Changes(string repo, List<Models.Change> changes, Models.ICommandLog log)
{ {
var needClean = new List<string>(); var restores = new List<string>();
var needCheckout = new List<string>();
try
{
foreach (var c in changes) foreach (var c in changes)
{ {
if (c.WorkTree == Models.ChangeState.Untracked || c.WorkTree == Models.ChangeState.Added) if (c.WorkTree == Models.ChangeState.Untracked || c.WorkTree == Models.ChangeState.Added)
needClean.Add(c.Path); {
var fullPath = Path.Combine(repo, c.Path);
if (Directory.Exists(fullPath))
Directory.Delete(fullPath, true);
else else
needCheckout.Add(c.Path); File.Delete(fullPath);
}
else
{
restores.Add(c.Path);
}
}
}
catch (Exception e)
{
Dispatcher.UIThread.Invoke(() =>
{
App.RaiseException(repo, $"Failed to discard changes. Reason: {e.Message}");
});
} }
for (int i = 0; i < needClean.Count; i += 10) for (int i = 0; i < restores.Count; i += 10)
{ {
var count = Math.Min(10, needClean.Count - i); var count = Math.Min(10, restores.Count - i);
new Clean(repo, needClean.GetRange(i, count)) { Log = log }.Exec(); new Restore(repo, restores.GetRange(i, count), "--worktree --recurse-submodules") { Log = log }.Exec();
}
for (int i = 0; i < needCheckout.Count; i += 10)
{
var count = Math.Min(10, needCheckout.Count - i);
new Restore(repo, needCheckout.GetRange(i, count), "--worktree --recurse-submodules") { Log = log }.Exec();
} }
} }
} }

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using Avalonia.Threading; using Avalonia.Threading;
@ -134,7 +135,7 @@ namespace SourceGit.Commands
return start.Exec(); return start.Exec();
} }
public static bool Finish(string repo, string type, string name, bool keepBranch, Models.ICommandLog log) public static bool Finish(string repo, string type, string name, bool squash, bool push, bool keepBranch, Models.ICommandLog log)
{ {
if (!SUPPORTED_BRANCH_TYPES.Contains(type)) if (!SUPPORTED_BRANCH_TYPES.Contains(type))
{ {
@ -146,11 +147,22 @@ namespace SourceGit.Commands
return false; return false;
} }
var option = keepBranch ? "-k" : string.Empty; var builder = new StringBuilder();
builder.Append("flow ");
builder.Append(type);
builder.Append(" finish ");
if (squash)
builder.Append("--squash ");
if (push)
builder.Append("--push ");
if (keepBranch)
builder.Append("-k ");
builder.Append(name);
var finish = new Command(); var finish = new Command();
finish.WorkingDirectory = repo; finish.WorkingDirectory = repo;
finish.Context = repo; finish.Context = repo;
finish.Args = $"flow {type} finish {option} {name}"; finish.Args = builder.ToString();
finish.Log = log; finish.Log = log;
return finish.Exec(); return finish.Exec();
} }

View file

@ -14,7 +14,7 @@ namespace SourceGit.Commands
{ {
WorkingDirectory = repo; WorkingDirectory = repo;
Context = repo; Context = repo;
Args = "branch -l --all -v --format=\"%(refname)%00%(objectname)%00%(HEAD)%00%(upstream)%00%(upstream:trackshort)\""; Args = "branch -l --all -v --format=\"%(refname)%00%(committerdate:unix)%00%(objectname)%00%(HEAD)%00%(upstream)%00%(upstream:trackshort)\"";
} }
public List<Models.Branch> Result() public List<Models.Branch> Result()
@ -49,7 +49,7 @@ namespace SourceGit.Commands
private Models.Branch ParseLine(string line) private Models.Branch ParseLine(string line)
{ {
var parts = line.Split('\0'); var parts = line.Split('\0');
if (parts.Length != 5) if (parts.Length != 6)
return null; return null;
var branch = new Models.Branch(); var branch = new Models.Branch();
@ -83,12 +83,13 @@ namespace SourceGit.Commands
} }
branch.FullName = refName; branch.FullName = refName;
branch.Head = parts[1]; branch.CommitterDate = ulong.Parse(parts[1]);
branch.IsCurrent = parts[2] == "*"; branch.Head = parts[2];
branch.Upstream = parts[3]; branch.IsCurrent = parts[3] == "*";
branch.Upstream = parts[4];
branch.IsUpstreamGone = false; branch.IsUpstreamGone = false;
if (branch.IsLocal && !string.IsNullOrEmpty(parts[4]) && !parts[4].Equals("=", StringComparison.Ordinal)) if (branch.IsLocal && !string.IsNullOrEmpty(parts[5]) && !parts[5].Equals("=", StringComparison.Ordinal))
branch.TrackStatus = new QueryTrackStatus(WorkingDirectory, branch.Name, branch.Upstream).Result(); branch.TrackStatus = new QueryTrackStatus(WorkingDirectory, branch.Name, branch.Upstream).Result();
else else
branch.TrackStatus = new Models.BranchTrackStatus(); branch.TrackStatus = new Models.BranchTrackStatus();

View file

@ -1,4 +1,7 @@
namespace SourceGit.Commands using System.Collections.Generic;
using System.Text;
namespace SourceGit.Commands
{ {
public class Submodule : Command public class Submodule : Command
{ {
@ -42,6 +45,28 @@
return Exec(); return Exec();
} }
public bool Update(List<Models.Submodule> modules, bool init, bool recursive, bool useRemote)
{
var builder = new StringBuilder();
builder.Append("submodule update");
if (init)
builder.Append(" --init");
if (recursive)
builder.Append(" --recursive");
if (useRemote)
builder.Append(" --remote");
if (modules.Count > 0)
{
builder.Append(" --");
foreach (var module in modules)
builder.Append($" \"{module.Path}\"");
}
Args = builder.ToString();
return Exec();
}
public bool Delete(string relativePath) public bool Delete(string relativePath)
{ {
Args = $"submodule deinit -f \"{relativePath}\""; Args = $"submodule deinit -f \"{relativePath}\"";

View file

@ -23,10 +23,17 @@ namespace SourceGit.Models
} }
} }
public enum BranchSortMode
{
Name = 0,
CommitterDate,
}
public class Branch public class Branch
{ {
public string Name { get; set; } public string Name { get; set; }
public string FullName { get; set; } public string FullName { get; set; }
public ulong CommitterDate { get; set; }
public string Head { get; set; } public string Head { get; set; }
public bool IsLocal { get; set; } public bool IsLocal { get; set; }
public bool IsCurrent { get; set; } public bool IsCurrent { get; set; }

View file

@ -64,8 +64,8 @@ namespace SourceGit.Models
{ {
const double unitWidth = 12; const double unitWidth = 12;
const double halfWidth = 6; const double halfWidth = 6;
const double unitHeight = 28; const double unitHeight = 1;
const double halfHeight = 14; const double halfHeight = 0.5;
var temp = new CommitGraph(); var temp = new CommitGraph();
var unsolved = new List<PathHelper>(); var unsolved = new List<PathHelper>();

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace SourceGit.Models namespace SourceGit.Models
@ -22,24 +22,24 @@ namespace SourceGit.Models
{ {
if (remote.TryGetVisitURL(out var url)) if (remote.TryGetVisitURL(out var url))
{ {
var trimmedUrl = url; var trimmedUrl = url.AsSpan();
if (url.EndsWith(".git")) if (url.EndsWith(".git"))
trimmedUrl = url.Substring(0, url.Length - 4); trimmedUrl = url.AsSpan(0, url.Length - 4);
if (url.StartsWith("https://github.com/", StringComparison.Ordinal)) if (url.StartsWith("https://github.com/", StringComparison.Ordinal))
outs.Add(new($"Github ({trimmedUrl.Substring(19)})", $"{url}/commit/")); outs.Add(new($"Github ({trimmedUrl.Slice(19)})", $"{url}/commit/"));
else if (url.StartsWith("https://gitlab.", StringComparison.Ordinal)) else if (url.StartsWith("https://gitlab.", StringComparison.Ordinal))
outs.Add(new($"GitLab ({trimmedUrl.Substring(trimmedUrl.Substring(15).IndexOf('/') + 16)})", $"{url}/-/commit/")); outs.Add(new($"GitLab ({trimmedUrl.Slice(trimmedUrl.Slice(15).IndexOf('/') + 16)})", $"{url}/-/commit/"));
else if (url.StartsWith("https://gitee.com/", StringComparison.Ordinal)) else if (url.StartsWith("https://gitee.com/", StringComparison.Ordinal))
outs.Add(new($"Gitee ({trimmedUrl.Substring(18)})", $"{url}/commit/")); outs.Add(new($"Gitee ({trimmedUrl.Slice(18)})", $"{url}/commit/"));
else if (url.StartsWith("https://bitbucket.org/", StringComparison.Ordinal)) else if (url.StartsWith("https://bitbucket.org/", StringComparison.Ordinal))
outs.Add(new($"BitBucket ({trimmedUrl.Substring(22)})", $"{url}/commits/")); outs.Add(new($"BitBucket ({trimmedUrl.Slice(22)})", $"{url}/commits/"));
else if (url.StartsWith("https://codeberg.org/", StringComparison.Ordinal)) else if (url.StartsWith("https://codeberg.org/", StringComparison.Ordinal))
outs.Add(new($"Codeberg ({trimmedUrl.Substring(21)})", $"{url}/commit/")); outs.Add(new($"Codeberg ({trimmedUrl.Slice(21)})", $"{url}/commit/"));
else if (url.StartsWith("https://gitea.org/", StringComparison.Ordinal)) else if (url.StartsWith("https://gitea.org/", StringComparison.Ordinal))
outs.Add(new($"Gitea ({trimmedUrl.Substring(18)})", $"{url}/commit/")); outs.Add(new($"Gitea ({trimmedUrl.Slice(18)})", $"{url}/commit/"));
else if (url.StartsWith("https://git.sr.ht/", StringComparison.Ordinal)) else if (url.StartsWith("https://git.sr.ht/", StringComparison.Ordinal))
outs.Add(new($"sourcehut ({trimmedUrl.Substring(18)})", $"{url}/commit/")); outs.Add(new($"sourcehut ({trimmedUrl.Slice(18)})", $"{url}/commit/"));
} }
} }

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
@ -38,6 +38,18 @@ namespace SourceGit.Models
set; set;
} = false; } = false;
public BranchSortMode LocalBranchSortMode
{
get;
set;
} = BranchSortMode.Name;
public BranchSortMode RemoteBranchSortMode
{
get;
set;
} = BranchSortMode.Name;
public TagSortMode TagSortMode public TagSortMode TagSortMode
{ {
get; get;
@ -110,6 +122,12 @@ namespace SourceGit.Models
set; set;
} = true; } = true;
public bool UpdateSubmodulesOnCheckoutBranch
{
get;
set;
} = true;
public AvaloniaList<Filter> HistoriesFilters public AvaloniaList<Filter> HistoriesFilters
{ {
get; get;
@ -326,28 +344,28 @@ namespace SourceGit.Models
if (filter.Mode == FilterMode.Included) if (filter.Mode == FilterMode.Included)
includedRefs.Add(filter.Pattern); includedRefs.Add(filter.Pattern);
else if (filter.Mode == FilterMode.Excluded) else if (filter.Mode == FilterMode.Excluded)
excludedBranches.Add($"--exclude=\"{filter.Pattern.Substring(11)}\" --decorate-refs-exclude=\"{filter.Pattern}\""); excludedBranches.Add($"--exclude=\"{filter.Pattern.AsSpan(11)}\" --decorate-refs-exclude=\"{filter.Pattern}\"");
} }
else if (filter.Type == FilterType.LocalBranchFolder) else if (filter.Type == FilterType.LocalBranchFolder)
{ {
if (filter.Mode == FilterMode.Included) if (filter.Mode == FilterMode.Included)
includedRefs.Add($"--branches={filter.Pattern.Substring(11)}/*"); includedRefs.Add($"--branches={filter.Pattern.AsSpan(11)}/*");
else if (filter.Mode == FilterMode.Excluded) else if (filter.Mode == FilterMode.Excluded)
excludedBranches.Add($"--exclude=\"{filter.Pattern.Substring(11)}/*\" --decorate-refs-exclude=\"{filter.Pattern}/*\""); excludedBranches.Add($"--exclude=\"{filter.Pattern.AsSpan(11)}/*\" --decorate-refs-exclude=\"{filter.Pattern}/*\"");
} }
else if (filter.Type == FilterType.RemoteBranch) else if (filter.Type == FilterType.RemoteBranch)
{ {
if (filter.Mode == FilterMode.Included) if (filter.Mode == FilterMode.Included)
includedRefs.Add(filter.Pattern); includedRefs.Add(filter.Pattern);
else if (filter.Mode == FilterMode.Excluded) else if (filter.Mode == FilterMode.Excluded)
excludedRemotes.Add($"--exclude=\"{filter.Pattern.Substring(13)}\" --decorate-refs-exclude=\"{filter.Pattern}\""); excludedRemotes.Add($"--exclude=\"{filter.Pattern.AsSpan(13)}\" --decorate-refs-exclude=\"{filter.Pattern}\"");
} }
else if (filter.Type == FilterType.RemoteBranchFolder) else if (filter.Type == FilterType.RemoteBranchFolder)
{ {
if (filter.Mode == FilterMode.Included) if (filter.Mode == FilterMode.Included)
includedRefs.Add($"--remotes={filter.Pattern.Substring(13)}/*"); includedRefs.Add($"--remotes={filter.Pattern.AsSpan(13)}/*");
else if (filter.Mode == FilterMode.Excluded) else if (filter.Mode == FilterMode.Excluded)
excludedRemotes.Add($"--exclude=\"{filter.Pattern.Substring(13)}/*\" --decorate-refs-exclude=\"{filter.Pattern}/*\""); excludedRemotes.Add($"--exclude=\"{filter.Pattern.AsSpan(13)}/*\" --decorate-refs-exclude=\"{filter.Pattern}/*\"");
} }
else if (filter.Type == FilterType.Tag) else if (filter.Type == FilterType.Tag)
{ {

View file

@ -42,7 +42,8 @@ namespace SourceGit.Models
new ShellOrTerminal("mac-terminal", "Terminal", ""), new ShellOrTerminal("mac-terminal", "Terminal", ""),
new ShellOrTerminal("iterm2", "iTerm", ""), new ShellOrTerminal("iterm2", "iTerm", ""),
new ShellOrTerminal("warp", "Warp", ""), new ShellOrTerminal("warp", "Warp", ""),
new ShellOrTerminal("ghostty", "Ghostty", "") new ShellOrTerminal("ghostty", "Ghostty", ""),
new ShellOrTerminal("kitty", "kitty", "")
}; };
} }
else else
@ -58,6 +59,7 @@ namespace SourceGit.Models
new ShellOrTerminal("foot", "Foot", "foot"), new ShellOrTerminal("foot", "Foot", "foot"),
new ShellOrTerminal("wezterm", "WezTerm", "wezterm"), new ShellOrTerminal("wezterm", "WezTerm", "wezterm"),
new ShellOrTerminal("ptyxis", "Ptyxis", "ptyxis"), new ShellOrTerminal("ptyxis", "Ptyxis", "ptyxis"),
new ShellOrTerminal("kitty", "kitty", "kitty"),
new ShellOrTerminal("custom", "Custom", ""), new ShellOrTerminal("custom", "Custom", ""),
}; };
} }

View file

@ -59,6 +59,8 @@ namespace SourceGit.Native
return "Warp"; return "Warp";
case "ghostty": case "ghostty":
return "Ghostty"; return "Ghostty";
case "kitty":
return "kitty";
} }
return string.Empty; return string.Empty;

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 B

View file

@ -40,6 +40,13 @@
<x:String x:Key="Text.AssumeUnchanged.Empty" xml:space="preserve">KEINE ALS UNVERÄNDERT ANGENOMMENEN DATEIEN</x:String> <x:String x:Key="Text.AssumeUnchanged.Empty" xml:space="preserve">KEINE ALS UNVERÄNDERT ANGENOMMENEN DATEIEN</x:String>
<x:String x:Key="Text.AssumeUnchanged.Remove" xml:space="preserve">ENTFERNEN</x:String> <x:String x:Key="Text.AssumeUnchanged.Remove" xml:space="preserve">ENTFERNEN</x:String>
<x:String x:Key="Text.BinaryNotSupported" xml:space="preserve">BINÄRE DATEI NICHT UNTERSTÜTZT!!!</x:String> <x:String x:Key="Text.BinaryNotSupported" xml:space="preserve">BINÄRE DATEI NICHT UNTERSTÜTZT!!!</x:String>
<x:String x:Key="Text.Bisect">Bisect</x:String>
<x:String x:Key="Text.Bisect.Abort">Abbrechen</x:String>
<x:String x:Key="Text.Bisect.Bad">Schlecht</x:String>
<x:String x:Key="Text.Bisect.Detecting">Bisecting. Ist der aktuelle HEAD gut oder fehlerhaft?</x:String>
<x:String x:Key="Text.Bisect.Good">Gut</x:String>
<x:String x:Key="Text.Bisect.Skip">Überspringen</x:String>
<x:String x:Key="Text.Bisect.WaitingForRange">Bisecting. Aktuellen Commit als gut oder schlecht markieren und einen anderen auschecken.</x:String>
<x:String x:Key="Text.Blame" xml:space="preserve">Blame</x:String> <x:String x:Key="Text.Blame" xml:space="preserve">Blame</x:String>
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">BLAME WIRD BEI DIESER DATEI NICHT UNTERSTÜTZT!!!</x:String> <x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">BLAME WIRD BEI DIESER DATEI NICHT UNTERSTÜTZT!!!</x:String>
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">Auschecken von ${0}$...</x:String> <x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">Auschecken von ${0}$...</x:String>
@ -62,6 +69,7 @@
<x:String x:Key="Text.BranchCM.Rename" xml:space="preserve">Benenne ${0}$ um...</x:String> <x:String x:Key="Text.BranchCM.Rename" xml:space="preserve">Benenne ${0}$ um...</x:String>
<x:String x:Key="Text.BranchCM.Tracking" xml:space="preserve">Setze verfolgten Branch...</x:String> <x:String x:Key="Text.BranchCM.Tracking" xml:space="preserve">Setze verfolgten Branch...</x:String>
<x:String x:Key="Text.BranchCompare" xml:space="preserve">Branch Vergleich</x:String> <x:String x:Key="Text.BranchCompare" xml:space="preserve">Branch Vergleich</x:String>
<x:String x:Key="Text.BranchUpstreamInvalid" xml:space="preserve">Ungültiger upstream!</x:String>
<x:String x:Key="Text.Bytes" xml:space="preserve">Bytes</x:String> <x:String x:Key="Text.Bytes" xml:space="preserve">Bytes</x:String>
<x:String x:Key="Text.Cancel" xml:space="preserve">ABBRECHEN</x:String> <x:String x:Key="Text.Cancel" xml:space="preserve">ABBRECHEN</x:String>
<x:String x:Key="Text.ChangeCM.CheckoutFirstParentRevision" xml:space="preserve">Auf Vorgänger-Revision zurücksetzen</x:String> <x:String x:Key="Text.ChangeCM.CheckoutFirstParentRevision" xml:space="preserve">Auf Vorgänger-Revision zurücksetzen</x:String>
@ -78,6 +86,7 @@
<x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">Lokale Änderungen:</x:String> <x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">Lokale Änderungen:</x:String>
<x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">Verwerfen</x:String> <x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">Verwerfen</x:String>
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Stashen &amp; wieder anwenden</x:String> <x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Stashen &amp; wieder anwenden</x:String>
<x:String x:Key="Text.Checkout.RecurseSubmodules" xml:space="preserve">Alle Submodule updaten</x:String>
<x:String x:Key="Text.Checkout.Target" xml:space="preserve">Branch:</x:String> <x:String x:Key="Text.Checkout.Target" xml:space="preserve">Branch:</x:String>
<x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry Pick</x:String> <x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry Pick</x:String>
<x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">Quelle an Commit-Nachricht anhängen</x:String> <x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">Quelle an Commit-Nachricht anhängen</x:String>
@ -102,8 +111,11 @@
<x:String x:Key="Text.CommitCM.CherryPickMultiple" xml:space="preserve">Mehrere cherry-picken</x:String> <x:String x:Key="Text.CommitCM.CherryPickMultiple" xml:space="preserve">Mehrere cherry-picken</x:String>
<x:String x:Key="Text.CommitCM.CompareWithHead" xml:space="preserve">Mit HEAD vergleichen</x:String> <x:String x:Key="Text.CommitCM.CompareWithHead" xml:space="preserve">Mit HEAD vergleichen</x:String>
<x:String x:Key="Text.CommitCM.CompareWithWorktree" xml:space="preserve">Mit Worktree vergleichen</x:String> <x:String x:Key="Text.CommitCM.CompareWithWorktree" xml:space="preserve">Mit Worktree vergleichen</x:String>
<x:String x:Key="Text.CommitCM.CopyAuthor" xml:space="preserve">Author</x:String>
<x:String x:Key="Text.CommitCM.CopyCommitter" xml:space="preserve">Committer</x:String>
<x:String x:Key="Text.CommitCM.CopyInfo" xml:space="preserve">Information</x:String> <x:String x:Key="Text.CommitCM.CopyInfo" xml:space="preserve">Information</x:String>
<x:String x:Key="Text.CommitCM.CopySHA" xml:space="preserve">SHA</x:String> <x:String x:Key="Text.CommitCM.CopySHA" xml:space="preserve">SHA</x:String>
<x:String x:Key="Text.CommitCM.CopySubject" xml:space="preserve">Betreff</x:String>
<x:String x:Key="Text.CommitCM.CustomAction" xml:space="preserve">Benutzerdefinierte Aktion</x:String> <x:String x:Key="Text.CommitCM.CustomAction" xml:space="preserve">Benutzerdefinierte Aktion</x:String>
<x:String x:Key="Text.CommitCM.InteractiveRebase" xml:space="preserve">Interactives Rebase von ${0}$ auf diesen Commit</x:String> <x:String x:Key="Text.CommitCM.InteractiveRebase" xml:space="preserve">Interactives Rebase von ${0}$ auf diesen Commit</x:String>
<x:String x:Key="Text.CommitCM.Merge" xml:space="preserve">Merge in ${0}$ hinein</x:String> <x:String x:Key="Text.CommitCM.Merge" xml:space="preserve">Merge in ${0}$ hinein</x:String>
@ -135,6 +147,7 @@
<x:String x:Key="Text.CommitDetail.Info.SHA" xml:space="preserve">SHA</x:String> <x:String x:Key="Text.CommitDetail.Info.SHA" xml:space="preserve">SHA</x:String>
<x:String x:Key="Text.CommitDetail.Info.WebLinks" xml:space="preserve">Im Browser öffnen</x:String> <x:String x:Key="Text.CommitDetail.Info.WebLinks" xml:space="preserve">Im Browser öffnen</x:String>
<x:String x:Key="Text.CommitMessageTextBox.MessagePlaceholder" xml:space="preserve">Details</x:String> <x:String x:Key="Text.CommitMessageTextBox.MessagePlaceholder" xml:space="preserve">Details</x:String>
<x:String x:Key="Text.CommitMessageTextBox.SubjectCount" xml:space="preserve">Betreff</x:String>
<x:String x:Key="Text.CommitMessageTextBox.SubjectPlaceholder" xml:space="preserve">Commit-Nachricht</x:String> <x:String x:Key="Text.CommitMessageTextBox.SubjectPlaceholder" xml:space="preserve">Commit-Nachricht</x:String>
<x:String x:Key="Text.Configure" xml:space="preserve">Repository Einstellungen</x:String> <x:String x:Key="Text.Configure" xml:space="preserve">Repository Einstellungen</x:String>
<x:String x:Key="Text.Configure.CommitMessageTemplate" xml:space="preserve">COMMIT TEMPLATE</x:String> <x:String x:Key="Text.Configure.CommitMessageTemplate" xml:space="preserve">COMMIT TEMPLATE</x:String>
@ -149,13 +162,16 @@
<x:String x:Key="Text.Configure.CustomAction.Scope.Branch" xml:space="preserve">Branch</x:String> <x:String x:Key="Text.Configure.CustomAction.Scope.Branch" xml:space="preserve">Branch</x:String>
<x:String x:Key="Text.Configure.CustomAction.Scope.Commit" xml:space="preserve">Commit</x:String> <x:String x:Key="Text.Configure.CustomAction.Scope.Commit" xml:space="preserve">Commit</x:String>
<x:String x:Key="Text.Configure.CustomAction.Scope.Repository" xml:space="preserve">Repository</x:String> <x:String x:Key="Text.Configure.CustomAction.Scope.Repository" xml:space="preserve">Repository</x:String>
<x:String x:Key="Text.Configure.CustomAction.WaitForExit" xml:space="preserve">Auf Beenden der Aktion warten</x:String>
<x:String x:Key="Text.Configure.Email" xml:space="preserve">Email Adresse</x:String> <x:String x:Key="Text.Configure.Email" xml:space="preserve">Email Adresse</x:String>
<x:String x:Key="Text.Configure.Email.Placeholder" xml:space="preserve">Email Adresse</x:String> <x:String x:Key="Text.Configure.Email.Placeholder" xml:space="preserve">Email Adresse</x:String>
<x:String x:Key="Text.Configure.Git" xml:space="preserve">GIT</x:String> <x:String x:Key="Text.Configure.Git" xml:space="preserve">GIT</x:String>
<x:String x:Key="Text.Configure.Git.AutoFetch" xml:space="preserve">Remotes automatisch fetchen</x:String> <x:String x:Key="Text.Configure.Git.AutoFetch" xml:space="preserve">Remotes automatisch fetchen</x:String>
<x:String x:Key="Text.Configure.Git.AutoFetchIntervalSuffix" xml:space="preserve">Minute(n)</x:String> <x:String x:Key="Text.Configure.Git.AutoFetchIntervalSuffix" xml:space="preserve">Minute(n)</x:String>
<x:String x:Key="Text.Configure.Git.DefaultRemote" xml:space="preserve">Standard Remote</x:String> <x:String x:Key="Text.Configure.Git.DefaultRemote" xml:space="preserve">Standard Remote</x:String>
<x:String x:Key="Text.Configure.Git.PreferredMergeMode" xml:space="preserve">Bevorzugter Merge Modus</x:String>
<x:String x:Key="Text.Configure.IssueTracker" xml:space="preserve">TICKETSYSTEM</x:String> <x:String x:Key="Text.Configure.IssueTracker" xml:space="preserve">TICKETSYSTEM</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleAzure" xml:space="preserve">Beispiel Azure DevOps Rule hinzufügen</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGiteeIssue" xml:space="preserve">Beispiel für Gitee Issue Regel einfügen</x:String> <x:String x:Key="Text.Configure.IssueTracker.AddSampleGiteeIssue" xml:space="preserve">Beispiel für Gitee Issue Regel einfügen</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGiteePullRequest" xml:space="preserve">Beispiel für Gitee Pull Request Regel einfügen</x:String> <x:String x:Key="Text.Configure.IssueTracker.AddSampleGiteePullRequest" xml:space="preserve">Beispiel für Gitee Pull Request Regel einfügen</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGithub" xml:space="preserve">Beispiel für Github-Regel hinzufügen</x:String> <x:String x:Key="Text.Configure.IssueTracker.AddSampleGithub" xml:space="preserve">Beispiel für Github-Regel hinzufügen</x:String>
@ -178,6 +194,10 @@
<x:String x:Key="Text.ConfigureWorkspace.Color" xml:space="preserve">Farbe</x:String> <x:String x:Key="Text.ConfigureWorkspace.Color" xml:space="preserve">Farbe</x:String>
<x:String x:Key="Text.ConfigureWorkspace.Name" xml:space="preserve">Name</x:String> <x:String x:Key="Text.ConfigureWorkspace.Name" xml:space="preserve">Name</x:String>
<x:String x:Key="Text.ConfigureWorkspace.Restore" xml:space="preserve">Zuletzt geöffnete Tabs beim Starten wiederherstellen</x:String> <x:String x:Key="Text.ConfigureWorkspace.Restore" xml:space="preserve">Zuletzt geöffnete Tabs beim Starten wiederherstellen</x:String>
<x:String x:Key="Text.ConfirmEmptyCommit.Continue" xml:space="preserve">WEITER</x:String>
<x:String x:Key="Text.ConfirmEmptyCommit.NoLocalChanges" xml:space="preserve">Leerer Commit erkannt! Möchtest du trotzdem fortfahren (--allow-empty)?</x:String>
<x:String x:Key="Text.ConfirmEmptyCommit.StageAllThenCommit" xml:space="preserve">ALLES STAGEN &amp; COMMITTEN</x:String>
<x:String x:Key="Text.ConfirmEmptyCommit.WithLocalChanges" xml:space="preserve">Leerer Commit erkannt! Möchtest du trotzdem fortfahren (--allow-empty) oder alle Änderungen stagen und dann committen?</x:String>
<x:String x:Key="Text.ConventionalCommit" xml:space="preserve">Konventionelle Commit-Hilfe</x:String> <x:String x:Key="Text.ConventionalCommit" xml:space="preserve">Konventionelle Commit-Hilfe</x:String>
<x:String x:Key="Text.ConventionalCommit.BreakingChanges" xml:space="preserve">Breaking Change:</x:String> <x:String x:Key="Text.ConventionalCommit.BreakingChanges" xml:space="preserve">Breaking Change:</x:String>
<x:String x:Key="Text.ConventionalCommit.ClosedIssue" xml:space="preserve">Geschlossenes Ticket:</x:String> <x:String x:Key="Text.ConventionalCommit.ClosedIssue" xml:space="preserve">Geschlossenes Ticket:</x:String>
@ -187,6 +207,7 @@
<x:String x:Key="Text.ConventionalCommit.Type" xml:space="preserve">Typ der Änderung:</x:String> <x:String x:Key="Text.ConventionalCommit.Type" xml:space="preserve">Typ der Änderung:</x:String>
<x:String x:Key="Text.Copy" xml:space="preserve">Kopieren</x:String> <x:String x:Key="Text.Copy" xml:space="preserve">Kopieren</x:String>
<x:String x:Key="Text.CopyAllText" xml:space="preserve">Kopiere gesamten Text</x:String> <x:String x:Key="Text.CopyAllText" xml:space="preserve">Kopiere gesamten Text</x:String>
<x:String x:Key="Text.CopyFullPath" xml:space="preserve">Ganzen Pfad kopieren</x:String>
<x:String x:Key="Text.CopyPath" xml:space="preserve">Pfad kopieren</x:String> <x:String x:Key="Text.CopyPath" xml:space="preserve">Pfad kopieren</x:String>
<x:String x:Key="Text.CreateBranch" xml:space="preserve">Branch erstellen...</x:String> <x:String x:Key="Text.CreateBranch" xml:space="preserve">Branch erstellen...</x:String>
<x:String x:Key="Text.CreateBranch.BasedOn" xml:space="preserve">Basierend auf:</x:String> <x:String x:Key="Text.CreateBranch.BasedOn" xml:space="preserve">Basierend auf:</x:String>
@ -236,7 +257,9 @@
<x:String x:Key="Text.Diff.Binary.Old" xml:space="preserve">ALT</x:String> <x:String x:Key="Text.Diff.Binary.Old" xml:space="preserve">ALT</x:String>
<x:String x:Key="Text.Diff.Copy" xml:space="preserve">Kopieren</x:String> <x:String x:Key="Text.Diff.Copy" xml:space="preserve">Kopieren</x:String>
<x:String x:Key="Text.Diff.FileModeChanged" xml:space="preserve">Dateimodus geändert</x:String> <x:String x:Key="Text.Diff.FileModeChanged" xml:space="preserve">Dateimodus geändert</x:String>
<x:String x:Key="Text.Diff.First" xml:space="preserve">Erste Differenz</x:String>
<x:String x:Key="Text.Diff.IgnoreWhitespace" xml:space="preserve">Ignoriere Leerzeichenänderungen</x:String> <x:String x:Key="Text.Diff.IgnoreWhitespace" xml:space="preserve">Ignoriere Leerzeichenänderungen</x:String>
<x:String x:Key="Text.Diff.Last" xml:space="preserve">Letzte Differenz</x:String>
<x:String x:Key="Text.Diff.LFS" xml:space="preserve">LFS OBJEKT ÄNDERUNG</x:String> <x:String x:Key="Text.Diff.LFS" xml:space="preserve">LFS OBJEKT ÄNDERUNG</x:String>
<x:String x:Key="Text.Diff.Next" xml:space="preserve">Nächste Änderung</x:String> <x:String x:Key="Text.Diff.Next" xml:space="preserve">Nächste Änderung</x:String>
<x:String x:Key="Text.Diff.NoChange" xml:space="preserve">KEINE ÄNDERUNG ODER NUR ZEILEN-ENDE ÄNDERUNGEN</x:String> <x:String x:Key="Text.Diff.NoChange" xml:space="preserve">KEINE ÄNDERUNG ODER NUR ZEILEN-ENDE ÄNDERUNGEN</x:String>
@ -447,8 +470,10 @@
<x:String x:Key="Text.Preferences.AI.Model" xml:space="preserve">Modell</x:String> <x:String x:Key="Text.Preferences.AI.Model" xml:space="preserve">Modell</x:String>
<x:String x:Key="Text.Preferences.AI.Name" xml:space="preserve">Name</x:String> <x:String x:Key="Text.Preferences.AI.Name" xml:space="preserve">Name</x:String>
<x:String x:Key="Text.Preferences.AI.Server" xml:space="preserve">Server</x:String> <x:String x:Key="Text.Preferences.AI.Server" xml:space="preserve">Server</x:String>
<x:String x:Key="Text.Preferences.AI.Streaming" xml:space="preserve">Streaming aktivieren</x:String>
<x:String x:Key="Text.Preferences.Appearance" xml:space="preserve">DARSTELLUNG</x:String> <x:String x:Key="Text.Preferences.Appearance" xml:space="preserve">DARSTELLUNG</x:String>
<x:String x:Key="Text.Preferences.Appearance.DefaultFont" xml:space="preserve">Standardschriftart</x:String> <x:String x:Key="Text.Preferences.Appearance.DefaultFont" xml:space="preserve">Standardschriftart</x:String>
<x:String x:Key="Text.Preferences.Appearance.EditorTabWidth" xml:space="preserve">Editor Tab Breite</x:String>
<x:String x:Key="Text.Preferences.Appearance.FontSize" xml:space="preserve">Schriftgröße</x:String> <x:String x:Key="Text.Preferences.Appearance.FontSize" xml:space="preserve">Schriftgröße</x:String>
<x:String x:Key="Text.Preferences.Appearance.FontSize.Default" xml:space="preserve">Standard</x:String> <x:String x:Key="Text.Preferences.Appearance.FontSize.Default" xml:space="preserve">Standard</x:String>
<x:String x:Key="Text.Preferences.Appearance.FontSize.Editor" xml:space="preserve">Texteditor</x:String> <x:String x:Key="Text.Preferences.Appearance.FontSize.Editor" xml:space="preserve">Texteditor</x:String>
@ -469,6 +494,7 @@
<x:String x:Key="Text.Preferences.General.MaxHistoryCommits" xml:space="preserve">Commit-Historie</x:String> <x:String x:Key="Text.Preferences.General.MaxHistoryCommits" xml:space="preserve">Commit-Historie</x:String>
<x:String x:Key="Text.Preferences.General.ShowAuthorTime" xml:space="preserve">Zeige Autor Zeitpunkt anstatt Commit Zeitpunkt</x:String> <x:String x:Key="Text.Preferences.General.ShowAuthorTime" xml:space="preserve">Zeige Autor Zeitpunkt anstatt Commit Zeitpunkt</x:String>
<x:String x:Key="Text.Preferences.General.ShowChildren" xml:space="preserve">Zeige Nachfolger in den Commit Details</x:String> <x:String x:Key="Text.Preferences.General.ShowChildren" xml:space="preserve">Zeige Nachfolger in den Commit Details</x:String>
<x:String x:Key="Text.Preferences.General.ShowTagsInGraph" xml:space="preserve">Zeige Tags im Commit Graph</x:String>
<x:String x:Key="Text.Preferences.General.SubjectGuideLength" xml:space="preserve">Längenvorgabe für Commit-Nachrichten</x:String> <x:String x:Key="Text.Preferences.General.SubjectGuideLength" xml:space="preserve">Längenvorgabe für Commit-Nachrichten</x:String>
<x:String x:Key="Text.Preferences.Git" xml:space="preserve">GIT</x:String> <x:String x:Key="Text.Preferences.Git" xml:space="preserve">GIT</x:String>
<x:String x:Key="Text.Preferences.Git.CRLF" xml:space="preserve">Aktiviere Auto-CRLF</x:String> <x:String x:Key="Text.Preferences.Git.CRLF" xml:space="preserve">Aktiviere Auto-CRLF</x:String>
@ -476,6 +502,7 @@
<x:String x:Key="Text.Preferences.Git.Email" xml:space="preserve">Benutzer Email</x:String> <x:String x:Key="Text.Preferences.Git.Email" xml:space="preserve">Benutzer Email</x:String>
<x:String x:Key="Text.Preferences.Git.Email.Placeholder" xml:space="preserve">Globale Git Benutzer Email</x:String> <x:String x:Key="Text.Preferences.Git.Email.Placeholder" xml:space="preserve">Globale Git Benutzer Email</x:String>
<x:String x:Key="Text.Preferences.Git.EnablePruneOnFetch" xml:space="preserve">Aktivere --prune beim fetchen</x:String> <x:String x:Key="Text.Preferences.Git.EnablePruneOnFetch" xml:space="preserve">Aktivere --prune beim fetchen</x:String>
<x:String x:Key="Text.Preferences.Git.IgnoreCRAtEOLInDiff" xml:space="preserve">Aktiviere --ignore-cr-at-eol beim Unterschied</x:String>
<x:String x:Key="Text.Preferences.Git.Invalid" xml:space="preserve">Diese App setzt Git (&gt;= 2.23.0) voraus</x:String> <x:String x:Key="Text.Preferences.Git.Invalid" xml:space="preserve">Diese App setzt Git (&gt;= 2.23.0) voraus</x:String>
<x:String x:Key="Text.Preferences.Git.Path" xml:space="preserve">Installationspfad</x:String> <x:String x:Key="Text.Preferences.Git.Path" xml:space="preserve">Installationspfad</x:String>
<x:String x:Key="Text.Preferences.Git.SSLVerify" xml:space="preserve">Aktiviere HTTP SSL Verifizierung</x:String> <x:String x:Key="Text.Preferences.Git.SSLVerify" xml:space="preserve">Aktiviere HTTP SSL Verifizierung</x:String>
@ -549,6 +576,9 @@
<x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">Branch:</x:String> <x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">Branch:</x:String>
<x:String x:Key="Text.Repository.Abort" xml:space="preserve">ABBRECHEN</x:String> <x:String x:Key="Text.Repository.Abort" xml:space="preserve">ABBRECHEN</x:String>
<x:String x:Key="Text.Repository.AutoFetching" xml:space="preserve">Änderungen automatisch von Remote fetchen...</x:String> <x:String x:Key="Text.Repository.AutoFetching" xml:space="preserve">Änderungen automatisch von Remote fetchen...</x:String>
<x:String x:Key="Text.Repository.BranchSort" xml:space="preserve">Sortieren</x:String>
<x:String x:Key="Text.Repository.BranchSort.ByCommitterDate" xml:space="preserve">Nach Commit Datum</x:String>
<x:String x:Key="Text.Repository.BranchSort.ByName" xml:space="preserve">Nach Name</x:String>
<x:String x:Key="Text.Repository.Clean" xml:space="preserve">Aufräumen (GC &amp; Prune)</x:String> <x:String x:Key="Text.Repository.Clean" xml:space="preserve">Aufräumen (GC &amp; Prune)</x:String>
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">Führt `git gc` auf diesem Repository aus.</x:String> <x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">Führt `git gc` auf diesem Repository aus.</x:String>
<x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">Filter aufheben</x:String> <x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">Filter aufheben</x:String>
@ -583,6 +613,7 @@
<x:String x:Key="Text.Repository.Search" xml:space="preserve">Commit suchen</x:String> <x:String x:Key="Text.Repository.Search" xml:space="preserve">Commit suchen</x:String>
<x:String x:Key="Text.Repository.Search.ByAuthor" xml:space="preserve">Autor</x:String> <x:String x:Key="Text.Repository.Search.ByAuthor" xml:space="preserve">Autor</x:String>
<x:String x:Key="Text.Repository.Search.ByCommitter" xml:space="preserve">Committer</x:String> <x:String x:Key="Text.Repository.Search.ByCommitter" xml:space="preserve">Committer</x:String>
<x:String x:Key="Text.Repository.Search.ByContent" xml:space="preserve">Inhalt</x:String>
<x:String x:Key="Text.Repository.Search.ByFile" xml:space="preserve">Dateiname</x:String> <x:String x:Key="Text.Repository.Search.ByFile" xml:space="preserve">Dateiname</x:String>
<x:String x:Key="Text.Repository.Search.ByMessage" xml:space="preserve">Commit-Nachricht</x:String> <x:String x:Key="Text.Repository.Search.ByMessage" xml:space="preserve">Commit-Nachricht</x:String>
<x:String x:Key="Text.Repository.Search.BySHA" xml:space="preserve">SHA</x:String> <x:String x:Key="Text.Repository.Search.BySHA" xml:space="preserve">SHA</x:String>
@ -601,6 +632,8 @@
<x:String x:Key="Text.Repository.Tags.Sort" xml:space="preserve">Sortiere</x:String> <x:String x:Key="Text.Repository.Tags.Sort" xml:space="preserve">Sortiere</x:String>
<x:String x:Key="Text.Repository.Terminal" xml:space="preserve">Öffne im Terminal</x:String> <x:String x:Key="Text.Repository.Terminal" xml:space="preserve">Öffne im Terminal</x:String>
<x:String x:Key="Text.Repository.UseRelativeTimeInHistories" xml:space="preserve">Verwende relative Zeitangaben in Verlauf</x:String> <x:String x:Key="Text.Repository.UseRelativeTimeInHistories" xml:space="preserve">Verwende relative Zeitangaben in Verlauf</x:String>
<x:String x:Key="Text.Repository.ViewLogs" xml:space="preserve">Logs ansehen</x:String>
<x:String x:Key="Text.Repository.Visit" xml:space="preserve">Öffne '{0}' im Browser</x:String>
<x:String x:Key="Text.Repository.Worktrees" xml:space="preserve">WORKTREES</x:String> <x:String x:Key="Text.Repository.Worktrees" xml:space="preserve">WORKTREES</x:String>
<x:String x:Key="Text.Repository.Worktrees.Add" xml:space="preserve">WORKTREE HINZUFÜGEN</x:String> <x:String x:Key="Text.Repository.Worktrees.Add" xml:space="preserve">WORKTREE HINZUFÜGEN</x:String>
<x:String x:Key="Text.Repository.Worktrees.Prune" xml:space="preserve">PRUNE</x:String> <x:String x:Key="Text.Repository.Worktrees.Prune" xml:space="preserve">PRUNE</x:String>
@ -651,6 +684,7 @@
<x:String x:Key="Text.Stash.Title" xml:space="preserve">Lokale Änderungen stashen</x:String> <x:String x:Key="Text.Stash.Title" xml:space="preserve">Lokale Änderungen stashen</x:String>
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">Anwenden</x:String> <x:String x:Key="Text.StashCM.Apply" xml:space="preserve">Anwenden</x:String>
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">Entfernen</x:String> <x:String x:Key="Text.StashCM.Drop" xml:space="preserve">Entfernen</x:String>
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">Als Path speichern...</x:String>
<x:String x:Key="Text.StashDropConfirm" xml:space="preserve">Stash entfernen</x:String> <x:String x:Key="Text.StashDropConfirm" xml:space="preserve">Stash entfernen</x:String>
<x:String x:Key="Text.StashDropConfirm.Label" xml:space="preserve">Entfernen:</x:String> <x:String x:Key="Text.StashDropConfirm.Label" xml:space="preserve">Entfernen:</x:String>
<x:String x:Key="Text.Stashes" xml:space="preserve">Stashes</x:String> <x:String x:Key="Text.Stashes" xml:space="preserve">Stashes</x:String>
@ -685,6 +719,10 @@
<x:String x:Key="Text.UpdateSubmodules.Target" xml:space="preserve">Submodul:</x:String> <x:String x:Key="Text.UpdateSubmodules.Target" xml:space="preserve">Submodul:</x:String>
<x:String x:Key="Text.UpdateSubmodules.UseRemote" xml:space="preserve">Verwende `--remote` Option</x:String> <x:String x:Key="Text.UpdateSubmodules.UseRemote" xml:space="preserve">Verwende `--remote` Option</x:String>
<x:String x:Key="Text.URL" xml:space="preserve">URL:</x:String> <x:String x:Key="Text.URL" xml:space="preserve">URL:</x:String>
<x:String x:Key="Text.ViewLogs" xml:space="preserve">Logs</x:String>
<x:String x:Key="Text.ViewLogs.Clear" xml:space="preserve">ALLES LÖSCHEN</x:String>
<x:String x:Key="Text.ViewLogs.CopyLog" xml:space="preserve">Kopieren</x:String>
<x:String x:Key="Text.ViewLogs.Delete" xml:space="preserve">Löschen</x:String>
<x:String x:Key="Text.Warn" xml:space="preserve">Warnung</x:String> <x:String x:Key="Text.Warn" xml:space="preserve">Warnung</x:String>
<x:String x:Key="Text.Welcome" xml:space="preserve">Willkommensseite</x:String> <x:String x:Key="Text.Welcome" xml:space="preserve">Willkommensseite</x:String>
<x:String x:Key="Text.Welcome.AddRootFolder" xml:space="preserve">Erstelle Gruppe</x:String> <x:String x:Key="Text.Welcome.AddRootFolder" xml:space="preserve">Erstelle Gruppe</x:String>
@ -714,8 +752,13 @@
<x:String x:Key="Text.WorkingCopy.CommitTip" xml:space="preserve">Klick-Ereignis auslösen</x:String> <x:String x:Key="Text.WorkingCopy.CommitTip" xml:space="preserve">Klick-Ereignis auslösen</x:String>
<x:String x:Key="Text.WorkingCopy.CommitToEdit" xml:space="preserve">Commit (Bearbeitung)</x:String> <x:String x:Key="Text.WorkingCopy.CommitToEdit" xml:space="preserve">Commit (Bearbeitung)</x:String>
<x:String x:Key="Text.WorkingCopy.CommitWithAutoStage" xml:space="preserve">Alle Änderungen stagen und committen</x:String> <x:String x:Key="Text.WorkingCopy.CommitWithAutoStage" xml:space="preserve">Alle Änderungen stagen und committen</x:String>
<x:String x:Key="Text.WorkingCopy.ConfirmCommitWithFilter">Du hast {0} Datei(en) gestaged, aber nur {1} werden angezeigt ({2} sind herausgefiltert). Willst du trotzdem fortfahren?</x:String>
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">KONFLIKTE ERKANNT</x:String> <x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">KONFLIKTE ERKANNT</x:String>
<x:String x:Key="Text.WorkingCopy.Conflicts.OpenExternalMergeTool" xml:space="preserve">EXTERNES MERGE-TOOL ÖFFNEN</x:String>
<x:String x:Key="Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts" xml:space="preserve">ALLE KONFLIKTE IN EXTERNEM MERGE-TOOL ÖFFNEN</x:String>
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">DATEI KONFLIKTE GELÖST</x:String> <x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">DATEI KONFLIKTE GELÖST</x:String>
<x:String x:Key="Text.WorkingCopy.Conflicts.UseMine" xml:space="preserve">MEINE VERSION VERWENDEN</x:String>
<x:String x:Key="Text.WorkingCopy.Conflicts.UseTheirs" xml:space="preserve">DEREN VERSION VERWENDEN</x:String>
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">NICHT-VERFOLGTE DATEIEN INKLUDIEREN</x:String> <x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">NICHT-VERFOLGTE DATEIEN INKLUDIEREN</x:String>
<x:String x:Key="Text.WorkingCopy.NoCommitHistories" xml:space="preserve">KEINE BISHERIGEN COMMIT-NACHRICHTEN</x:String> <x:String x:Key="Text.WorkingCopy.NoCommitHistories" xml:space="preserve">KEINE BISHERIGEN COMMIT-NACHRICHTEN</x:String>
<x:String x:Key="Text.WorkingCopy.NoCommitTemplates" xml:space="preserve">KEINE COMMIT TEMPLATES</x:String> <x:String x:Key="Text.WorkingCopy.NoCommitTemplates" xml:space="preserve">KEINE COMMIT TEMPLATES</x:String>

View file

@ -82,6 +82,7 @@
<x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">Local Changes:</x:String> <x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">Local Changes:</x:String>
<x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">Discard</x:String> <x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">Discard</x:String>
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Stash &amp; Reapply</x:String> <x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Stash &amp; Reapply</x:String>
<x:String x:Key="Text.Checkout.RecurseSubmodules" xml:space="preserve">Update all submodules</x:String>
<x:String x:Key="Text.Checkout.Target" xml:space="preserve">Branch:</x:String> <x:String x:Key="Text.Checkout.Target" xml:space="preserve">Branch:</x:String>
<x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry Pick</x:String> <x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry Pick</x:String>
<x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">Append source to commit message</x:String> <x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">Append source to commit message</x:String>
@ -322,6 +323,8 @@
<x:String x:Key="Text.GitFlow.FinishHotfix" xml:space="preserve">FLOW - Finish Hotfix</x:String> <x:String x:Key="Text.GitFlow.FinishHotfix" xml:space="preserve">FLOW - Finish Hotfix</x:String>
<x:String x:Key="Text.GitFlow.FinishRelease" xml:space="preserve">FLOW - Finish Release</x:String> <x:String x:Key="Text.GitFlow.FinishRelease" xml:space="preserve">FLOW - Finish Release</x:String>
<x:String x:Key="Text.GitFlow.FinishTarget" xml:space="preserve">Target:</x:String> <x:String x:Key="Text.GitFlow.FinishTarget" xml:space="preserve">Target:</x:String>
<x:String x:Key="Text.GitFlow.FinishWithPush" xml:space="preserve">Push to remote(s) after performing finish</x:String>
<x:String x:Key="Text.GitFlow.FinishWithSquash" xml:space="preserve">Squash during merge</x:String>
<x:String x:Key="Text.GitFlow.Hotfix" xml:space="preserve">Hotfix:</x:String> <x:String x:Key="Text.GitFlow.Hotfix" xml:space="preserve">Hotfix:</x:String>
<x:String x:Key="Text.GitFlow.HotfixPrefix" xml:space="preserve">Hotfix Prefix:</x:String> <x:String x:Key="Text.GitFlow.HotfixPrefix" xml:space="preserve">Hotfix Prefix:</x:String>
<x:String x:Key="Text.GitFlow.Init" xml:space="preserve">Initialize Git-Flow</x:String> <x:String x:Key="Text.GitFlow.Init" xml:space="preserve">Initialize Git-Flow</x:String>
@ -571,6 +574,9 @@
<x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">Branch:</x:String> <x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">Branch:</x:String>
<x:String x:Key="Text.Repository.Abort" xml:space="preserve">ABORT</x:String> <x:String x:Key="Text.Repository.Abort" xml:space="preserve">ABORT</x:String>
<x:String x:Key="Text.Repository.AutoFetching" xml:space="preserve">Auto fetching changes from remotes...</x:String> <x:String x:Key="Text.Repository.AutoFetching" xml:space="preserve">Auto fetching changes from remotes...</x:String>
<x:String x:Key="Text.Repository.BranchSort" xml:space="preserve">Sort</x:String>
<x:String x:Key="Text.Repository.BranchSort.ByCommitterDate" xml:space="preserve">By Committer Date</x:String>
<x:String x:Key="Text.Repository.BranchSort.ByName" xml:space="preserve">By Name</x:String>
<x:String x:Key="Text.Repository.Clean" xml:space="preserve">Cleanup(GC &amp; Prune)</x:String> <x:String x:Key="Text.Repository.Clean" xml:space="preserve">Cleanup(GC &amp; Prune)</x:String>
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">Run `git gc` command for this repository.</x:String> <x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">Run `git gc` command for this repository.</x:String>
<x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">Clear all</x:String> <x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">Clear all</x:String>
@ -601,7 +607,7 @@
<x:String x:Key="Text.Repository.OpenWithExternalTools" xml:space="preserve">Open in External Tools</x:String> <x:String x:Key="Text.Repository.OpenWithExternalTools" xml:space="preserve">Open in External Tools</x:String>
<x:String x:Key="Text.Repository.Refresh" xml:space="preserve">Refresh</x:String> <x:String x:Key="Text.Repository.Refresh" xml:space="preserve">Refresh</x:String>
<x:String x:Key="Text.Repository.Remotes" xml:space="preserve">REMOTES</x:String> <x:String x:Key="Text.Repository.Remotes" xml:space="preserve">REMOTES</x:String>
<x:String x:Key="Text.Repository.Remotes.Add" xml:space="preserve">ADD REMOTE</x:String> <x:String x:Key="Text.Repository.Remotes.Add" xml:space="preserve">Add Remote</x:String>
<x:String x:Key="Text.Repository.Search" xml:space="preserve">Search Commit</x:String> <x:String x:Key="Text.Repository.Search" xml:space="preserve">Search Commit</x:String>
<x:String x:Key="Text.Repository.Search.ByAuthor" xml:space="preserve">Author</x:String> <x:String x:Key="Text.Repository.Search.ByAuthor" xml:space="preserve">Author</x:String>
<x:String x:Key="Text.Repository.Search.ByCommitter" xml:space="preserve">Committer</x:String> <x:String x:Key="Text.Repository.Search.ByCommitter" xml:space="preserve">Committer</x:String>
@ -614,10 +620,10 @@
<x:String x:Key="Text.Repository.Skip" xml:space="preserve">SKIP</x:String> <x:String x:Key="Text.Repository.Skip" xml:space="preserve">SKIP</x:String>
<x:String x:Key="Text.Repository.Statistics" xml:space="preserve">Statistics</x:String> <x:String x:Key="Text.Repository.Statistics" xml:space="preserve">Statistics</x:String>
<x:String x:Key="Text.Repository.Submodules" xml:space="preserve">SUBMODULES</x:String> <x:String x:Key="Text.Repository.Submodules" xml:space="preserve">SUBMODULES</x:String>
<x:String x:Key="Text.Repository.Submodules.Add" xml:space="preserve">ADD SUBMODULE</x:String> <x:String x:Key="Text.Repository.Submodules.Add" xml:space="preserve">Add Submodule</x:String>
<x:String x:Key="Text.Repository.Submodules.Update" xml:space="preserve">UPDATE SUBMODULE</x:String> <x:String x:Key="Text.Repository.Submodules.Update" xml:space="preserve">Update Submodule</x:String>
<x:String x:Key="Text.Repository.Tags" xml:space="preserve">TAGS</x:String> <x:String x:Key="Text.Repository.Tags" xml:space="preserve">TAGS</x:String>
<x:String x:Key="Text.Repository.Tags.Add" xml:space="preserve">NEW TAG</x:String> <x:String x:Key="Text.Repository.Tags.Add" xml:space="preserve">New Tag</x:String>
<x:String x:Key="Text.Repository.Tags.OrderByCreatorDate" xml:space="preserve">By Creator Date</x:String> <x:String x:Key="Text.Repository.Tags.OrderByCreatorDate" xml:space="preserve">By Creator Date</x:String>
<x:String x:Key="Text.Repository.Tags.OrderByNameAsc" xml:space="preserve">By Name (Ascending)</x:String> <x:String x:Key="Text.Repository.Tags.OrderByNameAsc" xml:space="preserve">By Name (Ascending)</x:String>
<x:String x:Key="Text.Repository.Tags.OrderByNameDes" xml:space="preserve">By Name (Descending)</x:String> <x:String x:Key="Text.Repository.Tags.OrderByNameDes" xml:space="preserve">By Name (Descending)</x:String>
@ -625,9 +631,10 @@
<x:String x:Key="Text.Repository.Terminal" xml:space="preserve">Open in Terminal</x:String> <x:String x:Key="Text.Repository.Terminal" xml:space="preserve">Open in Terminal</x:String>
<x:String x:Key="Text.Repository.UseRelativeTimeInHistories" xml:space="preserve">Use relative time in histories</x:String> <x:String x:Key="Text.Repository.UseRelativeTimeInHistories" xml:space="preserve">Use relative time in histories</x:String>
<x:String x:Key="Text.Repository.ViewLogs" xml:space="preserve">View Logs</x:String> <x:String x:Key="Text.Repository.ViewLogs" xml:space="preserve">View Logs</x:String>
<x:String x:Key="Text.Repository.Visit" xml:space="preserve">Visit '{0}' in Browser</x:String>
<x:String x:Key="Text.Repository.Worktrees" xml:space="preserve">WORKTREES</x:String> <x:String x:Key="Text.Repository.Worktrees" xml:space="preserve">WORKTREES</x:String>
<x:String x:Key="Text.Repository.Worktrees.Add" xml:space="preserve">ADD WORKTREE</x:String> <x:String x:Key="Text.Repository.Worktrees.Add" xml:space="preserve">Add Worktree</x:String>
<x:String x:Key="Text.Repository.Worktrees.Prune" xml:space="preserve">PRUNE</x:String> <x:String x:Key="Text.Repository.Worktrees.Prune" xml:space="preserve">Prune</x:String>
<x:String x:Key="Text.RepositoryURL" xml:space="preserve">Git Repository URL</x:String> <x:String x:Key="Text.RepositoryURL" xml:space="preserve">Git Repository URL</x:String>
<x:String x:Key="Text.Reset" xml:space="preserve">Reset Current Branch To Revision</x:String> <x:String x:Key="Text.Reset" xml:space="preserve">Reset Current Branch To Revision</x:String>
<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>

View file

@ -86,6 +86,7 @@
<x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">Cambios Locales:</x:String> <x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">Cambios Locales:</x:String>
<x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">Descartar</x:String> <x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">Descartar</x:String>
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Stash &amp; Reaplicar</x:String> <x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Stash &amp; Reaplicar</x:String>
<x:String x:Key="Text.Checkout.RecurseSubmodules" xml:space="preserve">Actualizar todos los submódulos</x:String>
<x:String x:Key="Text.Checkout.Target" xml:space="preserve">Rama:</x:String> <x:String x:Key="Text.Checkout.Target" xml:space="preserve">Rama:</x:String>
<x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry Pick</x:String> <x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry Pick</x:String>
<x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">Añadir fuente al mensaje de commit</x:String> <x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">Añadir fuente al mensaje de commit</x:String>
@ -101,7 +102,7 @@
<x:String x:Key="Text.Clone.LocalName" xml:space="preserve">Nombre Local:</x:String> <x:String x:Key="Text.Clone.LocalName" xml:space="preserve">Nombre Local:</x:String>
<x:String x:Key="Text.Clone.LocalName.Placeholder" xml:space="preserve">Nombre del repositorio. Opcional.</x:String> <x:String x:Key="Text.Clone.LocalName.Placeholder" xml:space="preserve">Nombre del repositorio. Opcional.</x:String>
<x:String x:Key="Text.Clone.ParentFolder" xml:space="preserve">Carpeta Padre:</x:String> <x:String x:Key="Text.Clone.ParentFolder" xml:space="preserve">Carpeta Padre:</x:String>
<x:String x:Key="Text.Clone.RecurseSubmodules" xml:space="preserve">Inicializar y actualizar submodulos</x:String> <x:String x:Key="Text.Clone.RecurseSubmodules" xml:space="preserve">Inicializar y actualizar submódulos</x:String>
<x:String x:Key="Text.Clone.RemoteURL" xml:space="preserve">URL del Repositorio:</x:String> <x:String x:Key="Text.Clone.RemoteURL" xml:space="preserve">URL del Repositorio:</x:String>
<x:String x:Key="Text.Close" xml:space="preserve">CERRAR</x:String> <x:String x:Key="Text.Close" xml:space="preserve">CERRAR</x:String>
<x:String x:Key="Text.CodeEditor" xml:space="preserve">Editor</x:String> <x:String x:Key="Text.CodeEditor" xml:space="preserve">Editor</x:String>
@ -326,6 +327,8 @@
<x:String x:Key="Text.GitFlow.FinishHotfix" xml:space="preserve">FLOW - Finalizar Hotfix</x:String> <x:String x:Key="Text.GitFlow.FinishHotfix" xml:space="preserve">FLOW - Finalizar Hotfix</x:String>
<x:String x:Key="Text.GitFlow.FinishRelease" xml:space="preserve">FLOW - Finalizar Release</x:String> <x:String x:Key="Text.GitFlow.FinishRelease" xml:space="preserve">FLOW - Finalizar Release</x:String>
<x:String x:Key="Text.GitFlow.FinishTarget" xml:space="preserve">Destino:</x:String> <x:String x:Key="Text.GitFlow.FinishTarget" xml:space="preserve">Destino:</x:String>
<x:String x:Key="Text.GitFlow.FinishWithPush" xml:space="preserve">Push al/los remoto(s) después de Finalizar</x:String>
<x:String x:Key="Text.GitFlow.FinishWithSquash" xml:space="preserve">Squash durante el merge</x:String>
<x:String x:Key="Text.GitFlow.Hotfix" xml:space="preserve">Hotfix:</x:String> <x:String x:Key="Text.GitFlow.Hotfix" xml:space="preserve">Hotfix:</x:String>
<x:String x:Key="Text.GitFlow.HotfixPrefix" xml:space="preserve">Prefijo de Hotfix:</x:String> <x:String x:Key="Text.GitFlow.HotfixPrefix" xml:space="preserve">Prefijo de Hotfix:</x:String>
<x:String x:Key="Text.GitFlow.Init" xml:space="preserve">Inicializar Git-Flow</x:String> <x:String x:Key="Text.GitFlow.Init" xml:space="preserve">Inicializar Git-Flow</x:String>
@ -575,6 +578,9 @@
<x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">Rama:</x:String> <x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">Rama:</x:String>
<x:String x:Key="Text.Repository.Abort" xml:space="preserve">ABORTAR</x:String> <x:String x:Key="Text.Repository.Abort" xml:space="preserve">ABORTAR</x:String>
<x:String x:Key="Text.Repository.AutoFetching" xml:space="preserve">Auto fetching cambios desde remotos...</x:String> <x:String x:Key="Text.Repository.AutoFetching" xml:space="preserve">Auto fetching cambios desde remotos...</x:String>
<x:String x:Key="Text.Repository.BranchSort" xml:space="preserve">Ordenar</x:String>
<x:String x:Key="Text.Repository.BranchSort.ByCommitterDate" xml:space="preserve">Por Fecha de Committer</x:String>
<x:String x:Key="Text.Repository.BranchSort.ByName" xml:space="preserve">Por Nombre</x:String>
<x:String x:Key="Text.Repository.Clean" xml:space="preserve">Limpiar (GC &amp; Prune)</x:String> <x:String x:Key="Text.Repository.Clean" xml:space="preserve">Limpiar (GC &amp; Prune)</x:String>
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">Ejecutar comando `git gc` para este repositorio.</x:String> <x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">Ejecutar comando `git gc` para este repositorio.</x:String>
<x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">Limpiar todo</x:String> <x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">Limpiar todo</x:String>
@ -629,6 +635,7 @@
<x:String x:Key="Text.Repository.Terminal" xml:space="preserve">Abrir en Terminal</x:String> <x:String x:Key="Text.Repository.Terminal" xml:space="preserve">Abrir en Terminal</x:String>
<x:String x:Key="Text.Repository.UseRelativeTimeInHistories" xml:space="preserve">Usar tiempo relativo en las historias</x:String> <x:String x:Key="Text.Repository.UseRelativeTimeInHistories" xml:space="preserve">Usar tiempo relativo en las historias</x:String>
<x:String x:Key="Text.Repository.ViewLogs" xml:space="preserve">Ver Logs</x:String> <x:String x:Key="Text.Repository.ViewLogs" xml:space="preserve">Ver Logs</x:String>
<x:String x:Key="Text.Repository.Visit" xml:space="preserve">Visitar '{0}' en el Navegador</x:String>
<x:String x:Key="Text.Repository.Worktrees" xml:space="preserve">WORKTREES</x:String> <x:String x:Key="Text.Repository.Worktrees" xml:space="preserve">WORKTREES</x:String>
<x:String x:Key="Text.Repository.Worktrees.Add" xml:space="preserve">AÑADIR WORKTREE</x:String> <x:String x:Key="Text.Repository.Worktrees.Add" xml:space="preserve">AÑADIR WORKTREE</x:String>
<x:String x:Key="Text.Repository.Worktrees.Prune" xml:space="preserve">PRUNE</x:String> <x:String x:Key="Text.Repository.Worktrees.Prune" xml:space="preserve">PRUNE</x:String>

View file

@ -86,6 +86,7 @@
<x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">Локальные изменения:</x:String> <x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">Локальные изменения:</x:String>
<x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">Отклонить</x:String> <x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">Отклонить</x:String>
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Отложить и примненить повторно</x:String> <x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Отложить и примненить повторно</x:String>
<x:String x:Key="Text.Checkout.RecurseSubmodules" xml:space="preserve">Обновить все подкаталоги</x:String>
<x:String x:Key="Text.Checkout.Target" xml:space="preserve">Ветка:</x:String> <x:String x:Key="Text.Checkout.Target" xml:space="preserve">Ветка:</x:String>
<x:String x:Key="Text.CherryPick" xml:space="preserve"> Частичный выбор</x:String> <x:String x:Key="Text.CherryPick" xml:space="preserve"> Частичный выбор</x:String>
<x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">Добавить источник для ревизии сообщения</x:String> <x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">Добавить источник для ревизии сообщения</x:String>
@ -326,6 +327,8 @@
<x:String x:Key="Text.GitFlow.FinishHotfix" xml:space="preserve">ПРОЦЕСС - Закончить исправление</x:String> <x:String x:Key="Text.GitFlow.FinishHotfix" xml:space="preserve">ПРОЦЕСС - Закончить исправление</x:String>
<x:String x:Key="Text.GitFlow.FinishRelease" xml:space="preserve">ПРОЦЕСС - Завершить выпуск</x:String> <x:String x:Key="Text.GitFlow.FinishRelease" xml:space="preserve">ПРОЦЕСС - Завершить выпуск</x:String>
<x:String x:Key="Text.GitFlow.FinishTarget" xml:space="preserve">Цель:</x:String> <x:String x:Key="Text.GitFlow.FinishTarget" xml:space="preserve">Цель:</x:String>
<x:String x:Key="Text.GitFlow.FinishWithPush" xml:space="preserve">Выложить на удалённый(ые) после завершения</x:String>
<x:String x:Key="Text.GitFlow.FinishWithSquash" xml:space="preserve">Втиснуть при слиянии</x:String>
<x:String x:Key="Text.GitFlow.Hotfix" xml:space="preserve">Исправление:</x:String> <x:String x:Key="Text.GitFlow.Hotfix" xml:space="preserve">Исправление:</x:String>
<x:String x:Key="Text.GitFlow.HotfixPrefix" xml:space="preserve">Префикс исправлений:</x:String> <x:String x:Key="Text.GitFlow.HotfixPrefix" xml:space="preserve">Префикс исправлений:</x:String>
<x:String x:Key="Text.GitFlow.Init" xml:space="preserve">Создать Git-процесс</x:String> <x:String x:Key="Text.GitFlow.Init" xml:space="preserve">Создать Git-процесс</x:String>
@ -575,6 +578,9 @@
<x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">Ветка:</x:String> <x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">Ветка:</x:String>
<x:String x:Key="Text.Repository.Abort" xml:space="preserve">Отказ</x:String> <x:String x:Key="Text.Repository.Abort" xml:space="preserve">Отказ</x:String>
<x:String x:Key="Text.Repository.AutoFetching" xml:space="preserve">Автоматическое извлечение изменений с внешних репозиторий...</x:String> <x:String x:Key="Text.Repository.AutoFetching" xml:space="preserve">Автоматическое извлечение изменений с внешних репозиторий...</x:String>
<x:String x:Key="Text.Repository.BranchSort" xml:space="preserve">Сортировать</x:String>
<x:String x:Key="Text.Repository.BranchSort.ByCommitterDate" xml:space="preserve">По дате ревизора (исполнителя)</x:String>
<x:String x:Key="Text.Repository.BranchSort.ByName" xml:space="preserve">По имени</x:String>
<x:String x:Key="Text.Repository.Clean" xml:space="preserve">Очистить (Сбор мусора и удаление) </x:String> <x:String x:Key="Text.Repository.Clean" xml:space="preserve">Очистить (Сбор мусора и удаление) </x:String>
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">Запустить команду (git gc) для данного репозитория.</x:String> <x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">Запустить команду (git gc) для данного репозитория.</x:String>
<x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">Очистить всё</x:String> <x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">Очистить всё</x:String>
@ -628,7 +634,8 @@
<x:String x:Key="Text.Repository.Tags.Sort" xml:space="preserve">Сортировать</x:String> <x:String x:Key="Text.Repository.Tags.Sort" xml:space="preserve">Сортировать</x:String>
<x:String x:Key="Text.Repository.Terminal" xml:space="preserve">Открыть в терминале</x:String> <x:String x:Key="Text.Repository.Terminal" xml:space="preserve">Открыть в терминале</x:String>
<x:String x:Key="Text.Repository.UseRelativeTimeInHistories" xml:space="preserve">Использовать относительное время в историях</x:String> <x:String x:Key="Text.Repository.UseRelativeTimeInHistories" xml:space="preserve">Использовать относительное время в историях</x:String>
<x:String x:Key="Text.Repository.ViewLogs" xml:space="preserve">Просмотр логов</x:String> <x:String x:Key="Text.Repository.ViewLogs" xml:space="preserve">Просмотр журналов</x:String>
<x:String x:Key="Text.Repository.Visit" xml:space="preserve">Посетить '{0}' в браузере</x:String>
<x:String x:Key="Text.Repository.Worktrees" xml:space="preserve">РАБОЧИЕ КАТАЛОГИ</x:String> <x:String x:Key="Text.Repository.Worktrees" xml:space="preserve">РАБОЧИЕ КАТАЛОГИ</x:String>
<x:String x:Key="Text.Repository.Worktrees.Add" xml:space="preserve">ДОБАВИТЬ РАБОЧИЙ КАТАЛОГ</x:String> <x:String x:Key="Text.Repository.Worktrees.Add" xml:space="preserve">ДОБАВИТЬ РАБОЧИЙ КАТАЛОГ</x:String>
<x:String x:Key="Text.Repository.Worktrees.Prune" xml:space="preserve">ОБРЕЗАТЬ</x:String> <x:String x:Key="Text.Repository.Worktrees.Prune" xml:space="preserve">ОБРЕЗАТЬ</x:String>
@ -714,7 +721,7 @@
<x:String x:Key="Text.UpdateSubmodules.Target" xml:space="preserve">Подмодуль:</x:String> <x:String x:Key="Text.UpdateSubmodules.Target" xml:space="preserve">Подмодуль:</x:String>
<x:String x:Key="Text.UpdateSubmodules.UseRemote" xml:space="preserve">Использовать опцию (--remote)</x:String> <x:String x:Key="Text.UpdateSubmodules.UseRemote" xml:space="preserve">Использовать опцию (--remote)</x:String>
<x:String x:Key="Text.URL" xml:space="preserve">Сетевой адрес:</x:String> <x:String x:Key="Text.URL" xml:space="preserve">Сетевой адрес:</x:String>
<x:String x:Key="Text.ViewLogs" xml:space="preserve">Логи</x:String> <x:String x:Key="Text.ViewLogs" xml:space="preserve">Журналы</x:String>
<x:String x:Key="Text.ViewLogs.Clear" xml:space="preserve">ОЧИСТИТЬ ВСЁ</x:String> <x:String x:Key="Text.ViewLogs.Clear" xml:space="preserve">ОЧИСТИТЬ ВСЁ</x:String>
<x:String x:Key="Text.ViewLogs.CopyLog" xml:space="preserve">Копировать</x:String> <x:String x:Key="Text.ViewLogs.CopyLog" xml:space="preserve">Копировать</x:String>
<x:String x:Key="Text.ViewLogs.Delete" xml:space="preserve">Удалить</x:String> <x:String x:Key="Text.ViewLogs.Delete" xml:space="preserve">Удалить</x:String>

View file

@ -86,6 +86,7 @@
<x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">未提交更改 </x:String> <x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">未提交更改 </x:String>
<x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">丢弃更改</x:String> <x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">丢弃更改</x:String>
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">贮藏并自动恢复</x:String> <x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">贮藏并自动恢复</x:String>
<x:String x:Key="Text.Checkout.RecurseSubmodules" xml:space="preserve">同时更新所有子模块</x:String>
<x:String x:Key="Text.Checkout.Target" xml:space="preserve">目标分支 </x:String> <x:String x:Key="Text.Checkout.Target" xml:space="preserve">目标分支 </x:String>
<x:String x:Key="Text.CherryPick" xml:space="preserve">挑选提交</x:String> <x:String x:Key="Text.CherryPick" xml:space="preserve">挑选提交</x:String>
<x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">提交信息中追加来源信息</x:String> <x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">提交信息中追加来源信息</x:String>
@ -326,6 +327,8 @@
<x:String x:Key="Text.GitFlow.FinishHotfix" xml:space="preserve">结束修复分支</x:String> <x:String x:Key="Text.GitFlow.FinishHotfix" xml:space="preserve">结束修复分支</x:String>
<x:String x:Key="Text.GitFlow.FinishRelease" xml:space="preserve">结束版本分支</x:String> <x:String x:Key="Text.GitFlow.FinishRelease" xml:space="preserve">结束版本分支</x:String>
<x:String x:Key="Text.GitFlow.FinishTarget" xml:space="preserve">目标分支 </x:String> <x:String x:Key="Text.GitFlow.FinishTarget" xml:space="preserve">目标分支 </x:String>
<x:String x:Key="Text.GitFlow.FinishWithPush" xml:space="preserve">完成后自动推送</x:String>
<x:String x:Key="Text.GitFlow.FinishWithSquash" xml:space="preserve">压缩变更为单一提交后合并分支</x:String>
<x:String x:Key="Text.GitFlow.Hotfix" xml:space="preserve">修复分支 </x:String> <x:String x:Key="Text.GitFlow.Hotfix" xml:space="preserve">修复分支 </x:String>
<x:String x:Key="Text.GitFlow.HotfixPrefix" xml:space="preserve">修复分支名前缀 </x:String> <x:String x:Key="Text.GitFlow.HotfixPrefix" xml:space="preserve">修复分支名前缀 </x:String>
<x:String x:Key="Text.GitFlow.Init" xml:space="preserve">初始化GIT工作流</x:String> <x:String x:Key="Text.GitFlow.Init" xml:space="preserve">初始化GIT工作流</x:String>
@ -575,6 +578,9 @@
<x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">分支 </x:String> <x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">分支 </x:String>
<x:String x:Key="Text.Repository.Abort" xml:space="preserve">终止合并</x:String> <x:String x:Key="Text.Repository.Abort" xml:space="preserve">终止合并</x:String>
<x:String x:Key="Text.Repository.AutoFetching" xml:space="preserve">自动拉取远端变更中...</x:String> <x:String x:Key="Text.Repository.AutoFetching" xml:space="preserve">自动拉取远端变更中...</x:String>
<x:String x:Key="Text.Repository.BranchSort" xml:space="preserve">排序方式</x:String>
<x:String x:Key="Text.Repository.BranchSort.ByCommitterDate" xml:space="preserve">按提交时间</x:String>
<x:String x:Key="Text.Repository.BranchSort.ByName" xml:space="preserve">按名称</x:String>
<x:String x:Key="Text.Repository.Clean" xml:space="preserve">清理本仓库(GC)</x:String> <x:String x:Key="Text.Repository.Clean" xml:space="preserve">清理本仓库(GC)</x:String>
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">本操作将执行`git gc`命令。</x:String> <x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">本操作将执行`git gc`命令。</x:String>
<x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">清空过滤规则</x:String> <x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">清空过滤规则</x:String>
@ -629,6 +635,7 @@
<x:String x:Key="Text.Repository.Terminal" xml:space="preserve">在终端中打开</x:String> <x:String x:Key="Text.Repository.Terminal" xml:space="preserve">在终端中打开</x:String>
<x:String x:Key="Text.Repository.UseRelativeTimeInHistories" xml:space="preserve">在提交列表中使用相对时间</x:String> <x:String x:Key="Text.Repository.UseRelativeTimeInHistories" xml:space="preserve">在提交列表中使用相对时间</x:String>
<x:String x:Key="Text.Repository.ViewLogs" xml:space="preserve">查看命令日志</x:String> <x:String x:Key="Text.Repository.ViewLogs" xml:space="preserve">查看命令日志</x:String>
<x:String x:Key="Text.Repository.Visit" xml:space="preserve">访问远程仓库 '{0}'</x:String>
<x:String x:Key="Text.Repository.Worktrees" xml:space="preserve">工作树列表</x:String> <x:String x:Key="Text.Repository.Worktrees" xml:space="preserve">工作树列表</x:String>
<x:String x:Key="Text.Repository.Worktrees.Add" xml:space="preserve">新增工作树</x:String> <x:String x:Key="Text.Repository.Worktrees.Add" xml:space="preserve">新增工作树</x:String>
<x:String x:Key="Text.Repository.Worktrees.Prune" xml:space="preserve">清理</x:String> <x:String x:Key="Text.Repository.Worktrees.Prune" xml:space="preserve">清理</x:String>

View file

@ -86,6 +86,7 @@
<x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">未提交變更:</x:String> <x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">未提交變更:</x:String>
<x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">捨棄變更</x:String> <x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">捨棄變更</x:String>
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">擱置變更並自動復原</x:String> <x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">擱置變更並自動復原</x:String>
<x:String x:Key="Text.Checkout.RecurseSubmodules" xml:space="preserve">同時更新所有子模組</x:String>
<x:String x:Key="Text.Checkout.Target" xml:space="preserve">目標分支:</x:String> <x:String x:Key="Text.Checkout.Target" xml:space="preserve">目標分支:</x:String>
<x:String x:Key="Text.CherryPick" xml:space="preserve">揀選提交</x:String> <x:String x:Key="Text.CherryPick" xml:space="preserve">揀選提交</x:String>
<x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">提交資訊中追加來源資訊</x:String> <x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">提交資訊中追加來源資訊</x:String>
@ -326,6 +327,8 @@
<x:String x:Key="Text.GitFlow.FinishHotfix" xml:space="preserve">完成修復分支</x:String> <x:String x:Key="Text.GitFlow.FinishHotfix" xml:space="preserve">完成修復分支</x:String>
<x:String x:Key="Text.GitFlow.FinishRelease" xml:space="preserve">完成發行分支</x:String> <x:String x:Key="Text.GitFlow.FinishRelease" xml:space="preserve">完成發行分支</x:String>
<x:String x:Key="Text.GitFlow.FinishTarget" xml:space="preserve">目標分支:</x:String> <x:String x:Key="Text.GitFlow.FinishTarget" xml:space="preserve">目標分支:</x:String>
<x:String x:Key="Text.GitFlow.FinishWithPush" xml:space="preserve">完成後自動推送</x:String>
<x:String x:Key="Text.GitFlow.FinishWithSquash" xml:space="preserve">壓縮為單一提交後合併</x:String>
<x:String x:Key="Text.GitFlow.Hotfix" xml:space="preserve">修復分支:</x:String> <x:String x:Key="Text.GitFlow.Hotfix" xml:space="preserve">修復分支:</x:String>
<x:String x:Key="Text.GitFlow.HotfixPrefix" xml:space="preserve">修復分支前置詞:</x:String> <x:String x:Key="Text.GitFlow.HotfixPrefix" xml:space="preserve">修復分支前置詞:</x:String>
<x:String x:Key="Text.GitFlow.Init" xml:space="preserve">初始化 Git 工作流</x:String> <x:String x:Key="Text.GitFlow.Init" xml:space="preserve">初始化 Git 工作流</x:String>
@ -575,6 +578,9 @@
<x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">分支:</x:String> <x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">分支:</x:String>
<x:String x:Key="Text.Repository.Abort" xml:space="preserve">中止</x:String> <x:String x:Key="Text.Repository.Abort" xml:space="preserve">中止</x:String>
<x:String x:Key="Text.Repository.AutoFetching" xml:space="preserve">自動提取遠端變更中...</x:String> <x:String x:Key="Text.Repository.AutoFetching" xml:space="preserve">自動提取遠端變更中...</x:String>
<x:String x:Key="Text.Repository.BranchSort" xml:space="preserve">排序</x:String>
<x:String x:Key="Text.Repository.BranchSort.ByCommitterDate" xml:space="preserve">依建立時間</x:String>
<x:String x:Key="Text.Repository.BranchSort.ByName" xml:space="preserve">依名稱升序</x:String>
<x:String x:Key="Text.Repository.Clean" xml:space="preserve">清理本存放庫 (GC)</x:String> <x:String x:Key="Text.Repository.Clean" xml:space="preserve">清理本存放庫 (GC)</x:String>
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">本操作將執行 `git gc` 命令。</x:String> <x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">本操作將執行 `git gc` 命令。</x:String>
<x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">清空篩選規則</x:String> <x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">清空篩選規則</x:String>
@ -629,6 +635,7 @@
<x:String x:Key="Text.Repository.Terminal" xml:space="preserve">在終端機中開啟</x:String> <x:String x:Key="Text.Repository.Terminal" xml:space="preserve">在終端機中開啟</x:String>
<x:String x:Key="Text.Repository.UseRelativeTimeInHistories" xml:space="preserve">在提交列表中使用相對時間</x:String> <x:String x:Key="Text.Repository.UseRelativeTimeInHistories" xml:space="preserve">在提交列表中使用相對時間</x:String>
<x:String x:Key="Text.Repository.ViewLogs" xml:space="preserve">檢視 Git 指令記錄</x:String> <x:String x:Key="Text.Repository.ViewLogs" xml:space="preserve">檢視 Git 指令記錄</x:String>
<x:String x:Key="Text.Repository.Visit" xml:space="preserve">檢視遠端存放庫 '{0}'</x:String>
<x:String x:Key="Text.Repository.Worktrees" xml:space="preserve">工作區列表</x:String> <x:String x:Key="Text.Repository.Worktrees" xml:space="preserve">工作區列表</x:String>
<x:String x:Key="Text.Repository.Worktrees.Add" xml:space="preserve">新增工作區</x:String> <x:String x:Key="Text.Repository.Worktrees.Add" xml:space="preserve">新增工作區</x:String>
<x:String x:Key="Text.Repository.Worktrees.Prune" xml:space="preserve">清理</x:String> <x:String x:Key="Text.Repository.Worktrees.Prune" xml:space="preserve">清理</x:String>

View file

@ -25,7 +25,7 @@
<Color x:Key="Color.Diff.AddedHighlight">#A7E1A7</Color> <Color x:Key="Color.Diff.AddedHighlight">#A7E1A7</Color>
<Color x:Key="Color.Diff.DeletedHighlight">#F19B9D</Color> <Color x:Key="Color.Diff.DeletedHighlight">#F19B9D</Color>
<Color x:Key="Color.Link">#0000EE</Color> <Color x:Key="Color.Link">#0000EE</Color>
<Color x:Key="Color.InlineCode">#FFE5E5E5</Color> <Color x:Key="Color.InlineCode">#FFE4E4E4</Color>
</ResourceDictionary> </ResourceDictionary>
<ResourceDictionary x:Key="Dark"> <ResourceDictionary x:Key="Dark">
@ -52,7 +52,7 @@
<Color x:Key="Color.Diff.AddedHighlight">#A0308D3C</Color> <Color x:Key="Color.Diff.AddedHighlight">#A0308D3C</Color>
<Color x:Key="Color.Diff.DeletedHighlight">#A09F4247</Color> <Color x:Key="Color.Diff.DeletedHighlight">#A09F4247</Color>
<Color x:Key="Color.Link">#4DAAFC</Color> <Color x:Key="Color.Link">#4DAAFC</Color>
<Color x:Key="Color.InlineCode">#FF2E2E2E</Color> <Color x:Key="Color.InlineCode">#FF383838</Color>
</ResourceDictionary> </ResourceDictionary>
</ResourceDictionary.ThemeDictionaries> </ResourceDictionary.ThemeDictionaries>

View file

@ -10,6 +10,7 @@ namespace SourceGit.ViewModels
public string Name { get; private set; } = string.Empty; public string Name { get; private set; } = string.Empty;
public string Path { get; private set; } = string.Empty; public string Path { get; private set; } = string.Empty;
public object Backend { get; private set; } = null; public object Backend { get; private set; } = null;
public ulong TimeToSort { get; private set; } = 0;
public int Depth { get; set; } = 0; public int Depth { get; set; } = 0;
public bool IsSelected { get; set; } = false; public bool IsSelected { get; set; } = false;
public List<BranchTreeNode> Children { get; private set; } = new List<BranchTreeNode>(); public List<BranchTreeNode> Children { get; private set; } = new List<BranchTreeNode>();
@ -62,6 +63,12 @@ namespace SourceGit.ViewModels
public List<BranchTreeNode> Remotes => _remotes; public List<BranchTreeNode> Remotes => _remotes;
public List<string> InvalidExpandedNodes => _invalidExpandedNodes; public List<string> InvalidExpandedNodes => _invalidExpandedNodes;
public Builder(Models.BranchSortMode localSortMode, Models.BranchSortMode remoteSortMode)
{
_localSortMode = localSortMode;
_remoteSortMode = remoteSortMode;
}
public void SetExpandedNodes(List<string> expanded) public void SetExpandedNodes(List<string> expanded)
{ {
foreach (var node in expanded) foreach (var node in expanded)
@ -72,6 +79,7 @@ namespace SourceGit.ViewModels
{ {
var folders = new Dictionary<string, BranchTreeNode>(); var folders = new Dictionary<string, BranchTreeNode>();
var fakeRemoteTime = (ulong)remotes.Count;
foreach (var remote in remotes) foreach (var remote in remotes)
{ {
var path = $"refs/remotes/{remote.Name}"; var path = $"refs/remotes/{remote.Name}";
@ -81,8 +89,10 @@ namespace SourceGit.ViewModels
Path = path, Path = path,
Backend = remote, Backend = remote,
IsExpanded = bForceExpanded || _expanded.Contains(path), IsExpanded = bForceExpanded || _expanded.Contains(path),
TimeToSort = fakeRemoteTime,
}; };
fakeRemoteTime--;
folders.Add(path, node); folders.Add(path, node);
_remotes.Add(node); _remotes.Add(node);
} }
@ -108,12 +118,21 @@ namespace SourceGit.ViewModels
} }
folders.Clear(); folders.Clear();
SortNodes(_locals);
SortNodes(_remotes); if (_localSortMode == Models.BranchSortMode.Name)
SortNodesByName(_locals);
else
SortNodesByTime(_locals);
if (_remoteSortMode == Models.BranchSortMode.Name)
SortNodesByName(_remotes);
else
SortNodesByTime(_remotes);
} }
private void MakeBranchNode(Models.Branch branch, List<BranchTreeNode> roots, Dictionary<string, BranchTreeNode> folders, string prefix, bool bForceExpanded) private void MakeBranchNode(Models.Branch branch, List<BranchTreeNode> roots, Dictionary<string, BranchTreeNode> folders, string prefix, bool bForceExpanded)
{ {
var time = branch.CommitterDate;
var fullpath = $"{prefix}/{branch.Name}"; var fullpath = $"{prefix}/{branch.Name}";
var sepIdx = branch.Name.IndexOf('/', StringComparison.Ordinal); var sepIdx = branch.Name.IndexOf('/', StringComparison.Ordinal);
if (sepIdx == -1 || branch.IsDetachedHead) if (sepIdx == -1 || branch.IsDetachedHead)
@ -124,6 +143,7 @@ namespace SourceGit.ViewModels
Path = fullpath, Path = fullpath,
Backend = branch, Backend = branch,
IsExpanded = false, IsExpanded = false,
TimeToSort = time,
}); });
return; return;
} }
@ -138,6 +158,7 @@ namespace SourceGit.ViewModels
if (folders.TryGetValue(folder, out var val)) if (folders.TryGetValue(folder, out var val))
{ {
lastFolder = val; lastFolder = val;
lastFolder.TimeToSort = Math.Max(lastFolder.TimeToSort, time);
if (!lastFolder.IsExpanded) if (!lastFolder.IsExpanded)
lastFolder.IsExpanded |= (branch.IsCurrent || _expanded.Contains(folder)); lastFolder.IsExpanded |= (branch.IsCurrent || _expanded.Contains(folder));
} }
@ -148,6 +169,7 @@ namespace SourceGit.ViewModels
Name = name, Name = name,
Path = folder, Path = folder,
IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder), IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder),
TimeToSort = time,
}; };
roots.Add(lastFolder); roots.Add(lastFolder);
folders.Add(folder, lastFolder); folders.Add(folder, lastFolder);
@ -159,6 +181,7 @@ namespace SourceGit.ViewModels
Name = name, Name = name,
Path = folder, Path = folder,
IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder), IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder),
TimeToSort = time,
}; };
lastFolder.Children.Add(cur); lastFolder.Children.Add(cur);
folders.Add(folder, cur); folders.Add(folder, cur);
@ -175,10 +198,11 @@ namespace SourceGit.ViewModels
Path = fullpath, Path = fullpath,
Backend = branch, Backend = branch,
IsExpanded = false, IsExpanded = false,
TimeToSort = time,
}); });
} }
private void SortNodes(List<BranchTreeNode> nodes) private void SortNodesByName(List<BranchTreeNode> nodes)
{ {
nodes.Sort((l, r) => nodes.Sort((l, r) =>
{ {
@ -192,9 +216,39 @@ namespace SourceGit.ViewModels
}); });
foreach (var node in nodes) foreach (var node in nodes)
SortNodes(node.Children); SortNodesByName(node.Children);
} }
private void SortNodesByTime(List<BranchTreeNode> nodes)
{
nodes.Sort((l, r) =>
{
if (l.Backend is Models.Branch { IsDetachedHead: true })
return -1;
if (l.Backend is Models.Branch)
{
if (r.Backend is Models.Branch)
return r.TimeToSort == l.TimeToSort ? Models.NumericSort.Compare(l.Name, r.Name) : r.TimeToSort.CompareTo(l.TimeToSort);
else
return 1;
}
if (r.Backend is Models.Branch)
return -1;
if (r.TimeToSort == l.TimeToSort)
return Models.NumericSort.Compare(l.Name, r.Name);
return r.TimeToSort.CompareTo(l.TimeToSort);
});
foreach (var node in nodes)
SortNodesByTime(node.Children);
}
private readonly Models.BranchSortMode _localSortMode = Models.BranchSortMode.Name;
private readonly Models.BranchSortMode _remoteSortMode = Models.BranchSortMode.Name;
private readonly List<BranchTreeNode> _locals = new List<BranchTreeNode>(); private readonly List<BranchTreeNode> _locals = new List<BranchTreeNode>();
private readonly List<BranchTreeNode> _remotes = new List<BranchTreeNode>(); private readonly List<BranchTreeNode> _remotes = new List<BranchTreeNode>();
private readonly List<string> _invalidExpandedNodes = new List<string>(); private readonly List<string> _invalidExpandedNodes = new List<string>();

View file

@ -15,11 +15,24 @@ namespace SourceGit.ViewModels
set; set;
} }
public bool IsRecurseSubmoduleVisible
{
get;
private set;
}
public bool RecurseSubmodules
{
get => _repo.Settings.UpdateSubmodulesOnCheckoutBranch;
set => _repo.Settings.UpdateSubmodulesOnCheckoutBranch = value;
}
public Checkout(Repository repo, string branch) public Checkout(Repository repo, string branch)
{ {
_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()
@ -30,19 +43,22 @@ namespace SourceGit.ViewModels
var log = _repo.CreateLog($"Checkout '{Branch}'"); var log = _repo.CreateLog($"Checkout '{Branch}'");
Use(log); Use(log);
var updateSubmodules = IsRecurseSubmoduleVisible && RecurseSubmodules;
return Task.Run(() => return Task.Run(() =>
{ {
var changes = new Commands.CountLocalChangesWithoutUntracked(_repo.FullPath).Result(); var succ = false;
var needPopStash = false; var needPopStash = false;
if (changes > 0)
{
if (DiscardLocalChanges) if (DiscardLocalChanges)
{ {
Commands.Discard.All(_repo.FullPath, false, log); succ = new Commands.Checkout(_repo.FullPath).Use(log).Branch(Branch, true);
} }
else else
{ {
var succ = new Commands.Stash(_repo.FullPath).Use(log).Push("CHECKOUT_AUTO_STASH"); var changes = new Commands.CountLocalChangesWithoutUntracked(_repo.FullPath).Result();
if (changes > 0)
{
succ = new Commands.Stash(_repo.FullPath).Use(log).Push("CHECKOUT_AUTO_STASH");
if (!succ) if (!succ)
{ {
log.Complete(); log.Complete();
@ -52,11 +68,22 @@ namespace SourceGit.ViewModels
needPopStash = true; needPopStash = true;
} }
succ = new Commands.Checkout(_repo.FullPath).Use(log).Branch(Branch, false);
}
if (succ)
{
if (updateSubmodules)
{
var submodules = new Commands.QuerySubmodules(_repo.FullPath).Result();
if (submodules.Count > 0)
new Commands.Submodule(_repo.FullPath).Use(log).Update(submodules, true, true, false);
} }
var rs = new Commands.Checkout(_repo.FullPath).Use(log).Branch(Branch);
if (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();
@ -73,7 +100,7 @@ namespace SourceGit.ViewModels
}); });
Task.Delay(400).Wait(); Task.Delay(400).Wait();
return rs; return succ;
}); });
} }

View file

@ -15,11 +15,24 @@ namespace SourceGit.ViewModels
set; set;
} }
public bool IsRecurseSubmoduleVisible
{
get;
private set;
}
public bool RecurseSubmodules
{
get => _repo.Settings.UpdateSubmodulesOnCheckoutBranch;
set => _repo.Settings.UpdateSubmodulesOnCheckoutBranch = value;
}
public CheckoutCommit(Repository repo, Models.Commit commit) public CheckoutCommit(Repository repo, Models.Commit commit)
{ {
_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()
@ -30,19 +43,22 @@ namespace SourceGit.ViewModels
var log = _repo.CreateLog("Checkout Commit"); var log = _repo.CreateLog("Checkout Commit");
Use(log); Use(log);
var updateSubmodules = IsRecurseSubmoduleVisible && RecurseSubmodules;
return Task.Run(() => return Task.Run(() =>
{ {
var changes = new Commands.CountLocalChangesWithoutUntracked(_repo.FullPath).Result(); var succ = false;
var needPopStash = false; var needPop = false;
if (changes > 0)
{
if (DiscardLocalChanges) if (DiscardLocalChanges)
{ {
Commands.Discard.All(_repo.FullPath, false, log); succ = new Commands.Checkout(_repo.FullPath).Use(log).Commit(Commit.SHA, true);
} }
else else
{ {
var succ = new Commands.Stash(_repo.FullPath).Use(log).Push("CHECKOUT_AUTO_STASH"); var changes = new Commands.CountLocalChangesWithoutUntracked(_repo.FullPath).Result();
if (changes > 0)
{
succ = new Commands.Stash(_repo.FullPath).Use(log).Push("CHECKOUT_AUTO_STASH");
if (!succ) if (!succ)
{ {
log.Complete(); log.Complete();
@ -50,17 +66,28 @@ namespace SourceGit.ViewModels
return false; return false;
} }
needPopStash = true; needPop = true;
}
} }
var rs = new Commands.Checkout(_repo.FullPath).Use(log).Commit(Commit.SHA); succ = new Commands.Checkout(_repo.FullPath).Use(log).Commit(Commit.SHA, false);
if (needPopStash) }
rs = new Commands.Stash(_repo.FullPath).Use(log).Pop("stash@{0}");
if (succ)
{
if (updateSubmodules)
{
var submodules = new Commands.QuerySubmodules(_repo.FullPath).Result();
if (submodules.Count > 0)
new Commands.Submodule(_repo.FullPath).Use(log).Update(submodules, true, true, false);
}
if (needPop)
new Commands.Stash(_repo.FullPath).Use(log).Pop("stash@{0}");
}
log.Complete(); log.Complete();
CallUIThread(() => _repo.SetWatcherEnabled(true)); CallUIThread(() => _repo.SetWatcherEnabled(true));
return rs; return succ;
}); });
} }

View file

@ -101,7 +101,6 @@ namespace SourceGit.ViewModels
{ {
ProgressDescription = "Clone ..."; ProgressDescription = "Clone ...";
// Create a temp log.
var log = new CommandLog("Clone"); var log = new CommandLog("Clone");
Use(log); Use(log);
@ -139,12 +138,11 @@ namespace SourceGit.ViewModels
config.Set("remote.origin.sshkey", _sshKey); config.Set("remote.origin.sshkey", _sshKey);
} }
// individually update submodule (if any)
if (InitAndUpdateSubmodules) if (InitAndUpdateSubmodules)
{ {
var submoduleList = new Commands.QuerySubmodules(path).Result(); var submodules = new Commands.QuerySubmodules(path).Result();
foreach (var submodule in submoduleList) if (submodules.Count > 0)
new Commands.Submodule(path).Use(log).Update(submodule.Path, true, true, false); new Commands.Submodule(path).Use(log).Update(submodules, true, true, false);
} }
log.Complete(); log.Complete();

View file

@ -291,7 +291,7 @@ namespace SourceGit.ViewModels
ev.Handled = true; ev.Handled = true;
}; };
var fullPath = Path.Combine(_repo.FullPath, change.Path); var fullPath = Native.OS.GetAbsPath(_repo.FullPath, change.Path);
var explore = new MenuItem(); var explore = new MenuItem();
explore.Header = App.Text("RevealFile"); explore.Header = App.Text("RevealFile");
explore.Icon = App.CreateMenuIcon("Icons.Explore"); explore.Icon = App.CreateMenuIcon("Icons.Explore");
@ -362,11 +362,9 @@ namespace SourceGit.ViewModels
var resetToThisRevision = new MenuItem(); var resetToThisRevision = new MenuItem();
resetToThisRevision.Header = App.Text("ChangeCM.CheckoutThisRevision"); resetToThisRevision.Header = App.Text("ChangeCM.CheckoutThisRevision");
resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout"); resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout");
resetToThisRevision.Click += (_, ev) => resetToThisRevision.Click += async (_, ev) =>
{ {
var log = _repo.CreateLog($"Reset File to '{_commit.SHA}'"); await ResetToThisRevision(change.Path);
new Commands.Checkout(_repo.FullPath).Use(log).FileWithRevision(change.Path, $"{_commit.SHA}");
log.Complete();
ev.Handled = true; ev.Handled = true;
}; };
@ -374,14 +372,9 @@ namespace SourceGit.ViewModels
resetToFirstParent.Header = App.Text("ChangeCM.CheckoutFirstParentRevision"); resetToFirstParent.Header = App.Text("ChangeCM.CheckoutFirstParentRevision");
resetToFirstParent.Icon = App.CreateMenuIcon("Icons.File.Checkout"); resetToFirstParent.Icon = App.CreateMenuIcon("Icons.File.Checkout");
resetToFirstParent.IsEnabled = _commit.Parents.Count > 0; resetToFirstParent.IsEnabled = _commit.Parents.Count > 0;
resetToFirstParent.Click += (_, ev) => resetToFirstParent.Click += async (_, ev) =>
{ {
var log = _repo.CreateLog($"Reset File to '{_commit.SHA}~1'"); await ResetToParentRevision(change);
if (change.Index == Models.ChangeState.Renamed)
new Commands.Checkout(_repo.FullPath).Use(log).FileWithRevision(change.OriginalPath, $"{_commit.SHA}~1");
new Commands.Checkout(_repo.FullPath).Use(log).FileWithRevision(change.Path, $"{_commit.SHA}~1");
log.Complete();
ev.Handled = true; ev.Handled = true;
}; };
@ -389,8 +382,7 @@ namespace SourceGit.ViewModels
menu.Items.Add(resetToFirstParent); menu.Items.Add(resetToFirstParent);
menu.Items.Add(new MenuItem { Header = "-" }); menu.Items.Add(new MenuItem { Header = "-" });
if (File.Exists(Path.Combine(fullPath))) TryToAddContextMenuItemsForGitLFS(menu, fullPath, change.Path);
TryToAddContextMenuItemsForGitLFS(menu, change.Path);
} }
var copyPath = new MenuItem(); var copyPath = new MenuItem();
@ -407,7 +399,7 @@ namespace SourceGit.ViewModels
copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy"); copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy");
copyFullPath.Click += (_, e) => copyFullPath.Click += (_, e) =>
{ {
App.CopyText(Native.OS.GetAbsPath(_repo.FullPath, change.Path)); App.CopyText(fullPath);
e.Handled = true; e.Handled = true;
}; };
@ -419,7 +411,7 @@ namespace SourceGit.ViewModels
public ContextMenu CreateRevisionFileContextMenu(Models.Object file) public ContextMenu CreateRevisionFileContextMenu(Models.Object file)
{ {
var menu = new ContextMenu(); var menu = new ContextMenu();
var fullPath = Path.Combine(_repo.FullPath, file.Path); var fullPath = Native.OS.GetAbsPath(_repo.FullPath, file.Path);
var explore = new MenuItem(); var explore = new MenuItem();
explore.Header = App.Text("RevealFile"); explore.Header = App.Text("RevealFile");
explore.Icon = App.CreateMenuIcon("Icons.Explore"); explore.Icon = App.CreateMenuIcon("Icons.Explore");
@ -499,29 +491,25 @@ namespace SourceGit.ViewModels
menu.Items.Add(blame); menu.Items.Add(blame);
menu.Items.Add(new MenuItem() { Header = "-" }); menu.Items.Add(new MenuItem() { Header = "-" });
if (!_repo.IsBare)
{
var resetToThisRevision = new MenuItem(); var resetToThisRevision = new MenuItem();
resetToThisRevision.Header = App.Text("ChangeCM.CheckoutThisRevision"); resetToThisRevision.Header = App.Text("ChangeCM.CheckoutThisRevision");
resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout"); resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout");
resetToThisRevision.IsEnabled = File.Exists(fullPath); resetToThisRevision.Click += async (_, ev) =>
resetToThisRevision.Click += (_, ev) =>
{ {
var log = _repo.CreateLog($"Reset File to '{_commit.SHA}'"); await ResetToThisRevision(file.Path);
new Commands.Checkout(_repo.FullPath).Use(log).FileWithRevision(file.Path, $"{_commit.SHA}");
log.Complete();
ev.Handled = true; ev.Handled = true;
}; };
var change = _changes.Find(x => x.Path == file.Path) ?? new Models.Change() { Index = Models.ChangeState.None, Path = file.Path };
var resetToFirstParent = new MenuItem(); var resetToFirstParent = new MenuItem();
resetToFirstParent.Header = App.Text("ChangeCM.CheckoutFirstParentRevision"); resetToFirstParent.Header = App.Text("ChangeCM.CheckoutFirstParentRevision");
resetToFirstParent.Icon = App.CreateMenuIcon("Icons.File.Checkout"); resetToFirstParent.Icon = App.CreateMenuIcon("Icons.File.Checkout");
var fileInChanges = _changes.Find(x => x.Path == file.Path); resetToFirstParent.IsEnabled = _commit.Parents.Count > 0;
var fileIndex = fileInChanges?.Index; resetToFirstParent.Click += async (_, ev) =>
resetToFirstParent.IsEnabled = _commit.Parents.Count > 0 && fileIndex != Models.ChangeState.Renamed;
resetToFirstParent.Click += (_, ev) =>
{ {
var log = _repo.CreateLog($"Reset File to '{_commit.SHA}~1'"); await ResetToParentRevision(change);
new Commands.Checkout(_repo.FullPath).Use(log).FileWithRevision(file.Path, $"{_commit.SHA}~1");
log.Complete();
ev.Handled = true; ev.Handled = true;
}; };
@ -529,8 +517,8 @@ namespace SourceGit.ViewModels
menu.Items.Add(resetToFirstParent); menu.Items.Add(resetToFirstParent);
menu.Items.Add(new MenuItem() { Header = "-" }); menu.Items.Add(new MenuItem() { Header = "-" });
if (File.Exists(Path.Combine(fullPath))) TryToAddContextMenuItemsForGitLFS(menu, fullPath, file.Path);
TryToAddContextMenuItemsForGitLFS(menu, file.Path); }
var copyPath = new MenuItem(); var copyPath = new MenuItem();
copyPath.Header = App.Text("CopyPath"); copyPath.Header = App.Text("CopyPath");
@ -546,7 +534,7 @@ namespace SourceGit.ViewModels
copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy"); copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy");
copyFullPath.Click += (_, e) => copyFullPath.Click += (_, e) =>
{ {
App.CopyText(Native.OS.GetAbsPath(_repo.FullPath, file.Path)); App.CopyText(fullPath);
e.Handled = true; e.Handled = true;
}; };
@ -725,8 +713,11 @@ namespace SourceGit.ViewModels
} }
} }
private void TryToAddContextMenuItemsForGitLFS(ContextMenu menu, string path) private void TryToAddContextMenuItemsForGitLFS(ContextMenu menu, string fullPath, string path)
{ {
if (_repo.Remotes.Count == 0 || !File.Exists(fullPath))
return;
var lfsEnabled = new Commands.LFS(_repo.FullPath).IsEnabled(); var lfsEnabled = new Commands.LFS(_repo.FullPath).IsEnabled();
if (!lfsEnabled) if (!lfsEnabled)
return; return;
@ -738,7 +729,6 @@ namespace SourceGit.ViewModels
var lfsLock = new MenuItem(); var lfsLock = new MenuItem();
lfsLock.Header = App.Text("GitLFS.Locks.Lock"); lfsLock.Header = App.Text("GitLFS.Locks.Lock");
lfsLock.Icon = App.CreateMenuIcon("Icons.Lock"); lfsLock.Icon = App.CreateMenuIcon("Icons.Lock");
lfsLock.IsEnabled = _repo.Remotes.Count > 0;
if (_repo.Remotes.Count == 1) if (_repo.Remotes.Count == 1)
{ {
lfsLock.Click += async (_, e) => lfsLock.Click += async (_, e) =>
@ -777,7 +767,6 @@ namespace SourceGit.ViewModels
var lfsUnlock = new MenuItem(); var lfsUnlock = new MenuItem();
lfsUnlock.Header = App.Text("GitLFS.Locks.Unlock"); lfsUnlock.Header = App.Text("GitLFS.Locks.Unlock");
lfsUnlock.Icon = App.CreateMenuIcon("Icons.Unlock"); lfsUnlock.Icon = App.CreateMenuIcon("Icons.Unlock");
lfsUnlock.IsEnabled = _repo.Remotes.Count > 0;
if (_repo.Remotes.Count == 1) if (_repo.Remotes.Count == 1)
{ {
lfsUnlock.Click += async (_, e) => lfsUnlock.Click += async (_, e) =>
@ -867,6 +856,31 @@ namespace SourceGit.ViewModels
RevisionFileSearchSuggestion = suggestion; RevisionFileSearchSuggestion = suggestion;
} }
private Task ResetToThisRevision(string path)
{
var log = _repo.CreateLog($"Reset File to '{_commit.SHA}'");
return Task.Run(() =>
{
new Commands.Checkout(_repo.FullPath).Use(log).FileWithRevision(path, $"{_commit.SHA}");
log.Complete();
});
}
private Task ResetToParentRevision(Models.Change change)
{
var log = _repo.CreateLog($"Reset File to '{_commit.SHA}~1'");
return Task.Run(() =>
{
if (change.Index == Models.ChangeState.Renamed)
new Commands.Checkout(_repo.FullPath).Use(log).FileWithRevision(change.OriginalPath, $"{_commit.SHA}~1");
new Commands.Checkout(_repo.FullPath).Use(log).FileWithRevision(change.Path, $"{_commit.SHA}~1");
log.Complete();
});
}
[GeneratedRegex(@"\b(https?://|ftp://)[\w\d\._/\-~%@()+:?&=#!]*[\w\d/]")] [GeneratedRegex(@"\b(https?://|ftp://)[\w\d\._/\-~%@()+:?&=#!]*[\w\d/]")]
private static partial Regex REG_URL_FORMAT(); private static partial Regex REG_URL_FORMAT();

View file

@ -28,7 +28,14 @@ namespace SourceGit.ViewModels
public bool CheckoutAfterCreated public bool CheckoutAfterCreated
{ {
get => _repo.Settings.CheckoutBranchOnCreateBranch; get => _repo.Settings.CheckoutBranchOnCreateBranch;
set => _repo.Settings.CheckoutBranchOnCreateBranch = value; set
{
if (_repo.Settings.CheckoutBranchOnCreateBranch != value)
{
_repo.Settings.CheckoutBranchOnCreateBranch = value;
OnPropertyChanged();
}
}
} }
public bool IsBareRepository public bool IsBareRepository
@ -36,6 +43,18 @@ namespace SourceGit.ViewModels
get => _repo.IsBare; get => _repo.IsBare;
} }
public bool IsRecurseSubmoduleVisible
{
get;
private set;
}
public bool RecurseSubmodules
{
get => _repo.Settings.UpdateSubmodulesOnCheckoutBranch;
set => _repo.Settings.UpdateSubmodulesOnCheckoutBranch = value;
}
public CreateBranch(Repository repo, Models.Branch branch) public CreateBranch(Repository repo, Models.Branch branch)
{ {
_repo = repo; _repo = repo;
@ -48,6 +67,7 @@ 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)
@ -57,6 +77,7 @@ 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)
@ -66,6 +87,7 @@ 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)
@ -92,20 +114,21 @@ namespace SourceGit.ViewModels
var log = _repo.CreateLog($"Create Branch '{fixedName}'"); var log = _repo.CreateLog($"Create Branch '{fixedName}'");
Use(log); Use(log);
var updateSubmodules = IsRecurseSubmoduleVisible && RecurseSubmodules;
return Task.Run(() => return Task.Run(() =>
{ {
bool succ; bool succ = false;
if (CheckoutAfterCreated && !_repo.IsBare) if (CheckoutAfterCreated && !_repo.IsBare)
{ {
var changes = new Commands.CountLocalChangesWithoutUntracked(_repo.FullPath).Result();
var needPopStash = false; var needPopStash = false;
if (changes > 0)
{
if (DiscardLocalChanges) if (DiscardLocalChanges)
{ {
Commands.Discard.All(_repo.FullPath, false, log); succ = new Commands.Checkout(_repo.FullPath).Use(log).Branch(fixedName, _baseOnRevision, true);
} }
else else
{
var changes = new Commands.CountLocalChangesWithoutUntracked(_repo.FullPath).Result();
if (changes > 0)
{ {
succ = new Commands.Stash(_repo.FullPath).Use(log).Push("CREATE_BRANCH_AUTO_STASH"); succ = new Commands.Stash(_repo.FullPath).Use(log).Push("CREATE_BRANCH_AUTO_STASH");
if (!succ) if (!succ)
@ -117,12 +140,23 @@ namespace SourceGit.ViewModels
needPopStash = true; needPopStash = true;
} }
succ = new Commands.Checkout(_repo.FullPath).Use(log).Branch(fixedName, _baseOnRevision, false);
}
if (succ)
{
if (updateSubmodules)
{
var submodules = new Commands.QuerySubmodules(_repo.FullPath).Result();
if (submodules.Count > 0)
new Commands.Submodule(_repo.FullPath).Use(log).Update(submodules, true, true, false);
} }
succ = new Commands.Checkout(_repo.FullPath).Use(log).Branch(fixedName, _baseOnRevision);
if (needPopStash) if (needPopStash)
new Commands.Stash(_repo.FullPath).Use(log).Pop("stash@{0}"); new Commands.Stash(_repo.FullPath).Use(log).Pop("stash@{0}");
} }
}
else else
{ {
succ = Commands.Branch.Create(_repo.FullPath, fixedName, _baseOnRevision, log); succ = Commands.Branch.Create(_repo.FullPath, fixedName, _baseOnRevision, log);
@ -144,6 +178,8 @@ namespace SourceGit.ViewModels
if (_repo.HistoriesFilterMode == Models.FilterMode.Included) if (_repo.HistoriesFilterMode == Models.FilterMode.Included)
_repo.SetBranchFilterMode(fake, Models.FilterMode.Included, true, false); _repo.SetBranchFilterMode(fake, Models.FilterMode.Included, true, false);
ProgressDescription = "Waiting for branch updated...";
} }
_repo.MarkBranchesDirtyManually(); _repo.MarkBranchesDirtyManually();
@ -151,10 +187,7 @@ namespace SourceGit.ViewModels
}); });
if (CheckoutAfterCreated) if (CheckoutAfterCreated)
{
CallUIThread(() => ProgressDescription = "Waiting for branch updated...");
Task.Delay(400).Wait(); Task.Delay(400).Wait();
}
return true; return true;
}); });

View file

@ -13,6 +13,18 @@ namespace SourceGit.ViewModels
public bool IsRelease => _type == "release"; public bool IsRelease => _type == "release";
public bool IsHotfix => _type == "hotfix"; public bool IsHotfix => _type == "hotfix";
public bool Squash
{
get;
set;
} = false;
public bool AutoPush
{
get;
set;
} = false;
public bool KeepBranch public bool KeepBranch
{ {
get; get;
@ -39,7 +51,7 @@ namespace SourceGit.ViewModels
return Task.Run(() => return Task.Run(() =>
{ {
var succ = Commands.GitFlow.Finish(_repo.FullPath, _type, name, 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;

View file

@ -100,23 +100,32 @@ namespace SourceGit.ViewModels
public async void ProcessPopup() public async void ProcessPopup()
{ {
if (_popup is { InProgress: false }) if (_popup is { InProgress: false } dump)
{ {
if (!_popup.Check()) if (!dump.Check())
return; return;
_popup.InProgress = true; dump.InProgress = true;
var task = _popup.Sure(); var task = dump.Sure();
var finished = false;
if (task != null) if (task != null)
{ {
var finished = await task; try
_popup.InProgress = false; {
finished = await task;
}
catch (Exception e)
{
App.LogException(e);
}
dump.InProgress = false;
if (finished) if (finished)
Popup = null; Popup = null;
} }
else else
{ {
_popup.InProgress = false; dump.InProgress = false;
Popup = null; Popup = null;
} }
} }

View file

@ -583,30 +583,42 @@ namespace SourceGit.ViewModels
Task.Run(RefreshStashes); Task.Run(RefreshStashes);
} }
public void OpenInFileManager()
{
Native.OS.OpenInFileManager(_fullpath);
}
public void OpenInTerminal()
{
Native.OS.OpenTerminal(_fullpath);
}
public ContextMenu CreateContextMenuForExternalTools() public ContextMenu CreateContextMenuForExternalTools()
{ {
var tools = Native.OS.ExternalTools;
if (tools.Count == 0)
{
App.RaiseException(_fullpath, "No available external editors found!");
return null;
}
var menu = new ContextMenu(); var menu = new ContextMenu();
menu.Placement = PlacementMode.BottomEdgeAlignedLeft; menu.Placement = PlacementMode.BottomEdgeAlignedLeft;
RenderOptions.SetBitmapInterpolationMode(menu, BitmapInterpolationMode.HighQuality);
foreach (var tool in tools) RenderOptions.SetBitmapInterpolationMode(menu, BitmapInterpolationMode.HighQuality);
RenderOptions.SetEdgeMode(menu, EdgeMode.Antialias);
RenderOptions.SetTextRenderingMode(menu, TextRenderingMode.Antialias);
var explore = new MenuItem();
explore.Header = App.Text("Repository.Explore");
explore.Icon = App.CreateMenuIcon("Icons.Explore");
explore.Click += (_, e) =>
{
Native.OS.OpenInFileManager(_fullpath);
e.Handled = true;
};
var terminal = new MenuItem();
terminal.Header = App.Text("Repository.Terminal");
terminal.Icon = App.CreateMenuIcon("Icons.Terminal");
terminal.Click += (_, e) =>
{
Native.OS.OpenTerminal(_fullpath);
e.Handled = true;
};
menu.Items.Add(explore);
menu.Items.Add(terminal);
var tools = Native.OS.ExternalTools;
if (tools.Count > 0)
{
menu.Items.Add(new MenuItem() { Header = "-" });
foreach (var tool in Native.OS.ExternalTools)
{ {
var dupTool = tool; var dupTool = tool;
@ -621,6 +633,36 @@ namespace SourceGit.ViewModels
menu.Items.Add(item); menu.Items.Add(item);
} }
}
var urls = new Dictionary<string, string>();
foreach (var r in _remotes)
{
if (r.TryGetVisitURL(out var visit))
urls.Add(r.Name, visit);
}
if (urls.Count > 0)
{
menu.Items.Add(new MenuItem() { Header = "-" });
foreach (var url in urls)
{
var name = url.Key;
var addr = url.Value;
var item = new MenuItem();
item.Header = App.Text("Repository.Visit", name);
item.Icon = App.CreateMenuIcon("Icons.Remotes");
item.Click += (_, e) =>
{
Native.OS.OpenBrowser(addr);
e.Handled = true;
};
menu.Items.Add(item);
}
}
return menu; return menu;
} }
@ -1154,7 +1196,7 @@ namespace SourceGit.ViewModels
if (branch.IsLocal) if (branch.IsLocal)
{ {
if (_localChangesCount > 0) if (_localChangesCount > 0 || _submodules.Count > 0)
ShowPopup(new Checkout(this, branch.Name)); ShowPopup(new Checkout(this, branch.Name));
else else
ShowAndStartPopup(new Checkout(this, branch.Name)); ShowAndStartPopup(new Checkout(this, branch.Name));
@ -2187,6 +2229,51 @@ namespace SourceGit.ViewModels
return menu; return menu;
} }
public ContextMenu CreateContextMenuForBranchSortMode(bool local)
{
var mode = local ? _settings.LocalBranchSortMode : _settings.RemoteBranchSortMode;
var changeMode = new Action<Models.BranchSortMode>(m =>
{
if (local)
_settings.LocalBranchSortMode = m;
else
_settings.RemoteBranchSortMode = m;
var builder = BuildBranchTree(_branches, _remotes);
LocalBranchTrees = builder.Locals;
RemoteBranchTrees = builder.Remotes;
});
var byNameAsc = new MenuItem();
byNameAsc.Header = App.Text("Repository.BranchSort.ByName");
if (mode == Models.BranchSortMode.Name)
byNameAsc.Icon = App.CreateMenuIcon("Icons.Check");
byNameAsc.Click += (_, ev) =>
{
if (mode != Models.BranchSortMode.Name)
changeMode(Models.BranchSortMode.Name);
ev.Handled = true;
};
var byCommitterDate = new MenuItem();
byCommitterDate.Header = App.Text("Repository.BranchSort.ByCommitterDate");
if (mode == Models.BranchSortMode.CommitterDate)
byCommitterDate.Icon = App.CreateMenuIcon("Icons.Check");
byCommitterDate.Click += (_, ev) =>
{
if (mode != Models.BranchSortMode.CommitterDate)
changeMode(Models.BranchSortMode.CommitterDate);
ev.Handled = true;
};
var menu = new ContextMenu();
menu.Items.Add(byNameAsc);
menu.Items.Add(byCommitterDate);
return menu;
}
public ContextMenu CreateContextMenuForTagSortMode() public ContextMenu CreateContextMenuForTagSortMode()
{ {
var mode = _settings.TagSortMode; var mode = _settings.TagSortMode;
@ -2356,7 +2443,7 @@ namespace SourceGit.ViewModels
private BranchTreeNode.Builder BuildBranchTree(List<Models.Branch> branches, List<Models.Remote> remotes) private BranchTreeNode.Builder BuildBranchTree(List<Models.Branch> branches, List<Models.Remote> remotes)
{ {
var builder = new BranchTreeNode.Builder(); var builder = new BranchTreeNode.Builder(_settings.LocalBranchSortMode, _settings.RemoteBranchSortMode);
if (string.IsNullOrEmpty(_filter)) if (string.IsNullOrEmpty(_filter))
{ {
builder.SetExpandedNodes(_settings.ExpandedBranchNodesInSideBar); builder.SetExpandedNodes(_settings.ExpandedBranchNodesInSideBar);

View file

@ -46,7 +46,7 @@
<!-- Compare Targets --> <!-- Compare Targets -->
<Border Grid.Row="1"> <Border Grid.Row="1">
<Grid Margin="48,8,48,8" ColumnDefinitions="*,48,*"> <Grid Margin="48,8,48,8" ColumnDefinitions="*,48,*">
<Border Grid.Column="0" BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="1" Background="{DynamicResource Brush.Contents}" CornerRadius="4" Padding="4"> <Border Grid.Column="0" BorderBrush="{DynamicResource Brush.Diff.DeletedHighlight}" BorderThickness="1" Background="{DynamicResource Brush.Contents}" CornerRadius="4" Padding="4">
<Grid RowDefinitions="Auto,*"> <Grid RowDefinitions="Auto,*">
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto,Auto,Auto"> <Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto,Auto,Auto">
<v:Avatar Width="16" Height="16" <v:Avatar Width="16" Height="16"
@ -67,10 +67,10 @@
<!-- Swap Button --> <!-- Swap Button -->
<Button Grid.Column="1" Classes="icon_button" Command="{Binding Swap}" HorizontalAlignment="Center" ToolTip.Tip="{DynamicResource Text.Diff.SwapCommits}"> <Button Grid.Column="1" Classes="icon_button" Command="{Binding Swap}" HorizontalAlignment="Center" ToolTip.Tip="{DynamicResource Text.Diff.SwapCommits}">
<Path Width="16" Height="16" Fill="{DynamicResource Brush.FG2}" Data="{DynamicResource Icons.Compare}"/> <Path Width="16" Height="16" Data="{DynamicResource Icons.Compare}"/>
</Button> </Button>
<Border Grid.Column="2" BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="1" Background="{DynamicResource Brush.Contents}" CornerRadius="4" Padding="4"> <Border Grid.Column="2" BorderBrush="{DynamicResource Brush.Diff.AddedHighlight}" BorderThickness="1" Background="{DynamicResource Brush.Contents}" CornerRadius="4" Padding="4">
<Grid RowDefinitions="Auto,*"> <Grid RowDefinitions="Auto,*">
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto,Auto,Auto"> <Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto,Auto,Auto">
<v:Avatar Width="16" Height="16" <v:Avatar Width="16" Height="16"

View file

@ -17,6 +17,7 @@
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="32"/> <RowDefinition Height="32"/>
<RowDefinition Height="Auto" MinHeight="32"/> <RowDefinition Height="Auto" MinHeight="32"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
@ -35,11 +36,18 @@
<WrapPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center"> <WrapPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center">
<RadioButton GroupName="LocalChanges" <RadioButton GroupName="LocalChanges"
Margin="0,0,8,0" Margin="0,0,8,0"
Content="{DynamicResource Text.CreateBranch.LocalChanges.StashAndReply}" Content="{DynamicResource Text.Checkout.LocalChanges.StashAndReply}"
IsChecked="{Binding !DiscardLocalChanges, Mode=TwoWay}"/> IsChecked="{Binding !DiscardLocalChanges, Mode=TwoWay}"/>
<RadioButton GroupName="LocalChanges" <RadioButton GroupName="LocalChanges"
Content="{DynamicResource Text.CreateBranch.LocalChanges.Discard}"/> Content="{DynamicResource Text.Checkout.LocalChanges.Discard}"/>
</WrapPanel> </WrapPanel>
<CheckBox Grid.Row="2" Grid.Column="1"
Height="32"
Content="{DynamicResource Text.Checkout.RecurseSubmodules}"
IsChecked="{Binding RecurseSubmodules, Mode=TwoWay}"
IsVisible="{Binding IsRecurseSubmoduleVisible}"
ToolTip.Tip="--recurse-submodules"/>
</Grid> </Grid>
</StackPanel> </StackPanel>
</UserControl> </UserControl>

View file

@ -12,7 +12,7 @@
Classes="bold" Classes="bold"
Text="{DynamicResource Text.Checkout.Commit}" /> Text="{DynamicResource Text.Checkout.Commit}" />
<Grid Margin="0,16,0,0" RowDefinitions="32,Auto,Auto" ColumnDefinitions="Auto,*"> <Grid Margin="0,16,0,0" RowDefinitions="32,Auto,Auto,Auto" ColumnDefinitions="Auto,*">
<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"
@ -36,7 +36,14 @@
GroupName="LocalChanges"/> GroupName="LocalChanges"/>
</StackPanel> </StackPanel>
<Grid Grid.Row="2" Grid.Column="1" ColumnDefinitions="Auto,*" Margin="0,6,0,0"> <CheckBox Grid.Row="2" Grid.Column="1"
Height="32"
Content="{DynamicResource Text.Checkout.RecurseSubmodules}"
IsChecked="{Binding RecurseSubmodules, Mode=TwoWay}"
IsVisible="{Binding IsRecurseSubmoduleVisible}"
ToolTip.Tip="--recurse-submodules"/>
<Grid Grid.Row="3" Grid.Column="1" ColumnDefinitions="Auto,*" Margin="0,6,0,0">
<Path Grid.Column="0" <Path Grid.Column="0"
Width="14" Height="14" Width="14" Height="14"
Data="{StaticResource Icons.Error}" Data="{StaticResource Icons.Error}"

View file

@ -189,7 +189,7 @@
<Border Grid.Row="3" Grid.Column="1" Margin="12,0,0,0" MinHeight="24" IsVisible="{Binding HasDecorators}"> <Border Grid.Row="3" Grid.Column="1" Margin="12,0,0,0" MinHeight="24" IsVisible="{Binding HasDecorators}">
<v:CommitRefsPresenter Foreground="{DynamicResource Brush.FG1}" <v:CommitRefsPresenter Foreground="{DynamicResource Brush.FG1}"
FontFamily="{DynamicResource Fonts.Primary}" FontFamily="{DynamicResource Fonts.Primary}"
FontSize="11" FontSize="12"
AllowWrap="True" AllowWrap="True"
Margin="0,4,0,0" Margin="0,4,0,0"
UseGraphColor="False"/> UseGraphColor="False"/>

View file

@ -55,23 +55,29 @@ namespace SourceGit.Views
if (list == null) if (list == null)
return; return;
// Calculate drawing area. var container = list.ItemsPanelRoot as VirtualizingStackPanel;
double width = Bounds.Width - 273 - histories.AuthorNameColumnWidth.Value; if (container == null)
double height = Bounds.Height; return;
double startY = list.Scroll?.Offset.Y ?? 0;
double endY = startY + height + 28; var item = list.ContainerFromIndex(container.FirstRealizedIndex);
if (item == null)
return;
var width = histories.CommitListHeader.ColumnDefinitions[0].ActualWidth;
var height = Bounds.Height;
var rowHeight = item.Bounds.Height;
var startY = container.FirstRealizedIndex * rowHeight - item.TranslatePoint(new Point(0, 0), list).Value!.Y;
var endY = startY + height + 28;
// Apply scroll offset and clip.
using (context.PushClip(new Rect(0, 0, width, height))) using (context.PushClip(new Rect(0, 0, width, height)))
using (context.PushTransform(Matrix.CreateTranslation(0, -startY))) using (context.PushTransform(Matrix.CreateTranslation(0, -startY)))
{ {
// Draw contents DrawCurves(context, graph, startY, endY, rowHeight);
DrawCurves(context, graph, startY, endY); DrawAnchors(context, graph, startY, endY, rowHeight);
DrawAnchors(context, graph, startY, endY);
} }
} }
private void DrawCurves(DrawingContext context, Models.CommitGraph graph, double top, double bottom) private void DrawCurves(DrawingContext context, Models.CommitGraph graph, double top, double bottom, double rowHeight)
{ {
var grayedPen = new Pen(new SolidColorBrush(Colors.Gray, 0.4), Models.CommitGraph.Pens[0].Thickness); var grayedPen = new Pen(new SolidColorBrush(Colors.Gray, 0.4), Models.CommitGraph.Pens[0].Thickness);
var onlyHighlightCurrentBranch = OnlyHighlightCurrentBranch; var onlyHighlightCurrentBranch = OnlyHighlightCurrentBranch;
@ -82,16 +88,20 @@ namespace SourceGit.Views
{ {
if (link.IsMerged) if (link.IsMerged)
continue; continue;
if (link.End.Y < top)
var startY = link.Start.Y * rowHeight;
var endY = link.End.Y * rowHeight;
if (endY < top)
continue; continue;
if (link.Start.Y > bottom) if (startY > bottom)
break; break;
var geo = new StreamGeometry(); var geo = new StreamGeometry();
using (var ctx = geo.Open()) using (var ctx = geo.Open())
{ {
ctx.BeginFigure(link.Start, false); ctx.BeginFigure(new Point(link.Start.X, startY), false);
ctx.QuadraticBezierTo(link.Control, link.End); ctx.QuadraticBezierTo(new Point(link.Control.X, link.Control.Y * rowHeight), new Point(link.End.X, endY));
} }
context.DrawGeometry(null, grayedPen, geo); context.DrawGeometry(null, grayedPen, geo);
@ -100,10 +110,11 @@ namespace SourceGit.Views
foreach (var line in graph.Paths) foreach (var line in graph.Paths)
{ {
var last = line.Points[0]; var last = new Point(line.Points[0].X, line.Points[0].Y * rowHeight);
var size = line.Points.Count; var size = line.Points.Count;
var endY = line.Points[size - 1].Y * rowHeight;
if (line.Points[size - 1].Y < top) if (endY < top)
continue; continue;
if (last.Y > bottom) if (last.Y > bottom)
break; break;
@ -117,7 +128,7 @@ namespace SourceGit.Views
var ended = false; var ended = false;
for (int i = 1; i < size; i++) for (int i = 1; i < size; i++)
{ {
var cur = line.Points[i]; var cur = new Point(line.Points[i].X, line.Points[i].Y * rowHeight);
if (cur.Y < top) if (cur.Y < top)
{ {
last = cur; last = cur;
@ -173,23 +184,27 @@ namespace SourceGit.Views
{ {
if (onlyHighlightCurrentBranch && !link.IsMerged) if (onlyHighlightCurrentBranch && !link.IsMerged)
continue; continue;
if (link.End.Y < top)
var startY = link.Start.Y * rowHeight;
var endY = link.End.Y * rowHeight;
if (endY < top)
continue; continue;
if (link.Start.Y > bottom) if (startY > bottom)
break; break;
var geo = new StreamGeometry(); var geo = new StreamGeometry();
using (var ctx = geo.Open()) using (var ctx = geo.Open())
{ {
ctx.BeginFigure(link.Start, false); ctx.BeginFigure(new Point(link.Start.X, startY), false);
ctx.QuadraticBezierTo(link.Control, link.End); ctx.QuadraticBezierTo(new Point(link.Control.X, link.Control.Y * rowHeight), new Point(link.End.X, endY));
} }
context.DrawGeometry(null, Models.CommitGraph.Pens[link.Color], geo); context.DrawGeometry(null, Models.CommitGraph.Pens[link.Color], geo);
} }
} }
private void DrawAnchors(DrawingContext context, Models.CommitGraph graph, double top, double bottom) private void DrawAnchors(DrawingContext context, Models.CommitGraph graph, double top, double bottom, double rowHeight)
{ {
var dotFill = DotBrush; var dotFill = DotBrush;
var dotFillPen = new Pen(dotFill, 2); var dotFillPen = new Pen(dotFill, 2);
@ -198,9 +213,11 @@ namespace SourceGit.Views
foreach (var dot in graph.Dots) foreach (var dot in graph.Dots)
{ {
if (dot.Center.Y < top) var center = new Point(dot.Center.X, dot.Center.Y * rowHeight);
if (center.Y < top)
continue; continue;
if (dot.Center.Y > bottom) if (center.Y > bottom)
break; break;
var pen = Models.CommitGraph.Pens[dot.Color]; var pen = Models.CommitGraph.Pens[dot.Color];
@ -210,16 +227,16 @@ namespace SourceGit.Views
switch (dot.Type) switch (dot.Type)
{ {
case Models.CommitGraph.DotType.Head: case Models.CommitGraph.DotType.Head:
context.DrawEllipse(dotFill, pen, dot.Center, 6, 6); context.DrawEllipse(dotFill, pen, center, 6, 6);
context.DrawEllipse(pen.Brush, null, dot.Center, 3, 3); context.DrawEllipse(pen.Brush, null, center, 3, 3);
break; break;
case Models.CommitGraph.DotType.Merge: case Models.CommitGraph.DotType.Merge:
context.DrawEllipse(pen.Brush, null, dot.Center, 6, 6); context.DrawEllipse(pen.Brush, null, center, 6, 6);
context.DrawLine(dotFillPen, new Point(dot.Center.X, dot.Center.Y - 3), new Point(dot.Center.X, dot.Center.Y + 3)); context.DrawLine(dotFillPen, new Point(center.X, center.Y - 3), new Point(center.X, center.Y + 3));
context.DrawLine(dotFillPen, new Point(dot.Center.X - 3, dot.Center.Y), new Point(dot.Center.X + 3, dot.Center.Y)); context.DrawLine(dotFillPen, new Point(center.X - 3, center.Y), new Point(center.X + 3, center.Y));
break; break;
default: default:
context.DrawEllipse(dotFill, pen, dot.Center, 3, 3); context.DrawEllipse(dotFill, pen, center, 3, 3);
break; break;
} }
} }

View file

@ -104,6 +104,14 @@ namespace SourceGit.Views
if (_inlines.Count == 0) if (_inlines.Count == 0)
return; return;
var ro = new RenderOptions()
{
TextRenderingMode = TextRenderingMode.SubpixelAntialias,
EdgeMode = EdgeMode.Antialias
};
using (context.PushRenderOptions(ro))
{
var height = Bounds.Height; var height = Bounds.Height;
var width = Bounds.Width; var width = Bounds.Width;
foreach (var inline in _inlines) foreach (var inline in _inlines)
@ -124,6 +132,7 @@ namespace SourceGit.Views
} }
} }
} }
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{ {
@ -299,7 +308,7 @@ namespace SourceGit.Views
CultureInfo.CurrentCulture, CultureInfo.CurrentCulture,
FlowDirection.LeftToRight, FlowDirection.LeftToRight,
codeTypeface, codeTypeface,
fontSize, fontSize - 0.5,
foreground); foreground);
_inlines.Add(new Inline(x, link, elem)); _inlines.Add(new Inline(x, link, elem));
x += link.WidthIncludingTrailingWhitespace + 8; x += link.WidthIncludingTrailingWhitespace + 8;

View file

@ -52,7 +52,7 @@
<v:CommitRefsPresenter Margin="8,0,0,0" <v:CommitRefsPresenter Margin="8,0,0,0"
Foreground="{DynamicResource Brush.FG1}" Foreground="{DynamicResource Brush.FG1}"
FontFamily="{DynamicResource Fonts.Primary}" FontFamily="{DynamicResource Fonts.Primary}"
FontSize="11" FontSize="12"
VerticalAlignment="Center" VerticalAlignment="Center"
UseGraphColor="False"/> UseGraphColor="False"/>
<TextBlock Margin="4,0,0,0" <TextBlock Margin="4,0,0,0"

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" ColumnDefinitions="140,*"> <Grid Margin="0,16,0,0" RowDefinitions="32,32,Auto,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"
@ -83,6 +83,19 @@
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"
Content="{DynamicResource Text.Checkout.RecurseSubmodules}"
IsChecked="{Binding RecurseSubmodules, Mode=TwoWay}"
ToolTip.Tip="--recurse-submodules">
<CheckBox.IsVisible>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Path="IsBareRepository" Converter="{x:Static BoolConverters.Not}"/>
<Binding Path="CheckoutAfterCreated"/>
<Binding Path="IsRecurseSubmoduleVisible"/>
</MultiBinding>
</CheckBox.IsVisible>
</CheckBox>
</Grid> </Grid>
</StackPanel> </StackPanel>
</UserControl> </UserControl>

View file

@ -19,7 +19,7 @@
Classes="bold" Classes="bold"
Text="{DynamicResource Text.GitFlow.FinishHotfix}" Text="{DynamicResource Text.GitFlow.FinishHotfix}"
IsVisible="{Binding IsHotfix}"/> IsVisible="{Binding IsHotfix}"/>
<Grid Margin="0,16,0,0" RowDefinitions="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"
Margin="0,0,8,0" Margin="0,0,8,0"
@ -30,8 +30,19 @@
</StackPanel> </StackPanel>
<CheckBox Grid.Row="1" Grid.Column="1" <CheckBox Grid.Row="1" Grid.Column="1"
Content="{DynamicResource Text.GitFlow.FinishWithSquash}"
IsChecked="{Binding Squash, Mode=TwoWay}"
ToolTip.Tip="--squash"/>
<CheckBox Grid.Row="2" Grid.Column="1"
Content="{DynamicResource Text.GitFlow.FinishWithPush}"
IsChecked="{Binding AutoPush, Mode=TwoWay}"
ToolTip.Tip="--push"/>
<CheckBox Grid.Row="3" Grid.Column="1"
Content="{DynamicResource Text.GitFlow.KeepBranchAfterFinish}" Content="{DynamicResource Text.GitFlow.KeepBranchAfterFinish}"
IsChecked="{Binding KeepBranch, Mode=TwoWay}"/> IsChecked="{Binding KeepBranch, Mode=TwoWay}"
ToolTip.Tip="-k"/>
</Grid> </Grid>
</StackPanel> </StackPanel>
</UserControl> </UserControl>

View file

@ -30,7 +30,7 @@
Background="{DynamicResource Brush.Window}" Background="{DynamicResource Brush.Window}"
BorderThickness="0,0,0,1" BorderThickness="0,0,0,1"
BorderBrush="{DynamicResource Brush.Border0}"> BorderBrush="{DynamicResource Brush.Border0}">
<Grid> <Grid x:Name="CommitListHeader">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
<ColumnDefinition Width="3"/> <ColumnDefinition Width="3"/>
@ -76,7 +76,7 @@
<Style Selector="ListBoxItem"> <Style Selector="ListBoxItem">
<Setter Property="Margin" Value="0"/> <Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/> <Setter Property="Padding" Value="0"/>
<Setter Property="Height" Value="28"/> <Setter Property="Height" Value="26"/>
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate> <ControlTemplate>
<Grid> <Grid>
@ -145,7 +145,7 @@
Foreground="{DynamicResource Brush.FG1}" Foreground="{DynamicResource Brush.FG1}"
FontFamily="{DynamicResource Fonts.Primary}" FontFamily="{DynamicResource Fonts.Primary}"
ShowTags="{Binding Source={x:Static vm:Preferences.Instance}, Path=ShowTagsInGraph}" ShowTags="{Binding Source={x:Static vm:Preferences.Instance}, Path=ShowTagsInGraph}"
FontSize="11" FontSize="12"
VerticalAlignment="Center"> VerticalAlignment="Center">
<v:CommitRefsPresenter.UseGraphColor> <v:CommitRefsPresenter.UseGraphColor>
<MultiBinding Converter="{x:Static BoolConverters.Or}"> <MultiBinding Converter="{x:Static BoolConverters.Or}">

View file

@ -202,9 +202,20 @@
<Grid Grid.Row="2" x:Name="LeftSidebarGroups" Margin="0,4,0,0" RowDefinitions="28,Auto,28,Auto,28,Auto,28,Auto,28,Auto" SizeChanged="OnLeftSidebarSizeChanged"> <Grid Grid.Row="2" x:Name="LeftSidebarGroups" Margin="0,4,0,0" RowDefinitions="28,Auto,28,Auto,28,Auto,28,Auto,28,Auto" SizeChanged="OnLeftSidebarSizeChanged">
<!-- Local Branches --> <!-- Local Branches -->
<ToggleButton Grid.Row="0" Classes="group_expander" IsChecked="{Binding IsLocalBranchGroupExpanded, Mode=TwoWay}"> <ToggleButton Grid.Row="0" Classes="group_expander" IsChecked="{Binding IsLocalBranchGroupExpanded, Mode=TwoWay}">
<Grid ColumnDefinitions="16,*"> <Grid ColumnDefinitions="16,*,Auto,Auto">
<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" Text="{DynamicResource Text.Repository.LocalBranches}"/> <TextBlock Grid.Column="1" Classes="group_header_label" Margin="0" Text="{DynamicResource Text.Repository.LocalBranches}"/>
<Button Grid.Column="2"
Classes="icon_button"
Width="14"
Margin="8,0,0,0"
Click="OnOpenSortLocalBranchMenu"
ToolTip.Tip="{DynamicResource Text.Repository.BranchSort}">
<Path Width="12" Height="12" Data="{StaticResource Icons.Order}"/>
</Button>
<Button Grid.Column="3" Classes="icon_button" Width="14" Margin="8,0" Command="{Binding CreateNewBranch}" ToolTip.Tip="{DynamicResource Text.Repository.NewBranch}">
<Path Width="12" Height="12" Data="{StaticResource Icons.Branch.Add}"/>
</Button>
</Grid> </Grid>
</ToggleButton> </ToggleButton>
<v:BranchTree Grid.Row="1" <v:BranchTree Grid.Row="1"
@ -218,10 +229,18 @@
<!-- Remotes --> <!-- Remotes -->
<ToggleButton Grid.Row="2" Classes="group_expander" IsChecked="{Binding IsRemoteGroupExpanded, Mode=TwoWay}"> <ToggleButton Grid.Row="2" Classes="group_expander" IsChecked="{Binding IsRemoteGroupExpanded, Mode=TwoWay}">
<Grid ColumnDefinitions="16,*,Auto"> <Grid ColumnDefinitions="16,*,Auto,Auto">
<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" Text="{DynamicResource Text.Repository.Remotes}"/> <TextBlock Grid.Column="1" Classes="group_header_label" Margin="0" Text="{DynamicResource Text.Repository.Remotes}"/>
<Button Grid.Column="2" Classes="icon_button" Width="14" Margin="8,0" Command="{Binding AddRemote}" ToolTip.Tip="{DynamicResource Text.Repository.Remotes.Add}"> <Button Grid.Column="2"
Classes="icon_button"
Width="14"
Margin="8,0,0,0"
Click="OnOpenSortRemoteBranchMenu"
ToolTip.Tip="{DynamicResource Text.Repository.BranchSort}">
<Path Width="12" Height="12" Data="{StaticResource Icons.Order}"/>
</Button>
<Button Grid.Column="3" Classes="icon_button" Width="14" Margin="8,0" Command="{Binding AddRemote}" ToolTip.Tip="{DynamicResource Text.Repository.Remotes.Add}">
<Path Width="12" Height="12" Data="{StaticResource Icons.Remote.Add}"/> <Path Width="12" Height="12" Data="{StaticResource Icons.Remote.Add}"/>
</Button> </Button>
</Grid> </Grid>

View file

@ -403,6 +403,28 @@ namespace SourceGit.Views
e.Handled = true; e.Handled = true;
} }
private void OnOpenSortLocalBranchMenu(object sender, RoutedEventArgs e)
{
if (sender is Button button && DataContext is ViewModels.Repository repo)
{
var menu = repo.CreateContextMenuForBranchSortMode(true);
menu?.Open(button);
}
e.Handled = true;
}
private void OnOpenSortRemoteBranchMenu(object sender, RoutedEventArgs e)
{
if (sender is Button button && DataContext is ViewModels.Repository repo)
{
var menu = repo.CreateContextMenuForBranchSortMode(false);
menu?.Open(button);
}
e.Handled = true;
}
private void OnOpenSortTagMenu(object sender, RoutedEventArgs e) private void OnOpenSortTagMenu(object sender, RoutedEventArgs e)
{ {
if (sender is Button button && DataContext is ViewModels.Repository repo) if (sender is Button button && DataContext is ViewModels.Repository repo)

View file

@ -9,16 +9,8 @@
x:DataType="vm:Repository"> x:DataType="vm:Repository">
<Grid ColumnDefinitions="*,Auto,*"> <Grid ColumnDefinitions="*,Auto,*">
<StackPanel Grid.Column="0" Orientation="Horizontal" Margin="4,0,0,0"> <StackPanel Grid.Column="0" Orientation="Horizontal" Margin="4,0,0,0">
<Button Classes="icon_button" Width="32" Command="{Binding OpenInFileManager}" ToolTip.Tip="{DynamicResource Text.Repository.Explore}">
<Path Width="14" Height="14" Data="{StaticResource Icons.Explore}" Margin="0,2,0,0"/>
</Button>
<Button Classes="icon_button" Width="32" Click="OpenWithExternalTools" IsVisible="{Binding !IsBare}" ToolTip.Tip="{DynamicResource Text.Repository.OpenWithExternalTools}"> <Button Classes="icon_button" Width="32" Click="OpenWithExternalTools" IsVisible="{Binding !IsBare}" ToolTip.Tip="{DynamicResource Text.Repository.OpenWithExternalTools}">
<Path Width="13" Height="13" Data="{StaticResource Icons.OpenWith}"/> <Path Width="14" Height="14" Data="{StaticResource Icons.Explore}" Margin="0,2,0,0"/>
</Button>
<Button Classes="icon_button" Width="32" Command="{Binding OpenInTerminal}" ToolTip.Tip="{DynamicResource Text.Repository.Terminal}">
<Path Width="13" Height="13" Data="{StaticResource Icons.Terminal}"/>
</Button> </Button>
<Button Classes="icon_button" Width="32" Click="OpenGitLogs" ToolTip.Tip="{DynamicResource Text.Repository.ViewLogs}"> <Button Classes="icon_button" Width="32" Click="OpenGitLogs" ToolTip.Tip="{DynamicResource Text.Repository.ViewLogs}">

View file

@ -28,16 +28,16 @@
<TextBlock Grid.Column="4" Classes="primary" Text="{Binding CommitterTimeStr}" Foreground="{DynamicResource Brush.FG2}" Margin="8,0,0,0"/> <TextBlock Grid.Column="4" Classes="primary" Text="{Binding CommitterTimeStr}" Foreground="{DynamicResource Brush.FG2}" Margin="8,0,0,0"/>
</Grid> </Grid>
<TextBlock Grid.Row="1" Classes="primary" Text="{Binding Subject}" VerticalAlignment="Bottom"/> <TextBlock Grid.Row="1" Classes="primary" Text="{Binding Subject}" Margin="0,6,0,0"/>
</Grid> </Grid>
</DataTemplate> </DataTemplate>
</UserControl.DataTemplates> </UserControl.DataTemplates>
<Grid RowDefinitions="50,*" Margin="4"> <Grid RowDefinitions="Auto,*" Margin="4">
<!-- Compare Revision Info --> <!-- Compare Revision Info -->
<Grid Grid.Row="0" Margin="0,0,0,6" ColumnDefinitions="*,32,*,Auto"> <Grid Grid.Row="0" Margin="0,0,0,6" ColumnDefinitions="*,32,*,Auto">
<!-- Base Revision --> <!-- Base Revision -->
<Border Grid.Column="0" BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="1" Background="{DynamicResource Brush.Contents}" CornerRadius="4" Padding="4"> <Border Grid.Column="0" BorderBrush="{DynamicResource Brush.Diff.DeletedHighlight}" BorderThickness="1" Background="{DynamicResource Brush.Contents}" CornerRadius="4" Padding="4">
<ContentControl Content="{Binding StartPoint}"/> <ContentControl Content="{Binding StartPoint}"/>
</Border> </Border>
@ -47,7 +47,7 @@
</Button> </Button>
<!-- Right Revision --> <!-- Right Revision -->
<Border Grid.Column="2" BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="1" Background="{DynamicResource Brush.Contents}" CornerRadius="4" Padding="4"> <Border Grid.Column="2" BorderBrush="{DynamicResource Brush.Diff.AddedHighlight}" BorderThickness="1" Background="{DynamicResource Brush.Contents}" CornerRadius="4" Padding="4">
<ContentControl Content="{Binding EndPoint}"/> <ContentControl Content="{Binding EndPoint}"/>
</Border> </Border>

View file

@ -1502,7 +1502,7 @@ namespace SourceGit.Views
{ {
if (line.Content.Length > 10000) if (line.Content.Length > 10000)
{ {
builder.Append(line.Content.Substring(0, 1000)); builder.Append(line.Content.AsSpan(0, 1000));
builder.Append($"...({line.Content.Length - 1000} characters trimmed)"); builder.Append($"...({line.Content.Length - 1000} characters trimmed)");
} }
else else