Merge branch 'release/v8.36'

This commit is contained in:
leo 2024-10-28 09:33:22 +08:00
commit bb29476a80
No known key found for this signature in database
61 changed files with 1227 additions and 474 deletions

View file

@ -292,3 +292,8 @@ indent_size = 2
end_of_line = lf
[*.{cmd,bat}]
end_of_line = crlf
# YAML files
[*.{yml,yaml}]
indent_size = 2
end_of_line = lf

View file

@ -0,0 +1,42 @@
name: Localization Check
on:
push:
branches: [ develop ]
paths:
- 'src/Resources/Locales/**'
- 'README.md'
workflow_dispatch:
workflow_call:
jobs:
localization-check:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20.x'
- name: Install dependencies
run: npm install fs-extra@11.2.0 path@0.12.7 xml2js@0.6.2
- name: Run localization check
run: node build/scripts/localization-check.js
- name: Commit changes
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
if [ -n "$(git status --porcelain)" ]; then
git add README.md TRANSLATION.md
git commit -m 'doc: Update translation status and missing keys'
git push
else
echo "No changes to commit"
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

4
.gitignore vendored
View file

@ -23,6 +23,10 @@ ehthumbs_vista.db
bin/
obj/
# ignore ci node files
node_modules/
package.json
package-lock.json
build/resources/
build/SourceGit/

View file

@ -1,6 +1,6 @@
# SourceGit
# SourceGit - Opensource Git GUI client.
Opensource Git GUI client.
![stars](https://img.shields.io/github/stars/sourcegit-scm/sourcegit.svg) ![forks](https://img.shields.io/github/forks/sourcegit-scm/sourcegit.svg) ![license](https://img.shields.io/github/license/sourcegit-scm/sourcegit.svg) ![latest](https://img.shields.io/github/v/release/sourcegit-scm/sourcegit.svg) ![downloads](https://img.shields.io/github/downloads/sourcegit-scm/sourcegit/total)
## Highlights
@ -41,6 +41,10 @@ Opensource Git GUI client.
> [!WARNING]
> **Linux** only tested on **Debian 12** on both **X11** & **Wayland**.
## Translation Status
[![en_US](https://img.shields.io/badge/en__US-100%25-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-98.95%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-90.36%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-93.52%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-100.00%25-brightgreen)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-99.10%25-yellow)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-100.00%25-brightgreen)](TRANSLATION.md)
## How to Use
**To use this tool, you need to install Git(>=2.23.0) first.**
@ -81,6 +85,7 @@ For **macOS** users:
* Make sure your mac trusts all software from anywhere. For more information, search `spctl --master-disable`.
* Make sure [git-credential-manager](https://github.com/git-ecosystem/git-credential-manager/releases) is installed on your mac.
* You may need to run `sudo xattr -cr /Applications/SourceGit.app` to make sure the software works.
* You can run `echo $PATH > ~/Library/Application\ Support/SourceGit/PATH` to generate a custom PATH env file to introduce `PATH` env to SourceGit.
For **Linux** users:

View file

@ -16,6 +16,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{
.github\workflows\ci.yml = .github\workflows\ci.yml
.github\workflows\package.yml = .github\workflows\package.yml
.github\workflows\release.yml = .github\workflows\release.yml
.github\workflows\localization-check.yml = .github\workflows\localization-check.yml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{49A7C2D6-558C-4FAA-8F5D-EEE81497AED7}"

175
TRANSLATION.md Normal file
View file

@ -0,0 +1,175 @@
### de_DE.axaml: 98.95%
<details>
<summary>Missing Keys</summary>
- Text.Configure.Git.EnableSignOff
- Text.Configure.IssueTracker.AddSampleGitLabIssue
- Text.Configure.IssueTracker.AddSampleGitLabMergeRequest
- Text.Preference.Advanced
- Text.Preference.AI.AnalyzeDiffPrompt
- Text.Preference.AI.GenerateSubjectPrompt
- Text.WorkingCopy.ConfirmCommitWithoutFiles
</details>
### fr_FR.axaml: 90.36%
<details>
<summary>Missing Keys</summary>
- Text.About.Chart
- Text.AIAssistant
- Text.AIAssistant.Tip
- Text.CherryPick.AppendSourceToMessage
- Text.CherryPick.Mainline
- Text.CherryPick.Mainline.Tips
- Text.CommitCM.CherryPickMultiple
- Text.CommitCM.SquashCommitsSinceThis
- Text.CommitDetail.Info.WebLinks
- Text.Configure.Git.DefaultRemote
- Text.Configure.Git.EnableSignOff
- Text.Configure.IssueTracker.AddSampleGitLabIssue
- Text.Configure.IssueTracker.AddSampleGitLabMergeRequest
- Text.ConfigureWorkspace
- Text.ConfigureWorkspace.Color
- Text.ConfigureWorkspace.Restore
- Text.ConventionalCommit
- Text.ConventionalCommit.BreakingChanges
- Text.ConventionalCommit.ClosedIssue
- Text.ConventionalCommit.Detail
- Text.ConventionalCommit.Scope
- Text.ConventionalCommit.ShortDescription
- Text.ConventionalCommit.Type
- Text.Diff.IgnoreWhitespace
- Text.Discard.IncludeIgnored
- Text.FileHistory.FileChange
- Text.GitLFS.Locks.OnlyMine
- Text.Histories.Header.AuthorTime
- Text.Histories.Tips
- Text.Histories.Tips.MacOS
- Text.Histories.Tips.Prefix
- Text.Hotkeys.Repo.CommitWithAutoStage
- Text.Hotkeys.Repo.DiscardSelected
- Text.MoveRepositoryNode
- Text.MoveRepositoryNode.Target
- Text.Preference.Advanced
- Text.Preference.AI
- Text.Preference.AI.AnalyzeDiffPrompt
- Text.Preference.AI.ApiKey
- Text.Preference.AI.GenerateSubjectPrompt
- Text.Preference.AI.Model
- Text.Preference.AI.Server
- Text.Preference.General.ShowAuthorTime
- Text.Preference.Integration
- Text.Preference.Shell
- Text.Preference.Shell.Type
- Text.Preference.Shell.Path
- Text.Repository.AutoFetching
- Text.Repository.EnableReflog
- Text.Repository.Search.InCurrentBranch
- Text.ScanRepositories
- Text.ScanRepositories.RootDir
- Text.Squash.Into
- Text.Stash.OnlyStagedChanges
- Text.Stash.TipForSelectedFiles
- Text.Statistics.Overview
- Text.TagCM.CopyMessage
- Text.Welcome.Move
- Text.Welcome.ScanDefaultCloneDir
- Text.WorkingCopy.CommitTip
- Text.WorkingCopy.CommitWithAutoStage
- Text.WorkingCopy.ConfirmCommitWithoutFiles
- Text.Workspace
- Text.Workspace.Configure
</details>
### pt_BR.axaml: 93.52%
<details>
<summary>Missing Keys</summary>
- Text.About.Chart
- Text.AIAssistant
- Text.AIAssistant.Tip
- Text.CherryPick.AppendSourceToMessage
- Text.CherryPick.Mainline
- Text.CherryPick.Mainline.Tips
- Text.CommitCM.CherryPickMultiple
- Text.CommitCM.SquashCommitsSinceThis
- Text.CommitDetail.Info.ContainsIn
- Text.CommitDetail.Info.ContainsIn.Title
- Text.CommitDetail.Info.WebLinks
- Text.Configure.Git.DefaultRemote
- Text.Configure.Git.EnableSignOff
- Text.Configure.IssueTracker.AddSampleGitLabIssue
- Text.Configure.IssueTracker.AddSampleGitLabMergeRequest
- Text.ConfigureWorkspace
- Text.ConfigureWorkspace.Color
- Text.ConfigureWorkspace.Restore
- Text.ConventionalCommit
- Text.ConventionalCommit.BreakingChanges
- Text.ConventionalCommit.ClosedIssue
- Text.ConventionalCommit.Detail
- Text.ConventionalCommit.Scope
- Text.ConventionalCommit.ShortDescription
- Text.ConventionalCommit.Type
- Text.CopyAllText
- Text.Discard.IncludeIgnored
- Text.FileHistory.FileContent
- Text.FileHistory.FileChange
- Text.GitLFS.Locks.OnlyMine
- Text.MoveRepositoryNode
- Text.MoveRepositoryNode.Target
- Text.Preference.Advanced
- Text.Push.CheckSubmodules
- Text.Squash.Into
- Text.Stash.OnlyStagedChanges
- Text.Stash.TipForSelectedFiles
- Text.Statistics.Overview
- Text.TagCM.CopyMessage
- Text.WorkingCopy.Staged.UnstageAll
- Text.WorkingCopy.Unstaged
- Text.WorkingCopy.Unstaged.Stage
- Text.WorkingCopy.Unstaged.StageAll
</details>
### ru_RU.axaml: 100.00%
<details>
<summary>Missing Keys</summary>
</details>
### zh_CN.axaml: 99.10%
<details>
<summary>Missing Keys</summary>
- Text.Preference.AI
- Text.Preference.AI.AnalyzeDiffPrompt
- Text.Preference.AI.ApiKey
- Text.Preference.AI.GenerateSubjectPrompt
- Text.Preference.AI.Model
- Text.Preference.AI.Server
</details>
### zh_TW.axaml: 100.00%
<details>
<summary>Missing Keys</summary>
</details>

View file

@ -1 +1 @@
8.35
8.36

View file

@ -0,0 +1,59 @@
const fs = require('fs-extra');
const path = require('path');
const xml2js = require('xml2js');
const repoRoot = path.join(__dirname, '../../');
const localesDir = path.join(repoRoot, 'src/Resources/Locales');
const enUSFile = path.join(localesDir, 'en_US.axaml');
const outputFile = path.join(repoRoot, 'TRANSLATION.md');
const readmeFile = path.join(repoRoot, 'README.md');
const parser = new xml2js.Parser();
async function parseXml(filePath) {
const data = await fs.readFile(filePath);
return parser.parseStringPromise(data);
}
async function calculateTranslationRate() {
const enUSData = await parseXml(enUSFile);
const enUSKeys = new Set(enUSData.ResourceDictionary['x:String'].map(item => item.$['x:Key']));
const translationRates = [];
const badges = [];
const files = (await fs.readdir(localesDir)).filter(file => file !== 'en_US.axaml' && file.endsWith('.axaml'));
// Add en_US badge first
badges.push(`[![en_US](https://img.shields.io/badge/en__US-100%25-brightgreen)](TRANSLATION.md)`);
for (const file of files) {
const filePath = path.join(localesDir, file);
const localeData = await parseXml(filePath);
const localeKeys = new Set(localeData.ResourceDictionary['x:String'].map(item => item.$['x:Key']));
const missingKeys = [...enUSKeys].filter(key => !localeKeys.has(key));
const translationRate = ((enUSKeys.size - missingKeys.length) / enUSKeys.size) * 100;
translationRates.push(`### ${file}: ${translationRate.toFixed(2)}%\n`);
translationRates.push(`<details>\n<summary>Missing Keys</summary>\n\n${missingKeys.map(key => `- ${key}`).join('\n')}\n\n</details>`);
// Add badges
const locale = file.replace('.axaml', '').replace('_', '__');
const badgeColor = translationRate === 100 ? 'brightgreen' : translationRate >= 75 ? 'yellow' : 'red';
badges.push(`[![${locale}](https://img.shields.io/badge/${locale}-${translationRate.toFixed(2)}%25-${badgeColor})](TRANSLATION.md)`);
}
console.log(translationRates.join('\n\n'));
await fs.writeFile(outputFile, translationRates.join('\n\n') + '\n', 'utf8');
// Update README.md
let readmeContent = await fs.readFile(readmeFile, 'utf8');
const badgeSection = `## Translation Status\n\n${badges.join(' ')}`;
console.log(badgeSection);
readmeContent = readmeContent.replace(/## Translation Status\n\n.*\n\n/, badgeSection + '\n\n');
await fs.writeFile(readmeFile, readmeContent, 'utf8');
}
calculateTranslationRate().catch(err => console.error(err));

View file

@ -195,6 +195,10 @@ namespace SourceGit.Commands
if (OperatingSystem.IsLinux())
start.Environment.Add("LANG", "en_US.UTF-8");
// Fix macOS `PATH` env
if (OperatingSystem.IsMacOS() && !string.IsNullOrEmpty(Native.OS.CustomPathEnv))
start.Environment.Add("PATH", Native.OS.CustomPathEnv);
// Force using this app as git editor.
switch (Editor)
{

View file

@ -4,19 +4,37 @@ namespace SourceGit.Commands
{
public class Commit : Command
{
public Commit(string repo, string message, bool amend, bool allowEmpty = false)
public Commit(string repo, string message, bool amend, bool signOff)
{
var file = Path.GetTempFileName();
File.WriteAllText(file, message);
_tmpFile = Path.GetTempFileName();
File.WriteAllText(_tmpFile, message);
WorkingDirectory = repo;
Context = repo;
TraitErrorAsOutput = true;
Args = $"commit --file=\"{file}\"";
Args = $"commit --allow-empty --file=\"{_tmpFile}\"";
if (amend)
Args += " --amend --no-edit";
if (allowEmpty)
Args += " --allow-empty";
if (signOff)
Args += " --signoff";
}
public bool Run()
{
var succ = Exec();
try
{
File.Delete(_tmpFile);
}
catch
{
// Ignore
}
return succ;
}
private string _tmpFile = string.Empty;
}
}

View file

@ -4,7 +4,7 @@ namespace SourceGit.Commands
{
public class Fetch : Command
{
public Fetch(string repo, string remote, bool prune, bool noTags, Action<string> outputHandler)
public Fetch(string repo, string remote, bool noTags, Action<string> outputHandler)
{
_outputHandler = outputHandler;
WorkingDirectory = repo;
@ -13,9 +13,6 @@ namespace SourceGit.Commands
SSHKey = new Config(repo).Get($"remote.{remote}.sshkey");
Args = "fetch --progress --verbose ";
if (prune)
Args += "--prune ";
if (noTags)
Args += "--no-tags ";
else
@ -24,16 +21,6 @@ namespace SourceGit.Commands
Args += remote;
}
public Fetch(string repo, string remote, string localBranch, string remoteBranch, Action<string> outputHandler)
{
_outputHandler = outputHandler;
WorkingDirectory = repo;
Context = repo;
TraitErrorAsOutput = true;
SSHKey = new Config(repo).Get($"remote.{remote}.sshkey");
Args = $"fetch --progress --verbose {remote} {remoteBranch}:{localBranch}";
}
protected override void OnReadline(string line)
{
_outputHandler?.Invoke(line);

View file

@ -32,31 +32,36 @@ namespace SourceGit.Commands
{
try
{
var summaries = new List<string>();
var summarybuilder = new StringBuilder();
var bodyBuilder = new StringBuilder();
foreach (var change in _changes)
{
if (_cancelToken.IsCancellationRequested)
return "";
_onProgress?.Invoke($"Analyzing {change.Path}...");
var summary = GenerateChangeSummary(change);
summaries.Add(summary);
summarybuilder.Append("- ");
summarybuilder.Append(summary);
summarybuilder.Append("(file: ");
summarybuilder.Append(change.Path);
summarybuilder.Append(")");
summarybuilder.AppendLine();
bodyBuilder.Append("- ");
bodyBuilder.Append(summary);
bodyBuilder.AppendLine();
}
if (_cancelToken.IsCancellationRequested)
return "";
_onProgress?.Invoke($"Generating commit message...");
var builder = new StringBuilder();
builder.Append(GenerateSubject(string.Join("", summaries)));
builder.Append("\n");
foreach (var summary in summaries)
{
builder.Append("\n- ");
builder.Append(summary.Trim());
}
return builder.ToString();
var body = bodyBuilder.ToString();
var subject = GenerateSubject(summarybuilder.ToString());
return string.Format("{0}\n\n{1}", subject, body);
}
catch (Exception e)
{
@ -70,15 +75,7 @@ namespace SourceGit.Commands
var rs = new GetDiffContent(_repo, new Models.DiffOption(change, false)).ReadToEnd();
var diff = rs.IsSuccess ? rs.StdOut : "unknown change";
var prompt = new StringBuilder();
prompt.AppendLine("You are an expert developer specialist in creating commits.");
prompt.AppendLine("Provide a super concise one sentence overall changes summary of the user `git diff` output following strictly the next rules:");
prompt.AppendLine("- Do not use any code snippets, imports, file routes or bullets points.");
prompt.AppendLine("- Do not mention the route of file that has been change.");
prompt.AppendLine("- Simply describe the MAIN GOAL of the changes.");
prompt.AppendLine("- Output directly the summary in plain text.`");
var rsp = Models.OpenAI.Chat(prompt.ToString(), $"Here is the `git diff` output: {diff}", _cancelToken);
var rsp = Models.OpenAI.Chat(Models.OpenAI.AnalyzeDiffPrompt, $"Here is the `git diff` output: {diff}", _cancelToken);
if (rsp != null && rsp.Choices.Count > 0)
return rsp.Choices[0].Message.Content;
@ -87,24 +84,7 @@ namespace SourceGit.Commands
private string GenerateSubject(string summary)
{
var prompt = new StringBuilder();
prompt.AppendLine("You are an expert developer specialist in creating commits messages.");
prompt.AppendLine("Your only goal is to retrieve a single commit message.");
prompt.AppendLine("Based on the provided user changes, combine them in ONE SINGLE commit message retrieving the global idea, following strictly the next rules:");
prompt.AppendLine("- Assign the commit {type} according to the next conditions:");
prompt.AppendLine(" feat: Only when adding a new feature.");
prompt.AppendLine(" fix: When fixing a bug.");
prompt.AppendLine(" docs: When updating documentation.");
prompt.AppendLine(" style: When changing elements styles or design and/or making changes to the code style (formatting, missing semicolons, etc.) without changing the code logic.");
prompt.AppendLine(" test: When adding or updating tests. ");
prompt.AppendLine(" chore: When making changes to the build process or auxiliary tools and libraries. ");
prompt.AppendLine(" revert: When undoing a previous commit.");
prompt.AppendLine(" refactor: When restructuring code without changing its external behavior, or is any of the other refactor types.");
prompt.AppendLine("- Do not add any issues numeration, explain your output nor introduce your answer.");
prompt.AppendLine("- Output directly only one commit message in plain text with the next format: {type}: {commit_message}.");
prompt.AppendLine("- Be as concise as possible, keep the message under 50 characters.");
var rsp = Models.OpenAI.Chat(prompt.ToString(), $"Here are the summaries changes: {summary}", _cancelToken);
var rsp = Models.OpenAI.Chat(Models.OpenAI.GenerateSubjectPrompt, $"Here are the summaries changes:\n{summary}", _cancelToken);
if (rsp != null && rsp.Choices.Count > 0)
return rsp.Choices[0].Message.Content;

View file

@ -112,15 +112,7 @@ namespace SourceGit.Commands
if (data.Length < 8)
return;
var idx = data.IndexOf(' ', StringComparison.Ordinal);
if (idx == -1)
{
_current.Parents.Add(data);
return;
}
_current.Parents.Add(data.Substring(0, idx));
_current.Parents.Add(data.Substring(idx + 1));
_current.Parents.AddRange(data.Split(separator: ' ', options: StringSplitOptions.RemoveEmptyEntries));
}
private void MarkFirstMerged()

View file

@ -73,15 +73,7 @@ namespace SourceGit.Commands
if (data.Length < 8)
return;
var idx = data.IndexOf(' ', StringComparison.Ordinal);
if (idx == -1)
{
_current.Commit.Parents.Add(data);
return;
}
_current.Commit.Parents.Add(data.Substring(0, idx));
_current.Commit.Parents.Add(data.Substring(idx + 1));
_current.Commit.Parents.AddRange(data.Split(separator: ' ', options: StringSplitOptions.RemoveEmptyEntries));
}
private List<Models.CommitWithMessage> _commits = new List<Models.CommitWithMessage>();

23
src/Commands/UpdateRef.cs Normal file
View file

@ -0,0 +1,23 @@
using System;
namespace SourceGit.Commands
{
public class UpdateRef : Command
{
public UpdateRef(string repo, string refName, string toRevision, Action<string> outputHandler)
{
_outputHandler = outputHandler;
WorkingDirectory = repo;
Context = repo;
Args = $"update-ref {refName} {toRevision}";
}
protected override void OnReadline(string line)
{
_outputHandler?.Invoke(line);
}
private Action<string> _outputHandler;
}
}

View file

@ -24,9 +24,12 @@ namespace SourceGit.Models
set => SetProperty(ref _content, value);
}
public string Apply(List<Change> changes)
public string Apply(Branch branch, List<Change> changes)
{
var content = _content.Replace("${files_num}", $"{changes.Count}");
var content = _content
.Replace("${files_num}", $"{changes.Count}")
.Replace("${branch_name}", branch.Name);
var matches = REG_COMMIT_TEMPLATE_FILES().Matches(content);
if (matches.Count == 0)
return content;

View file

@ -65,7 +65,7 @@ namespace SourceGit.Models
new ExternalMerger(2, "vscode_insiders", "Visual Studio Code - Insiders", "/usr/share/code-insiders/code-insiders", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""),
new ExternalMerger(3, "kdiff3", "KDiff3", "/usr/bin/kdiff3", "\"$REMOTE\" -b \"$BASE\" \"$LOCAL\" -o \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""),
new ExternalMerger(4, "beyond_compare", "Beyond Compare", "/usr/bin/bcomp", "\"$REMOTE\" \"$LOCAL\" \"$BASE\" \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""),
new ExternalMerger(5, "meld", "Meld", "/usr/bin/meld", "\"$LOCAL\" \"$BASE\" \"$REMOTE\" -output \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""),
new ExternalMerger(5, "meld", "Meld", "/usr/bin/meld", "\"$LOCAL\" \"$BASE\" \"$REMOTE\" --output \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""),
new ExternalMerger(6, "codium", "VSCodium", "/usr/share/codium/bin/codium", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""),
new ExternalMerger(7, "p4merge", "P4Merge", "/usr/local/bin/p4merge", "-tw 4 \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"", "-tw 4 \"$LOCAL\" \"$REMOTE\""),
};

70
src/Models/NumericSort.cs Normal file
View file

@ -0,0 +1,70 @@
namespace SourceGit.Models
{
public static class NumericSort
{
public static int Compare(string s1, string s2)
{
int len1 = s1.Length;
int len2 = s2.Length;
int marker1 = 0;
int marker2 = 0;
char[] tmp1 = new char[len1];
char[] tmp2 = new char[len2];
while (marker1 < len1 && marker2 < len2)
{
char c1 = s1[marker1];
char c2 = s2[marker2];
int loc1 = 0;
int loc2 = 0;
bool isDigit1 = char.IsDigit(c1);
do
{
tmp1[loc1] = c1;
loc1++;
marker1++;
if (marker1 < len1)
c1 = s1[marker1];
else
break;
} while (char.IsDigit(c1) == isDigit1);
bool isDigit2 = char.IsDigit(c2);
do
{
tmp2[loc2] = c2;
loc2++;
marker2++;
if (marker2 < len2)
c2 = s2[marker2];
else
break;
} while (char.IsDigit(c2) == isDigit2);
string sub1 = new string(tmp1, 0, loc1);
string sub2 = new string(tmp2, 0, loc2);
int result;
if (isDigit1 && isDigit2)
{
int num1 = int.Parse(sub1);
int num2 = int.Parse(sub2);
result = num1 - num2;
}
else
{
result = string.Compare(sub1, sub2, System.StringComparison.Ordinal);
}
if (result != 0)
return result;
}
return len1 - len2;
}
}
}

View file

@ -94,6 +94,18 @@ namespace SourceGit.Models
set;
}
public static string AnalyzeDiffPrompt
{
get;
set;
}
public static string GenerateSubjectPrompt
{
get;
set;
}
public static bool IsValid
{
get => !string.IsNullOrEmpty(Server) && !string.IsNullOrEmpty(Model);
@ -113,14 +125,14 @@ namespace SourceGit.Models
try
{
var task = client.PostAsync(Server, req, cancellation);
task.Wait();
task.Wait(cancellation);
var rsp = task.Result;
if (!rsp.IsSuccessStatusCode)
throw new Exception($"AI service returns error code {rsp.StatusCode}");
var reader = rsp.Content.ReadAsStringAsync(cancellation);
reader.Wait();
reader.Wait(cancellation);
return JsonSerializer.Deserialize(reader.Result, JsonCodeGen.Default.OpenAIChatResponse);
}

View file

@ -70,12 +70,6 @@ namespace SourceGit.Models
set;
} = true;
public bool AutoStageBeforeCommit
{
get;
set;
} = false;
public AvaloniaList<string> Filters
{
get;
@ -112,6 +106,12 @@ namespace SourceGit.Models
set;
} = 10;
public bool EnableSignOffForCommit
{
get;
set;
} = false;
public void PushCommitMessage(string message)
{
var existIdx = CommitMessages.IndexOf(message);
@ -169,6 +169,32 @@ namespace SourceGit.Models
return rule;
}
public IssueTrackerRule AddGitLabIssueTracker(string repoURL)
{
var rule = new IssueTrackerRule()
{
Name = "GitLab ISSUE",
RegexString = "#(\\d+)",
URLTemplate = string.IsNullOrEmpty(repoURL) ? "https://gitlab.com/username/repository/-/issues/$1" : $"{repoURL}/-/issues/$1",
};
IssueTrackerRules.Add(rule);
return rule;
}
public IssueTrackerRule AddGitLabMergeRequestTracker(string repoURL)
{
var rule = new IssueTrackerRule()
{
Name = "GitLab MR",
RegexString = "!(\\d+)",
URLTemplate = string.IsNullOrEmpty(repoURL) ? "https://gitlab.com/username/repository/-/merge_requests/$1" : $"{repoURL}/-/merge_requests/$1",
};
IssueTrackerRules.Add(rule);
return rule;
}
public void RemoveIssueTracker(IssueTrackerRule rule)
{
if (rule != null)

View file

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.Versioning;
using System.Text;
using Avalonia;
@ -19,30 +18,9 @@ namespace SourceGit.Native
DisableDefaultApplicationMenuItems = true,
});
{
var startInfo = new ProcessStartInfo();
startInfo.FileName = "zsh";
startInfo.Arguments = "--login -c \"echo $PATH\"";
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardOutput = true;
startInfo.StandardOutputEncoding = Encoding.UTF8;
try
{
var proc = new Process() { StartInfo = startInfo };
proc.Start();
var pathData = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
if (proc.ExitCode == 0)
Environment.SetEnvironmentVariable("PATH", pathData);
proc.Close();
}
catch
{
// Ignore error.
}
}
var customPathFile = Path.Combine(OS.DataDir, "PATH");
if (File.Exists(customPathFile))
OS.CustomPathEnv = File.ReadAllText(customPathFile).Trim();
}
public string FindGitExecutable()

View file

@ -26,6 +26,7 @@ namespace SourceGit.Native
public static string GitExecutable { get; set; } = string.Empty;
public static string ShellOrTerminal { get; set; } = string.Empty;
public static List<Models.ExternalTool> ExternalTools { get; set; } = [];
public static string CustomPathEnv { get; set; } = string.Empty;
static OS()
{

View file

@ -49,7 +49,7 @@
<x:String x:Key="Text.BinaryNotSupported" xml:space="preserve">BINÄRE DATEI NICHT UNTERSTÜTZT!!!</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.BranchCM.Checkout" xml:space="preserve">Auscheken von ${0}$...</x:String>
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">Auschecken von ${0}$...</x:String>
<x:String x:Key="Text.BranchCM.CompareWithBranch" xml:space="preserve">Mit Branch vergleichen</x:String>
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">Mit HEAD vergleichen</x:String>
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">Mit Worktree vergleichen</x:String>
@ -161,6 +161,13 @@
<x:String x:Key="Text.ConfigureWorkspace" xml:space="preserve">Arbeitsplätze</x:String>
<x:String x:Key="Text.ConfigureWorkspace.Color" xml:space="preserve">Farbe</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.ConventionalCommit" xml:space="preserve">Konventionelle Commit-Hilfe</x:String>
<x:String x:Key="Text.ConventionalCommit.BreakingChanges" xml:space="preserve">Inkompatible Änderung:</x:String>
<x:String x:Key="Text.ConventionalCommit.ClosedIssue" xml:space="preserve">Geschlossenes Ticket:</x:String>
<x:String x:Key="Text.ConventionalCommit.Detail" xml:space="preserve">Änderungen im Detail:</x:String>
<x:String x:Key="Text.ConventionalCommit.Scope" xml:space="preserve">Geltungsbereich:</x:String>
<x:String x:Key="Text.ConventionalCommit.ShortDescription" xml:space="preserve">Kurzbeschreibung:</x:String>
<x:String x:Key="Text.ConventionalCommit.Type" xml:space="preserve">Art der Änderung:</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.CopyMessage" xml:space="preserve">COMMIT-NACHRICHT KOPIEREN</x:String>
@ -243,7 +250,6 @@
<x:String x:Key="Text.Fetch" xml:space="preserve">Fetch</x:String>
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Alle Remotes fetchen</x:String>
<x:String x:Key="Text.Fetch.NoTags" xml:space="preserve">Ohne Tags fetchen</x:String>
<x:String x:Key="Text.Fetch.Prune" xml:space="preserve">Alle verwaisten Branches entfernen</x:String>
<x:String x:Key="Text.Fetch.Remote" xml:space="preserve">Remote:</x:String>
<x:String x:Key="Text.Fetch.Title" xml:space="preserve">Remote-Änderungen fetchen</x:String>
<x:String x:Key="Text.FileCM.AssumeUnchanged" xml:space="preserve">Als unverändert annehmen</x:String>
@ -324,6 +330,9 @@
<x:String x:Key="Text.Histories.Header.SHA" xml:space="preserve">SHA</x:String>
<x:String x:Key="Text.Histories.Header.Time" xml:space="preserve">COMMIT ZEITPUNKT</x:String>
<x:String x:Key="Text.Histories.Selected" xml:space="preserve">{0} COMMITS AUSGEWÄHLT</x:String>
<x:String x:Key="Text.Histories.Tips" xml:space="preserve">Halte 'Strg' oder 'Umschalt', um mehrere Commits auszuwählen.</x:String>
<x:String x:Key="Text.Histories.Tips.MacOS" xml:space="preserve">Halte ⌘ oder ⇧, um mehrere Commits auszuwählen</x:String>
<x:String x:Key="Text.Histories.Tips.Prefix" xml:space="preserve">TIPPS:</x:String>
<x:String x:Key="Text.Hotkeys" xml:space="preserve">Tastaturkürzel Referenz</x:String>
<x:String x:Key="Text.Hotkeys.Global" xml:space="preserve">GLOBAL</x:String>
<x:String x:Key="Text.Hotkeys.Global.CancelPopup" xml:space="preserve">Aktuelles Popup schließen</x:String>
@ -484,7 +493,6 @@
<x:String x:Key="Text.RemoteCM.Fetch" xml:space="preserve">Fetch</x:String>
<x:String x:Key="Text.RemoteCM.OpenInBrowser" xml:space="preserve">Im Browser öffnen</x:String>
<x:String x:Key="Text.RemoteCM.Prune" xml:space="preserve">Prune</x:String>
<x:String x:Key="Text.RemoteCM.Prune.Target" xml:space="preserve">Ziel:</x:String>
<x:String x:Key="Text.RemoveWorktree" xml:space="preserve">Bestätige das entfernen des Worktrees</x:String>
<x:String x:Key="Text.RemoveWorktree.Force" xml:space="preserve">Aktiviere `--force` Option</x:String>
<x:String x:Key="Text.RemoveWorktree.Target" xml:space="preserve">Ziel:</x:String>
@ -499,6 +507,7 @@
<x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">Alles löschen</x:String>
<x:String x:Key="Text.Repository.Configure" xml:space="preserve">Repository Einstellungen</x:String>
<x:String x:Key="Text.Repository.Continue" xml:space="preserve">WEITER</x:String>
<x:String x:Key="Text.Repository.EnableReflog" xml:space="preserve">Option '--reflog' einschalten</x:String>
<x:String x:Key="Text.Repository.Explore" xml:space="preserve">Öffne im Datei-Browser</x:String>
<x:String x:Key="Text.Repository.Filter" xml:space="preserve">Suche Branches/Tags/Submodule</x:String>
<x:String x:Key="Text.Repository.FilterCommitPrefix" xml:space="preserve">GEFILTERT:</x:String>
@ -591,6 +600,7 @@
<x:String x:Key="Text.Submodule.Remove" xml:space="preserve">Submodul löschen</x:String>
<x:String x:Key="Text.Sure" xml:space="preserve">OK</x:String>
<x:String x:Key="Text.TagCM.Copy" xml:space="preserve">Tag-Namen kopieren</x:String>
<x:String x:Key="Text.TagCM.CopyMessage" xml:space="preserve">Tag-Nachricht kopieren</x:String>
<x:String x:Key="Text.TagCM.Delete" xml:space="preserve">Lösche ${0}$...</x:String>
<x:String x:Key="Text.TagCM.Push" xml:space="preserve">Pushe ${0}$...</x:String>
<x:String x:Key="Text.URL" xml:space="preserve">URL:</x:String>
@ -622,7 +632,6 @@
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">Ignoriere Dateien im selben Ordner</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ignoriere nur diese Datei</x:String>
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Amend</x:String>
<x:String x:Key="Text.WorkingCopy.AutoStage" xml:space="preserve">Auto-Stage</x:String>
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Du kannst diese Datei jetzt stagen.</x:String>
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">COMMIT</x:String>
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">COMMIT &amp; PUSH</x:String>

View file

@ -143,9 +143,12 @@
<x:String x:Key="Text.Configure.Git.AutoFetch" xml:space="preserve">Fetch remotes automatically</x:String>
<x:String x:Key="Text.Configure.Git.AutoFetchIntervalSuffix" xml:space="preserve">Minute(s)</x:String>
<x:String x:Key="Text.Configure.Git.DefaultRemote" xml:space="preserve">Default Remote</x:String>
<x:String x:Key="Text.Configure.Git.EnableSignOff" xml:space="preserve">Enable --signoff for commit</x:String>
<x:String x:Key="Text.Configure.IssueTracker" xml:space="preserve">ISSUE TRACKER</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGithub" xml:space="preserve">Add Sample Github Rule</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleJira" xml:space="preserve">Add Sample Jira Rule</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGitLabIssue" xml:space="preserve">Add Sample GitLab Issue Rule</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGitLabMergeRequest" xml:space="preserve">Add Sample GitLab Merge Request Rule</x:String>
<x:String x:Key="Text.Configure.IssueTracker.NewRule" xml:space="preserve">New Rule</x:String>
<x:String x:Key="Text.Configure.IssueTracker.Regex" xml:space="preserve">Issue Regex Expression:</x:String>
<x:String x:Key="Text.Configure.IssueTracker.RuleName" xml:space="preserve">Rule Name:</x:String>
@ -247,7 +250,6 @@
<x:String x:Key="Text.Fetch" xml:space="preserve">Fetch</x:String>
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Fetch all remotes</x:String>
<x:String x:Key="Text.Fetch.NoTags" xml:space="preserve">Fetch without tags</x:String>
<x:String x:Key="Text.Fetch.Prune" xml:space="preserve">Prune remote dead branches</x:String>
<x:String x:Key="Text.Fetch.Remote" xml:space="preserve">Remote:</x:String>
<x:String x:Key="Text.Fetch.Title" xml:space="preserve">Fetch Remote Changes</x:String>
<x:String x:Key="Text.FileCM.AssumeUnchanged" xml:space="preserve">Assume unchanged</x:String>
@ -399,10 +401,13 @@
<x:String x:Key="Text.Period.LastYear" xml:space="preserve">Last year</x:String>
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} years ago</x:String>
<x:String x:Key="Text.Preference" xml:space="preserve">Preference</x:String>
<x:String x:Key="Text.Preference.Advanced" xml:space="preserve">Advanced Options</x:String>
<x:String x:Key="Text.Preference.AI" xml:space="preserve">OPEN AI</x:String>
<x:String x:Key="Text.Preference.AI.Server" xml:space="preserve">Server</x:String>
<x:String x:Key="Text.Preference.AI.AnalyzeDiffPrompt" xml:space="preserve">Analyze Diff Prompt</x:String>
<x:String x:Key="Text.Preference.AI.ApiKey" xml:space="preserve">API Key</x:String>
<x:String x:Key="Text.Preference.AI.GenerateSubjectPrompt" xml:space="preserve">Generate Subject Prompt</x:String>
<x:String x:Key="Text.Preference.AI.Model" xml:space="preserve">Model</x:String>
<x:String x:Key="Text.Preference.AI.Server" xml:space="preserve">Server</x:String>
<x:String x:Key="Text.Preference.Appearance" xml:space="preserve">APPEARANCE</x:String>
<x:String x:Key="Text.Preference.Appearance.DefaultFont" xml:space="preserve">Default Font</x:String>
<x:String x:Key="Text.Preference.Appearance.DefaultFontSize" xml:space="preserve">Default Font Size</x:String>
@ -491,7 +496,6 @@
<x:String x:Key="Text.RemoteCM.Fetch" xml:space="preserve">Fetch</x:String>
<x:String x:Key="Text.RemoteCM.OpenInBrowser" xml:space="preserve">Open In Browser</x:String>
<x:String x:Key="Text.RemoteCM.Prune" xml:space="preserve">Prune</x:String>
<x:String x:Key="Text.RemoteCM.Prune.Target" xml:space="preserve">Target:</x:String>
<x:String x:Key="Text.RemoveWorktree" xml:space="preserve">Confirm to Remove Worktree</x:String>
<x:String x:Key="Text.RemoveWorktree.Force" xml:space="preserve">Enable `--force` Option</x:String>
<x:String x:Key="Text.RemoveWorktree.Target" xml:space="preserve">Target:</x:String>
@ -631,13 +635,13 @@
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">Ignore files in the same folder</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ignore this file only</x:String>
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Amend</x:String>
<x:String x:Key="Text.WorkingCopy.AutoStage" xml:space="preserve">Auto-Stage</x:String>
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">You can stage this file now.</x:String>
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">COMMIT</x:String>
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">COMMIT &amp; PUSH</x:String>
<x:String x:Key="Text.WorkingCopy.CommitMessageHelper" xml:space="preserve">Template/Histories</x:String>
<x:String x:Key="Text.WorkingCopy.CommitTip" xml:space="preserve">Trigger click event</x:String>
<x:String x:Key="Text.WorkingCopy.CommitWithAutoStage" xml:space="preserve">Stage all changes and commit</x:String>
<x:String x:Key="Text.WorkingCopy.ConfirmCommitWithoutFiles" xml:space="preserve">Empty commit detected! Do you want to continue (--allow-empty)?</x:String>
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">CONFLICTS DETECTED</x:String>
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">FILE CONFLICTS ARE RESOLVED</x:String>
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">INCLUDE UNTRACKED FILES</x:String>

View file

@ -229,7 +229,6 @@
<x:String x:Key="Text.Fetch" xml:space="preserve">Fetch</x:String>
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Fetch toutes les branches distantes</x:String>
<x:String x:Key="Text.Fetch.NoTags" xml:space="preserve">Fetch sans les tags</x:String>
<x:String x:Key="Text.Fetch.Prune" xml:space="preserve">Élaguer les branches mortes distantes</x:String>
<x:String x:Key="Text.Fetch.Remote" xml:space="preserve">Remote :</x:String>
<x:String x:Key="Text.Fetch.Title" xml:space="preserve">Récupérer les changements distants</x:String>
<x:String x:Key="Text.FileCM.AssumeUnchanged" xml:space="preserve">Présumer inchangé</x:String>
@ -454,7 +453,6 @@
<x:String x:Key="Text.RemoteCM.Fetch" xml:space="preserve">Fetch</x:String>
<x:String x:Key="Text.RemoteCM.OpenInBrowser" xml:space="preserve">Open In Browser</x:String>
<x:String x:Key="Text.RemoteCM.Prune" xml:space="preserve">Prune</x:String>
<x:String x:Key="Text.RemoteCM.Prune.Target" xml:space="preserve">Target:</x:String>
<x:String x:Key="Text.RemoveWorktree" xml:space="preserve">Confirm to Remove Worktree</x:String>
<x:String x:Key="Text.RemoveWorktree.Force" xml:space="preserve">Enable `--force` Option</x:String>
<x:String x:Key="Text.RemoveWorktree.Target" xml:space="preserve">Target:</x:String>
@ -582,7 +580,6 @@
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">Ignorer les fichiers dans le même dossier</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">N'ignorer que ce fichier</x:String>
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Amender</x:String>
<x:String x:Key="Text.WorkingCopy.AutoStage" xml:space="preserve">Auto-Index</x:String>
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Vous pouvez indexer ce fichier.</x:String>
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">COMMIT</x:String>
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">COMMIT &amp; PUSH</x:String>

View file

@ -2,102 +2,102 @@
<ResourceDictionary.MergedDictionaries>
<ResourceInclude Source="avares://SourceGit/Resources/Locales/en_US.axaml"/>
</ResourceDictionary.MergedDictionaries>
<x:String x:Key="Text.About" xml:space="preserve">Sobre</x:String>
<x:String x:Key="Text.About.Menu" xml:space="preserve">Sobre o SourceGit</x:String>
<x:String x:Key="Text.About.BuildWith" xml:space="preserve">• Construído com </x:String>
<x:String x:Key="Text.About.Copyright" xml:space="preserve">© 2024 sourcegit-scm</x:String>
<x:String x:Key="Text.About.Editor" xml:space="preserve">• Editor de Texto de </x:String>
<x:String x:Key="Text.About.Fonts" xml:space="preserve">• Fontes monoespaçadas de </x:String>
<x:String x:Key="Text.About.Menu" xml:space="preserve">Sobre o SourceGit</x:String>
<x:String x:Key="Text.About.SourceCode" xml:space="preserve">• Código-fonte pode ser encontrado em </x:String>
<x:String x:Key="Text.About.SubTitle" xml:space="preserve">Cliente Git GUI Livre e de Código Aberto</x:String>
<x:String x:Key="Text.AddWorktree" xml:space="preserve">Adicionar Worktree</x:String>
<x:String x:Key="Text.AddWorktree.WhatToCheckout" xml:space="preserve">O que Checar:</x:String>
<x:String x:Key="Text.AddWorktree.WhatToCheckout.Existing" xml:space="preserve">Branch Existente</x:String>
<x:String x:Key="Text.AddWorktree.WhatToCheckout.CreateNew" xml:space="preserve">Criar Nova Branch</x:String>
<x:String x:Key="Text.AddWorktree.Location" xml:space="preserve">Localização:</x:String>
<x:String x:Key="Text.About" xml:space="preserve">Sobre</x:String>
<x:String x:Key="Text.AddWorktree.Location.Placeholder" xml:space="preserve">Caminho para este worktree. Caminho relativo é suportado.</x:String>
<x:String x:Key="Text.AddWorktree.Name" xml:space="preserve">Nome da Branch:</x:String>
<x:String x:Key="Text.AddWorktree.Location" xml:space="preserve">Localização:</x:String>
<x:String x:Key="Text.AddWorktree.Name.Placeholder" xml:space="preserve">Opcional. O padrão é o nome da pasta de destino.</x:String>
<x:String x:Key="Text.AddWorktree.Name" xml:space="preserve">Nome do Branch:</x:String>
<x:String x:Key="Text.AddWorktree.Tracking.Toggle" xml:space="preserve">Rastreando branch remoto</x:String>
<x:String x:Key="Text.AddWorktree.Tracking" xml:space="preserve">Rastrear Branch:</x:String>
<x:String x:Key="Text.AddWorktree.Tracking.Toggle" xml:space="preserve">Rastreando branch remota</x:String>
<x:String x:Key="Text.Apply" xml:space="preserve">Patch</x:String>
<x:String x:Key="Text.Apply.Error" xml:space="preserve">Erro</x:String>
<x:String x:Key="Text.AddWorktree.WhatToCheckout.CreateNew" xml:space="preserve">Criar Novo Branch</x:String>
<x:String x:Key="Text.AddWorktree.WhatToCheckout.Existing" xml:space="preserve">Branch Existente</x:String>
<x:String x:Key="Text.AddWorktree.WhatToCheckout" xml:space="preserve">O que Checar:</x:String>
<x:String x:Key="Text.AddWorktree" xml:space="preserve">Adicionar Worktree</x:String>
<x:String x:Key="Text.Apply.Error.Desc" xml:space="preserve">Erros levantados e se recusa a aplicar o patch</x:String>
<x:String x:Key="Text.Apply.ErrorAll" xml:space="preserve">Erro Total</x:String>
<x:String x:Key="Text.Apply.Error" xml:space="preserve">Erro</x:String>
<x:String x:Key="Text.Apply.ErrorAll.Desc" xml:space="preserve">Semelhante a 'erro', mas mostra mais</x:String>
<x:String x:Key="Text.Apply.File" xml:space="preserve">Arquivo de Patch:</x:String>
<x:String x:Key="Text.Apply.ErrorAll" xml:space="preserve">Erro Total</x:String>
<x:String x:Key="Text.Apply.File.Placeholder" xml:space="preserve">Selecione o arquivo .patch para aplicar</x:String>
<x:String x:Key="Text.Apply.File" xml:space="preserve">Arquivo de Patch:</x:String>
<x:String x:Key="Text.Apply.IgnoreWS" xml:space="preserve">Ignorar mudanças de espaço em branco</x:String>
<x:String x:Key="Text.Apply.NoWarn" xml:space="preserve">Sem Aviso</x:String>
<x:String x:Key="Text.Apply.NoWarn.Desc" xml:space="preserve">Desativa o aviso de espaço em branco no final</x:String>
<x:String x:Key="Text.Apply.NoWarn" xml:space="preserve">Sem Aviso</x:String>
<x:String x:Key="Text.Apply.Title" xml:space="preserve">Aplicar Patch</x:String>
<x:String x:Key="Text.Apply.Warn" xml:space="preserve">Aviso</x:String>
<x:String x:Key="Text.Apply.Warn.Desc" xml:space="preserve">Emite avisos para alguns erros, mas aplica</x:String>
<x:String x:Key="Text.Apply.Warn" xml:space="preserve">Aviso</x:String>
<x:String x:Key="Text.Apply.WS" xml:space="preserve">Espaço em Branco:</x:String>
<x:String x:Key="Text.Archive" xml:space="preserve">Arquivar...</x:String>
<x:String x:Key="Text.Archive.File" xml:space="preserve">Salvar Arquivo Como:</x:String>
<x:String x:Key="Text.Apply" xml:space="preserve">Patch</x:String>
<x:String x:Key="Text.Archive.File.Placeholder" xml:space="preserve">Selecione o caminho do arquivo de arquivo</x:String>
<x:String x:Key="Text.Archive.File" xml:space="preserve">Salvar Arquivo Como:</x:String>
<x:String x:Key="Text.Archive.Revision" xml:space="preserve">Revisão:</x:String>
<x:String x:Key="Text.Archive.Title" xml:space="preserve">Arquivar</x:String>
<x:String x:Key="Text.Archive" xml:space="preserve">Arquivar...</x:String>
<x:String x:Key="Text.Askpass" xml:space="preserve">SourceGit Askpass</x:String>
<x:String x:Key="Text.AssumeUnchanged" xml:space="preserve">ARQUIVOS ASSUMIDOS COMO INALTERADOS</x:String>
<x:String x:Key="Text.AssumeUnchanged.Empty" xml:space="preserve">NENHUM ARQUIVO ASSUMIDO COMO INALTERADO</x:String>
<x:String x:Key="Text.AssumeUnchanged.Empty" xml:space="preserve">NENHUM ARQUIVO CONSIDERADO SEM ALTERAÇÕES</x:String>
<x:String x:Key="Text.AssumeUnchanged.Remove" xml:space="preserve">REMOVER</x:String>
<x:String x:Key="Text.AssumeUnchanged" xml:space="preserve">ARQUIVOS CONSIDERADOS SEM ALTERAÇÕES</x:String>
<x:String x:Key="Text.BinaryNotSupported" xml:space="preserve">ARQUIVO BINÁRIO NÃO SUPORTADO!!!</x:String>
<x:String x:Key="Text.Blame" xml:space="preserve">Responsabilizar</x:String>
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">RESPONSABILIZAÇÃO PARA ESTE ARQUIVO NÃO SUPORTADA!!!</x:String>
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">Checar ${0}$...</x:String>
<x:String x:Key="Text.Blame" xml:space="preserve">Blame</x:String>
<x:String x:Key="Text.BlameTypeNotSupported" xml:space="preserve">BLAME NESTE ARQUIVO NÃO É SUPORTADO!!!</x:String>
<x:String x:Key="Text.BranchCM.Checkout" xml:space="preserve">Checkout ${0}$...</x:String>
<x:String x:Key="Text.BranchCM.CompareWithBranch" xml:space="preserve">Comparar com Branch</x:String>
<x:String x:Key="Text.BranchCM.CompareWithHead" xml:space="preserve">Comparar com HEAD</x:String>
<x:String x:Key="Text.BranchCM.CompareWithWorktree" xml:space="preserve">Comparar com Worktree</x:String>
<x:String x:Key="Text.BranchCM.CopyName" xml:space="preserve">Copiar Nome da Branch</x:String>
<x:String x:Key="Text.BranchCM.CopyName" xml:space="preserve">Copiar Nome do Branch</x:String>
<x:String x:Key="Text.BranchCM.Delete" xml:space="preserve">Excluir ${0}$...</x:String>
<x:String x:Key="Text.BranchCM.DeleteMultiBranches" xml:space="preserve">Excluir {0} branches selecionadas</x:String>
<x:String x:Key="Text.BranchCM.DeleteMultiBranches" xml:space="preserve">Excluir {0} branches selecionados</x:String>
<x:String x:Key="Text.BranchCM.DiscardAll" xml:space="preserve">Descartar todas as alterações</x:String>
<x:String x:Key="Text.BranchCM.FastForward" xml:space="preserve">Avançar para ${0}$</x:String>
<x:String x:Key="Text.BranchCM.FastForward" xml:space="preserve">Fast-Forward para ${0}$</x:String>
<x:String x:Key="Text.BranchCM.Finish" xml:space="preserve">Git Flow - Finalizar ${0}$</x:String>
<x:String x:Key="Text.BranchCM.Merge" xml:space="preserve">Mesclar ${0}$ em ${1}$...</x:String>
<x:String x:Key="Text.BranchCM.Pull" xml:space="preserve">Puxar ${0}$</x:String>
<x:String x:Key="Text.BranchCM.PullInto" xml:space="preserve">Puxar ${0}$ para ${1}$...</x:String>
<x:String x:Key="Text.BranchCM.Push" xml:space="preserve">Empurrar ${0}$</x:String>
<x:String x:Key="Text.BranchCM.Push" xml:space="preserve">Subir ${0}$</x:String>
<x:String x:Key="Text.BranchCM.Rebase" xml:space="preserve">Rebase ${0}$ em ${1}$...</x:String>
<x:String x:Key="Text.BranchCM.Rename" xml:space="preserve">Renomear ${0}$...</x:String>
<x:String x:Key="Text.BranchCM.Tracking" xml:space="preserve">Definir Branch de Rastreamento</x:String>
<x:String x:Key="Text.BranchCM.UnsetUpstream" xml:space="preserve">Desfazer Upstream</x:String>
<x:String x:Key="Text.BranchCompare" xml:space="preserve">Comparar Branch</x:String>
<x:String x:Key="Text.BranchCM.UnsetUpstream" xml:space="preserve">Remover Upstream</x:String>
<x:String x:Key="Text.BranchCompare" xml:space="preserve">Comparação de Branches</x:String>
<x:String x:Key="Text.Bytes" xml:space="preserve">Bytes</x:String>
<x:String x:Key="Text.Cancel" xml:space="preserve">CANCELAR</x:String>
<x:String x:Key="Text.ChangeCM.CheckoutFirstParentRevision" xml:space="preserve">Resetar para Revisão Pai</x:String>
<x:String x:Key="Text.ChangeCM.CheckoutThisRevision" xml:space="preserve">Resetar para Esta Revisão</x:String>
<x:String x:Key="Text.ChangeCM.CheckoutFirstParentRevision" xml:space="preserve">Resetar to Revisão Pai</x:String>
<x:String x:Key="Text.ChangeDisplayMode" xml:space="preserve">ALTERAR MODO DE EXIBIÇÃO</x:String>
<x:String x:Key="Text.ChangeDisplayMode.Grid" xml:space="preserve">Mostrar como Grade</x:String>
<x:String x:Key="Text.ChangeDisplayMode.Grid" xml:space="preserve">Mostrar como Lista de Arquivos e Diretórios</x:String>
<x:String x:Key="Text.ChangeDisplayMode.List" xml:space="preserve">Mostrar como Lista de Caminhos</x:String>
<x:String x:Key="Text.ChangeDisplayMode.Tree" xml:space="preserve">Mostrar como Árvore de Arquivos do Sistema</x:String>
<x:String x:Key="Text.Checkout" xml:space="preserve">Checkout Branch</x:String>
<x:String x:Key="Text.Checkout.Commit" xml:space="preserve">Checkout Commit</x:String>
<x:String x:Key="Text.Checkout.Commit.Warning" xml:space="preserve">Aviso: Ao fazer o checkout de um commit, seu Head ficará desanexado</x:String>
<x:String x:Key="Text.ChangeDisplayMode.Tree" xml:space="preserve">Mostrar como Árvore de Sistema de Arquivos</x:String>
<x:String x:Key="Text.ChangeDisplayMode" xml:space="preserve">ALTERAR MODO DE EXIBIÇÃO</x:String>
<x:String x:Key="Text.Checkout.Commit.Target" xml:space="preserve">Commit:</x:String>
<x:String x:Key="Text.Checkout.Target" xml:space="preserve">Branch:</x:String>
<x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">Alterações Locais:</x:String>
<x:String x:Key="Text.Checkout.Commit.Warning" xml:space="preserve">Aviso: Ao fazer o checkout de um commit, seu Head ficará desanexado</x:String>
<x:String x:Key="Text.Checkout.Commit" xml:space="preserve">Checkout Commit</x:String>
<x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">Descartar</x:String>
<x:String x:Key="Text.Checkout.LocalChanges.DoNothing" xml:space="preserve">Nada</x:String>
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Stash &amp; Reaplicar</x:String>
<x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry-Pick</x:String>
<x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">Alterações Locais:</x:String>
<x:String x:Key="Text.Checkout.Target" xml:space="preserve">Branch:</x:String>
<x:String x:Key="Text.Checkout" xml:space="preserve">Checkout Branch</x:String>
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">Commit(s):</x:String>
<x:String x:Key="Text.CherryPick.CommitChanges" xml:space="preserve">Commitar todas as alterações</x:String>
<x:String x:Key="Text.ClearStashes" xml:space="preserve">Limpar Stashes</x:String>
<x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry-Pick</x:String>
<x:String x:Key="Text.ClearStashes.Message" xml:space="preserve">Você está tentando limpar todas as stashes. Tem certeza que deseja continuar?</x:String>
<x:String x:Key="Text.Clone" xml:space="preserve">Clonar Repositório Remoto</x:String>
<x:String x:Key="Text.Clone.AdditionalParam" xml:space="preserve">Parâmetros Extras:</x:String>
<x:String x:Key="Text.ClearStashes" xml:space="preserve">Limpar Stashes</x:String>
<x:String x:Key="Text.Clone.AdditionalParam.Placeholder" xml:space="preserve">Argumentos adicionais para clonar o repositório. Opcional.</x:String>
<x:String x:Key="Text.Clone.LocalName" xml:space="preserve">Nome Local:</x:String>
<x:String x:Key="Text.Clone.AdditionalParam" xml:space="preserve">Parâmetros Extras:</x:String>
<x:String x:Key="Text.Clone.LocalName.Placeholder" xml:space="preserve">Nome do repositório. Opcional.</x:String>
<x:String x:Key="Text.Clone.LocalName" xml:space="preserve">Nome Local:</x:String>
<x:String x:Key="Text.Clone.ParentFolder" xml:space="preserve">Pasta Pai:</x:String>
<x:String x:Key="Text.Clone.RemoteURL" xml:space="preserve">URL do Repositório:</x:String>
<x:String x:Key="Text.Clone" xml:space="preserve">Clonar Repositório Remoto</x:String>
<x:String x:Key="Text.Close" xml:space="preserve">FECHAR</x:String>
<x:String x:Key="Text.CodeEditor" xml:space="preserve">Editor</x:String>
<x:String x:Key="Text.CommitCM.CherryPick" xml:space="preserve">Cherry-Pick Este Commit</x:String>
<x:String x:Key="Text.CommitCM.Checkout" xml:space="preserve">Checar Commit</x:String>
<x:String x:Key="Text.CommitCM.CherryPick" xml:space="preserve">Cherry-Pick Este Commit</x:String>
<x:String x:Key="Text.CommitCM.CompareWithHead" xml:space="preserve">Comparar com HEAD</x:String>
<x:String x:Key="Text.CommitCM.CompareWithWorktree" xml:space="preserve">Comparar com Worktree</x:String>
<x:String x:Key="Text.CommitCM.CopyInfo" xml:space="preserve">Copiar Informações</x:String>
@ -109,12 +109,11 @@
<x:String x:Key="Text.CommitCM.Reword" xml:space="preserve">Modificar Mensagem</x:String>
<x:String x:Key="Text.CommitCM.SaveAsPatch" xml:space="preserve">Salvar como Patch...</x:String>
<x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">Mesclar ao Commit Pai</x:String>
<x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">ALTERAÇÕES</x:String>
<x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">Buscar Alterações...</x:String>
<x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">ARQUIVOS</x:String>
<x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">ALTERAÇÕES</x:String>
<x:String x:Key="Text.CommitDetail.Files.LFS" xml:space="preserve">Arquivo LFS</x:String>
<x:String x:Key="Text.CommitDetail.Files.Submodule" xml:space="preserve">Submódulo</x:String>
<x:String x:Key="Text.CommitDetail.Info" xml:space="preserve">INFORMAÇÃO</x:String>
<x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">ARQUIVOS</x:String>
<x:String x:Key="Text.CommitDetail.Info.Author" xml:space="preserve">AUTOR</x:String>
<x:String x:Key="Text.CommitDetail.Info.Changed" xml:space="preserve">ALTERADO</x:String>
<x:String x:Key="Text.CommitDetail.Info.Committer" xml:space="preserve">COMMITTER</x:String>
@ -123,86 +122,88 @@
<x:String x:Key="Text.CommitDetail.Info.Parents" xml:space="preserve">PAIS</x:String>
<x:String x:Key="Text.CommitDetail.Info.Refs" xml:space="preserve">REFERÊNCIAS</x:String>
<x:String x:Key="Text.CommitDetail.Info.SHA" xml:space="preserve">SHA</x:String>
<x:String x:Key="Text.CommitMessageTextBox.SubjectPlaceholder" xml:space="preserve">Insira o assunto do commit</x:String>
<x:String x:Key="Text.CommitDetail.Info" xml:space="preserve">INFORMAÇÃO</x:String>
<x:String x:Key="Text.CommitMessageTextBox.MessagePlaceholder" xml:space="preserve">Descrição</x:String>
<x:String x:Key="Text.Configure" xml:space="preserve">Configurar Repositório</x:String>
<x:String x:Key="Text.Configure.CommitMessageTemplate" xml:space="preserve">TEMPLATE DE COMMIT</x:String>
<x:String x:Key="Text.Configure.CommitMessageTemplate.Name" xml:space="preserve">Nome do Template:</x:String>
<x:String x:Key="Text.CommitMessageTextBox.SubjectPlaceholder" xml:space="preserve">Insira o assunto do commit</x:String>
<x:String x:Key="Text.Configure.CommitMessageTemplate.Content" xml:space="preserve">Conteúdo do Template:</x:String>
<x:String x:Key="Text.Configure.Email" xml:space="preserve">Endereço de Email</x:String>
<x:String x:Key="Text.Configure.CommitMessageTemplate.Name" xml:space="preserve">Nome do Template:</x:String>
<x:String x:Key="Text.Configure.CommitMessageTemplate" xml:space="preserve">TEMPLATE DE COMMIT</x:String>
<x:String x:Key="Text.Configure.Email.Placeholder" xml:space="preserve">Endereço de email</x:String>
<x:String x:Key="Text.Configure.Git" xml:space="preserve">GIT</x:String>
<x:String x:Key="Text.Configure.Email" xml:space="preserve">Endereço de Email</x:String>
<x:String x:Key="Text.Configure.Git.AutoFetch" xml:space="preserve">Buscar remotos automaticamente</x:String>
<x:String x:Key="Text.Configure.Git.AutoFetchIntervalSuffix" xml:space="preserve">Minuto(s)</x:String>
<x:String x:Key="Text.Configure.IssueTracker" xml:space="preserve">RASTREADOR DE PROBLEMAS</x:String>
<x:String x:Key="Text.Configure.Git" xml:space="preserve">GIT</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGithub" xml:space="preserve">Adicionar Regra de Exemplo do Github</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleJira" xml:space="preserve">Adicionar Regra de Exemplo do Jira</x:String>
<x:String x:Key="Text.Configure.IssueTracker.NewRule" xml:space="preserve">Nova Regra</x:String>
<x:String x:Key="Text.Configure.IssueTracker.Regex" xml:space="preserve">Expressão Regex de Issue:</x:String>
<x:String x:Key="Text.Configure.IssueTracker.RuleName" xml:space="preserve">Nome da Regra:</x:String>
<x:String x:Key="Text.Configure.IssueTracker.URLTemplate" xml:space="preserve">URL de Resultado:</x:String>
<x:String x:Key="Text.Configure.IssueTracker.URLTemplate.Tip" xml:space="preserve">Por favor, use $1, $2 para acessar os valores de grupos do regex.</x:String>
<x:String x:Key="Text.Configure.Proxy" xml:space="preserve">Proxy HTTP</x:String>
<x:String x:Key="Text.Configure.IssueTracker.URLTemplate" xml:space="preserve">URL de Resultado:</x:String>
<x:String x:Key="Text.Configure.IssueTracker" xml:space="preserve">RASTREADOR DE PROBLEMAS</x:String>
<x:String x:Key="Text.Configure.Proxy.Placeholder" xml:space="preserve">Proxy HTTP usado por este repositório</x:String>
<x:String x:Key="Text.Configure.User" xml:space="preserve">Nome de Usuário</x:String>
<x:String x:Key="Text.Configure.Proxy" xml:space="preserve">Proxy HTTP</x:String>
<x:String x:Key="Text.Configure.User.Placeholder" xml:space="preserve">Nome de usuário para este repositório</x:String>
<x:String x:Key="Text.Configure.User" xml:space="preserve">Nome de Usuário</x:String>
<x:String x:Key="Text.Configure" xml:space="preserve">Configurar Repositório</x:String>
<x:String x:Key="Text.Copy" xml:space="preserve">Copiar</x:String>
<x:String x:Key="Text.CopyFileName" xml:space="preserve">Copiar Nome do Arquivo</x:String>
<x:String x:Key="Text.CopyMessage" xml:space="preserve">COPIAR MENSAGEM</x:String>
<x:String x:Key="Text.CopyPath" xml:space="preserve">Copiar Caminho</x:String>
<x:String x:Key="Text.CopyFileName" xml:space="preserve">Copiar Nome do Arquivo</x:String>
<x:String x:Key="Text.CreateBranch" xml:space="preserve">Criar Branch...</x:String>
<x:String x:Key="Text.CreateBranch.BasedOn" xml:space="preserve">Baseado Em:</x:String>
<x:String x:Key="Text.CreateBranch.Checkout" xml:space="preserve">Checar a branch criada</x:String>
<x:String x:Key="Text.CreateBranch.LocalChanges" xml:space="preserve">Alterações Locais:</x:String>
<x:String x:Key="Text.CreateBranch.Checkout" xml:space="preserve">Checar o branch criado</x:String>
<x:String x:Key="Text.CreateBranch.LocalChanges.Discard" xml:space="preserve">Descartar</x:String>
<x:String x:Key="Text.CreateBranch.LocalChanges.DoNothing" xml:space="preserve">Não Fazer Nada</x:String>
<x:String x:Key="Text.CreateBranch.LocalChanges.StashAndReply" xml:space="preserve">Guardar &amp; Reaplicar</x:String>
<x:String x:Key="Text.CreateBranch.Name" xml:space="preserve">Nome da Nova Branch:</x:String>
<x:String x:Key="Text.CreateBranch.Name.Placeholder" xml:space="preserve">Insira o nome da branch.</x:String>
<x:String x:Key="Text.CreateBranch.LocalChanges" xml:space="preserve">Alterações Locais:</x:String>
<x:String x:Key="Text.CreateBranch.Name.Placeholder" xml:space="preserve">Insira o nome do branch.</x:String>
<x:String x:Key="Text.CreateBranch.Name" xml:space="preserve">Nome do Novo Branch:</x:String>
<x:String x:Key="Text.CreateBranch.Title" xml:space="preserve">Criar Branch Local</x:String>
<x:String x:Key="Text.CreateTag" xml:space="preserve">Criar Tag...</x:String>
<x:String x:Key="Text.CreateBranch" xml:space="preserve">Criar Branch...</x:String>
<x:String x:Key="Text.CreateTag.BasedOn" xml:space="preserve">Nova Tag Em:</x:String>
<x:String x:Key="Text.CreateTag.GPGSign" xml:space="preserve">Assinatura GPG</x:String>
<x:String x:Key="Text.CreateTag.Message" xml:space="preserve">Mensagem da Tag:</x:String>
<x:String x:Key="Text.CreateTag.Message.Placeholder" xml:space="preserve">Opcional.</x:String>
<x:String x:Key="Text.CreateTag.Name" xml:space="preserve">Nome da Tag:</x:String>
<x:String x:Key="Text.CreateTag.Message" xml:space="preserve">Mensagem da Tag:</x:String>
<x:String x:Key="Text.CreateTag.Name.Placeholder" xml:space="preserve">Formato recomendado: v1.0.0-alpha</x:String>
<x:String x:Key="Text.CreateTag.Name" xml:space="preserve">Nome da Tag:</x:String>
<x:String x:Key="Text.CreateTag.PushToAllRemotes" xml:space="preserve">Enviar para todos os remotos após criação</x:String>
<x:String x:Key="Text.CreateTag.Title" xml:space="preserve">Criar Nova Tag</x:String>
<x:String x:Key="Text.CreateTag.Type" xml:space="preserve">Tipo:</x:String>
<x:String x:Key="Text.CreateTag.Type.Annotated" xml:space="preserve">anotada</x:String>
<x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">leve</x:String>
<x:String x:Key="Text.CreateTag.Type" xml:space="preserve">Tipo:</x:String>
<x:String x:Key="Text.CreateTag" xml:space="preserve">Criar Tag...</x:String>
<x:String x:Key="Text.CtrlClickTip" xml:space="preserve">Pressione Ctrl para iniciar diretamente</x:String>
<x:String x:Key="Text.Cut" xml:space="preserve">Recortar</x:String>
<x:String x:Key="Text.DeleteBranch" xml:space="preserve">Excluir Branch</x:String>
<x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">Branch:</x:String>
<x:String x:Key="Text.DeleteBranch.IsRemoteTip" xml:space="preserve">Você está prestes a excluir uma branch remota!!!</x:String>
<x:String x:Key="Text.DeleteBranch.WithTrackingRemote" xml:space="preserve">Também excluir branch remota ${0}$</x:String>
<x:String x:Key="Text.DeleteMultiBranch" xml:space="preserve">Excluir Múltiplas Branches</x:String>
<x:String x:Key="Text.DeleteMultiBranch.Tip" xml:space="preserve">Você está tentando excluir várias branches de uma vez. Certifique-se de verificar antes de agir!</x:String>
<x:String x:Key="Text.DeleteRemote" xml:space="preserve">Excluir Remoto</x:String>
<x:String x:Key="Text.DeleteBranch.WithTrackingRemote" xml:space="preserve">Também excluir branch remoto ${0}$</x:String>
<x:String x:Key="Text.DeleteBranch" xml:space="preserve">Excluir Branch</x:String>
<x:String x:Key="Text.DeleteMultiBranch.Tip" xml:space="preserve">Você está tentando excluir vários branches de uma vez. Certifique-se de verificar antes de agir!</x:String>
<x:String x:Key="Text.DeleteMultiBranch" xml:space="preserve">Excluir Múltiplos Branches</x:String>
<x:String x:Key="Text.DeleteRemote.Remote" xml:space="preserve">Remoto:</x:String>
<x:String x:Key="Text.DeleteRemote" xml:space="preserve">Excluir Remoto</x:String>
<x:String x:Key="Text.DeleteRepositoryNode.Target" xml:space="preserve">Alvo:</x:String>
<x:String x:Key="Text.DeleteRepositoryNode.TitleForGroup" xml:space="preserve">Confirmar Exclusão do Grupo</x:String>
<x:String x:Key="Text.DeleteRepositoryNode.TitleForRepository" xml:space="preserve">Confirmar Exclusão do Repositório</x:String>
<x:String x:Key="Text.DeleteSubmodule" xml:space="preserve">Excluir Submódulo</x:String>
<x:String x:Key="Text.DeleteSubmodule.Path" xml:space="preserve">Caminho do Submódulo:</x:String>
<x:String x:Key="Text.DeleteTag" xml:space="preserve">Excluir Tag</x:String>
<x:String x:Key="Text.DeleteSubmodule" xml:space="preserve">Excluir Submódulo</x:String>
<x:String x:Key="Text.DeleteTag.Tag" xml:space="preserve">Tag:</x:String>
<x:String x:Key="Text.DeleteTag.WithRemote" xml:space="preserve">Excluir dos repositórios remotos</x:String>
<x:String x:Key="Text.Diff.Binary" xml:space="preserve">DIFERENÇA BINÁRIA</x:String>
<x:String x:Key="Text.DeleteTag" xml:space="preserve">Excluir Tag</x:String>
<x:String x:Key="Text.Diff.Binary.New" xml:space="preserve">NOVO</x:String>
<x:String x:Key="Text.Diff.Binary.Old" xml:space="preserve">ANTIGO</x:String>
<x:String x:Key="Text.Diff.Binary" xml:space="preserve">DIFERENÇA BINÁRIA</x:String>
<x:String x:Key="Text.Diff.Copy" xml:space="preserve">Copiar</x:String>
<x:String x:Key="Text.Diff.FileModeChanged" xml:space="preserve">Modo de Arquivo Alterado</x:String>
<x:String x:Key="Text.Diff.IgnoreWhitespace" xml:space="preserve">Ignorar mudanças de espaço em branco</x:String>
<x:String x:Key="Text.Diff.LFS" xml:space="preserve">MUDANÇA DE OBJETO LFS</x:String>
<x:String x:Key="Text.Diff.Next" xml:space="preserve">Próxima Diferença</x:String>
<x:String x:Key="Text.Diff.NoChange" xml:space="preserve">SEM MUDANÇAS OU APENAS MUDANÇAS DE EOL</x:String>
<x:String x:Key="Text.Diff.Prev" xml:space="preserve">Diferença Anterior</x:String>
<x:String x:Key="Text.Diff.ShowHiddenSymbols" xml:space="preserve">Mostrar símbolos ocultos</x:String>
<x:String x:Key="Text.Diff.SideBySide" xml:space="preserve">Diferença Lado a Lado</x:String>
<x:String x:Key="Text.Diff.Submodule" xml:space="preserve">SUBMÓDULO</x:String>
<x:String x:Key="Text.Diff.Submodule.New" xml:space="preserve">NOVO</x:String>
<x:String x:Key="Text.Diff.Submodule" xml:space="preserve">SUBMÓDULO</x:String>
<x:String x:Key="Text.Diff.SwapCommits" xml:space="preserve">Trocar</x:String>
<x:String x:Key="Text.Diff.SyntaxHighlight" xml:space="preserve">Realce de Sintaxe</x:String>
<x:String x:Key="Text.Diff.ToggleWordWrap" xml:space="preserve">Quebra de Linha</x:String>
@ -211,23 +212,22 @@
<x:String x:Key="Text.Diff.VisualLines.Incr" xml:space="preserve">Aumentar Número de Linhas Visíveis</x:String>
<x:String x:Key="Text.Diff.Welcome" xml:space="preserve">SELECIONE O ARQUIVO PARA VISUALIZAR AS MUDANÇAS</x:String>
<x:String x:Key="Text.DiffWithMerger" xml:space="preserve">Abrir na Ferramenta de Mesclagem</x:String>
<x:String x:Key="Text.Discard" xml:space="preserve">Descartar Alterações</x:String>
<x:String x:Key="Text.Discard.All" xml:space="preserve">Todas as alterações locais na cópia de trabalho.</x:String>
<x:String x:Key="Text.Discard.Changes" xml:space="preserve">Alterações:</x:String>
<x:String x:Key="Text.Discard.Total" xml:space="preserve">Um total de {0} alterações será descartado</x:String>
<x:String x:Key="Text.Discard.Warning" xml:space="preserve">Você não pode desfazer esta ação!!!</x:String>
<x:String x:Key="Text.Discard" xml:space="preserve">Descartar Alterações</x:String>
<x:String x:Key="Text.EditRepositoryNode.Bookmark" xml:space="preserve">Favorito:</x:String>
<x:String x:Key="Text.EditRepositoryNode.Name" xml:space="preserve">Novo Nome:</x:String>
<x:String x:Key="Text.EditRepositoryNode.Target" xml:space="preserve">Alvo:</x:String>
<x:String x:Key="Text.EditRepositoryNode.TitleForGroup" xml:space="preserve">Editar Grupo Selecionado</x:String>
<x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">Editar Repositório Selecionado</x:String>
<x:String x:Key="Text.FastForwardWithoutCheck" xml:space="preserve">Fast-Forward (sem checkout)</x:String>
<x:String x:Key="Text.Fetch" xml:space="preserve">Buscar</x:String>
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Buscar todos os remotos</x:String>
<x:String x:Key="Text.Fetch.NoTags" xml:space="preserve">Buscar sem tags</x:String>
<x:String x:Key="Text.Fetch.Prune" xml:space="preserve">Prune remotos mortos</x:String>
<x:String x:Key="Text.Fetch.Remote" xml:space="preserve">Remoto:</x:String>
<x:String x:Key="Text.Fetch.Title" xml:space="preserve">Buscar Alterações Remotas</x:String>
<x:String x:Key="Text.Fetch" xml:space="preserve">Buscar</x:String>
<x:String x:Key="Text.FileCM.AssumeUnchanged" xml:space="preserve">Assumir não alterado</x:String>
<x:String x:Key="Text.FileCM.Discard" xml:space="preserve">Descartar...</x:String>
<x:String x:Key="Text.FileCM.DiscardMulti" xml:space="preserve">Descartar {0} arquivos...</x:String>
@ -242,11 +242,10 @@
<x:String x:Key="Text.FileCM.Unstage" xml:space="preserve">Desfazer Preparação</x:String>
<x:String x:Key="Text.FileCM.UnstageMulti" xml:space="preserve">Desfazer Preparação de {0} arquivos</x:String>
<x:String x:Key="Text.FileCM.UnstageSelectedLines" xml:space="preserve">Desfazer Preparação nas Linhas Selecionadas</x:String>
<x:String x:Key="Text.FileCM.UseTheirs" xml:space="preserve">Usar Deles (checkout --theirs)</x:String>
<x:String x:Key="Text.FileCM.UseMine" xml:space="preserve">Usar Meu (checkout --ours)</x:String>
<x:String x:Key="Text.FileCM.UseTheirs" xml:space="preserve">Usar Deles (checkout --theirs)</x:String>
<x:String x:Key="Text.FileHistory" xml:space="preserve">Histórico de Arquivos</x:String>
<x:String x:Key="Text.Filter" xml:space="preserve">FILTRO</x:String>
<x:String x:Key="Text.GitFlow" xml:space="preserve">Git-Flow</x:String>
<x:String x:Key="Text.GitFlow.DevelopBranch" xml:space="preserve">Branch de Desenvolvimento:</x:String>
<x:String x:Key="Text.GitFlow.Feature" xml:space="preserve">Feature:</x:String>
<x:String x:Key="Text.GitFlow.FeaturePrefix" xml:space="preserve">Prefixo da Feature:</x:String>
@ -269,80 +268,87 @@
<x:String x:Key="Text.GitFlow.StartRelease" xml:space="preserve">Iniciar Release...</x:String>
<x:String x:Key="Text.GitFlow.StartReleaseTitle" xml:space="preserve">FLOW - Iniciar Release</x:String>
<x:String x:Key="Text.GitFlow.TagPrefix" xml:space="preserve">Prefixo da Tag de Versão:</x:String>
<x:String x:Key="Text.GitLFS" xml:space="preserve">Git LFS</x:String>
<x:String x:Key="Text.GitLFS.AddTrackPattern" xml:space="preserve">Adicionar Padrão de Rastreamento...</x:String>
<x:String x:Key="Text.GitFlow" xml:space="preserve">Git-Flow</x:String>
<x:String x:Key="Text.GitLFS.AddTrackPattern.IsFilename" xml:space="preserve">Padrão é nome do arquivo</x:String>
<x:String x:Key="Text.GitLFS.AddTrackPattern.Pattern" xml:space="preserve">Padrão Personalizado:</x:String>
<x:String x:Key="Text.GitLFS.AddTrackPattern.Title" xml:space="preserve">Adicionar Padrão de Rastreamento ao Git LFS</x:String>
<x:String x:Key="Text.GitLFS.Fetch" xml:space="preserve">Buscar</x:String>
<x:String x:Key="Text.GitLFS.Fetch.Title" xml:space="preserve">Buscar Objetos LFS</x:String>
<x:String x:Key="Text.GitLFS.AddTrackPattern" xml:space="preserve">Adicionar Padrão de Rastreamento...</x:String>
<x:String x:Key="Text.GitLFS.Fetch.Tips" xml:space="preserve">Execute `git lfs fetch` para baixar objetos Git LFS. Isso não atualiza a cópia de trabalho.</x:String>
<x:String x:Key="Text.GitLFS.Fetch.Title" xml:space="preserve">Buscar Objetos LFS</x:String>
<x:String x:Key="Text.GitLFS.Fetch" xml:space="preserve">Buscar</x:String>
<x:String x:Key="Text.GitLFS.Install" xml:space="preserve">Instalar hooks do Git LFS</x:String>
<x:String x:Key="Text.GitLFS.Locks" xml:space="preserve">Mostrar Locks</x:String>
<x:String x:Key="Text.GitLFS.Locks.Empty" xml:space="preserve">Sem Arquivos Bloqueados</x:String>
<x:String x:Key="Text.GitLFS.Locks.Lock" xml:space="preserve">Bloquear</x:String>
<x:String x:Key="Text.GitLFS.Locks.Title" xml:space="preserve">Locks LFS</x:String>
<x:String x:Key="Text.GitLFS.Locks.Unlock" xml:space="preserve">Desbloquear</x:String>
<x:String x:Key="Text.GitLFS.Locks.UnlockForce" xml:space="preserve">Forçar Desbloqueio</x:String>
<x:String x:Key="Text.GitLFS.Prune" xml:space="preserve">Prune</x:String>
<x:String x:Key="Text.GitLFS.Locks" xml:space="preserve">Mostrar Locks</x:String>
<x:String x:Key="Text.GitLFS.Prune.Tips" xml:space="preserve">Execute `git lfs prune` para excluir arquivos LFS antigos do armazenamento local</x:String>
<x:String x:Key="Text.GitLFS.Pull" xml:space="preserve">Puxar</x:String>
<x:String x:Key="Text.GitLFS.Pull.Title" xml:space="preserve">Puxar Objetos LFS</x:String>
<x:String x:Key="Text.GitLFS.Prune" xml:space="preserve">Prune</x:String>
<x:String x:Key="Text.GitLFS.Pull.Tips" xml:space="preserve">Execute `git lfs pull` para baixar todos os arquivos Git LFS para a referência atual e checkout</x:String>
<x:String x:Key="Text.GitLFS.Push" xml:space="preserve">Enviar</x:String>
<x:String x:Key="Text.GitLFS.Push.Title" xml:space="preserve">Enviar Objetos LFS</x:String>
<x:String x:Key="Text.GitLFS.Pull.Title" xml:space="preserve">Puxar Objetos LFS</x:String>
<x:String x:Key="Text.GitLFS.Pull" xml:space="preserve">Puxar</x:String>
<x:String x:Key="Text.GitLFS.Push.Tips" xml:space="preserve">Envie arquivos grandes enfileirados para o endpoint Git LFS</x:String>
<x:String x:Key="Text.GitLFS.Push.Title" xml:space="preserve">Enviar Objetos LFS</x:String>
<x:String x:Key="Text.GitLFS.Push" xml:space="preserve">Enviar</x:String>
<x:String x:Key="Text.GitLFS.Remote" xml:space="preserve">Remoto:</x:String>
<x:String x:Key="Text.GitLFS.Track" xml:space="preserve">Rastrear arquivos nomeados '{0}'</x:String>
<x:String x:Key="Text.GitLFS.TrackByExtension" xml:space="preserve">Rastrear todos os arquivos *{0}</x:String>
<x:String x:Key="Text.Histories" xml:space="preserve">Históricos</x:String>
<x:String x:Key="Text.GitLFS" xml:space="preserve">Git LFS</x:String>
<x:String x:Key="Text.Histories.DisplayMode" xml:space="preserve">Alternar Layout Horizontal/Vertical</x:String>
<x:String x:Key="Text.Histories.Header.Author" xml:space="preserve">AUTOR</x:String>
<x:String x:Key="Text.Histories.Header.AuthorTime" xml:space="preserve">DATA DO AUTOR</x:String>
<x:String x:Key="Text.Histories.Header.GraphAndSubject" xml:space="preserve">GRÁFICO &amp; ASSUNTO</x:String>
<x:String x:Key="Text.Histories.Header.SHA" xml:space="preserve">SHA</x:String>
<x:String x:Key="Text.Histories.Header.Time" xml:space="preserve">HORA DO COMMIT</x:String>
<x:String x:Key="Text.Histories.Selected" xml:space="preserve">SELECIONADO {0} COMMITS</x:String>
<x:String x:Key="Text.Hotkeys" xml:space="preserve">Referência de Atalhos de Teclado</x:String>
<x:String x:Key="Text.Hotkeys.Global" xml:space="preserve">GLOBAL</x:String>
<x:String x:Key="Text.Histories.Tips.MacOS" xml:space="preserve">Segure ⌘ ou ⇧ para selecionar múltiplos commits.</x:String>
<x:String x:Key="Text.Histories.Tips.Prefix" xml:space="preserve">DICAS:</x:String>
<x:String x:Key="Text.Histories.Tips" xml:space="preserve">Segure 'Ctrl' ou 'Shift' para selecionar múltiplos commits.</x:String>
<x:String x:Key="Text.Histories" xml:space="preserve">Históricos</x:String>
<x:String x:Key="Text.Hotkeys.Global.CancelPopup" xml:space="preserve">Cancelar popup atual</x:String>
<x:String x:Key="Text.Hotkeys.Global.CloseTab" xml:space="preserve">Fechar página atual</x:String>
<x:String x:Key="Text.Hotkeys.Global.GotoPrevTab" xml:space="preserve">Ir para a página anterior</x:String>
<x:String x:Key="Text.Hotkeys.Global.GotoNextTab" xml:space="preserve">Ir para a próxima página</x:String>
<x:String x:Key="Text.Hotkeys.Global.GotoPrevTab" xml:space="preserve">Ir para a página anterior</x:String>
<x:String x:Key="Text.Hotkeys.Global.NewTab" xml:space="preserve">Criar nova página</x:String>
<x:String x:Key="Text.Hotkeys.Global.OpenPreference" xml:space="preserve">Abrir diálogo de preferências</x:String>
<x:String x:Key="Text.Hotkeys.Repo" xml:space="preserve">REPOSITÓRIO</x:String>
<x:String x:Key="Text.Hotkeys.Global" xml:space="preserve">GLOBAL</x:String>
<x:String x:Key="Text.Hotkeys.Repo.Commit" xml:space="preserve">Commitar mudanças preparadas</x:String>
<x:String x:Key="Text.Hotkeys.Repo.CommitAndPush" xml:space="preserve">Commitar e enviar mudanças preparadas</x:String>
<x:String x:Key="Text.Hotkeys.Repo.CommitWithAutoStage" xml:space="preserve">Preparar todas as mudanças e commitar</x:String>
<x:String x:Key="Text.Hotkeys.Repo.DiscardSelected" xml:space="preserve">Descartar mudanças selecionadas</x:String>
<x:String x:Key="Text.Hotkeys.Repo.GoHome" xml:space="preserve">Modo de Dashboard (Padrão)</x:String>
<x:String x:Key="Text.Hotkeys.Repo.OpenSearchCommits" xml:space="preserve">Modo de busca de commits</x:String>
<x:String x:Key="Text.Hotkeys.Repo.Refresh" xml:space="preserve">Forçar recarregamento deste repositório</x:String>
<x:String x:Key="Text.Hotkeys.Repo.StageOrUnstageSelected" xml:space="preserve">Preparar/Despreparar mudanças selecionadas</x:String>
<x:String x:Key="Text.Hotkeys.Repo.OpenSearchCommits" xml:space="preserve">Modo de busca de commits</x:String>
<x:String x:Key="Text.Hotkeys.Repo.ViewChanges" xml:space="preserve">Alternar para 'Mudanças'</x:String>
<x:String x:Key="Text.Hotkeys.Repo.ViewHistories" xml:space="preserve">Alternar para 'Históricos'</x:String>
<x:String x:Key="Text.Hotkeys.Repo.ViewStashes" xml:space="preserve">Alternar para 'Stashes'</x:String>
<x:String x:Key="Text.Hotkeys.TextEditor" xml:space="preserve">EDITOR DE TEXTO</x:String>
<x:String x:Key="Text.Hotkeys.Repo" xml:space="preserve">REPOSITÓRIO</x:String>
<x:String x:Key="Text.Hotkeys.TextEditor.CloseSearch" xml:space="preserve">Fechar painel de busca</x:String>
<x:String x:Key="Text.Hotkeys.TextEditor.GotoNextMatch" xml:space="preserve">Encontrar próxima correspondência</x:String>
<x:String x:Key="Text.Hotkeys.TextEditor.GotoPrevMatch" xml:space="preserve">Encontrar correspondência anterior</x:String>
<x:String x:Key="Text.Hotkeys.TextEditor.Search" xml:space="preserve">Abrir painel de busca</x:String>
<x:String x:Key="Text.Hotkeys.TextEditor" xml:space="preserve">EDITOR DE TEXTO</x:String>
<x:String x:Key="Text.Hotkeys" xml:space="preserve">Referência de Atalhos de Teclado</x:String>
<x:String x:Key="Text.Hunk.Discard" xml:space="preserve">Descartar</x:String>
<x:String x:Key="Text.Hunk.Stage" xml:space="preserve">Preparar</x:String>
<x:String x:Key="Text.Hunk.Unstage" xml:space="preserve">Despreparar</x:String>
<x:String x:Key="Text.Hunk.Discard" xml:space="preserve">Descartar</x:String>
<x:String x:Key="Text.Init" xml:space="preserve">Inicializar Repositório</x:String>
<x:String x:Key="Text.Init.Path" xml:space="preserve">Caminho:</x:String>
<x:String x:Key="Text.Init" xml:space="preserve">Inicializar Repositório</x:String>
<x:String x:Key="Text.InProgress.CherryPick" xml:space="preserve">Cherry-Pick em andamento. Pressione 'Abort' para restaurar o HEAD original.</x:String>
<x:String x:Key="Text.InProgress.Merge" xml:space="preserve">Merge em andamento. Pressione 'Abort' para restaurar o HEAD original.</x:String>
<x:String x:Key="Text.InProgress.Rebase" xml:space="preserve">Rebase em andamento. Pressione 'Abort' para restaurar o HEAD original.</x:String>
<x:String x:Key="Text.InProgress.Revert" xml:space="preserve">Revert em andamento. Pressione 'Abort' para restaurar o HEAD original.</x:String>
<x:String x:Key="Text.InteractiveRebase" xml:space="preserve">Rebase Interativo</x:String>
<x:String x:Key="Text.InteractiveRebase.Target" xml:space="preserve">Ramo Alvo:</x:String>
<x:String x:Key="Text.InteractiveRebase.On" xml:space="preserve">Em:</x:String>
<x:String x:Key="Text.InteractiveRebase.Target" xml:space="preserve">Ramo Alvo:</x:String>
<x:String x:Key="Text.InteractiveRebase" xml:space="preserve">Rebase Interativo</x:String>
<x:String x:Key="Text.Launcher.Error" xml:space="preserve">ERRO</x:String>
<x:String x:Key="Text.Launcher.Info" xml:space="preserve">AVISO</x:String>
<x:String x:Key="Text.Merge" xml:space="preserve">Mesclar Ramo</x:String>
<x:String x:Key="Text.Merge.Into" xml:space="preserve">Para:</x:String>
<x:String x:Key="Text.Merge.Mode" xml:space="preserve">Opção de Mesclagem:</x:String>
<x:String x:Key="Text.Merge.Source" xml:space="preserve">Ramo de Origem:</x:String>
<x:String x:Key="Text.Merge" xml:space="preserve">Mesclar Ramo</x:String>
<x:String x:Key="Text.Name" xml:space="preserve">Nome:</x:String>
<x:String x:Key="Text.NotConfigured" xml:space="preserve">O Git NÃO foi configurado. Por favor, vá para [Preferências] e configure primeiro.</x:String>
<x:String x:Key="Text.OpenAppDataDir" xml:space="preserve">Abrir Pasta de Dados do Aplicativo</x:String>
@ -356,68 +362,79 @@
<x:String x:Key="Text.PageTabBar.Tab.CopyPath" xml:space="preserve">Copiar Caminho do Repositório</x:String>
<x:String x:Key="Text.PageTabBar.Welcome.Title" xml:space="preserve">Repositórios</x:String>
<x:String x:Key="Text.Paste" xml:space="preserve">Colar</x:String>
<x:String x:Key="Text.Period.JustNow" xml:space="preserve">Agora mesmo</x:String>
<x:String x:Key="Text.Period.MinutesAgo" xml:space="preserve">{0} minutos atrás</x:String>
<x:String x:Key="Text.Period.HoursAgo" xml:space="preserve">{0} horas atrás</x:String>
<x:String x:Key="Text.Period.Yesterday" xml:space="preserve">Ontem</x:String>
<x:String x:Key="Text.Period.DaysAgo" xml:space="preserve">{0} dias atrás</x:String>
<x:String x:Key="Text.Period.HoursAgo" xml:space="preserve">{0} horas atrás</x:String>
<x:String x:Key="Text.Period.JustNow" xml:space="preserve">Agora mesmo</x:String>
<x:String x:Key="Text.Period.LastMonth" xml:space="preserve">Mês passado</x:String>
<x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">{0} meses atrás</x:String>
<x:String x:Key="Text.Period.LastYear" xml:space="preserve">Ano passado</x:String>
<x:String x:Key="Text.Period.MinutesAgo" xml:space="preserve">{0} minutos atrás</x:String>
<x:String x:Key="Text.Period.MonthsAgo" xml:space="preserve">{0} meses atrás</x:String>
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} anos atrás</x:String>
<x:String x:Key="Text.Preference" xml:space="preserve">Preferências</x:String>
<x:String x:Key="Text.Preference.Appearance" xml:space="preserve">APARÊNCIA</x:String>
<x:String x:Key="Text.Period.Yesterday" xml:space="preserve">Ontem</x:String>
<x:String x:Key="Text.Preference.AI.AnalyzeDiffPrompt" xml:space="preserve">Prompt para Analisar Diff</x:String>
<x:String x:Key="Text.Preference.AI.ApiKey" xml:space="preserve">Chave da API</x:String>
<x:String x:Key="Text.Preference.AI.GenerateSubjectPrompt" xml:space="preserve">Prompt para Gerar Título</x:String>
<x:String x:Key="Text.Preference.AI.Model" xml:space="preserve">Modelo</x:String>
<x:String x:Key="Text.Preference.AI.Server" xml:space="preserve">Servidor</x:String>
<x:String x:Key="Text.Preference.AI" xml:space="preserve">INTELIGÊNCIA ARTIFICIAL</x:String>
<x:String x:Key="Text.Preference.Appearance.DefaultFont" xml:space="preserve">Fonte Padrão</x:String>
<x:String x:Key="Text.Preference.Appearance.DefaultFontSize" xml:space="preserve">Tamanho da Fonte Padrão</x:String>
<x:String x:Key="Text.Preference.Appearance.MonospaceFont" xml:space="preserve">Fonte Monoespaçada</x:String>
<x:String x:Key="Text.Preference.Appearance.OnlyUseMonoFontInEditor" xml:space="preserve">Usar apenas fonte monoespaçada no editor de texto</x:String>
<x:String x:Key="Text.Preference.Appearance.OnlyUseMonoFontInEditor" xml:space="preserve">Usar fonte monoespaçada apenas no editor de texto</x:String>
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">Tema</x:String>
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">Sobrescrever Tema</x:String>
<x:String x:Key="Text.Preference.Appearance.UseFixedTabWidth" xml:space="preserve">Usar largura fixa da aba na barra de título</x:String>
<x:String x:Key="Text.Preference.DiffMerge" xml:space="preserve">FERRAMENTA DE DIF/MERGE</x:String>
<x:String x:Key="Text.Preference.Appearance.ThemeOverrides" xml:space="preserve">Substituições de Tema</x:String>
<x:String x:Key="Text.Preference.Appearance.UseFixedTabWidth" xml:space="preserve">Usar largura fixa de aba na barra de título</x:String>
<x:String x:Key="Text.Preference.Appearance.UseNativeWindowFrame" xml:space="preserve">Usar moldura de janela nativa</x:String>
<x:String x:Key="Text.Preference.Appearance" xml:space="preserve">APARÊNCIA</x:String>
<x:String x:Key="Text.Preference.DiffMerge.Path.Placeholder" xml:space="preserve">Insira o caminho para a ferramenta de diff/merge</x:String>
<x:String x:Key="Text.Preference.DiffMerge.Path" xml:space="preserve">Caminho de Instalação</x:String>
<x:String x:Key="Text.Preference.DiffMerge.Path.Placeholder" xml:space="preserve">Insira o caminho para a ferramenta de dif/merge</x:String>
<x:String x:Key="Text.Preference.DiffMerge.Type" xml:space="preserve">Ferramenta</x:String>
<x:String x:Key="Text.Preference.General" xml:space="preserve">GERAL</x:String>
<x:String x:Key="Text.Preference.DiffMerge" xml:space="preserve">FERRAMENTA DE DIFF/MERGE</x:String>
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">Verificar atualizações na inicialização</x:String>
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">Idioma</x:String>
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">Commits do Histórico</x:String>
<x:String x:Key="Text.Preference.General.ShowAuthorTime" xml:space="preserve">Mostrar data do autor em vez da data do commit no gráfico</x:String>
<x:String x:Key="Text.Preference.General.SubjectGuideLength" xml:space="preserve">Comprimento do Guia de Assunto</x:String>
<x:String x:Key="Text.Preference.Git" xml:space="preserve">GIT</x:String>
<x:String x:Key="Text.Preference.General" xml:space="preserve">GERAL</x:String>
<x:String x:Key="Text.Preference.Git.CRLF" xml:space="preserve">Habilitar Auto CRLF</x:String>
<x:String x:Key="Text.Preference.Git.DefaultCloneDir" xml:space="preserve">Diretório Padrão de Clone</x:String>
<x:String x:Key="Text.Preference.Git.Email" xml:space="preserve">E-mail do Usuário</x:String>
<x:String x:Key="Text.Preference.Git.Email.Placeholder" xml:space="preserve">E-mail global do usuário git</x:String>
<x:String x:Key="Text.Preference.Git.Path" xml:space="preserve">Caminho de Instalação</x:String>
<x:String x:Key="Text.Preference.Git.User" xml:space="preserve">Nome do Usuário</x:String>
<x:String x:Key="Text.Preference.Git.User.Placeholder" xml:space="preserve">Nome global do usuário git</x:String>
<x:String x:Key="Text.Preference.Git.Version" xml:space="preserve">Versão do Git</x:String>
<x:String x:Key="Text.Preference.Git.DefaultCloneDir" xml:space="preserve">Diretório de Clone Padrão</x:String>
<x:String x:Key="Text.Preference.Git.Email.Placeholder" xml:space="preserve">Email global do usuário git</x:String>
<x:String x:Key="Text.Preference.Git.Email" xml:space="preserve">Email do Usuário</x:String>
<x:String x:Key="Text.Preference.Git.Invalid" xml:space="preserve">Git (>= 2.23.0) é necessário para este aplicativo</x:String>
<x:String x:Key="Text.Preference.GPG" xml:space="preserve">ASSINATURA GPG</x:String>
<x:String x:Key="Text.Preference.GPG.CommitEnabled" xml:space="preserve">Assinatura GPG de Commit</x:String>
<x:String x:Key="Text.Preference.GPG.TagEnabled" xml:space="preserve">Assinatura GPG de Tag</x:String>
<x:String x:Key="Text.Preference.Git.Path" xml:space="preserve">Caminho de Instalação</x:String>
<x:String x:Key="Text.Preference.Git.User.Placeholder" xml:space="preserve">Nome global do usuário git</x:String>
<x:String x:Key="Text.Preference.Git.User" xml:space="preserve">Nome do Usuário</x:String>
<x:String x:Key="Text.Preference.Git.Version" xml:space="preserve">Versão do Git</x:String>
<x:String x:Key="Text.Preference.Git" xml:space="preserve">GIT</x:String>
<x:String x:Key="Text.Preference.GPG.CommitEnabled" xml:space="preserve">Assinatura GPG de commit</x:String>
<x:String x:Key="Text.Preference.GPG.Format" xml:space="preserve">Formato GPG</x:String>
<x:String x:Key="Text.Preference.GPG.Path.Placeholder" xml:space="preserve">Insira o caminho para o programa gpg instalado</x:String>
<x:String x:Key="Text.Preference.GPG.Path" xml:space="preserve">Caminho de Instalação do Programa</x:String>
<x:String x:Key="Text.Preference.GPG.Path.Placeholder" xml:space="preserve">Insira o caminho do programa gpg instalado</x:String>
<x:String x:Key="Text.Preference.GPG.UserKey" xml:space="preserve">Chave de Assinatura do Usuário</x:String>
<x:String x:Key="Text.Preference.GPG.TagEnabled" xml:space="preserve">Assinatura GPG de tag</x:String>
<x:String x:Key="Text.Preference.GPG.UserKey.Placeholder" xml:space="preserve">Chave de assinatura gpg do usuário</x:String>
<x:String x:Key="Text.PruneRemote" xml:space="preserve">Prunar Remoto</x:String>
<x:String x:Key="Text.Preference.GPG.UserKey" xml:space="preserve">Chave de Assinatura do Usuário</x:String>
<x:String x:Key="Text.Preference.GPG" xml:space="preserve">ASSINATURA GPG</x:String>
<x:String x:Key="Text.Preference.Integration" xml:space="preserve">INTEGRAÇÃO</x:String>
<x:String x:Key="Text.Preference.Shell.Path" xml:space="preserve">Caminho</x:String>
<x:String x:Key="Text.Preference.Shell.Type" xml:space="preserve">Shell/Terminal</x:String>
<x:String x:Key="Text.Preference.Shell" xml:space="preserve">SHELL/TERMINAL</x:String>
<x:String x:Key="Text.Preference" xml:space="preserve">Preferências</x:String>
<x:String x:Key="Text.PruneRemote.Target" xml:space="preserve">Alvo:</x:String>
<x:String x:Key="Text.PruneWorktrees" xml:space="preserve">Podar Worktrees</x:String>
<x:String x:Key="Text.PruneRemote" xml:space="preserve">Prunar Remoto</x:String>
<x:String x:Key="Text.PruneWorktrees.Tip" xml:space="preserve">Podar informações de worktree em `$GIT_DIR/worktrees`</x:String>
<x:String x:Key="Text.Pull" xml:space="preserve">Puxar</x:String>
<x:String x:Key="Text.PruneWorktrees" xml:space="preserve">Podar Worktrees</x:String>
<x:String x:Key="Text.Pull.Branch" xml:space="preserve">Branch:</x:String>
<x:String x:Key="Text.Pull.FetchAllBranches" xml:space="preserve">Buscar todos os branches</x:String>
<x:String x:Key="Text.Pull.Into" xml:space="preserve">Para:</x:String>
<x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">Alterações Locais:</x:String>
<x:String x:Key="Text.Pull.LocalChanges.Discard" xml:space="preserve">Descartar</x:String>
<x:String x:Key="Text.Pull.LocalChanges.DoNothing" xml:space="preserve">Não Fazer Nada</x:String>
<x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">Guardar &amp; Reaplicar</x:String>
<x:String x:Key="Text.Pull.LocalChanges" xml:space="preserve">Alterações Locais:</x:String>
<x:String x:Key="Text.Pull.NoTags" xml:space="preserve">Buscar sem tags</x:String>
<x:String x:Key="Text.Pull.Remote" xml:space="preserve">Remoto:</x:String>
<x:String x:Key="Text.Pull.Title" xml:space="preserve">Puxar (Buscar &amp; Mesclar)</x:String>
<x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">Usar rebase em vez de merge</x:String>
<x:String x:Key="Text.Push" xml:space="preserve">Empurrar</x:String>
<x:String x:Key="Text.Pull" xml:space="preserve">Puxar</x:String>
<x:String x:Key="Text.Push.Force" xml:space="preserve">Forçar push</x:String>
<x:String x:Key="Text.Push.Local" xml:space="preserve">Branch Local:</x:String>
<x:String x:Key="Text.Push.Remote" xml:space="preserve">Remoto:</x:String>
@ -425,178 +442,185 @@
<x:String x:Key="Text.Push.To" xml:space="preserve">Branch Remoto:</x:String>
<x:String x:Key="Text.Push.Tracking" xml:space="preserve">Definir como branch de rastreamento</x:String>
<x:String x:Key="Text.Push.WithAllTags" xml:space="preserve">Empurrar todas as tags</x:String>
<x:String x:Key="Text.PushTag" xml:space="preserve">Empurrar Tag para o Remoto</x:String>
<x:String x:Key="Text.Push" xml:space="preserve">Empurrar</x:String>
<x:String x:Key="Text.PushTag.PushAllRemotes" xml:space="preserve">Empurrar para todos os remotos</x:String>
<x:String x:Key="Text.PushTag.Remote" xml:space="preserve">Remoto:</x:String>
<x:String x:Key="Text.PushTag.Tag" xml:space="preserve">Tag:</x:String>
<x:String x:Key="Text.PushTag" xml:space="preserve">Empurrar Tag para o Remoto</x:String>
<x:String x:Key="Text.Quit" xml:space="preserve">Sair</x:String>
<x:String x:Key="Text.Rebase" xml:space="preserve">Rebase da Branch Atual</x:String>
<x:String x:Key="Text.Rebase.AutoStash" xml:space="preserve">Guardar &amp; reaplicar alterações locais</x:String>
<x:String x:Key="Text.Rebase.On" xml:space="preserve">Em:</x:String>
<x:String x:Key="Text.Rebase.Target" xml:space="preserve">Rebase:</x:String>
<x:String x:Key="Text.Rebase" xml:space="preserve">Rebase da Branch Atual</x:String>
<x:String x:Key="Text.RefetchAvatar" xml:space="preserve">Atualizar</x:String>
<x:String x:Key="Text.Remote.AddTitle" xml:space="preserve">Adicionar Remoto</x:String>
<x:String x:Key="Text.Remote.EditTitle" xml:space="preserve">Editar Remoto</x:String>
<x:String x:Key="Text.Remote.Name" xml:space="preserve">Nome:</x:String>
<x:String x:Key="Text.Remote.Name.Placeholder" xml:space="preserve">Nome do remoto</x:String>
<x:String x:Key="Text.Remote.URL" xml:space="preserve">URL do Repositório:</x:String>
<x:String x:Key="Text.Remote.Name" xml:space="preserve">Nome:</x:String>
<x:String x:Key="Text.Remote.URL.Placeholder" xml:space="preserve">URL do repositório git remoto</x:String>
<x:String x:Key="Text.Remote.URL" xml:space="preserve">URL do Repositório:</x:String>
<x:String x:Key="Text.RemoteCM.CopyURL" xml:space="preserve">Copiar URL</x:String>
<x:String x:Key="Text.RemoteCM.Delete" xml:space="preserve">Excluir...</x:String>
<x:String x:Key="Text.RemoteCM.Edit" xml:space="preserve">Editar...</x:String>
<x:String x:Key="Text.RemoteCM.Fetch" xml:space="preserve">Buscar</x:String>
<x:String x:Key="Text.RemoteCM.OpenInBrowser" xml:space="preserve">Abrir no Navegador</x:String>
<x:String x:Key="Text.RemoteCM.Prune" xml:space="preserve">Podar</x:String>
<x:String x:Key="Text.RemoteCM.Prune.Target" xml:space="preserve">Alvo:</x:String>
<x:String x:Key="Text.RemoveWorktree" xml:space="preserve">Confirmar Remoção de Worktree</x:String>
<x:String x:Key="Text.RemoveWorktree.Force" xml:space="preserve">Habilitar Opção `--force`</x:String>
<x:String x:Key="Text.RemoveWorktree.Target" xml:space="preserve">Alvo:</x:String>
<x:String x:Key="Text.RenameBranch" xml:space="preserve">Renomear Branch</x:String>
<x:String x:Key="Text.RenameBranch.Name" xml:space="preserve">Novo Nome:</x:String>
<x:String x:Key="Text.RemoveWorktree" xml:space="preserve">Confirmar Remoção de Worktree</x:String>
<x:String x:Key="Text.RenameBranch.Name.Placeholder" xml:space="preserve">Nome único para este branch</x:String>
<x:String x:Key="Text.RenameBranch.Name" xml:space="preserve">Novo Nome:</x:String>
<x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">Branch:</x:String>
<x:String x:Key="Text.RenameBranch" xml:space="preserve">Renomear Branch</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">Buscando automaticamente mudanças dos remotos...</x:String>
<x:String x:Key="Text.Repository.Clean" xml:space="preserve">Limpar (GC &amp; Podar)</x:String>
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">Execute o comando `git gc` para este repositório.</x:String>
<x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">Limpar tudo</x:String>
<x:String x:Key="Text.Repository.Configure" xml:space="preserve">Configurar este repositório</x:String>
<x:String x:Key="Text.Repository.Continue" xml:space="preserve">CONTINUAR</x:String>
<x:String x:Key="Text.Repository.EnableReflog" xml:space="preserve">Habilitar opção '--reflog'</x:String>
<x:String x:Key="Text.Repository.Explore" xml:space="preserve">Abrir no Navegador de Arquivos</x:String>
<x:String x:Key="Text.Repository.Filter" xml:space="preserve">Pesquisar Branches/Tags/Submódulos</x:String>
<x:String x:Key="Text.Repository.FilterCommitPrefix" xml:space="preserve">FILTRADO POR:</x:String>
<x:String x:Key="Text.Repository.FirstParentFilterToggle" xml:space="preserve">Habilitar opção '--first-parent'</x:String>
<x:String x:Key="Text.Repository.LocalBranches" xml:space="preserve">BRANCHES LOCAIS</x:String>
<x:String x:Key="Text.Repository.NavigateToCurrentHead" xml:space="preserve">Navegar para HEAD</x:String>
<x:String x:Key="Text.Repository.FirstParentFilterToggle" xml:space="preserve">Filtro do Primeiro Pai</x:String>
<x:String x:Key="Text.Repository.NewBranch" xml:space="preserve">Criar Branch</x:String>
<x:String x:Key="Text.Repository.OpenIn" xml:space="preserve">Abrir em {0}</x:String>
<x:String x:Key="Text.Repository.OpenWithExternalTools" xml:space="preserve">Abrir em Ferramentas Externas</x:String>
<x:String x:Key="Text.Repository.Refresh" xml:space="preserve">Atualizar</x:String>
<x:String x:Key="Text.Repository.Remotes" xml:space="preserve">REMOTOS</x:String>
<x:String x:Key="Text.Repository.Remotes.Add" xml:space="preserve">ADICIONAR REMOTO</x:String>
<x:String x:Key="Text.Repository.Remotes" xml:space="preserve">REMOTOS</x:String>
<x:String x:Key="Text.Repository.Resolve" xml:space="preserve">RESOLVER</x:String>
<x:String x:Key="Text.Repository.Search" xml:space="preserve">Pesquisar Commit</x:String>
<x:String x:Key="Text.Repository.Search.ByFile" xml:space="preserve">Arquivo</x:String>
<x:String x:Key="Text.Repository.Search.ByMessage" xml:space="preserve">Mensagem</x:String>
<x:String x:Key="Text.Repository.Search.BySHA" xml:space="preserve">SHA</x:String>
<x:String x:Key="Text.Repository.Search.ByUser" xml:space="preserve">Autor &amp; Committer</x:String>
<x:String x:Key="Text.Repository.Search.InCurrentBranch" xml:space="preserve">Branch Atual</x:String>
<x:String x:Key="Text.Repository.Search" xml:space="preserve">Pesquisar Commit</x:String>
<x:String x:Key="Text.Repository.ShowTagsAsTree" xml:space="preserve">Mostrar Tags como Árvore</x:String>
<x:String x:Key="Text.Repository.Statistics" xml:space="preserve">Estatísticas</x:String>
<x:String x:Key="Text.Repository.Submodules" xml:space="preserve">SUBMÓDULOS</x:String>
<x:String x:Key="Text.Repository.Submodules.Add" xml:space="preserve">ADICIONAR SUBMÓDULO</x:String>
<x:String x:Key="Text.Repository.Submodules.Update" xml:space="preserve">ATUALIZAR SUBMÓDULO</x:String>
<x:String x:Key="Text.Repository.Tags" xml:space="preserve">TAGS</x:String>
<x:String x:Key="Text.Repository.Submodules" xml:space="preserve">SUBMÓDULOS</x:String>
<x:String x:Key="Text.Repository.Tags.Add" xml:space="preserve">NOVA TAG</x:String>
<x:String x:Key="Text.Repository.Tags" xml:space="preserve">TAGS</x:String>
<x:String x:Key="Text.Repository.Terminal" xml:space="preserve">Abrir no Terminal</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">ADICIONAR WORKTREE</x:String>
<x:String x:Key="Text.Repository.Worktrees.Prune" xml:space="preserve">PODAR</x:String>
<x:String x:Key="Text.Repository.Worktrees" xml:space="preserve">WORKTREES</x:String>
<x:String x:Key="Text.RepositoryURL" xml:space="preserve">URL do Repositório Git</x:String>
<x:String x:Key="Text.Reset" xml:space="preserve">Resetar Branch Atual para Revisão</x:String>
<x:String x:Key="Text.Reset.Mode" xml:space="preserve">Modo de Reset:</x:String>
<x:String x:Key="Text.Reset.MoveTo" xml:space="preserve">Mover Para:</x:String>
<x:String x:Key="Text.Reset.Target" xml:space="preserve">Branch Atual:</x:String>
<x:String x:Key="Text.Reset" xml:space="preserve">Resetar Branch Atual para Revisão</x:String>
<x:String x:Key="Text.RevealFile" xml:space="preserve">Revelar no Explorador de Arquivos</x:String>
<x:String x:Key="Text.Revert" xml:space="preserve">Reverter Commit</x:String>
<x:String x:Key="Text.Revert.Commit" xml:space="preserve">Commit:</x:String>
<x:String x:Key="Text.Revert.CommitChanges" xml:space="preserve">Commitar alterações de reversão</x:String>
<x:String x:Key="Text.Reword" xml:space="preserve">Reescrever Mensagem do Commit</x:String>
<x:String x:Key="Text.Revert" xml:space="preserve">Reverter Commit</x:String>
<x:String x:Key="Text.Reword.Tip" xml:space="preserve">Use 'Shift+Enter' para inserir uma nova linha. 'Enter' é a tecla de atalho do botão OK</x:String>
<x:String x:Key="Text.Reword" xml:space="preserve">Reescrever Mensagem do Commit</x:String>
<x:String x:Key="Text.Running" xml:space="preserve">Executando. Por favor, aguarde...</x:String>
<x:String x:Key="Text.Save" xml:space="preserve">SALVAR</x:String>
<x:String x:Key="Text.SaveAs" xml:space="preserve">Salvar Como...</x:String>
<x:String x:Key="Text.SaveAsPatchSuccess" xml:space="preserve">Patch salvo com sucesso!</x:String>
<x:String x:Key="Text.SelfUpdate" xml:space="preserve">Verificar atualizações...</x:String>
<x:String x:Key="Text.ScanRepositories.RootDir" xml:space="preserve">Diretório Raiz:</x:String>
<x:String x:Key="Text.ScanRepositories" xml:space="preserve">Escanear Repositórios</x:String>
<x:String x:Key="Text.SelfUpdate.Available" xml:space="preserve">Nova versão deste software disponível: </x:String>
<x:String x:Key="Text.SelfUpdate.Error" xml:space="preserve">Falha ao verificar atualizações!</x:String>
<x:String x:Key="Text.SelfUpdate.GotoDownload" xml:space="preserve">Baixar</x:String>
<x:String x:Key="Text.SelfUpdate.IgnoreThisVersion" xml:space="preserve">Ignorar esta versão</x:String>
<x:String x:Key="Text.SelfUpdate.Title" xml:space="preserve">Atualização de Software</x:String>
<x:String x:Key="Text.SelfUpdate.UpToDate" xml:space="preserve">Não há atualizações disponíveis no momento.</x:String>
<x:String x:Key="Text.SelfUpdate" xml:space="preserve">Verificar atualizações...</x:String>
<x:String x:Key="Text.Squash" xml:space="preserve">Squash Commits</x:String>
<x:String x:Key="Text.SSHKey" xml:space="preserve">Chave SSH Privada:</x:String>
<x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Caminho para a chave SSH privada</x:String>
<x:String x:Key="Text.SSHKey" xml:space="preserve">Chave SSH Privada:</x:String>
<x:String x:Key="Text.Start" xml:space="preserve">INICIAR</x:String>
<x:String x:Key="Text.Stash" xml:space="preserve">Stash</x:String>
<x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">Incluir arquivos não rastreados</x:String>
<x:String x:Key="Text.Stash.Message" xml:space="preserve">Mensagem:</x:String>
<x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">Opcional. Nome deste stash</x:String>
<x:String x:Key="Text.Stash.Message" xml:space="preserve">Mensagem:</x:String>
<x:String x:Key="Text.Stash.Title" xml:space="preserve">Guardar Alterações Locais</x:String>
<x:String x:Key="Text.Stash" xml:space="preserve">Stash</x:String>
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">Aplicar</x:String>
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">Descartar</x:String>
<x:String x:Key="Text.StashCM.Pop" xml:space="preserve">Pop</x:String>
<x:String x:Key="Text.StashDropConfirm" xml:space="preserve">Descartar Stash</x:String>
<x:String x:Key="Text.StashDropConfirm.Label" xml:space="preserve">Descartar:</x:String>
<x:String x:Key="Text.Stashes" xml:space="preserve">Stashes</x:String>
<x:String x:Key="Text.StashDropConfirm" xml:space="preserve">Descartar Stash</x:String>
<x:String x:Key="Text.Stashes.Changes" xml:space="preserve">ALTERAÇÕES</x:String>
<x:String x:Key="Text.Stashes.Stashes" xml:space="preserve">STASHES</x:String>
<x:String x:Key="Text.Statistics" xml:space="preserve">Estatísticas</x:String>
<x:String x:Key="Text.Stashes" xml:space="preserve">Stashes</x:String>
<x:String x:Key="Text.Statistics.CommitAmount" xml:space="preserve">COMMITS</x:String>
<x:String x:Key="Text.Statistics.Committer" xml:space="preserve">COMMITTER</x:String>
<x:String x:Key="Text.Statistics.ThisMonth" xml:space="preserve">MÊS</x:String>
<x:String x:Key="Text.Statistics.ThisWeek" xml:space="preserve">SEMANA</x:String>
<x:String x:Key="Text.Statistics.TotalCommits" xml:space="preserve">COMMITS: </x:String>
<x:String x:Key="Text.Statistics.TotalAuthors" xml:space="preserve">AUTORES: </x:String>
<x:String x:Key="Text.Submodule" xml:space="preserve">SUBMÓDULOS</x:String>
<x:String x:Key="Text.Statistics.TotalCommits" xml:space="preserve">COMMITS: </x:String>
<x:String x:Key="Text.Statistics" xml:space="preserve">Estatísticas</x:String>
<x:String x:Key="Text.Submodule.Add" xml:space="preserve">Adicionar Submódulo</x:String>
<x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">Copiar Caminho Relativo</x:String>
<x:String x:Key="Text.Submodule.FetchNested" xml:space="preserve">Buscar submódulos aninhados</x:String>
<x:String x:Key="Text.Submodule.Open" xml:space="preserve">Abrir Repositório do Submódulo</x:String>
<x:String x:Key="Text.Submodule.RelativePath" xml:space="preserve">Caminho Relativo:</x:String>
<x:String x:Key="Text.Submodule.RelativePath.Placeholder" xml:space="preserve">Pasta relativa para armazenar este módulo.</x:String>
<x:String x:Key="Text.Submodule.RelativePath" xml:space="preserve">Caminho Relativo:</x:String>
<x:String x:Key="Text.Submodule.Remove" xml:space="preserve">Excluir Submódulo</x:String>
<x:String x:Key="Text.Submodule" xml:space="preserve">SUBMÓDULOS</x:String>
<x:String x:Key="Text.Sure" xml:space="preserve">OK</x:String>
<x:String x:Key="Text.TagCM.Copy" xml:space="preserve">Copiar Nome da Tag</x:String>
<x:String x:Key="Text.TagCM.Delete" xml:space="preserve">Excluir ${0}$...</x:String>
<x:String x:Key="Text.TagCM.Push" xml:space="preserve">Enviar ${0}$...</x:String>
<x:String x:Key="Text.URL" xml:space="preserve">URL:</x:String>
<x:String x:Key="Text.UpdateSubmodules" xml:space="preserve">Atualizar Submódulos</x:String>
<x:String x:Key="Text.UpdateSubmodules.All" xml:space="preserve">Todos os submódulos</x:String>
<x:String x:Key="Text.UpdateSubmodules.Init" xml:space="preserve">Inicializar conforme necessário</x:String>
<x:String x:Key="Text.UpdateSubmodules.Recursive" xml:space="preserve">Recursivamente</x:String>
<x:String x:Key="Text.UpdateSubmodules.Target" xml:space="preserve">Submódulo:</x:String>
<x:String x:Key="Text.UpdateSubmodules.UseRemote" xml:space="preserve">Usar opção --remote</x:String>
<x:String x:Key="Text.UpdateSubmodules" xml:space="preserve">Atualizar Submódulos</x:String>
<x:String x:Key="Text.URL" xml:space="preserve">URL:</x:String>
<x:String x:Key="Text.Warn" xml:space="preserve">Aviso</x:String>
<x:String x:Key="Text.Welcome" xml:space="preserve">Página de Boas-vindas</x:String>
<x:String x:Key="Text.Welcome.AddRootFolder" xml:space="preserve">Criar Grupo Raíz</x:String>
<x:String x:Key="Text.Welcome.AddSubFolder" xml:space="preserve">Criar Subgrupo</x:String>
<x:String x:Key="Text.Welcome.Clone" xml:space="preserve">Clonar Repositório</x:String>
<x:String x:Key="Text.Welcome.Delete" xml:space="preserve">Excluir</x:String>
<x:String x:Key="Text.Welcome.DragDropTip" xml:space="preserve">ARRASTAR E SOLTAR PASTAS SUPORTADO. AGRUPAMENTO PERSONALIZADO SUPORTADO.</x:String>
<x:String x:Key="Text.Welcome.Edit" xml:space="preserve">Editar</x:String>
<x:String x:Key="Text.Welcome.Move" xml:space="preserve">Mover para Outro Grupo</x:String>
<x:String x:Key="Text.Welcome.OpenAllInNode" xml:space="preserve">Abrir Todos os Repositórios</x:String>
<x:String x:Key="Text.Welcome.OpenOrInit" xml:space="preserve">Abrir Repositório</x:String>
<x:String x:Key="Text.Welcome.OpenTerminal" xml:space="preserve">Abrir Terminal</x:String>
<x:String x:Key="Text.Welcome.ScanDefaultCloneDir" xml:space="preserve">Reescanear Repositórios no Diretório de Clone Padrão</x:String>
<x:String x:Key="Text.Welcome.Search" xml:space="preserve">Buscar Repositórios...</x:String>
<x:String x:Key="Text.Welcome.Sort" xml:space="preserve">Ordenar</x:String>
<x:String x:Key="Text.WorkingCopy" xml:space="preserve">Alterações</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String>
<x:String x:Key="Text.Welcome" xml:space="preserve">Página de Boas-vindas</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.Extension" xml:space="preserve">Ignorar todos os arquivos *{0}</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.ExtensionInSameFolder" xml:space="preserve">Ignorar arquivos *{0} na mesma pasta</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">Ignorar arquivos na mesma pasta</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Ignorar apenas este arquivo</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore" xml:space="preserve">Git Ignore</x:String>
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Corrigir</x:String>
<x:String x:Key="Text.WorkingCopy.AutoStage" xml:space="preserve">Auto-Stage</x:String>
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Você pode stagear este arquivo agora.</x:String>
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">COMMIT</x:String>
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">COMMIT &amp; PUSH</x:String>
<x:String x:Key="Text.WorkingCopy.CommitMessageHelper" xml:space="preserve">Template/Histories</x:String>
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">COMMITAR E ENVIAR</x:String>
<x:String x:Key="Text.WorkingCopy.CommitMessageHelper" xml:space="preserve">Modelo/Históricos</x:String>
<x:String x:Key="Text.WorkingCopy.CommitTip" xml:space="preserve">Acionar evento de clique</x:String>
<x:String x:Key="Text.WorkingCopy.CommitWithAutoStage" xml:space="preserve">Preparar todas as mudanças e commitar</x:String>
<x:String x:Key="Text.WorkingCopy.ConfirmCommitWithoutFiles" xml:space="preserve">Commit vazio detectado! Deseja continuar (--allow-empty)?</x:String>
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">CONFLITOS DE ARQUIVO RESOLVIDOS</x:String>
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">CONFLITOS DETECTADOS</x:String>
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">CONFLITOS DE ARQUIVOS RESOLVIDOS</x:String>
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">INCLUIR ARQUIVOS NÃO RASTREADOS</x:String>
<x:String x:Key="Text.WorkingCopy.NoCommitHistories" xml:space="preserve">NENHUMA MENSAGEM DE ENTRADA RECENTE</x:String>
<x:String x:Key="Text.WorkingCopy.NoCommitTemplates" xml:space="preserve">NENHUM TEMPLATE DE COMMIT</x:String>
<x:String x:Key="Text.WorkingCopy.Staged" xml:space="preserve">STAGED</x:String>
<x:String x:Key="Text.WorkingCopy.NoCommitHistories" xml:space="preserve">SEM MENSAGENS DE ENTRADA RECENTES</x:String>
<x:String x:Key="Text.WorkingCopy.NoCommitTemplates" xml:space="preserve">SEM MODELOS DE COMMIT</x:String>
<x:String x:Key="Text.WorkingCopy.ResolveTip" xml:space="preserve">Clique com o botão direito nos arquivos selecionados e escolha como resolver conflitos.</x:String>
<x:String x:Key="Text.WorkingCopy.Staged.Unstage" xml:space="preserve">DESSTAGEAR</x:String>
<x:String x:Key="Text.WorkingCopy.Staged.UnstageAll" xml:space="preserve">DESSTAGEAR TODOS</x:String>
<x:String x:Key="Text.WorkingCopy.Unstaged" xml:space="preserve">NÃO STAGED</x:String>
<x:String x:Key="Text.WorkingCopy.Unstaged.Stage" xml:space="preserve">STAGEAR</x:String>
<x:String x:Key="Text.WorkingCopy.Unstaged.StageAll" xml:space="preserve">STAGEAR TODOS</x:String>
<x:String x:Key="Text.WorkingCopy.Staged" xml:space="preserve">STAGED</x:String>
<x:String x:Key="Text.WorkingCopy.Unstaged.ViewAssumeUnchaged" xml:space="preserve">VER SUPOR NÃO ALTERADO</x:String>
<x:String x:Key="Text.WorkingCopy.UseCommitTemplate" xml:space="preserve">Template: ${0}$</x:String>
<x:String x:Key="Text.WorkingCopy.ResolveTip" xml:space="preserve">Clique com o botão direito nos arquivos selecionados e escolha como resolver conflitos.</x:String>
<x:String x:Key="Text.Worktree" xml:space="preserve">WORKTREE</x:String>
<x:String x:Key="Text.WorkingCopy" xml:space="preserve">Alterações</x:String>
<x:String x:Key="Text.Workspace.Configure" xml:space="preserve">Configurar Espaços de Trabalho...</x:String>
<x:String x:Key="Text.Workspace" xml:space="preserve">ESPAÇO DE TRABALHO: </x:String>
<x:String x:Key="Text.Worktree.CopyPath" xml:space="preserve">Copiar Caminho</x:String>
<x:String x:Key="Text.Worktree.Lock" xml:space="preserve">Travar</x:String>
<x:String x:Key="Text.Worktree.Remove" xml:space="preserve">Remover</x:String>
<x:String x:Key="Text.Worktree.Unlock" xml:space="preserve">Destravar</x:String>
<x:String x:Key="Text.Worktree" xml:space="preserve">WORKTREE</x:String>
</ResourceDictionary>

View file

@ -74,8 +74,8 @@
<x:String x:Key="Text.ChangeCM.CheckoutFirstParentRevision" xml:space="preserve">Сбросить родительскую ревизию</x:String>
<x:String x:Key="Text.ChangeDisplayMode" xml:space="preserve">ИЗМЕНИТЬ РЕЖИМ ОТОБРАЖЕНИЯ</x:String>
<x:String x:Key="Text.ChangeDisplayMode.Grid" xml:space="preserve">Показывать в виде списка файлов и каталогов</x:String>
<x:String x:Key="Text.ChangeDisplayMode.List" xml:space="preserve">Показать в виде списка путей</x:String>
<x:String x:Key="Text.ChangeDisplayMode.Tree" xml:space="preserve">Показать в виде дерева файловой системы</x:String>
<x:String x:Key="Text.ChangeDisplayMode.List" xml:space="preserve">Показывать в виде списка путей</x:String>
<x:String x:Key="Text.ChangeDisplayMode.Tree" xml:space="preserve">Показывать в виде дерева файловой системы</x:String>
<x:String x:Key="Text.Checkout" xml:space="preserve">Проверить ветку</x:String>
<x:String x:Key="Text.Checkout.Commit" xml:space="preserve">Проверить фиксацию</x:String>
<x:String x:Key="Text.Checkout.Commit.Warning" xml:space="preserve">Предупреждение: При выполнении проверки фиксации ваша голова будет отсоединена</x:String>
@ -146,9 +146,12 @@
<x:String x:Key="Text.Configure.Git.AutoFetch" xml:space="preserve">Автоматическое извлечение внешних хранилищ</x:String>
<x:String x:Key="Text.Configure.Git.AutoFetchIntervalSuffix" xml:space="preserve">Минут(а/ы)</x:String>
<x:String x:Key="Text.Configure.Git.DefaultRemote" xml:space="preserve">Удалённое хранилище по-умолчанию</x:String>
<x:String x:Key="Text.Configure.Git.EnableSignOff" xml:space="preserve">Разрешить --signoff для фиксации</x:String>
<x:String x:Key="Text.Configure.IssueTracker" xml:space="preserve">ОТСЛЕЖИВАНИЕ ПРОБЛЕМ</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGithub" xml:space="preserve">Добавить пример правила для Git</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleJira" xml:space="preserve">Добавить пример правила Jira</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGitLabIssue" xml:space="preserve">Добавить пример правила выдачи GitLab</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGitLabMergeRequest" xml:space="preserve">Добавить пример правила запроса на слияние в GitLab</x:String>
<x:String x:Key="Text.Configure.IssueTracker.NewRule" xml:space="preserve">Новое правило</x:String>
<x:String x:Key="Text.Configure.IssueTracker.Regex" xml:space="preserve">Проблема с регулярным выражением:</x:String>
<x:String x:Key="Text.Configure.IssueTracker.RuleName" xml:space="preserve">Имя правила:</x:String>
@ -220,7 +223,7 @@
<x:String x:Key="Text.Diff.Copy" xml:space="preserve">Копировать</x:String>
<x:String x:Key="Text.Diff.FileModeChanged" xml:space="preserve">Режим файла изменён</x:String>
<x:String x:Key="Text.Diff.IgnoreWhitespace" xml:space="preserve">Игнорировать изменение пробелов</x:String>
<x:String x:Key="Text.Diff.ShowHiddenSymbols" xml:space="preserve">Показать скрытые символы</x:String>
<x:String x:Key="Text.Diff.ShowHiddenSymbols" xml:space="preserve">Показывать скрытые символы</x:String>
<x:String x:Key="Text.Diff.LFS" xml:space="preserve">ИЗМЕНЕНИЕ ОБЪЕКТА ХБФ</x:String>
<x:String x:Key="Text.Diff.Next" xml:space="preserve">Следующее различие</x:String>
<x:String x:Key="Text.Diff.NoChange" xml:space="preserve">НИКАКИХ ИЗМЕНЕНИЙ ИЛИ МЕНЯЕТСЯ ТОЛЬКО EOL</x:String>
@ -251,7 +254,6 @@
<x:String x:Key="Text.Fetch" xml:space="preserve">Извлечь</x:String>
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Извлечь все внешние хранилища</x:String>
<x:String x:Key="Text.Fetch.NoTags" xml:space="preserve">Извлечь без меток</x:String>
<x:String x:Key="Text.Fetch.Prune" xml:space="preserve">Удалить внешние мёртвые ветки</x:String>
<x:String x:Key="Text.Fetch.Remote" xml:space="preserve">Внешнее хранилище:</x:String>
<x:String x:Key="Text.Fetch.Title" xml:space="preserve">Извлечь внешние изменения</x:String>
<x:String x:Key="Text.FileCM.AssumeUnchanged" xml:space="preserve">Допустить без изменений</x:String>
@ -306,7 +308,7 @@
<x:String x:Key="Text.GitLFS.Fetch.Title" xml:space="preserve">Извлечь объекты ХБФ</x:String>
<x:String x:Key="Text.GitLFS.Fetch.Tips" xml:space="preserve">Запустить `git lfs fetch", чтобы загрузить объекты ХБФ Git. При этом рабочая копия не обновляется.</x:String>
<x:String x:Key="Text.GitLFS.Install" xml:space="preserve">Установить перехват ХБФ Git</x:String>
<x:String x:Key="Text.GitLFS.Locks" xml:space="preserve">Показать блокировки</x:String>
<x:String x:Key="Text.GitLFS.Locks" xml:space="preserve">Показывать блокировки</x:String>
<x:String x:Key="Text.GitLFS.Locks.Empty" xml:space="preserve">Нет заблокированных файлов</x:String>
<x:String x:Key="Text.GitLFS.Locks.Lock" xml:space="preserve">Блокировка</x:String>
<x:String x:Key="Text.GitLFS.Locks.OnlyMine" xml:space="preserve">Показывать только мои блокировки</x:String>
@ -403,10 +405,13 @@
<x:String x:Key="Text.Period.LastYear" xml:space="preserve">В пролому году</x:String>
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} лет назад</x:String>
<x:String x:Key="Text.Preference" xml:space="preserve">Параметры</x:String>
<x:String x:Key="Text.Preference.Advanced" xml:space="preserve">Расширенные опции</x:String>
<x:String x:Key="Text.Preference.AI" xml:space="preserve">ОТКРЫТЬ ИИ</x:String>
<x:String x:Key="Text.Preference.AI.Server" xml:space="preserve">Сервер</x:String>
<x:String x:Key="Text.Preference.AI.ApiKey" xml:space="preserve">Ключ API</x:String>
<x:String x:Key="Text.Preference.AI.AnalyzeDiffPrompt" xml:space="preserve">Запрос на анализ различий</x:String>
<x:String x:Key="Text.Preference.AI.GenerateSubjectPrompt" xml:space="preserve">Сгенерировать запрос на тему</x:String>
<x:String x:Key="Text.Preference.AI.Model" xml:space="preserve">Модель</x:String>
<x:String x:Key="Text.Preference.AI.Server" xml:space="preserve">Сервер</x:String>
<x:String x:Key="Text.Preference.Appearance" xml:space="preserve">ВИД</x:String>
<x:String x:Key="Text.Preference.Appearance.DefaultFont" xml:space="preserve">Шрифт по-умолчанию</x:String>
<x:String x:Key="Text.Preference.Appearance.DefaultFontSize" xml:space="preserve">Размер шрифта по-умолчанию</x:String>
@ -424,7 +429,7 @@
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">Проверить обновления при старте</x:String>
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">Язык</x:String>
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">История фиксаций</x:String>
<x:String x:Key="Text.Preference.General.ShowAuthorTime" xml:space="preserve">Показать время автора вместо времени фиксации на графике</x:String>
<x:String x:Key="Text.Preference.General.ShowAuthorTime" xml:space="preserve">Показывать время автора вместо времени фиксации на графике</x:String>
<x:String x:Key="Text.Preference.General.SubjectGuideLength" xml:space="preserve">Длина темы фиксации</x:String>
<x:String x:Key="Text.Preference.Git" xml:space="preserve">GIT</x:String>
<x:String x:Key="Text.Preference.Git.CRLF" xml:space="preserve">Включить автозавершение CRLF</x:String>
@ -495,7 +500,6 @@
<x:String x:Key="Text.RemoteCM.Fetch" xml:space="preserve">Извлечь</x:String>
<x:String x:Key="Text.RemoteCM.OpenInBrowser" xml:space="preserve">Открыть в браузере</x:String>
<x:String x:Key="Text.RemoteCM.Prune" xml:space="preserve">Удалить</x:String>
<x:String x:Key="Text.RemoteCM.Prune.Target" xml:space="preserve">Цель:</x:String>
<x:String x:Key="Text.RemoveWorktree" xml:space="preserve">Подтвердить удаление рабочего дерева</x:String>
<x:String x:Key="Text.RemoveWorktree.Force" xml:space="preserve">Включить опцию `--force`</x:String>
<x:String x:Key="Text.RemoveWorktree.Target" xml:space="preserve">Цель:</x:String>
@ -510,6 +514,7 @@
<x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">Очистить всё</x:String>
<x:String x:Key="Text.Repository.Configure" xml:space="preserve">Настройка этого хранилища</x:String>
<x:String x:Key="Text.Repository.Continue" xml:space="preserve">ПРОДОЛЖИТЬ</x:String>
<x:String x:Key="Text.Repository.EnableReflog" xml:space="preserve">Разрешить опцию '--reflog'</x:String>
<x:String x:Key="Text.Repository.Explore" xml:space="preserve">Открыть в файловом менеджере</x:String>
<x:String x:Key="Text.Repository.Filter" xml:space="preserve">Поиск веток, меток и подмодулей</x:String>
<x:String x:Key="Text.Repository.FilterCommitPrefix" xml:space="preserve">ОТФИЛЬТРОВАНО ОТ:</x:String>
@ -529,7 +534,7 @@
<x:String x:Key="Text.Repository.Search.BySHA" xml:space="preserve">SHA</x:String>
<x:String x:Key="Text.Repository.Search.ByUser" xml:space="preserve">Автор и исполнитель</x:String>
<x:String x:Key="Text.Repository.Search.InCurrentBranch" xml:space="preserve">Текущая ветка</x:String>
<x:String x:Key="Text.Repository.ShowTagsAsTree" xml:space="preserve">Показать метки как дерево</x:String>
<x:String x:Key="Text.Repository.ShowTagsAsTree" xml:space="preserve">Показывать метки как дерево</x:String>
<x:String x:Key="Text.Repository.Statistics" xml:space="preserve">Статистики </x:String>
<x:String x:Key="Text.Repository.Submodules" xml:space="preserve">ПОДМОДУЛИ</x:String>
<x:String x:Key="Text.Repository.Submodules.Add" xml:space="preserve">ДОБАВИТЬ ПОДМОДУЛЬ</x:String>
@ -634,13 +639,13 @@
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">Игнорировать файлы в том же каталоге</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">Игнорировать только эти файлы</x:String>
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">Изменить</x:String>
<x:String x:Key="Text.WorkingCopy.AutoStage" xml:space="preserve">Автоподготовка</x:String>
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">Теперь вы можете подготовитть этот файл.</x:String>
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">ЗАФИКСИРОВАТЬ</x:String>
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">ЗАФИКСИРОВАТЬ и ОТПРАВИТЬ</x:String>
<x:String x:Key="Text.WorkingCopy.CommitMessageHelper" xml:space="preserve">Шаблон/Истории</x:String>
<x:String x:Key="Text.WorkingCopy.CommitTip" xml:space="preserve">Запустить событие щелчка</x:String>
<x:String x:Key="Text.WorkingCopy.CommitWithAutoStage" xml:space="preserve">Подготовить все изменения и зафиксировать</x:String>
<x:String x:Key="Text.WorkingCopy.ConfirmCommitWithoutFiles" xml:space="preserve">Обнаружена пустая фиксация! Вы хотите продолжить (--allow-empty)?</x:String>
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">ОБНАРУЖЕНЫ КОНФЛИКТЫ</x:String>
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">КОНФЛИКТЫ ФАЙЛОВ РАЗРЕШЕНЫ</x:String>
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">ВКЛЮЧИТЬ НЕОТСЛЕЖИВАЕМЫЕ ФАЙЛЫ</x:String>

View file

@ -146,9 +146,12 @@
<x:String x:Key="Text.Configure.Git.AutoFetch" xml:space="preserve">启用定时自动拉取远程更新</x:String>
<x:String x:Key="Text.Configure.Git.AutoFetchIntervalSuffix" xml:space="preserve">分钟</x:String>
<x:String x:Key="Text.Configure.Git.DefaultRemote" xml:space="preserve">默认远程</x:String>
<x:String x:Key="Text.Configure.Git.EnableSignOff" xml:space="preserve">提交信息追加署名 (--signoff)</x:String>
<x:String x:Key="Text.Configure.IssueTracker" xml:space="preserve">ISSUE追踪</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGithub" xml:space="preserve">新增匹配Github Issue规则</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleJira" xml:space="preserve">新增匹配Jira规则</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGitLabIssue" xml:space="preserve">新增匹配GitLab议题规则</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGitLabMergeRequest" xml:space="preserve">新增匹配GitLab合并请求规则</x:String>
<x:String x:Key="Text.Configure.IssueTracker.NewRule" xml:space="preserve">新增自定义规则</x:String>
<x:String x:Key="Text.Configure.IssueTracker.Regex" xml:space="preserve">匹配ISSUE的正则表达式 </x:String>
<x:String x:Key="Text.Configure.IssueTracker.RuleName" xml:space="preserve">规则名 </x:String>
@ -250,7 +253,6 @@
<x:String x:Key="Text.Fetch" xml:space="preserve">拉取(fetch)</x:String>
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">拉取所有的远程仓库</x:String>
<x:String x:Key="Text.Fetch.NoTags" xml:space="preserve">不拉取远程标签</x:String>
<x:String x:Key="Text.Fetch.Prune" xml:space="preserve">自动清理远程已删除分支</x:String>
<x:String x:Key="Text.Fetch.Remote" xml:space="preserve">远程仓库 </x:String>
<x:String x:Key="Text.Fetch.Title" xml:space="preserve">拉取远程仓库内容</x:String>
<x:String x:Key="Text.FileCM.AssumeUnchanged" xml:space="preserve">不跟踪此文件的更改</x:String>
@ -402,6 +404,7 @@
<x:String x:Key="Text.Period.LastYear" xml:space="preserve">一年前</x:String>
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0}年前</x:String>
<x:String x:Key="Text.Preference" xml:space="preserve">偏好设置</x:String>
<x:String x:Key="Text.Preference.Advanced" xml:space="preserve">高级设置</x:String>
<x:String x:Key="Text.Preference.Appearance" xml:space="preserve">外观配置</x:String>
<x:String x:Key="Text.Preference.Appearance.DefaultFont" xml:space="preserve">缺省字体</x:String>
<x:String x:Key="Text.Preference.Appearance.DefaultFontSize" xml:space="preserve">默认字体大小</x:String>
@ -629,13 +632,13 @@
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">忽略同目录下所有文件</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">忽略本文件</x:String>
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">修补(--amend)</x:String>
<x:String x:Key="Text.WorkingCopy.AutoStage" xml:space="preserve">自动暂存</x:String>
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">现在您已可将其加入暂存区中</x:String>
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">提交</x:String>
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">提交并推送</x:String>
<x:String x:Key="Text.WorkingCopy.CommitMessageHelper" xml:space="preserve">历史输入/模板</x:String>
<x:String x:Key="Text.WorkingCopy.CommitTip" xml:space="preserve">触发点击事件</x:String>
<x:String x:Key="Text.WorkingCopy.CommitWithAutoStage" xml:space="preserve">自动暂存所有变更并提交</x:String>
<x:String x:Key="Text.WorkingCopy.ConfirmCommitWithoutFiles" xml:space="preserve">提交未包含变更文件!是否继续(--allow-empty)</x:String>
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">检测到冲突</x:String>
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">文件冲突已解决</x:String>
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">显示未跟踪文件</x:String>

View file

@ -146,9 +146,12 @@
<x:String x:Key="Text.Configure.Git.AutoFetch" xml:space="preserve">啟用定時自動提取 (fetch) 遠端更新</x:String>
<x:String x:Key="Text.Configure.Git.AutoFetchIntervalSuffix" xml:space="preserve">分鐘</x:String>
<x:String x:Key="Text.Configure.Git.DefaultRemote" xml:space="preserve">預設遠端存放庫</x:String>
<x:String x:Key="Text.Configure.Git.EnableSignOff" xml:space="preserve">提交訊息追加署名 (--signoff)</x:String>
<x:String x:Key="Text.Configure.IssueTracker" xml:space="preserve">Issue 追蹤</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGithub" xml:space="preserve">新增符合 GitHub Issue 規則</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleJira" xml:space="preserve">新增符合 Jira 規則</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGitLabIssue" xml:space="preserve">新增符合 GitLab 議題規則</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGitLabMergeRequest" xml:space="preserve">新增符合 GitLab 合併請求規則</x:String>
<x:String x:Key="Text.Configure.IssueTracker.NewRule" xml:space="preserve">新增自訂規則</x:String>
<x:String x:Key="Text.Configure.IssueTracker.Regex" xml:space="preserve">符合 Issue 的正則表達式:</x:String>
<x:String x:Key="Text.Configure.IssueTracker.RuleName" xml:space="preserve">規則名稱:</x:String>
@ -250,7 +253,6 @@
<x:String x:Key="Text.Fetch" xml:space="preserve">提取 (fetch)</x:String>
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">提取所有的遠端存放庫</x:String>
<x:String x:Key="Text.Fetch.NoTags" xml:space="preserve">不提取遠端標籤</x:String>
<x:String x:Key="Text.Fetch.Prune" xml:space="preserve">自動清理遠端已刪除分支</x:String>
<x:String x:Key="Text.Fetch.Remote" xml:space="preserve">遠端存放庫:</x:String>
<x:String x:Key="Text.Fetch.Title" xml:space="preserve">提取遠端存放庫內容</x:String>
<x:String x:Key="Text.FileCM.AssumeUnchanged" xml:space="preserve">不追蹤此檔案的變更</x:String>
@ -402,10 +404,13 @@
<x:String x:Key="Text.Period.LastYear" xml:space="preserve">一年前</x:String>
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">{0} 年前</x:String>
<x:String x:Key="Text.Preference" xml:space="preserve">偏好設定</x:String>
<x:String x:Key="Text.Preference.Advanced" xml:space="preserve">進階設定</x:String>
<x:String x:Key="Text.Preference.AI" xml:space="preserve">OpenAI</x:String>
<x:String x:Key="Text.Preference.AI.Server" xml:space="preserve">伺服器</x:String>
<x:String x:Key="Text.Preference.AI.ApiKey" xml:space="preserve">API 金鑰</x:String>
<x:String x:Key="Text.Preference.AI.Model" xml:space="preserve">模型</x:String>
<x:String x:Key="Text.Preference.AI.AnalyzeDiffPrompt" xml:space="preserve">分析變更差異提示詞</x:String>
<x:String x:Key="Text.Preference.AI.GenerateSubjectPrompt" xml:space="preserve">產生提交訊息提示詞</x:String>
<x:String x:Key="Text.Preference.Appearance" xml:space="preserve">外觀設定</x:String>
<x:String x:Key="Text.Preference.Appearance.DefaultFont" xml:space="preserve">預設字型</x:String>
<x:String x:Key="Text.Preference.Appearance.DefaultFontSize" xml:space="preserve">預設字型大小</x:String>
@ -494,7 +499,6 @@
<x:String x:Key="Text.RemoteCM.Fetch" xml:space="preserve">提取 (fetch) 更新</x:String>
<x:String x:Key="Text.RemoteCM.OpenInBrowser" xml:space="preserve">在瀏覽器中存取網址</x:String>
<x:String x:Key="Text.RemoteCM.Prune" xml:space="preserve">清理遠端已刪除分支</x:String>
<x:String x:Key="Text.RemoteCM.Prune.Target" xml:space="preserve">目標:</x:String>
<x:String x:Key="Text.RemoveWorktree" xml:space="preserve">刪除工作區操作確認</x:String>
<x:String x:Key="Text.RemoveWorktree.Force" xml:space="preserve">啟用 [--force] 選項</x:String>
<x:String x:Key="Text.RemoveWorktree.Target" xml:space="preserve">目標工作區:</x:String>
@ -634,13 +638,13 @@
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.InSameFolder" xml:space="preserve">忽略同路徑下所有檔案</x:String>
<x:String x:Key="Text.WorkingCopy.AddToGitIgnore.SingleFile" xml:space="preserve">忽略本檔案</x:String>
<x:String x:Key="Text.WorkingCopy.Amend" xml:space="preserve">修補 (--amend)</x:String>
<x:String x:Key="Text.WorkingCopy.AutoStage" xml:space="preserve">自動暫存</x:String>
<x:String x:Key="Text.WorkingCopy.CanStageTip" xml:space="preserve">現在您已可將其加入暫存區中</x:String>
<x:String x:Key="Text.WorkingCopy.Commit" xml:space="preserve">提 交</x:String>
<x:String x:Key="Text.WorkingCopy.CommitAndPush" xml:space="preserve">提交並推送</x:String>
<x:String x:Key="Text.WorkingCopy.CommitMessageHelper" xml:space="preserve">歷史輸入/範本</x:String>
<x:String x:Key="Text.WorkingCopy.CommitTip" xml:space="preserve">觸發點擊事件</x:String>
<x:String x:Key="Text.WorkingCopy.CommitWithAutoStage" xml:space="preserve">自動暫存全部變更並提交</x:String>
<x:String x:Key="Text.WorkingCopy.ConfirmCommitWithoutFiles" xml:space="preserve">未包含任何檔案變更! 您是否仍要提交 (--allow-empty)?</x:String>
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">檢測到衝突</x:String>
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">檔案衝突已解決</x:String>
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">顯示未追蹤檔案</x:String>

View file

@ -100,7 +100,7 @@ namespace SourceGit.ViewModels
{
SetProgressDescription("Fetching from added remote ...");
new Commands.Config(_repo.FullPath).Set($"remote.{_name}.sshkey", _useSSH ? SSHKey : null);
new Commands.Fetch(_repo.FullPath, _name, true, false, SetProgressDescription).Exec();
new Commands.Fetch(_repo.FullPath, _name, false, SetProgressDescription).Exec();
}
CallUIThread(() =>
{

View file

@ -194,9 +194,9 @@ namespace SourceGit.ViewModels
return -1;
if (l.Backend is Models.Branch)
return r.Backend is Models.Branch ? string.Compare(l.Name, r.Name, StringComparison.Ordinal) : 1;
return r.Backend is Models.Branch ? Models.NumericSort.Compare(l.Name, r.Name) : 1;
return r.Backend is Models.Branch ? -1 : string.Compare(l.Name, r.Name, StringComparison.Ordinal);
return r.Backend is Models.Branch ? -1 : Models.NumericSort.Compare(l.Name, r.Name);
});
foreach (var node in nodes)

View file

@ -114,9 +114,9 @@ namespace SourceGit.ViewModels
nodes.Sort((l, r) =>
{
if (l.IsFolder)
return r.IsFolder ? string.Compare(l.FullPath, r.FullPath, StringComparison.Ordinal) : -1;
return r.IsFolder ? 1 : string.Compare(l.FullPath, r.FullPath, StringComparison.Ordinal);
if (l.IsFolder == r.IsFolder)
return Models.NumericSort.Compare(l.FullPath, r.FullPath);
return l.IsFolder ? -1 : 1;
});
}

View file

@ -0,0 +1,19 @@
namespace SourceGit.ViewModels
{
public class ConfirmCommitWithoutFiles
{
public ConfirmCommitWithoutFiles(WorkingCopy wc, bool autoPush)
{
_wc = wc;
_autoPush = autoPush;
}
public void Continue()
{
_wc.CommitWithoutFiles(_autoPush);
}
private readonly WorkingCopy _wc;
private bool _autoPush;
}
}

View file

@ -68,12 +68,13 @@ namespace SourceGit.ViewModels
{
builder.Append("(");
builder.Append(_scope);
builder.Append("): ");
builder.Append(")");
}
else
{
if (string.IsNullOrEmpty(_breakingChanges))
builder.Append(": ");
}
else
builder.Append("!: ");
builder.Append(_description);
builder.Append("\n\n");

View file

@ -31,7 +31,7 @@ namespace SourceGit.ViewModels
return Task.Run(() =>
{
new Commands.Fetch(_repo.FullPath, To.Remote, Local.Name, To.Name, SetProgressDescription).Exec();
new Commands.UpdateRef(_repo.FullPath, Local.FullName, To.FullName, SetProgressDescription).Exec();
CallUIThread(() => _repo.SetWatcherEnabled(true));
return true;
});

View file

@ -22,12 +22,6 @@ namespace SourceGit.ViewModels
set;
}
public bool Prune
{
get;
set;
} = true;
public bool NoTags
{
get => _repo.Settings.FetchWithoutTags;
@ -53,13 +47,13 @@ namespace SourceGit.ViewModels
foreach (var remote in _repo.Remotes)
{
SetProgressDescription($"Fetching remote: {remote.Name}");
new Commands.Fetch(_repo.FullPath, remote.Name, Prune, NoTags, SetProgressDescription).Exec();
new Commands.Fetch(_repo.FullPath, remote.Name, NoTags, SetProgressDescription).Exec();
}
}
else
{
SetProgressDescription($"Fetching remote: {SelectedRemote.Name}");
new Commands.Fetch(_repo.FullPath, SelectedRemote.Name, Prune, NoTags, SetProgressDescription).Exec();
new Commands.Fetch(_repo.FullPath, SelectedRemote.Name, NoTags, SetProgressDescription).Exec();
}
CallUIThread(() =>

View file

@ -80,21 +80,23 @@ namespace SourceGit.ViewModels
private void UpdateVisibleLocks()
{
var visible = new List<Models.LFSLock>();
if (!_showOnlyMyLocks)
{
VisibleLocks = _cachedLocks;
foreach (var lfsLock in _cachedLocks)
visible.Add(lfsLock);
}
else
{
var visible = new List<Models.LFSLock>();
foreach (var lfsLock in _cachedLocks)
{
if (lfsLock.User == _userName)
visible.Add(lfsLock);
}
VisibleLocks = visible;
}
VisibleLocks = visible;
}
private string _repo;

View file

@ -25,6 +25,7 @@ namespace SourceGit.ViewModels
_instance.PrepareGit();
_instance.PrepareShellOrTerminal();
_instance.PrepareWorkspaces();
_instance.PrepareOpenAIPrompt();
return _instance;
}
@ -315,6 +316,32 @@ namespace SourceGit.ViewModels
}
}
public string OpenAIAnalyzeDiffPrompt
{
get => Models.OpenAI.AnalyzeDiffPrompt;
set
{
if (value != Models.OpenAI.AnalyzeDiffPrompt)
{
Models.OpenAI.AnalyzeDiffPrompt = value;
OnPropertyChanged();
}
}
}
public string OpenAIGenerateSubjectPrompt
{
get => Models.OpenAI.GenerateSubjectPrompt;
set
{
if (value != Models.OpenAI.GenerateSubjectPrompt)
{
Models.OpenAI.GenerateSubjectPrompt = value;
OnPropertyChanged();
}
}
}
public uint StatisticsSampleColor
{
get => _statisticsSampleColor;
@ -527,6 +554,45 @@ namespace SourceGit.ViewModels
}
}
private void PrepareOpenAIPrompt()
{
if (string.IsNullOrEmpty(Models.OpenAI.AnalyzeDiffPrompt))
{
Models.OpenAI.AnalyzeDiffPrompt = """
You are an expert developer specialist in creating commits.
Provide a super concise one sentence overall changes summary of the user `git diff` output following strictly the next rules:
- Do not use any code snippets, imports, file routes or bullets points.
- Do not mention the route of file that has been change.
- Write clear, concise, and descriptive messages that explain the MAIN GOAL made of the changes.
- Use the present tense and active voice in the message, for example, "Fix bug" instead of "Fixed bug.".
- Use the imperative mood, which gives the message a sense of command, e.g. "Add feature" instead of "Added feature".
- Avoid using general terms like "update" or "change", be specific about what was updated or changed.
- Avoid using terms like "The main goal of", just output directly the summary in plain text
""";
}
if (string.IsNullOrEmpty(Models.OpenAI.GenerateSubjectPrompt))
{
Models.OpenAI.GenerateSubjectPrompt = """
You are an expert developer specialist in creating commits messages.
Your only goal is to retrieve a single commit message.
Based on the provided user changes, combine them in ONE SINGLE commit message retrieving the global idea, following strictly the next rules:
- Assign the commit {type} according to the next conditions:
feat: Only when adding a new feature.
fix: When fixing a bug.
docs: When updating documentation.
style: When changing elements styles or design and/or making changes to the code style (formatting, missing semicolons, etc.) without changing the code logic.
test: When adding or updating tests.
chore: When making changes to the build process or auxiliary tools and libraries.
revert: When undoing a previous commit.
refactor: When restructuring code without changing its external behavior, or is any of the other refactor types.
- Do not add any issues numeration, explain your output nor introduce your answer.
- Output directly only one commit message in plain text with the next format: {type}: {commit_message}.
- Be as concise as possible, keep the message under 50 characters.
""";
}
}
private RepositoryNode FindNodeRecursive(string id, List<RepositoryNode> collection)
{
foreach (var node in collection)

View file

@ -147,7 +147,7 @@ namespace SourceGit.ViewModels
if (FetchAllBranches)
{
SetProgressDescription($"Fetching remote: {_selectedRemote.Name}...");
rs = new Commands.Fetch(_repo.FullPath, _selectedRemote.Name, false, NoTags, SetProgressDescription).Exec();
rs = new Commands.Fetch(_repo.FullPath, _selectedRemote.Name, NoTags, SetProgressDescription).Exec();
if (!rs)
return false;

View file

@ -1355,8 +1355,9 @@ namespace SourceGit.ViewModels
};
menu.Items.Add(checkout);
var worktree = _worktrees.Find(x => x.Branch == branch.FullName);
var upstream = _branches.Find(x => x.FullName == branch.Upstream);
if (upstream != null)
if (upstream != null && worktree == null)
{
var fastForward = new MenuItem();
fastForward.Header = new Views.NameHighlightedTextBlock("BranchCM.FastForward", upstream.FriendlyName);
@ -2113,7 +2114,7 @@ namespace SourceGit.ViewModels
IsAutoFetching = true;
Dispatcher.UIThread.Invoke(() => OnPropertyChanged(nameof(IsAutoFetching)));
new Commands.Fetch(_fullpath, "--all", true, false, null) { RaiseError = false }.Exec();
new Commands.Fetch(_fullpath, "--all", false, null) { RaiseError = false }.Exec();
_lastFetchTime = DateTime.Now;
IsAutoFetching = false;
Dispatcher.UIThread.Invoke(() => OnPropertyChanged(nameof(IsAutoFetching)));

View file

@ -60,6 +60,12 @@ namespace SourceGit.ViewModels
set => SetProperty(ref _httpProxy, value);
}
public bool EnableSignOffForCommit
{
get => _repo.Settings.EnableSignOffForCommit;
set => _repo.Settings.EnableSignOffForCommit = value;
}
public bool EnableAutoFetch
{
get => _repo.Settings.EnableAutoFetch;
@ -166,6 +172,34 @@ namespace SourceGit.ViewModels
SelectedIssueTrackerRule = _repo.Settings.AddJiraIssueTracker();
}
public void AddSampleGitLabIssueTracker()
{
foreach (var remote in _repo.Remotes)
{
if (remote.TryGetVisitURL(out string url))
{
SelectedIssueTrackerRule = _repo.Settings.AddGitLabIssueTracker(url);
return;
}
}
SelectedIssueTrackerRule = _repo.Settings.AddGitLabIssueTracker(null);
}
public void AddSampleGitLabMergeRequestTracker()
{
foreach (var remote in _repo.Remotes)
{
if (remote.TryGetVisitURL(out string url))
{
SelectedIssueTrackerRule = _repo.Settings.AddGitLabMergeRequestTracker(url);
return;
}
}
SelectedIssueTrackerRule = _repo.Settings.AddGitLabMergeRequestTracker(null);
}
public void NewIssueTracker()
{
SelectedIssueTrackerRule = _repo.Settings.AddNewIssueTracker();

View file

@ -39,7 +39,7 @@ namespace SourceGit.ViewModels
return Task.Run(() =>
{
var succ = new Commands.Commit(_repo.FullPath, _message, true, true).Exec();
var succ = new Commands.Commit(_repo.FullPath, _message, true, _repo.Settings.EnableSignOffForCommit).Run();
CallUIThread(() => _repo.SetWatcherEnabled(true));
return succ;
});

View file

@ -35,7 +35,7 @@ namespace SourceGit.ViewModels
{
var succ = new Commands.Reset(_repo.FullPath, Target.SHA, "--soft").Exec();
if (succ)
succ = new Commands.Commit(_repo.FullPath, _message, true).Exec();
succ = new Commands.Commit(_repo.FullPath, _message, true, _repo.Settings.EnableSignOffForCommit).Run();
CallUIThread(() => _repo.SetWatcherEnabled(true));
return succ;
});

View file

@ -33,11 +33,6 @@ namespace SourceGit.ViewModels
public class WorkingCopy : ObservableObject
{
public string RepoPath
{
get => _repo.FullPath;
}
public bool IncludeUntracked
{
get => _repo.IncludeUntracked;
@ -79,12 +74,6 @@ namespace SourceGit.ViewModels
private set => SetProperty(ref _isCommitting, value);
}
public bool AutoStageBeforeCommit
{
get => _repo.Settings.AutoStageBeforeCommit;
set => _repo.Settings.AutoStageBeforeCommit = value;
}
public bool UseAmend
{
get => _useAmend;
@ -414,19 +403,43 @@ namespace SourceGit.ViewModels
}
}
public void GenerateCommitMessageByAI()
{
if (!Models.OpenAI.IsValid)
{
App.RaiseException(_repo.FullPath, "Bad configuration for OpenAI");
return;
}
if (_staged is { Count: > 0 })
{
var dialog = new Views.AIAssistant(_repo.FullPath, _staged, generated => CommitMessage = generated);
App.OpenDialog(dialog);
}
else
{
App.RaiseException(_repo.FullPath, "No files added to commit!");
}
}
public void Commit()
{
DoCommit(AutoStageBeforeCommit, false);
DoCommit(false, false, false);
}
public void CommitWithAutoStage()
{
DoCommit(true, false);
DoCommit(true, false, false);
}
public void CommitWithPush()
{
DoCommit(AutoStageBeforeCommit, true);
DoCommit(false, true, false);
}
public void CommitWithoutFiles(bool autoPush)
{
DoCommit(false, autoPush, true);
}
public ContextMenu CreateContextMenuForUnstagedChanges()
@ -1158,7 +1171,7 @@ namespace SourceGit.ViewModels
item.Icon = App.CreateMenuIcon("Icons.Code");
item.Click += (_, e) =>
{
CommitMessage = template.Apply(_staged);
CommitMessage = template.Apply(_repo.CurrentBranch, _staged);
e.Handled = true;
};
menu.Items.Add(item);
@ -1274,7 +1287,7 @@ namespace SourceGit.ViewModels
_repo.SetWatcherEnabled(true);
}
private void DoCommit(bool autoStage, bool autoPush)
private void DoCommit(bool autoStage, bool autoPush, bool allowEmpty)
{
if (!PopupHost.CanCreatePopup())
{
@ -1288,23 +1301,16 @@ namespace SourceGit.ViewModels
return;
}
if (!_useAmend)
if (!_useAmend && !allowEmpty)
{
if (autoStage)
if ((autoStage && _count == 0) || (!autoStage && _staged.Count == 0))
{
if (_count == 0)
App.OpenDialog(new Views.ConfirmCommitWithoutFiles()
{
App.RaiseException(_repo.FullPath, "No files added to commit!");
return;
}
}
else
{
if (_staged.Count == 0)
{
App.RaiseException(_repo.FullPath, "No files added to commit!");
return;
}
DataContext = new ConfirmCommitWithoutFiles(this, autoPush)
});
return;
}
}
@ -1319,7 +1325,7 @@ namespace SourceGit.ViewModels
succ = new Commands.Add(_repo.FullPath, _repo.IncludeUntracked).Exec();
if (succ)
succ = new Commands.Commit(_repo.FullPath, _commitMessage, _useAmend).Exec();
succ = new Commands.Commit(_repo.FullPath, _commitMessage, _useAmend, _repo.Settings.EnableSignOffForCommit).Run();
Dispatcher.UIThread.Post(() =>
{

View file

@ -7,7 +7,6 @@
xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="120"
x:Class="SourceGit.Views.AIAssistant"
x:DataType="vm:WorkingCopy"
x:Name="ThisControl"
Icon="/App.ico"
Title="{DynamicResource Text.AIAssistant}"
@ -55,6 +54,7 @@
Margin="16"
FontSize="{Binding Source={x:Static vm:Preference.Instance}, Path=DefaultFontSize, Converter={x:Static c:DoubleConverters.Decrease}}"
HorizontalAlignment="Center"
Text="Generating commit message... Please wait!"
TextTrimming="CharacterEllipsis"/>
</Grid>
</v:ChromelessWindow>

View file

@ -1,3 +1,5 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
@ -13,28 +15,36 @@ namespace SourceGit.Views
{
_cancel = new CancellationTokenSource();
InitializeComponent();
ProgressMessage.Text = "Generating commit message... Please wait!";
}
public void GenerateCommitMessage()
public AIAssistant(string repo, List<Models.Change> changes, Action<string> onDone)
{
if (DataContext is ViewModels.WorkingCopy vm)
_repo = repo;
_changes = changes;
_onDone = onDone;
_cancel = new CancellationTokenSource();
InitializeComponent();
}
protected override void OnOpened(EventArgs e)
{
base.OnOpened(e);
if (string.IsNullOrEmpty(_repo))
return;
Task.Run(() =>
{
Task.Run(() =>
var message = new Commands.GenerateCommitMessage(_repo, _changes, _cancel.Token, SetDescription).Result();
if (_cancel.IsCancellationRequested)
return;
Dispatcher.UIThread.Invoke(() =>
{
var message = new Commands.GenerateCommitMessage(vm.RepoPath, vm.Staged, _cancel.Token, SetDescription).Result();
if (_cancel.IsCancellationRequested)
return;
Dispatcher.UIThread.Invoke(() =>
{
if (DataContext is ViewModels.WorkingCopy wc)
wc.CommitMessage = message;
Close();
});
}, _cancel.Token);
}
_onDone?.Invoke(message);
Close();
});
}, _cancel.Token);
}
protected override void OnClosing(WindowClosingEventArgs e)
@ -50,12 +60,12 @@ namespace SourceGit.Views
private void SetDescription(string message)
{
Dispatcher.UIThread.Invoke(() =>
{
ProgressMessage.Text = message;
});
Dispatcher.UIThread.Invoke(() => ProgressMessage.Text = message);
}
private string _repo;
private List<Models.Change> _changes;
private Action<string> _onDone;
private CancellationTokenSource _cancel;
}
}

View file

@ -128,10 +128,9 @@ namespace SourceGit.Views
foreach (var part in parts)
chars.Add(part[0]);
if (chars.Count >= 2)
if (chars.Count >= 2 && char.IsAsciiLetterOrDigit(chars[0]) && char.IsAsciiLetterOrDigit(chars[^1]))
return string.Format("{0}{1}", chars[0], chars[^1]);
if (chars.Count == 1)
return string.Format("{0}", chars[0]);
return name.Substring(0, 1);
}

View file

@ -0,0 +1,74 @@
<v:ChromelessWindow xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:v="using:SourceGit.Views"
xmlns:vm="using:SourceGit.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.ConfirmCommitWithoutFiles"
x:DataType="vm:ConfirmCommitWithoutFiles"
x:Name="ThisControl"
Icon="/App.ico"
Title="{DynamicResource Text.Warn}"
SizeToContent="WidthAndHeight"
CanResize="False"
WindowStartupLocation="CenterOwner">
<Grid RowDefinitions="Auto,Auto,Auto">
<!-- TitleBar -->
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30" IsVisible="{Binding !#ThisControl.UseSystemWindowFrame}">
<Border Grid.Column="0" Grid.ColumnSpan="3"
Background="{DynamicResource Brush.TitleBar}"
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}"
PointerPressed="BeginMoveWindow"/>
<Path Grid.Column="0"
Width="14" Height="14"
Data="{StaticResource Icons.Error}"
Margin="10,0,0,0"
IsVisible="{OnPlatform True, macOS=False}"/>
<v:CaptionButtonsMacOS Grid.Column="0"
Margin="0,2,0,0"
IsCloseButtonOnly="True"
IsVisible="{OnPlatform False, macOS=True}"/>
<TextBlock Grid.Column="0" Grid.ColumnSpan="3"
Classes="bold"
Text="{DynamicResource Text.Warn}"
HorizontalAlignment="Center" VerticalAlignment="Center"
IsHitTestVisible="False"/>
<v:CaptionButtons Grid.Column="2"
IsCloseButtonOnly="True"
IsVisible="{OnPlatform True, macOS=False}"/>
</Grid>
<!-- Body -->
<Border Grid.Row="1" Margin="16">
<TextBlock Text="{DynamicResource Text.WorkingCopy.ConfirmCommitWithoutFiles}"/>
</Border>
<!-- Buttons -->
<StackPanel Grid.Row="2" Margin="0,0,0,16" Orientation="Horizontal" HorizontalAlignment="Center">
<Button Classes="flat"
Width="80"
Height="30"
Margin="4,0"
Click="Sure"
Content="{DynamicResource Text.Sure}"
HorizontalAlignment="Center"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"/>
<Button Classes="flat primary"
Width="80"
Height="30"
Margin="4,0"
Click="CloseWindow"
Content="{DynamicResource Text.Cancel}"
HorizontalAlignment="Center"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"/>
</StackPanel>
</Grid>
</v:ChromelessWindow>

View file

@ -0,0 +1,33 @@
using Avalonia.Input;
using Avalonia.Interactivity;
namespace SourceGit.Views
{
public partial class ConfirmCommitWithoutFiles : ChromelessWindow
{
public ConfirmCommitWithoutFiles()
{
InitializeComponent();
}
private void BeginMoveWindow(object _, PointerPressedEventArgs e)
{
BeginMoveDrag(e);
}
private void Sure(object _1, RoutedEventArgs _2)
{
if (DataContext is ViewModels.ConfirmCommitWithoutFiles vm)
{
vm.Continue();
}
Close();
}
private void CloseWindow(object _1, RoutedEventArgs _2)
{
Close();
}
}
}

View file

@ -16,7 +16,7 @@
SizeToContent="Height"
CanResize="False"
WindowStartupLocation="CenterOwner">
<Grid RowDefinitions="Auto,Auto,Auto" MinWidth="494">
<Grid RowDefinitions="Auto,Auto,Auto">
<!-- TitleBar -->
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30" IsVisible="{Binding !#ThisControl.UseSystemWindowFrame}">
<Border Grid.Column="0" Grid.ColumnSpan="3"

View file

@ -11,7 +11,7 @@
<TextBlock FontSize="18"
Classes="bold"
Text="{DynamicResource Text.Fetch.Title}"/>
<Grid Margin="0,16,0,0" RowDefinitions="32,32,32,32" ColumnDefinitions="120,*">
<Grid Margin="0,16,0,0" RowDefinitions="32,32,32" ColumnDefinitions="120,*">
<TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0"
@ -37,10 +37,6 @@
IsChecked="{Binding FetchAllRemotes, Mode=TwoWay}"/>
<CheckBox Grid.Row="2" Grid.Column="1"
Content="{DynamicResource Text.Fetch.Prune}"
IsChecked="{Binding Prune, Mode=TwoWay}"/>
<CheckBox Grid.Row="3" Grid.Column="1"
Content="{DynamicResource Text.Fetch.NoTags}"
IsChecked="{Binding NoTags, Mode=TwoWay}"/>
</Grid>

View file

@ -308,7 +308,7 @@ namespace SourceGit.Views
[GeneratedRegex(@"^\[[\w\s]+\]")]
private static partial Regex REG_KEYWORD_FORMAT1();
[GeneratedRegex(@"^\w+([\<\(][\w\s_\-\*,]+[\>\)])?\s?:\s")]
[GeneratedRegex(@"^\S+([\<\(][\w\s_\-\*,]+[\>\)])?\!?\s?:\s")]
private static partial Regex REG_KEYWORD_FORMAT2();
private List<Models.Hyperlink> _matches = null;

View file

@ -465,7 +465,7 @@
<TextBlock Classes="bold" Margin="4,0,0,0" Text="{DynamicResource Text.Preference.AI}"/>
</StackPanel>
<Rectangle Margin="0,8" Fill="{DynamicResource Brush.Border2}" Height=".6" HorizontalAlignment="Stretch"/>
<Grid Margin="8,0,0,0" RowDefinitions="32,32,32">
<Grid Margin="8,0,0,0" RowDefinitions="32,32,32,32,Auto,Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="IntegrationLabel"/>
<ColumnDefinition Width="*"/>
@ -496,7 +496,42 @@
<TextBox Grid.Row="2" Grid.Column="1"
Height="28"
CornerRadius="3"
PasswordChar="*"
Text="{Binding OpenAIApiKey, Mode=TwoWay}"/>
<ToggleButton Grid.Row="3" Grid.Column="1" Classes="group_expander" x:Name="OpenAIAdvancedOptions" HorizontalAlignment="Right">
<TextBlock Margin="0" Text="{DynamicResource Text.Preference.Advanced}"/>
</ToggleButton>
<TextBlock Grid.Row="4" Grid.Column="0"
Text="{DynamicResource Text.Preference.AI.AnalyzeDiffPrompt}"
HorizontalAlignment="Right"
Margin="0,0,16,0"
IsVisible="{Binding #OpenAIAdvancedOptions.IsChecked}"/>
<TextBox Grid.Row="4" Grid.Column="1"
Height="120"
Margin="0,2"
CornerRadius="3"
VerticalContentAlignment="Top"
Text="{Binding OpenAIAnalyzeDiffPrompt, Mode=TwoWay}"
AcceptsReturn="true"
TextWrapping="Wrap"
IsVisible="{Binding #OpenAIAdvancedOptions.IsChecked}"/>
<TextBlock Grid.Row="5" Grid.Column="0"
Text="{DynamicResource Text.Preference.AI.GenerateSubjectPrompt}"
HorizontalAlignment="Right"
Margin="0,0,16,0"
IsVisible="{Binding #OpenAIAdvancedOptions.IsChecked}"/>
<TextBox Grid.Row="5" Grid.Column="1"
Height="120"
Margin="0,2"
CornerRadius="3"
VerticalContentAlignment="Top"
Text="{Binding OpenAIGenerateSubjectPrompt, Mode=TwoWay}"
AcceptsReturn="true"
TextWrapping="Wrap"
IsVisible="{Binding #OpenAIAdvancedOptions.IsChecked}"/>
</Grid>
</StackPanel>
</TabItem>

View file

@ -51,7 +51,7 @@
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Configure.Git}"/>
</TabItem.Header>
<Grid Margin="16,4,16,8" RowDefinitions="32,32,32,32,32,32,32,32" ColumnDefinitions="Auto,*">
<Grid Margin="16,4,16,8" RowDefinitions="32,32,32,32,32,32,32,32,32" ColumnDefinitions="Auto,*">
<TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,8,0"
@ -123,10 +123,14 @@
IsChecked="{Binding GPGCommitSigningEnabled, Mode=TwoWay}"/>
<CheckBox Grid.Row="6" Grid.Column="1"
Content="{DynamicResource Text.Configure.Git.EnableSignOff}"
IsChecked="{Binding EnableSignOffForCommit, Mode=TwoWay}"/>
<CheckBox Grid.Row="7" Grid.Column="1"
Content="{DynamicResource Text.Preference.GPG.TagEnabled}"
IsChecked="{Binding GPGTagSigningEnabled, Mode=TwoWay}"/>
<StackPanel Grid.Row="7" Grid.Column="1" Orientation="Horizontal">
<StackPanel Grid.Row="8" Grid.Column="1" Orientation="Horizontal">
<CheckBox x:Name="AutoFetchCheckBox"
Content="{DynamicResource Text.Configure.Git.AutoFetch}"
IsChecked="{Binding EnableAutoFetch, Mode=TwoWay}"/>
@ -227,7 +231,7 @@
<TextBlock Margin="0,12,0,0" Text="{DynamicResource Text.Configure.CommitMessageTemplate.Content}"/>
<v:CommitMessageTextBox Margin="0,4,0,0" Height="100" Text="{Binding Content, Mode=TwoWay}"/>
<TextBlock Margin="0,2,0,0"
Text="You can use ${files_num}, ${files} and ${files:N} where N is the max number of file paths to output."
Text="You can use ${files_num}, ${branch_name}, ${files} and ${files:N} where N is the max number of file paths to output."
Foreground="{DynamicResource Brush.FG2}"
TextWrapping="Wrap"/>
</StackPanel>
@ -283,6 +287,8 @@
<MenuItem Header="-"/>
<MenuItem Header="{DynamicResource Text.Configure.IssueTracker.AddSampleGithub}" Command="{Binding AddSampleGithubIssueTracker}"/>
<MenuItem Header="{DynamicResource Text.Configure.IssueTracker.AddSampleJira}" Command="{Binding AddSampleJiraIssueTracker}"/>
<MenuItem Header="{DynamicResource Text.Configure.IssueTracker.AddSampleGitLabIssue}" Command="{Binding AddSampleGitLabIssueTracker}"/>
<MenuItem Header="{DynamicResource Text.Configure.IssueTracker.AddSampleGitLabMergeRequest}" Command="{Binding AddSampleGitLabMergeRequestTracker}"/>
</MenuFlyout>
</Button.Flyout>
<Path Width="14" Height="14" Data="{StaticResource Icons.Plus}"/>

View file

@ -284,7 +284,7 @@ namespace SourceGit.Views
node.Children.Sort((l, r) =>
{
if (l.IsFolder == r.IsFolder)
return string.Compare(l.Name, r.Name, StringComparison.Ordinal);
return Models.NumericSort.Compare(l.Name, r.Name);
return l.IsFolder ? -1 : 1;
});

View file

@ -6,7 +6,6 @@ using System.Text;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Data;
using Avalonia.Input;
using Avalonia.Interactivity;
@ -72,6 +71,8 @@ namespace SourceGit.Views
{
_usePresenter = usePresenter;
_isOld = isOld;
Margin = new Thickness(8, 0);
ClipToBounds = true;
}
@ -145,6 +146,89 @@ namespace SourceGit.Views
private bool _isOld = false;
}
public class LineModifyTypeMargin : AbstractMargin
{
public LineModifyTypeMargin()
{
Margin = new Thickness(1, 0);
ClipToBounds = true;
}
public override void Render(DrawingContext context)
{
var presenter = this.FindAncestorOfType<ThemedTextDiffPresenter>();
if (presenter == null)
return;
var lines = presenter.GetLines();
var view = TextView;
if (view != null && view.VisualLinesValid)
{
var typeface = view.CreateTypeface();
foreach (var line in view.VisualLines)
{
if (line.IsDisposed || line.FirstDocumentLine == null || line.FirstDocumentLine.IsDeleted)
continue;
var index = line.FirstDocumentLine.LineNumber;
if (index > lines.Count)
break;
var info = lines[index - 1];
var y = line.GetTextLineVisualYPosition(line.TextLines[0], VisualYPosition.LineMiddle) - view.VerticalOffset;
var indicator = null as FormattedText;
if (info.Type == Models.TextDiffLineType.Added)
{
indicator = new FormattedText(
"+",
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
typeface,
presenter.FontSize,
Brushes.Green);
}
else if (info.Type == Models.TextDiffLineType.Deleted)
{
indicator = new FormattedText(
"-",
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
typeface,
presenter.FontSize,
Brushes.Red);
}
if (indicator != null)
context.DrawText(indicator, new Point(0, y - indicator.Height * 0.5));
}
}
}
protected override Size MeasureOverride(Size availableSize)
{
var presenter = this.FindAncestorOfType<ThemedTextDiffPresenter>();
if (presenter == null)
return new Size(0, 0);
var maxLineNumber = presenter.GetMaxLineNumber();
var typeface = TextView.CreateTypeface();
var test = new FormattedText(
$"-",
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
typeface,
presenter.FontSize,
Brushes.White);
return new Size(test.Width, 0);
}
protected override void OnDataContextChanged(EventArgs e)
{
base.OnDataContextChanged(e);
InvalidateMeasure();
}
}
public class LineBackgroundRenderer : IBackgroundRenderer
{
public KnownLayer Layer => KnownLayer.Background;
@ -674,10 +758,11 @@ namespace SourceGit.Views
{
public CombinedTextDiffPresenter() : base(new TextArea(), new TextDocument())
{
TextArea.LeftMargins.Add(new LineNumberMargin(false, true) { Margin = new Thickness(8, 0) });
TextArea.LeftMargins.Add(new LineNumberMargin(false, true));
TextArea.LeftMargins.Add(new VerticalSeperatorMargin());
TextArea.LeftMargins.Add(new LineNumberMargin(false, false) { Margin = new Thickness(8, 0) });
TextArea.LeftMargins.Add(new LineNumberMargin(false, false));
TextArea.LeftMargins.Add(new VerticalSeperatorMargin());
TextArea.LeftMargins.Add(new LineModifyTypeMargin());
}
public override List<Models.TextDiffLine> GetLines()
@ -878,8 +963,9 @@ namespace SourceGit.Views
{
public SingleSideTextDiffPresenter() : base(new TextArea(), new TextDocument())
{
TextArea.LeftMargins.Add(new LineNumberMargin(true, false) { Margin = new Thickness(8, 0) });
TextArea.LeftMargins.Add(new LineNumberMargin(true, false));
TextArea.LeftMargins.Add(new VerticalSeperatorMargin());
TextArea.LeftMargins.Add(new LineModifyTypeMargin());
}
public override List<Models.TextDiffLine> GetLines()

View file

@ -185,7 +185,7 @@
<v:CommitMessageTextBox Grid.Row="2" Text="{Binding CommitMessage, Mode=TwoWay}"/>
<!-- Commit Options -->
<Grid Grid.Row="3" Margin="0,6,0,0" ColumnDefinitions="Auto,Auto,Auto,Auto,Auto,*,Auto,Auto,Auto,Auto">
<Grid Grid.Row="3" Margin="0,6,0,0" ColumnDefinitions="Auto,Auto,Auto,Auto,*,Auto,Auto,Auto,Auto">
<Button Grid.Column="0"
Classes="icon_button"
Margin="4,0,0,0" Padding="0"
@ -199,7 +199,7 @@
<Button Grid.Column="1"
Classes="icon_button"
Margin="4,2,0,0"
Click="OnOpenAIAssist"
Command="{Binding GenerateCommitMessageByAI}"
ToolTip.Tip="{DynamicResource Text.AIAssistant.Tip}"
ToolTip.Placement="Top"
ToolTip.VerticalOffset="0">
@ -217,22 +217,15 @@
</Button>
<CheckBox Grid.Column="3"
Height="24"
Margin="4,0,0,0"
HorizontalAlignment="Left"
IsChecked="{Binding AutoStageBeforeCommit, Mode=TwoWay}"
Content="{DynamicResource Text.WorkingCopy.AutoStage}"/>
<CheckBox Grid.Column="4"
Height="24"
Margin="8,0,0,0"
HorizontalAlignment="Left"
IsChecked="{Binding UseAmend, Mode=TwoWay}"
Content="{DynamicResource Text.WorkingCopy.Amend}"/>
<v:LoadingIcon Grid.Column="6" Width="18" Height="18" IsVisible="{Binding IsCommitting}"/>
<v:LoadingIcon Grid.Column="5" Width="18" Height="18" IsVisible="{Binding IsCommitting}"/>
<Button Grid.Column="7"
<Button Grid.Column="6"
Classes="flat primary"
Content="{DynamicResource Text.WorkingCopy.Commit}"
Height="28"
@ -257,13 +250,13 @@
</Button>
<!-- Invisible button just to add another hotkey `Ctrl+Shift+Enter` to commit with auto-stage -->
<Button Grid.Column="8"
<Button Grid.Column="7"
Width="0" Height="0"
Background="Transparent"
Command="{Binding CommitWithAutoStage}"
HotKey="{OnPlatform Ctrl+Shift+Enter, macOS=⌘+Shift+Enter}"/>
<Button Grid.Column="9"
<Button Grid.Column="8"
Classes="flat"
Content="{DynamicResource Text.WorkingCopy.CommitAndPush}"
Height="28"

View file

@ -120,31 +120,6 @@ namespace SourceGit.Views
e.Handled = true;
}
private void OnOpenAIAssist(object _, RoutedEventArgs e)
{
if (!Models.OpenAI.IsValid)
{
App.RaiseException(null, "Bad configuration for OpenAI");
return;
}
if (DataContext is ViewModels.WorkingCopy vm)
{
if (vm.Staged is { Count: > 0 })
{
var dialog = new AIAssistant() { DataContext = vm };
dialog.GenerateCommitMessage();
App.OpenDialog(dialog);
}
else
{
App.RaiseException(null, "No files added to commit!");
}
}
e.Handled = true;
}
private void OnOpenConventionalCommitHelper(object _, RoutedEventArgs e)
{
if (DataContext is ViewModels.WorkingCopy vm)