Compare commits

...

11 commits

Author SHA1 Message Date
leo
a824adf6d3
code_style: run dotnet format
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Localization Check / localization-check (push) Waiting to run
Signed-off-by: leo <longshuang@msn.cn>
2024-11-14 21:15:40 +08:00
leo
28c93da73b
ux: show Unset menu item only if it is necessary (#690)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-14 21:12:18 +08:00
leo
04697093a8
localization: update Text.Repository.FilterCommits.Default (#690)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-14 20:56:49 +08:00
leo
1298a22b00
ux: use dynamic icon for filter tips.
Signed-off-by: leo <longshuang@msn.cn>
2024-11-14 20:53:59 +08:00
leo
44557c066c
enhance: clear histories filter if there's a filter that has different modes with the new one (#690)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-14 20:22:08 +08:00
leo
a53787c754
fix: git rebase --continue fail (#693)
* fix the exit code when start `SourceGit` as core editor (rebasing).
* redesign the layout of working copy page for in-progress states.

Signed-off-by: leo <longshuang@msn.cn>
2024-11-14 19:19:58 +08:00
github-actions[bot]
bb90c86649 doc: Update translation status and missing keys 2024-11-14 07:21:47 +00:00
leo
ca5bc4b4df
refactor: rewrite the histories filter function to supports both include and exclude modes (#690)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-14 15:15:48 +08:00
leo
e3ffe3ef6c
enhance: supports Azure OpenAI REST API (#695)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-14 14:56:21 +08:00
github-actions[bot]
3c5a4741bf doc: Update translation status and missing keys 2024-11-14 01:18:29 +00:00
TheGthr
7ffebec8a6
Add missing fr_FR keys (#696)
* localization: add missing fr_FR keys

---------

Co-authored-by: Theo GAUTHIER <theo.gauthier@soprasteria.com>
2024-11-14 09:18:09 +08:00
34 changed files with 1193 additions and 610 deletions

View file

@ -47,7 +47,7 @@
## 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-100.00%25-brightgreen)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-99.57%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-86.31%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-99.57%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-100.00%25-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-100.00%25-brightgreen)](TRANSLATION.md)
[![en_US](https://img.shields.io/badge/en__US-100%25-brightgreen)](TRANSLATION.md) [![de__DE](https://img.shields.io/badge/de__DE-99.57%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-99.14%25-yellow)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-98.42%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-99.14%25-yellow)](TRANSLATION.md) [![ru__RU](https://img.shields.io/badge/ru__RU-99.57%25-yellow)](TRANSLATION.md) [![zh__CN](https://img.shields.io/badge/zh__CN-100.00%25-brightgreen)](TRANSLATION.md) [![zh__TW](https://img.shields.io/badge/zh__TW-100.00%25-brightgreen)](TRANSLATION.md)
## How to Use

View file

@ -1,14 +1,16 @@
### de_DE.axaml: 100.00%
### de_DE.axaml: 99.57%
<details>
<summary>Missing Keys</summary>
- Text.Repository.FilterCommits.Default
- Text.Repository.FilterCommits.Exclude
- Text.Repository.FilterCommits.Include
</details>
### es_ES.axaml: 99.57%
### es_ES.axaml: 99.14%
<details>
@ -17,114 +19,33 @@
- Text.Preference.Appearance.FontSize
- Text.Preference.Appearance.FontSize.Default
- Text.Preference.Appearance.FontSize.Editor
- Text.Repository.FilterCommits.Default
- Text.Repository.FilterCommits.Exclude
- Text.Repository.FilterCommits.Include
</details>
### fr_FR.axaml: 86.31%
### fr_FR.axaml: 98.42%
<details>
<summary>Missing Keys</summary>
- Text.About.Chart
- Text.AIAssistant
- Text.AIAssistant.Tip
- Text.BranchCM.FetchInto
- Text.ChangeCM.GenerateCommitMessage
- Text.CherryPick.AppendSourceToMessage
- Text.CherryPick.Mainline
- Text.CherryPick.Mainline.Tips
- Text.CommitCM.CherryPickMultiple
- Text.CommitCM.CustomAction
- Text.CommitCM.SquashCommitsSinceThis
- Text.CommitDetail.Info.WebLinks
- Text.Configure.CustomAction
- Text.Configure.CustomAction.Arguments
- Text.Configure.CustomAction.Arguments.Tip
- Text.Configure.CustomAction.Executable
- Text.Configure.CustomAction.Name
- Text.Configure.CustomAction.Scope
- Text.Configure.CustomAction.Scope.Commit
- Text.Configure.CustomAction.Scope.Repository
- Text.Configure.Git.DefaultRemote
- Text.Configure.Git.EnablePruneOnFetch
- Text.Configure.Git.EnableSignOff
- Text.Configure.IssueTracker.AddSampleGitLabIssue
- Text.Configure.IssueTracker.AddSampleGitLabMergeRequest
- Text.Configure.OpenAI
- Text.Configure.OpenAI.Prefered
- Text.Configure.OpenAI.Prefered.Tip
- 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.Diff.SaveAsPatch
- Text.Diff.VisualLines.All
- Text.Discard.IncludeIgnored
- Text.ExecuteCustomAction
- Text.ExecuteCustomAction.Name
- 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.CreateBranchOnCommit
- Text.Hotkeys.Repo.DiscardSelected
- Text.Hotkeys.Repo.Fetch
- Text.Hotkeys.Repo.Pull
- Text.Hotkeys.Repo.Push
- Text.IssueLinkCM.OpenInBrowser
- Text.IssueLinkCM.CopyLink
- Text.MoveRepositoryNode
- Text.MoveRepositoryNode.Target
- Text.Preference.AI
- Text.Preference.AI.AnalyzeDiffPrompt
- Text.Preference.AI.ApiKey
- Text.Preference.AI.GenerateSubjectPrompt
- Text.Preference.AI.Model
- Text.Preference.AI.Name
- Text.Preference.AI.Server
- Text.Preference.Appearance.FontSize
- Text.Preference.Appearance.FontSize.Default
- Text.Preference.Appearance.FontSize.Editor
- Text.Preference.General.ShowAuthorTime
- Text.Preference.Integration
- Text.Preference.Shell
- Text.Preference.Shell.Type
- Text.Preference.Shell.Path
- Text.Repository.AutoFetching
- Text.Repository.CustomActions
- Text.Repository.CustomActions.Empty
- Text.Repository.EnableReflog
- Text.Repository.Search.InCurrentBranch
- Text.Repository.FilterCommits.Default
- Text.Repository.FilterCommits.Exclude
- Text.Repository.FilterCommits.Include
- Text.ScanRepositories
- Text.ScanRepositories.RootDir
- Text.Squash.Into
- Text.Stash.KeepIndex
- 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: 99.57%
### pt_BR.axaml: 99.14%
<details>
@ -133,16 +54,21 @@
- Text.Preference.Appearance.FontSize
- Text.Preference.Appearance.FontSize.Default
- Text.Preference.Appearance.FontSize.Editor
- Text.Repository.FilterCommits.Default
- Text.Repository.FilterCommits.Exclude
- Text.Repository.FilterCommits.Include
</details>
### ru_RU.axaml: 100.00%
### ru_RU.axaml: 99.57%
<details>
<summary>Missing Keys</summary>
- Text.Repository.FilterCommits.Default
- Text.Repository.FilterCommits.Exclude
- Text.Repository.FilterCommits.Include
</details>

View file

@ -478,17 +478,20 @@ namespace SourceGit
if (args.Length <= 1 || !args[0].Equals("--rebase-message-editor", StringComparison.Ordinal))
return false;
exitCode = 0;
var file = args[1];
var filename = Path.GetFileName(file);
if (!filename.Equals("COMMIT_EDITMSG", StringComparison.OrdinalIgnoreCase))
return true;
var jobsFile = Path.Combine(Path.GetDirectoryName(file)!, "sourcegit_rebase_jobs.json");
var gitDir = Path.GetDirectoryName(file)!;
var jobsFile = Path.Combine(gitDir, "sourcegit_rebase_jobs.json");
if (!File.Exists(jobsFile))
return true;
var collection = JsonSerializer.Deserialize(File.ReadAllText(jobsFile), JsonCodeGen.Default.InteractiveRebaseJobCollection);
var doneFile = Path.Combine(Path.GetDirectoryName(file)!, "rebase-merge", "done");
var doneFile = Path.Combine(gitDir, "rebase-merge", "done");
if (!File.Exists(doneFile))
return true;
@ -499,7 +502,6 @@ namespace SourceGit
var job = collection.Jobs[done.Length - 1];
File.WriteAllText(file, job.Message);
exitCode = 0;
return true;
}

View file

@ -0,0 +1,22 @@
using Avalonia.Data.Converters;
using Avalonia.Media;
namespace SourceGit.Converters
{
public static class FilterModeConverters
{
public static readonly FuncValueConverter<Models.FilterMode, IBrush> ToBorderBrush =
new FuncValueConverter<Models.FilterMode, IBrush>(v =>
{
switch (v)
{
case Models.FilterMode.Included:
return Brushes.Green;
case Models.FilterMode.Excluded:
return Brushes.Red;
default:
return Brushes.Transparent;
}
});
}
}

60
src/Models/Filter.cs Normal file
View file

@ -0,0 +1,60 @@
using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.Models
{
public enum FilterType
{
LocalBranch = 0,
LocalBranchFolder,
RemoteBranch,
RemoteBranchFolder,
Tag,
}
public enum FilterMode
{
None = 0,
Included,
Excluded,
}
public class Filter : ObservableObject
{
public string Pattern
{
get => _pattern;
set => SetProperty(ref _pattern, value);
}
public FilterType Type
{
get;
set;
} = FilterType.LocalBranch;
public FilterMode Mode
{
get => _mode;
set => SetProperty(ref _mode, value);
}
public bool IsBranch
{
get => Type != FilterType.Tag;
}
public Filter()
{
}
public Filter(string pattern, FilterType type, FilterMode mode)
{
_pattern = pattern;
_mode = mode;
Type = type;
}
private string _pattern = string.Empty;
private FilterMode _mode = FilterMode.None;
}
}

View file

@ -155,7 +155,12 @@ namespace SourceGit.Models
var client = new HttpClient() { Timeout = TimeSpan.FromSeconds(60) };
if (!string.IsNullOrEmpty(ApiKey))
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {ApiKey}");
{
if (Server.Contains("openai.azure.com/", StringComparison.Ordinal))
client.DefaultRequestHeaders.Add("api-key", ApiKey);
else
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {ApiKey}");
}
var req = new StringContent(JsonSerializer.Serialize(chat, JsonCodeGen.Default.OpenAIChatRequest), Encoding.UTF8, "application/json");
try

View file

@ -1,4 +1,9 @@
using Avalonia.Collections;
using System;
using System.Collections.Generic;
using System.Text;
using Avalonia.Collections;
using Avalonia.Threading;
namespace SourceGit.Models
{
@ -76,11 +81,11 @@ namespace SourceGit.Models
set;
} = true;
public AvaloniaList<string> Filters
public AvaloniaList<Filter> HistoriesFilters
{
get;
set;
} = new AvaloniaList<string>();
} = new AvaloniaList<Filter>();
public AvaloniaList<CommitTemplate> CommitTemplates
{
@ -148,6 +153,197 @@ namespace SourceGit.Models
set;
} = "---";
public FilterMode GetHistoriesFilterMode(string pattern, FilterType type)
{
foreach (var filter in HistoriesFilters)
{
if (filter.Type != type)
continue;
if (filter.Pattern.Equals(pattern, StringComparison.Ordinal))
return filter.Mode;
}
return FilterMode.None;
}
public bool UpdateHistoriesFilter(string pattern, FilterType type, FilterMode mode)
{
// Clear all filters when there's a filter that has different mode.
if (mode != FilterMode.None)
{
var clear = false;
foreach (var filter in HistoriesFilters)
{
if (filter.Mode != mode)
{
clear = true;
break;
}
}
if (clear)
{
HistoriesFilters.Clear();
HistoriesFilters.Add(new Filter(pattern, type, mode));
return true;
}
}
else
{
for (int i = 0; i < HistoriesFilters.Count; i++)
{
var filter = HistoriesFilters[i];
if (filter.Type == type && filter.Pattern.Equals(pattern, StringComparison.Ordinal))
{
HistoriesFilters.RemoveAt(i);
return true;
}
}
return false;
}
for (int i = 0; i < HistoriesFilters.Count; i++)
{
var filter = HistoriesFilters[i];
if (filter.Type != type)
continue;
if (filter.Pattern.Equals(pattern, StringComparison.Ordinal))
return false;
}
HistoriesFilters.Add(new Filter(pattern, type, mode));
return true;
}
public string BuildHistoriesFilter()
{
var builder = new StringBuilder();
var excludedBranches = new List<string>();
var excludedRemotes = new List<string>();
var excludedTags = new List<string>();
var includedBranches = new List<string>();
var includedRemotes = new List<string>();
var includedTags = new List<string>();
foreach (var filter in HistoriesFilters)
{
if (filter.Type == FilterType.LocalBranch)
{
var name = filter.Pattern.Substring(11);
var b = $"{name.Substring(0, name.Length - 1)}[{name[^1]}]";
if (filter.Mode == FilterMode.Included)
includedBranches.Add(b);
else if (filter.Mode == FilterMode.Excluded)
excludedBranches.Add(b);
}
else if (filter.Type == FilterType.LocalBranchFolder)
{
if (filter.Mode == FilterMode.Included)
includedBranches.Add($"{filter.Pattern.Substring(11)}/*");
else if (filter.Mode == FilterMode.Excluded)
excludedBranches.Add($"{filter.Pattern.Substring(11)}/*");
}
else if (filter.Type == FilterType.RemoteBranch)
{
var name = filter.Pattern.Substring(13);
var r = $"{name.Substring(0, name.Length - 1)}[{name[^1]}]";
if (filter.Mode == FilterMode.Included)
includedRemotes.Add(r);
else if (filter.Mode == FilterMode.Excluded)
excludedRemotes.Add(r);
}
else if (filter.Type == FilterType.RemoteBranchFolder)
{
if (filter.Mode == FilterMode.Included)
includedRemotes.Add($"{filter.Pattern.Substring(13)}/*");
else if (filter.Mode == FilterMode.Excluded)
excludedRemotes.Add($"{filter.Pattern.Substring(13)}/*");
}
else if (filter.Type == FilterType.Tag)
{
var name = filter.Pattern;
var t = $"{name.Substring(0, name.Length - 1)}[{name[^1]}]";
if (filter.Mode == FilterMode.Included)
includedTags.Add(t);
else if (filter.Mode == FilterMode.Excluded)
excludedTags.Add(t);
}
}
foreach (var b in excludedBranches)
{
builder.Append("--exclude=");
builder.Append(b);
builder.Append(' ');
}
if (includedBranches.Count > 0)
{
foreach (var b in includedBranches)
{
builder.Append("--branches=");
builder.Append(b);
builder.Append(' ');
}
}
else if (excludedBranches.Count > 0 || (includedRemotes.Count == 0 && includedTags.Count == 0))
{
builder.Append("--exclude=HEA[D] ");
builder.Append("--branches ");
}
foreach (var r in excludedRemotes)
{
builder.Append("--exclude=");
builder.Append(r);
builder.Append(' ');
}
if (includedRemotes.Count > 0)
{
foreach (var r in includedRemotes)
{
builder.Append("--remotes=");
builder.Append(r);
builder.Append(' ');
}
}
else if (excludedRemotes.Count > 0 || (includedBranches.Count == 0 && includedTags.Count == 0))
{
builder.Append("--exclude=origin/HEA[D] ");
builder.Append("--remotes ");
}
foreach (var t in excludedTags)
{
builder.Append("--exclude=");
builder.Append(t);
builder.Append(' ');
}
if (includedTags.Count > 0)
{
foreach (var t in includedTags)
{
builder.Append("--tags=");
builder.Append(t);
builder.Append(' ');
}
}
else if (excludedTags.Count > 0 || (includedBranches.Count == 0 && includedRemotes.Count == 0))
{
builder.Append("--tags ");
}
return builder.ToString();
}
public void PushCommitMessage(string message)
{
var existIdx = CommitMessages.IndexOf(message);

View file

@ -1,10 +1,19 @@
namespace SourceGit.Models
using CommunityToolkit.Mvvm.ComponentModel;
namespace SourceGit.Models
{
public class Tag
public class Tag : ObservableObject
{
public string Name { get; set; }
public string SHA { get; set; }
public string Message { get; set; }
public bool IsFiltered { get; set; }
public string Name { get; set; } = string.Empty;
public string SHA { get; set; } = string.Empty;
public string Message { get; set; } = string.Empty;
public FilterMode FilterMode
{
get => _filterMode;
set => SetProperty(ref _filterMode, value);
}
private FilterMode _filterMode = FilterMode.None;
}
}

View file

@ -113,22 +113,11 @@ namespace SourceGit.Models
if (_updateTags > 0)
{
_updateTags = 0;
Task.Run(() =>
{
_repo.RefreshTags();
_repo.RefreshBranches();
_repo.RefreshCommits();
});
}
else
{
Task.Run(() =>
{
_repo.RefreshBranches();
_repo.RefreshCommits();
});
Task.Run(_repo.RefreshTags);
}
Task.Run(_repo.RefreshBranches);
Task.Run(_repo.RefreshCommits);
Task.Run(_repo.RefreshWorkingCopyChanges);
Task.Run(_repo.RefreshWorktrees);
}

View file

@ -292,7 +292,6 @@
<x:String x:Key="Text.FileHistory" xml:space="preserve">Datei Historie</x:String>
<x:String x:Key="Text.FileHistory.FileContent" xml:space="preserve">INHALT</x:String>
<x:String x:Key="Text.FileHistory.FileChange" xml:space="preserve">ÄNDERUNGEN</x:String>
<x:String x:Key="Text.Filter" xml:space="preserve">FILTER</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">Development-Branch:</x:String>
<x:String x:Key="Text.GitFlow.Feature" xml:space="preserve">Feature:</x:String>
@ -544,7 +543,6 @@
<x:String x:Key="Text.Repository.EnableReflog" xml:space="preserve">Aktiviere '--reflog' Option</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>
<x:String x:Key="Text.Repository.LocalBranches" xml:space="preserve">LOKALE BRANCHES</x:String>
<x:String x:Key="Text.Repository.NavigateToCurrentHead" xml:space="preserve">Zum HEAD wechseln</x:String>
<x:String x:Key="Text.Repository.FirstParentFilterToggle" xml:space="preserve">Aktiviere '--first-parent' Option</x:String>

View file

@ -289,7 +289,6 @@
<x:String x:Key="Text.FileHistory" xml:space="preserve">File History</x:String>
<x:String x:Key="Text.FileHistory.FileContent" xml:space="preserve">CONTENT</x:String>
<x:String x:Key="Text.FileHistory.FileChange" xml:space="preserve">CHANGE</x:String>
<x:String x:Key="Text.Filter" xml:space="preserve">FILTER</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">Development Branch:</x:String>
<x:String x:Key="Text.GitFlow.Feature" xml:space="preserve">Feature:</x:String>
@ -541,7 +540,9 @@
<x:String x:Key="Text.Repository.EnableReflog" xml:space="preserve">Enable '--reflog' Option</x:String>
<x:String x:Key="Text.Repository.Explore" xml:space="preserve">Open in File Browser</x:String>
<x:String x:Key="Text.Repository.Filter" xml:space="preserve">Search Branches/Tags/Submodules</x:String>
<x:String x:Key="Text.Repository.FilterCommitPrefix" xml:space="preserve">FILTERED BY:</x:String>
<x:String x:Key="Text.Repository.FilterCommits.Default" xml:space="preserve">Unset</x:String>
<x:String x:Key="Text.Repository.FilterCommits.Exclude" xml:space="preserve">Hide in commit graph</x:String>
<x:String x:Key="Text.Repository.FilterCommits.Include" xml:space="preserve">Filter in commit graph</x:String>
<x:String x:Key="Text.Repository.LocalBranches" xml:space="preserve">LOCAL BRANCHES</x:String>
<x:String x:Key="Text.Repository.NavigateToCurrentHead" xml:space="preserve">Navigate to HEAD</x:String>
<x:String x:Key="Text.Repository.FirstParentFilterToggle" xml:space="preserve">Enable '--first-parent' Option</x:String>

View file

@ -294,7 +294,6 @@
<x:String x:Key="Text.FileHistory" xml:space="preserve">Historial de Archivos</x:String>
<x:String x:Key="Text.FileHistory.FileContent" xml:space="preserve">CONTENIDO</x:String>
<x:String x:Key="Text.FileHistory.FileChange" xml:space="preserve">CAMBIO</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">Rama de Desarrollo:</x:String>
<x:String x:Key="Text.GitFlow.Feature" xml:space="preserve">Feature:</x:String>
@ -542,7 +541,6 @@
<x:String x:Key="Text.Repository.EnableReflog" xml:space="preserve">Habilitar Opción '--reflog'</x:String>
<x:String x:Key="Text.Repository.Explore" xml:space="preserve">Abrir en el Explorador</x:String>
<x:String x:Key="Text.Repository.Filter" xml:space="preserve">Buscar Ramas/Etiquetas/Submódulos</x:String>
<x:String x:Key="Text.Repository.FilterCommitPrefix" xml:space="preserve">FILTRAR POR:</x:String>
<x:String x:Key="Text.Repository.LocalBranches" xml:space="preserve">RAMAS LOCALES</x:String>
<x:String x:Key="Text.Repository.NavigateToCurrentHead" xml:space="preserve">Navegar a HEAD</x:String>
<x:String x:Key="Text.Repository.FirstParentFilterToggle" xml:space="preserve">Habilitar Opción '--first-parent'</x:String>

View file

@ -3,23 +3,26 @@
<ResourceInclude Source="avares://SourceGit/Resources/Locales/en_US.axaml"/>
</ResourceDictionary.MergedDictionaries>
<x:String x:Key="Text.About" xml:space="preserve">À propos</x:String>
<x:String x:Key="Text.About.Menu" xml:space="preserve">À propos de SourceGit</x:String>
<x:String x:Key="Text.About.BuildWith" xml:space="preserve">• Compilé avec </x:String>
<x:String x:Key="Text.About.Chart" xml:space="preserve">• Le graphique est rendu par </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">• TextEditor de </x:String>
<x:String x:Key="Text.About.Fonts" xml:space="preserve">• Les polices Monospace proviennent de </x:String>
<x:String x:Key="Text.About.Menu" xml:space="preserve">À propos de SourceGit</x:String>
<x:String x:Key="Text.About.SourceCode" xml:space="preserve">• Le code source est disponible sur </x:String>
<x:String x:Key="Text.About.SubTitle" xml:space="preserve">Client Git Open Source et Gratuit</x:String>
<x:String x:Key="Text.AddWorktree" xml:space="preserve">Ajouter un Worktree</x:String>
<x:String x:Key="Text.AddWorktree.WhatToCheckout" xml:space="preserve">What to Checkout:</x:String>
<x:String x:Key="Text.AddWorktree.WhatToCheckout.CreateNew" xml:space="preserve">Créer une nouvelle branche</x:String>
<x:String x:Key="Text.AddWorktree.WhatToCheckout.Existing" xml:space="preserve">Branche existante</x:String>
<x:String x:Key="Text.AddWorktree.Location" xml:space="preserve">Emplacement :</x:String>
<x:String x:Key="Text.AddWorktree.Location.Placeholder" xml:space="preserve">Chemin vers ce worktree. Relatif supporté.</x:String>
<x:String x:Key="Text.AddWorktree.Name" xml:space="preserve">Nom de branche:</x:String>
<x:String x:Key="Text.AddWorktree.Name.Placeholder" xml:space="preserve">Optionnel. Nom du dossier de destination par défaut.</x:String>
<x:String x:Key="Text.AddWorktree.Tracking" xml:space="preserve">Suivre la branche :</x:String>
<x:String x:Key="Text.AddWorktree.Tracking.Toggle" xml:space="preserve">Suivi de la branche distante</x:String>
<x:String x:Key="Text.AddWorktree.WhatToCheckout" xml:space="preserve">What to Checkout:</x:String>
<x:String x:Key="Text.AddWorktree.WhatToCheckout.CreateNew" xml:space="preserve">Créer une nouvelle branche</x:String>
<x:String x:Key="Text.AddWorktree.WhatToCheckout.Existing" xml:space="preserve">Branche existante</x:String>
<x:String x:Key="Text.AIAssistant" xml:space="preserve">Assistant IA</x:String>
<x:String x:Key="Text.AIAssistant.Tip" xml:space="preserve">Utiliser l'IA pour générer un message de commit</x:String>
<x:String x:Key="Text.Apply" xml:space="preserve">Appliquer</x:String>
<x:String x:Key="Text.Apply.Error" xml:space="preserve">Erreur</x:String>
<x:String x:Key="Text.Apply.Error.Desc" xml:space="preserve">Soulever les erreurs et refuser d'appliquer le patch</x:String>
@ -55,6 +58,7 @@
<x:String x:Key="Text.BranchCM.DeleteMultiBranches" xml:space="preserve">Supprimer {0} branches sélectionnées</x:String>
<x:String x:Key="Text.BranchCM.DiscardAll" xml:space="preserve">Rejeter tous les changements</x:String>
<x:String x:Key="Text.BranchCM.FastForward" xml:space="preserve">Fast-Forward vers ${0}$</x:String>
<x:String x:Key="Text.BranchCM.FetchInto" xml:space="preserve">Fetch ${0}$ vers ${1}$...</x:String>
<x:String x:Key="Text.BranchCM.Finish" xml:space="preserve">Git Flow - Terminer ${0}$</x:String>
<x:String x:Key="Text.BranchCM.Merge" xml:space="preserve">Fusionner ${0}$ dans ${1}$...</x:String>
<x:String x:Key="Text.BranchCM.Pull" xml:space="preserve">Tirer ${0}$</x:String>
@ -69,6 +73,7 @@
<x:String x:Key="Text.Cancel" xml:space="preserve">ANNULER</x:String>
<x:String x:Key="Text.ChangeCM.CheckoutFirstParentRevision" xml:space="preserve">Réinitialiser à la révision parente</x:String>
<x:String x:Key="Text.ChangeCM.CheckoutThisRevision" xml:space="preserve">Réinitialiser à cette révision</x:String>
<x:String x:Key="Text.ChangeCM.GenerateCommitMessage" xml:space="preserve">Générer un message de commit</x:String>
<x:String x:Key="Text.ChangeDisplayMode" xml:space="preserve">CHANGER LE MODE D'AFFICHAGE</x:String>
<x:String x:Key="Text.ChangeDisplayMode.Grid" xml:space="preserve">Afficher comme liste de dossiers/fichiers</x:String>
<x:String x:Key="Text.ChangeDisplayMode.List" xml:space="preserve">Afficher comme liste de chemins</x:String>
@ -77,6 +82,7 @@
<x:String x:Key="Text.Checkout.Commit" xml:space="preserve">Checkout ce commit</x:String>
<x:String x:Key="Text.Checkout.Commit.Target" xml:space="preserve">Commit :</x:String>
<x:String x:Key="Text.Checkout.Commit.Warning" xml:space="preserve">Avertissement: un checkout vers un commit aboutiera vers un HEAD détaché</x:String>
<x:String x:Key="Text.Checkout.Target" xml:space="preserve">Branche:</x:String>
<x:String x:Key="Text.Checkout.LocalChanges" xml:space="preserve">Changements locaux :</x:String>
<x:String x:Key="Text.Checkout.LocalChanges.Discard" xml:space="preserve">Annuler</x:String>
<x:String x:Key="Text.Checkout.LocalChanges.DoNothing" xml:space="preserve">Ne rien faire</x:String>
@ -85,9 +91,11 @@
<x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry-Pick de ce commit</x:String>
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">Commit :</x:String>
<x:String x:Key="Text.CherryPick.CommitChanges" xml:space="preserve">Commit tous les changements</x:String>
<x:String x:Key="Text.CherryPick.Mainline" xml:space="preserve">Ligne principale :</x:String>
<x:String x:Key="Text.CherryPick.Title" xml:space="preserve">Cherry Pick</x:String>
<x:String x:Key="Text.ClearStashes" xml:space="preserve">Supprimer les stashes</x:String>
<x:String x:Key="Text.ClearStashes.Message" xml:space="preserve">Vous essayez de supprimer tous les stashes. Êtes-vous sûr de vouloir continuer ?</x:String>
<x:String x:Key="Text.Clone" xml:space="preserve">Cloner repository distant</x:String>
<x:String x:Key="Text.Clone.AdditionalParam" xml:space="preserve">Paramètres supplémentaires :</x:String>
<x:String x:Key="Text.Clone.AdditionalParam.Placeholder" xml:space="preserve">Arguments additionnels au clônage. Optionnel.</x:String>
<x:String x:Key="Text.Clone.LocalName" xml:space="preserve">Nom local :</x:String>
@ -103,6 +111,7 @@
<x:String x:Key="Text.CommitCM.CompareWithWorktree" xml:space="preserve">Comparer avec le worktree</x:String>
<x:String x:Key="Text.CommitCM.CopyInfo" xml:space="preserve">Copier les informations</x:String>
<x:String x:Key="Text.CommitCM.CopySHA" xml:space="preserve">Copier le SHA</x:String>
<x:String x:Key="Text.CommitCM.CustomAction" xml:space="preserve">Action personnalisée</x:String>
<x:String x:Key="Text.CommitCM.InteractiveRebase" xml:space="preserve">Rebase interactif de ${0}$ ici</x:String>
<x:String x:Key="Text.CommitCM.Rebase" xml:space="preserve">Rebaser ${0}$ ici</x:String>
<x:String x:Key="Text.CommitCM.Reset" xml:space="preserve">Réinitialiser ${0}$ ici</x:String>
@ -110,6 +119,7 @@
<x:String x:Key="Text.CommitCM.Reword" xml:space="preserve">Reformuler</x:String>
<x:String x:Key="Text.CommitCM.SaveAsPatch" xml:space="preserve">Enregistrer en tant que patch...</x:String>
<x:String x:Key="Text.CommitCM.Squash" xml:space="preserve">Squash dans le parent</x:String>
<x:String x:Key="Text.CommitCM.SquashCommitsSinceThis" xml:space="preserve">Squash les commits enfants ici</x:String>
<x:String x:Key="Text.CommitDetail.Changes" xml:space="preserve">CHANGEMENTS</x:String>
<x:String x:Key="Text.CommitDetail.Changes.Search" xml:space="preserve">Rechercher les changements...</x:String>
<x:String x:Key="Text.CommitDetail.Files" xml:space="preserve">FICHIERS</x:String>
@ -126,29 +136,56 @@
<x:String x:Key="Text.CommitDetail.Info.Parents" xml:space="preserve">PARENTS</x:String>
<x:String x:Key="Text.CommitDetail.Info.Refs" xml:space="preserve">REFS</x:String>
<x:String x:Key="Text.CommitDetail.Info.SHA" xml:space="preserve">SHA</x:String>
<x:String x:Key="Text.CommitMessageTextBox.MessagePlaceholder" xml:space="preserve">Description</x:String>
<x:String x:Key="Text.CommitDetail.Info.WebLinks" xml:space="preserve">Ouvrir dans le navigateur</x:String>
<x:String x:Key="Text.CommitMessageTextBox.SubjectPlaceholder" xml:space="preserve">Entrez le message du commit</x:String>
<x:String x:Key="Text.CommitMessageTextBox.MessagePlaceholder" xml:space="preserve">Description</x:String>
<x:String x:Key="Text.Configure" xml:space="preserve">Configurer le dépôt</x:String>
<x:String x:Key="Text.Configure.CommitMessageTemplate" xml:space="preserve">MODÈLE DE COMMIT</x:String>
<x:String x:Key="Text.Configure.CommitMessageTemplate.Content" xml:space="preserve">Contenu de modèle:</x:String>
<x:String x:Key="Text.Configure.CommitMessageTemplate.Name" xml:space="preserve">Nom de modèle:</x:String>
<x:String x:Key="Text.Configure.CommitMessageTemplate.Content" xml:space="preserve">Contenu de modèle:</x:String>
<x:String x:Key="Text.Configure.CustomAction" xml:space="preserve">ACTION PERSONNALISÉE</x:String>
<x:String x:Key="Text.Configure.CustomAction.Arguments" xml:space="preserve">Arguments :</x:String>
<x:String x:Key="Text.Configure.CustomAction.Arguments.Tip" xml:space="preserve">${REPO} - Chemin du repository; ${SHA} - SHA du commit sélectionné</x:String>
<x:String x:Key="Text.Configure.CustomAction.Executable" xml:space="preserve">Fichier exécutable :</x:String>
<x:String x:Key="Text.Configure.CustomAction.Name" xml:space="preserve">Nom :</x:String>
<x:String x:Key="Text.Configure.CustomAction.Scope" xml:space="preserve">Portée :</x:String>
<x:String x:Key="Text.Configure.CustomAction.Scope.Commit" xml:space="preserve">Commit</x:String>
<x:String x:Key="Text.Configure.CustomAction.Scope.Repository" xml:space="preserve">Repository</x:String>
<x:String x:Key="Text.Configure.Email" xml:space="preserve">Adresse e-mail</x:String>
<x:String x:Key="Text.Configure.Email.Placeholder" xml:space="preserve">Adresse e-mail</x:String>
<x:String x:Key="Text.Configure.Git" xml:space="preserve">GIT</x:String>
<x:String x:Key="Text.Configure.Git.AutoFetch" xml:space="preserve">Fetch les dépôts distants automatiquement</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">Dépôt par défaut</x:String>
<x:String x:Key="Text.Configure.Git.EnablePruneOnFetch" xml:space="preserve">Activer --prune pour fetch</x:String>
<x:String x:Key="Text.Configure.Git.EnableSignOff" xml:space="preserve">Activer --signoff pour commit</x:String>
<x:String x:Key="Text.Configure.IssueTracker" xml:space="preserve">SUIVI DES PROBLÈMES</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGithub" xml:space="preserve">Ajouter une règle d'exemple Github</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleJira" xml:space="preserve">Ajouter une règle d'exemple Jira</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGitLabIssue" xml:space="preserve">Ajouter une règle d'exemple pour Incidents GitLab</x:String>
<x:String x:Key="Text.Configure.IssueTracker.AddSampleGitLabMergeRequest" xml:space="preserve">Ajouter une règle d'exemple pour Merge Request GitLab</x:String>
<x:String x:Key="Text.Configure.IssueTracker.NewRule" xml:space="preserve">Nouvelle règle</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">Nom de règle :</x:String>
<x:String x:Key="Text.Configure.IssueTracker.URLTemplate.Tip" xml:space="preserve">Veuillez utiliser $1, $2 pour accéder aux valeurs des groupes regex.</x:String>
<x:String x:Key="Text.Configure.IssueTracker.URLTemplate" xml:space="preserve">URL résultant:</x:String>
<x:String x:Key="Text.Configure.IssueTracker.URLTemplate.Tip" xml:space="preserve">Veuillez utiliser $1, $2 pour accéder aux valeurs des groupes regex.</x:String>
<x:String x:Key="Text.Configure.OpenAI" xml:space="preserve">IA</x:String>
<x:String x:Key="Text.Configure.OpenAI.Prefered" xml:space="preserve">Service préféré:</x:String>
<x:String x:Key="Text.Configure.OpenAI.Prefered.Tip" xml:space="preserve">Si le 'Service préféré' est défini, SourceGit l'utilisera seulement dans ce repository. Sinon, si plus d'un service est disponible, un menu contextuel permettant de choisir l'un d'eux sera affiché.</x:String>
<x:String x:Key="Text.Configure.Proxy" xml:space="preserve">Proxy HTTP</x:String>
<x:String x:Key="Text.Configure.Proxy.Placeholder" xml:space="preserve">Proxy HTTP utilisé par ce dépôt</x:String>
<x:String x:Key="Text.Configure.User" xml:space="preserve">Nom d'utilisateur</x:String>
<x:String x:Key="Text.Configure.User.Placeholder" xml:space="preserve">Nom d'utilisateur pour ce dépôt</x:String>
<x:String x:Key="Text.ConfigureWorkspace" xml:space="preserve">Espaces de travail</x:String>
<x:String x:Key="Text.ConfigureWorkspace.Color" xml:space="preserve">Couleur</x:String>
<x:String x:Key="Text.ConfigureWorkspace.Restore" xml:space="preserve">Restaurer les onglets au démarrage</x:String>
<x:String x:Key="Text.ConventionalCommit" xml:space="preserve">Assistant Commits Conventionnels</x:String>
<x:String x:Key="Text.ConventionalCommit.BreakingChanges" xml:space="preserve">Changement Radical :</x:String>
<x:String x:Key="Text.ConventionalCommit.ClosedIssue" xml:space="preserve">Incident Clos :</x:String>
<x:String x:Key="Text.ConventionalCommit.Detail" xml:space="preserve">Détail des Modifications :</x:String>
<x:String x:Key="Text.ConventionalCommit.Scope" xml:space="preserve">Portée :</x:String>
<x:String x:Key="Text.ConventionalCommit.ShortDescription" xml:space="preserve">Courte Description :</x:String>
<x:String x:Key="Text.ConventionalCommit.Type" xml:space="preserve">Type de Changement :</x:String>
<x:String x:Key="Text.Copy" xml:space="preserve">Copier</x:String>
<x:String x:Key="Text.CopyAllText" xml:space="preserve">Copier tout le texte</x:String>
<x:String x:Key="Text.CopyFileName" xml:space="preserve">Copier le nom de fichier</x:String>
@ -198,10 +235,12 @@
<x:String x:Key="Text.Diff.Binary.Old" xml:space="preserve">ANCIEN</x:String>
<x:String x:Key="Text.Diff.Copy" xml:space="preserve">Copier</x:String>
<x:String x:Key="Text.Diff.FileModeChanged" xml:space="preserve">Mode de fichier changé</x:String>
<x:String x:Key="Text.Diff.IgnoreWhitespace" xml:space="preserve">Ignorer les changements d'espaces</x:String>
<x:String x:Key="Text.Diff.LFS" xml:space="preserve">CHANGEMENT D'OBJET LFS</x:String>
<x:String x:Key="Text.Diff.Next" xml:space="preserve">Différence suivante</x:String>
<x:String x:Key="Text.Diff.NoChange" xml:space="preserve">PAS DE CHANGEMENT OU SEULEMENT EN FIN DE LIGNE</x:String>
<x:String x:Key="Text.Diff.Prev" xml:space="preserve">Différence précédente</x:String>
<x:String x:Key="Text.Diff.SaveAsPatch" xml:space="preserve">Enregistrer en tant que patch</x:String>
<x:String x:Key="Text.Diff.ShowHiddenSymbols" xml:space="preserve">Afficher les caractères invisibles</x:String>
<x:String x:Key="Text.Diff.SideBySide" xml:space="preserve">Diff côte-à-côte</x:String>
<x:String x:Key="Text.Diff.Submodule" xml:space="preserve">SOUS-MODULE</x:String>
@ -210,6 +249,7 @@
<x:String x:Key="Text.Diff.SyntaxHighlight" xml:space="preserve">Coloration syntaxique</x:String>
<x:String x:Key="Text.Diff.ToggleWordWrap" xml:space="preserve">Retour à la ligne</x:String>
<x:String x:Key="Text.Diff.UseMerger" xml:space="preserve">Ouvrir dans l'outil de fusion</x:String>
<x:String x:Key="Text.Diff.VisualLines.All" xml:space="preserve">Voir toutes les lignes</x:String>
<x:String x:Key="Text.Diff.VisualLines.Decr" xml:space="preserve">Réduit le nombre de ligne visibles</x:String>
<x:String x:Key="Text.Diff.VisualLines.Incr" xml:space="preserve">Augmente le nombre de ligne visibles</x:String>
<x:String x:Key="Text.Diff.Welcome" xml:space="preserve">SÉLECTIONNEZ UN FICHIER POUR VOIR LES CHANGEMENTS</x:String>
@ -217,6 +257,7 @@
<x:String x:Key="Text.Discard" xml:space="preserve">Rejeter les changements</x:String>
<x:String x:Key="Text.Discard.All" xml:space="preserve">Tous les changements dans la copie de travail.</x:String>
<x:String x:Key="Text.Discard.Changes" xml:space="preserve">Changements :</x:String>
<x:String x:Key="Text.Discard.IncludeIgnored" xml:space="preserve">Inclure les fichiers ignorés</x:String>
<x:String x:Key="Text.Discard.Total" xml:space="preserve">{0} changements seront rejetés</x:String>
<x:String x:Key="Text.Discard.Warning" xml:space="preserve">Vous ne pouvez pas annuler cette action !!!</x:String>
<x:String x:Key="Text.EditRepositoryNode.Bookmark" xml:space="preserve">Signet :</x:String>
@ -224,6 +265,8 @@
<x:String x:Key="Text.EditRepositoryNode.Target" xml:space="preserve">Cible :</x:String>
<x:String x:Key="Text.EditRepositoryNode.TitleForGroup" xml:space="preserve">Éditer le groupe sélectionné</x:String>
<x:String x:Key="Text.EditRepositoryNode.TitleForRepository" xml:space="preserve">Éditer le dépôt sélectionné</x:String>
<x:String x:Key="Text.ExecuteCustomAction" xml:space="preserve">Lancer action personnalisée</x:String>
<x:String x:Key="Text.ExecuteCustomAction.Name" xml:space="preserve">Nom de l'action :</x:String>
<x:String x:Key="Text.FastForwardWithoutCheck" xml:space="preserve">Fast-Forward (sans checkout)</x:String>
<x:String x:Key="Text.Fetch" xml:space="preserve">Fetch</x:String>
<x:String x:Key="Text.Fetch.AllRemotes" xml:space="preserve">Fetch toutes les branches distantes</x:String>
@ -248,63 +291,68 @@
<x:String x:Key="Text.FileCM.UseTheirs" xml:space="preserve">Utiliser les leurs (checkout --theirs)</x:String>
<x:String x:Key="Text.FileHistory" xml:space="preserve">Historique du fichier</x:String>
<x:String x:Key="Text.FileHistory.FileContent" xml:space="preserve">CONTENU</x:String>
<x:String x:Key="Text.Filter" xml:space="preserve">FILTRER</x:String>
<x:String x:Key="Text.FileHistory.FileChange" xml:space="preserve">MODIFICATION</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">Development Branch:</x:String>
<x:String x:Key="Text.GitFlow.DevelopBranch" xml:space="preserve">Branche de développement :</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">Feature Prefix:</x:String>
<x:String x:Key="Text.GitFlow.FinishFeature" xml:space="preserve">FLOW - Finish Feature</x:String>
<x:String x:Key="Text.GitFlow.FinishHotfix" xml:space="preserve">FLOW - Finish Hotfix</x:String>
<x:String x:Key="Text.GitFlow.FinishRelease" xml:space="preserve">FLOW - Finish Release</x:String>
<x:String x:Key="Text.GitFlow.FinishTarget" xml:space="preserve">Target:</x:String>
<x:String x:Key="Text.GitFlow.FinishFeature" xml:space="preserve">FLOW - Terminer Feature</x:String>
<x:String x:Key="Text.GitFlow.FinishHotfix" xml:space="preserve">FLOW - Terminer Hotfix</x:String>
<x:String x:Key="Text.GitFlow.FinishRelease" xml:space="preserve">FLOW - Terminer Release</x:String>
<x:String x:Key="Text.GitFlow.FinishTarget" xml:space="preserve">Cible:</x:String>
<x:String x:Key="Text.GitFlow.Hotfix" xml:space="preserve">Hotfix:</x:String>
<x:String x:Key="Text.GitFlow.HotfixPrefix" xml:space="preserve">Hotfix Prefix:</x:String>
<x:String x:Key="Text.GitFlow.Init" xml:space="preserve">Initialize Git-Flow</x:String>
<x:String x:Key="Text.GitFlow.KeepBranchAfterFinish" xml:space="preserve">Keep branch</x:String>
<x:String x:Key="Text.GitFlow.ProductionBranch" xml:space="preserve">Production Branch:</x:String>
<x:String x:Key="Text.GitFlow.Release" xml:space="preserve">Release:</x:String>
<x:String x:Key="Text.GitFlow.ReleasePrefix" xml:space="preserve">Release Prefix:</x:String>
<x:String x:Key="Text.GitFlow.StartFeature" xml:space="preserve">Start Feature...</x:String>
<x:String x:Key="Text.GitFlow.StartFeatureTitle" xml:space="preserve">FLOW - Start Feature</x:String>
<x:String x:Key="Text.GitFlow.StartHotfix" xml:space="preserve">Start Hotfix...</x:String>
<x:String x:Key="Text.GitFlow.StartHotfixTitle" xml:space="preserve">FLOW - Start Hotfix</x:String>
<x:String x:Key="Text.GitFlow.StartPlaceholder" xml:space="preserve">Enter name</x:String>
<x:String x:Key="Text.GitFlow.StartRelease" xml:space="preserve">Start Release...</x:String>
<x:String x:Key="Text.GitFlow.StartReleaseTitle" xml:space="preserve">FLOW - Start Release</x:String>
<x:String x:Key="Text.GitFlow.TagPrefix" xml:space="preserve">Version Tag Prefix:</x:String>
<x:String x:Key="Text.GitFlow.Init" xml:space="preserve">Initialiser Git-Flow</x:String>
<x:String x:Key="Text.GitFlow.KeepBranchAfterFinish" xml:space="preserve">Garder la branche</x:String>
<x:String x:Key="Text.GitFlow.ProductionBranch" xml:space="preserve">Branche de production :</x:String>
<x:String x:Key="Text.GitFlow.Release" xml:space="preserve">Release :</x:String>
<x:String x:Key="Text.GitFlow.ReleasePrefix" xml:space="preserve">Release Prefix :</x:String>
<x:String x:Key="Text.GitFlow.StartFeature" xml:space="preserve">Commencer Feature...</x:String>
<x:String x:Key="Text.GitFlow.StartFeatureTitle" xml:space="preserve">FLOW - Commencer Feature</x:String>
<x:String x:Key="Text.GitFlow.StartHotfix" xml:space="preserve">Commencer Hotfix...</x:String>
<x:String x:Key="Text.GitFlow.StartHotfixTitle" xml:space="preserve">FLOW - Commencer Hotfix</x:String>
<x:String x:Key="Text.GitFlow.StartPlaceholder" xml:space="preserve">Saisir le nom</x:String>
<x:String x:Key="Text.GitFlow.StartRelease" xml:space="preserve">Commencer Release...</x:String>
<x:String x:Key="Text.GitFlow.StartReleaseTitle" xml:space="preserve">FLOW - Commencer Release</x:String>
<x:String x:Key="Text.GitFlow.TagPrefix" xml:space="preserve">Préfixe Tag de Version :</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">Add Track Pattern...</x:String>
<x:String x:Key="Text.GitLFS.AddTrackPattern.IsFilename" xml:space="preserve">Pattern is file name</x:String>
<x:String x:Key="Text.GitLFS.AddTrackPattern.Pattern" xml:space="preserve">Custom Pattern:</x:String>
<x:String x:Key="Text.GitLFS.AddTrackPattern.Title" xml:space="preserve">Add Track Pattern to Git LFS</x:String>
<x:String x:Key="Text.GitLFS.AddTrackPattern" xml:space="preserve">Ajouter un pattern de suivi...</x:String>
<x:String x:Key="Text.GitLFS.AddTrackPattern.IsFilename" xml:space="preserve">Le pattern est un nom de fichier</x:String>
<x:String x:Key="Text.GitLFS.AddTrackPattern.Pattern" xml:space="preserve">Pattern personnalisé :</x:String>
<x:String x:Key="Text.GitLFS.AddTrackPattern.Title" xml:space="preserve">Ajouter un pattern de suivi à Git LFS</x:String>
<x:String x:Key="Text.GitLFS.Fetch" xml:space="preserve">Fetch</x:String>
<x:String x:Key="Text.GitLFS.Fetch.Title" xml:space="preserve">Fetch LFS Objects</x:String>
<x:String x:Key="Text.GitLFS.Fetch.Tips" xml:space="preserve">Run `git lfs fetch` to download Git LFS objects. This does not update the working copy.</x:String>
<x:String x:Key="Text.GitLFS.Install" xml:space="preserve">Install Git LFS hooks</x:String>
<x:String x:Key="Text.GitLFS.Locks" xml:space="preserve">Show Locks</x:String>
<x:String x:Key="Text.GitLFS.Locks.Empty" xml:space="preserve">No Locked Files</x:String>
<x:String x:Key="Text.GitLFS.Locks.Lock" xml:space="preserve">Lock</x:String>
<x:String x:Key="Text.GitLFS.Locks.Title" xml:space="preserve">LFS Locks</x:String>
<x:String x:Key="Text.GitLFS.Locks.Unlock" xml:space="preserve">Unlock</x:String>
<x:String x:Key="Text.GitLFS.Locks.UnlockForce" xml:space="preserve">Force Unlock</x:String>
<x:String x:Key="Text.GitLFS.Fetch.Title" xml:space="preserve">Fetch les objets LFS</x:String>
<x:String x:Key="Text.GitLFS.Fetch.Tips" xml:space="preserve">Lancer `git lfs fetch` pour télécharger les objets Git LFS. Cela ne met pas à jour la copie de travail.</x:String>
<x:String x:Key="Text.GitLFS.Install" xml:space="preserve">Installer les hooks Git LFS</x:String>
<x:String x:Key="Text.GitLFS.Locks" xml:space="preserve">Afficher les verrous</x:String>
<x:String x:Key="Text.GitLFS.Locks.Empty" xml:space="preserve">Pas de fichiers verrouillés</x:String>
<x:String x:Key="Text.GitLFS.Locks.Lock" xml:space="preserve">Verrouiller</x:String>
<x:String x:Key="Text.GitLFS.Locks.OnlyMine" xml:space="preserve">Afficher seulement mes verrous</x:String>
<x:String x:Key="Text.GitLFS.Locks.Title" xml:space="preserve">Verrous LFS</x:String>
<x:String x:Key="Text.GitLFS.Locks.Unlock" xml:space="preserve">Déverouiller</x:String>
<x:String x:Key="Text.GitLFS.Locks.UnlockForce" xml:space="preserve">Forcer le déverouillage</x:String>
<x:String x:Key="Text.GitLFS.Prune" xml:space="preserve">Prune</x:String>
<x:String x:Key="Text.GitLFS.Prune.Tips" xml:space="preserve">Run `git lfs prune` to delete old LFS files from local storage</x:String>
<x:String x:Key="Text.GitLFS.Prune.Tips" xml:space="preserve">Lancer `git lfs prune` pour supprimer les anciens fichier LFS du stockage local</x:String>
<x:String x:Key="Text.GitLFS.Pull" xml:space="preserve">Pull</x:String>
<x:String x:Key="Text.GitLFS.Pull.Title" xml:space="preserve">Pull LFS Objects</x:String>
<x:String x:Key="Text.GitLFS.Pull.Tips" xml:space="preserve">Run `git lfs pull` to download all Git LFS files for current ref &amp; checkout</x:String>
<x:String x:Key="Text.GitLFS.Pull.Title" xml:space="preserve">Pull les objets LFS</x:String>
<x:String x:Key="Text.GitLFS.Pull.Tips" xml:space="preserve">Lancer `git lfs pull` pour télécharger tous les fichier Git LFS de la référence actuelle &amp; checkout</x:String>
<x:String x:Key="Text.GitLFS.Push" xml:space="preserve">Push</x:String>
<x:String x:Key="Text.GitLFS.Push.Title" xml:space="preserve">Push LFS Objects</x:String>
<x:String x:Key="Text.GitLFS.Push.Tips" xml:space="preserve">Push queued large files to the Git LFS endpoint</x:String>
<x:String x:Key="Text.GitLFS.Remote" xml:space="preserve">Remote:</x:String>
<x:String x:Key="Text.GitLFS.Track" xml:space="preserve">Track files named '{0}'</x:String>
<x:String x:Key="Text.GitLFS.TrackByExtension" xml:space="preserve">Track all *{0} files</x:String>
<x:String x:Key="Text.GitLFS.Push.Title" xml:space="preserve">Push les objets LFS</x:String>
<x:String x:Key="Text.GitLFS.Push.Tips" xml:space="preserve">Transférer les fichiers volumineux en file d'attente vers le point de terminaison Git LFS</x:String>
<x:String x:Key="Text.GitLFS.Remote" xml:space="preserve">Dépôt :</x:String>
<x:String x:Key="Text.GitLFS.Track" xml:space="preserve">Suivre les fichiers appelés '{0}'</x:String>
<x:String x:Key="Text.GitLFS.TrackByExtension" xml:space="preserve">Suivre tous les fichiers *{0}</x:String>
<x:String x:Key="Text.Histories" xml:space="preserve">Historique</x:String>
<x:String x:Key="Text.Histories.DisplayMode" xml:space="preserve">Basculer entre dispositions Horizontal/Vertical</x:String>
<x:String x:Key="Text.Histories.Header.Author" xml:space="preserve">AUTEUR</x:String>
<x:String x:Key="Text.Histories.Header.AuthorTime" xml:space="preserve">HEURE DE L'AUTEUR</x:String>
<x:String x:Key="Text.Histories.Header.GraphAndSubject" xml:space="preserve">GRAPHE &amp; SUJET</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">HEURE DE COMMIT</x:String>
<x:String x:Key="Text.Histories.Selected" xml:space="preserve">{0} COMMITS SÉLECTIONNÉS</x:String>
<x:String x:Key="Text.Histories.Tips" xml:space="preserve">Maintenir 'Ctrl' ou 'Shift' enfoncée pour sélectionner plusieurs commits.</x:String>
<x:String x:Key="Text.Histories.Tips.MacOS" xml:space="preserve">Maintenir ⌘ ou ⇧ enfoncée pour sélectionner plusieurs commits.</x:String>
<x:String x:Key="Text.Histories.Tips.Prefix" xml:space="preserve">CONSEILS:</x:String>
<x:String x:Key="Text.Hotkeys" xml:space="preserve">Référence des raccourcis clavier</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">Annuler le popup en cours</x:String>
@ -316,7 +364,13 @@
<x:String x:Key="Text.Hotkeys.Repo" xml:space="preserve">DÉPÔT</x:String>
<x:String x:Key="Text.Hotkeys.Repo.Commit" xml:space="preserve">Commit les changements de l'index</x:String>
<x:String x:Key="Text.Hotkeys.Repo.CommitAndPush" xml:space="preserve">Commit et pousser les changements de l'index</x:String>
<x:String x:Key="Text.Hotkeys.Repo.CommitWithAutoStage" xml:space="preserve">Ajouter tous les changements et commit</x:String>
<x:String x:Key="Text.Hotkeys.Repo.CreateBranchOnCommit" xml:space="preserve">Créer une nouvelle branche basée sur le commit actuel</x:String>
<x:String x:Key="Text.Hotkeys.Repo.DiscardSelected" xml:space="preserve">Rejeter les changements sélectionnés</x:String>
<x:String x:Key="Text.Hotkeys.Repo.Fetch" xml:space="preserve">Fetch, démarre directement</x:String>
<x:String x:Key="Text.Hotkeys.Repo.GoHome" xml:space="preserve">Mode tableau de bord (Défaut)</x:String>
<x:String x:Key="Text.Hotkeys.Repo.Pull" xml:space="preserve">Pull, démarre directement</x:String>
<x:String x:Key="Text.Hotkeys.Repo.Push" xml:space="preserve">Push, démarre directement</x:String>
<x:String x:Key="Text.Hotkeys.Repo.Refresh" xml:space="preserve">Forcer le rechargement du dépôt</x:String>
<x:String x:Key="Text.Hotkeys.Repo.StageOrUnstageSelected" xml:space="preserve">Ajouter/Retirer les changements sélectionnés de l'index</x:String>
<x:String x:Key="Text.Hotkeys.Repo.OpenSearchCommits" xml:space="preserve">Recherche de commit</x:String>
@ -331,26 +385,30 @@
<x:String x:Key="Text.Hunk.Stage" xml:space="preserve">Stage</x:String>
<x:String x:Key="Text.Hunk.Unstage" xml:space="preserve">Retirer de l'index</x:String>
<x:String x:Key="Text.Hunk.Discard" xml:space="preserve">Rejeter</x:String>
<x:String x:Key="Text.Init" xml:space="preserve">Initialize Repository</x:String>
<x:String x:Key="Text.Init.Path" xml:space="preserve">Path:</x:String>
<x:String x:Key="Text.InProgress.CherryPick" xml:space="preserve">Cherry-Pick in progress. Press 'Abort' to restore original HEAD.</x:String>
<x:String x:Key="Text.InProgress.Merge" xml:space="preserve">Merge request in progress. Press 'Abort' to restore original HEAD.</x:String>
<x:String x:Key="Text.InProgress.Rebase" xml:space="preserve">Rebase in progress. Press 'Abort' to restore original HEAD.</x:String>
<x:String x:Key="Text.InProgress.Revert" xml:space="preserve">Revert in progress. Press 'Abort' to restore original HEAD.</x:String>
<x:String x:Key="Text.InteractiveRebase" xml:space="preserve">Interactive Rebase</x:String>
<x:String x:Key="Text.InteractiveRebase.Target" xml:space="preserve">Target Branch:</x:String>
<x:String x:Key="Text.InteractiveRebase.On" xml:space="preserve">On:</x:String>
<x:String x:Key="Text.Launcher.Error" xml:space="preserve">ERROR</x:String>
<x:String x:Key="Text.Init" xml:space="preserve">Initialiser le repository</x:String>
<x:String x:Key="Text.Init.Path" xml:space="preserve">Chemin :</x:String>
<x:String x:Key="Text.InProgress.CherryPick" xml:space="preserve">Cherry-Pick en cours. Appuyer sur 'Abort' pour restaurer le HEAD d'origine.</x:String>
<x:String x:Key="Text.InProgress.Merge" xml:space="preserve">Merge request in progress. Appuyer sur 'Abort' pour restaurer le HEAD d'origine.</x:String>
<x:String x:Key="Text.InProgress.Rebase" xml:space="preserve">Rebase in progress. Appuyer sur 'Abort' pour restaurer le HEAD d'origine.</x:String>
<x:String x:Key="Text.InProgress.Revert" xml:space="preserve">Revert in progress. Appuyer sur 'Abort' pour restaurer le HEAD d'origine.</x:String>
<x:String x:Key="Text.InteractiveRebase" xml:space="preserve">Rebase interactif</x:String>
<x:String x:Key="Text.InteractiveRebase.Target" xml:space="preserve">Branche cible :</x:String>
<x:String x:Key="Text.InteractiveRebase.On" xml:space="preserve">Sur :</x:String>
<x:String x:Key="Text.IssueLinkCM.OpenInBrowser" xml:space="preserve">Ouvrir dans le navigateur</x:String>
<x:String x:Key="Text.IssueLinkCM.CopyLink" xml:space="preserve">Copier le lien</x:String>
<x:String x:Key="Text.Launcher.Error" xml:space="preserve">ERREUR</x:String>
<x:String x:Key="Text.Launcher.Info" xml:space="preserve">NOTICE</x:String>
<x:String x:Key="Text.Merge" xml:space="preserve">Merge Branch</x:String>
<x:String x:Key="Text.Merge.Into" xml:space="preserve">Into:</x:String>
<x:String x:Key="Text.Merge.Mode" xml:space="preserve">Merge Option:</x:String>
<x:String x:Key="Text.Merge.Source" xml:space="preserve">Source Branch:</x:String>
<x:String x:Key="Text.Merge" xml:space="preserve">Merger la branche </x:String>
<x:String x:Key="Text.Merge.Into" xml:space="preserve">Dans :</x:String>
<x:String x:Key="Text.Merge.Mode" xml:space="preserve">Option de merge:</x:String>
<x:String x:Key="Text.Merge.Source" xml:space="preserve">Branche source :</x:String>
<x:String x:Key="Text.MoveRepositoryNode" xml:space="preserve">Déplacer le noeud du repository</x:String>
<x:String x:Key="Text.MoveRepositoryNode.Target" xml:space="preserve">Sélectionnier le noeud parent pour :</x:String>
<x:String x:Key="Text.Name" xml:space="preserve">Nom :</x:String>
<x:String x:Key="Text.NotConfigured" xml:space="preserve">Git n'a PAS été configuré. Veuillez d'abord le faire dans le menu Préférence.</x:String>
<x:String x:Key="Text.OpenAppDataDir" xml:space="preserve">Ouvrir le dossier AppData</x:String>
<x:String x:Key="Text.OpenWith" xml:space="preserve">Open With...</x:String>
<x:String x:Key="Text.Optional" xml:space="preserve">Optional.</x:String>
<x:String x:Key="Text.OpenWith" xml:space="preserve">Ouvrir avec...</x:String>
<x:String x:Key="Text.Optional" xml:space="preserve">Optionnel.</x:String>
<x:String x:Key="Text.PageTabBar.New" xml:space="preserve">Créer un nouvel onglet</x:String>
<x:String x:Key="Text.PageTabBar.Tab.Bookmark" xml:space="preserve">Bookmark</x:String>
<x:String x:Key="Text.PageTabBar.Tab.Close" xml:space="preserve">Fermer l'onglet</x:String>
@ -369,8 +427,17 @@
<x:String x:Key="Text.Period.LastYear" xml:space="preserve">L'an dernier</x:String>
<x:String x:Key="Text.Period.YearsAgo" xml:space="preserve">il y a {0} ans</x:String>
<x:String x:Key="Text.Preference" xml:space="preserve">Préférences</x:String>
<x:String x:Key="Text.Preference.AI" xml:space="preserve">IA</x:String>
<x:String x:Key="Text.Preference.AI.AnalyzeDiffPrompt" xml:space="preserve">Analyser Diff Prompt</x:String>
<x:String x:Key="Text.Preference.AI.ApiKey" xml:space="preserve">Clé d'API</x:String>
<x:String x:Key="Text.Preference.AI.GenerateSubjectPrompt" xml:space="preserve">Générer le sujet de Prompt</x:String>
<x:String x:Key="Text.Preference.AI.Model" xml:space="preserve">Modèle</x:String>
<x:String x:Key="Text.Preference.AI.Name" xml:space="preserve">Nom</x:String>
<x:String x:Key="Text.Preference.AI.Server" xml:space="preserve">Serveur</x:String>
<x:String x:Key="Text.Preference.Appearance" xml:space="preserve">APPARENCE</x:String>
<x:String x:Key="Text.Preference.Appearance.DefaultFont" xml:space="preserve">Police par défaut</x:String>
<x:String x:Key="Text.Preference.Appearance.DefaultFontSize" xml:space="preserve">Taille de police par défaut</x:String>
<x:String x:Key="Text.Preference.Appearance.EditorFontSize" xml:space="preserve">Taille de police de l'éditeur</x:String>
<x:String x:Key="Text.Preference.Appearance.MonospaceFont" xml:space="preserve">Police monospace</x:String>
<x:String x:Key="Text.Preference.Appearance.OnlyUseMonoFontInEditor" xml:space="preserve">N'utiliser que des polices monospace pour l'éditeur de texte</x:String>
<x:String x:Key="Text.Preference.Appearance.Theme" xml:space="preserve">Thème</x:String>
@ -385,6 +452,7 @@
<x:String x:Key="Text.Preference.General.Check4UpdatesOnStartup" xml:space="preserve">Vérifier les mises à jour au démarrage</x:String>
<x:String x:Key="Text.Preference.General.Locale" xml:space="preserve">Language</x:String>
<x:String x:Key="Text.Preference.General.MaxHistoryCommits" xml:space="preserve">Historique de commits</x:String>
<x:String x:Key="Text.Preference.General.ShowAuthorTime" xml:space="preserve">Afficher l'heure de l'auteur au lieu de l'heure de validation dans le graphique</x:String>
<x:String x:Key="Text.Preference.General.SubjectGuideLength" xml:space="preserve">Guide de longueur du sujet</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">Activer auto CRLF</x:String>
@ -404,6 +472,10 @@
<x:String x:Key="Text.Preference.GPG.Path.Placeholder" xml:space="preserve">Saisir le chemin d'installation vers le programme GPG</x:String>
<x:String x:Key="Text.Preference.GPG.UserKey" xml:space="preserve">Clé de signature de l'utilisateur</x:String>
<x:String x:Key="Text.Preference.GPG.UserKey.Placeholder" xml:space="preserve">Clé de signature GPG de l'utilisateur</x:String>
<x:String x:Key="Text.Preference.Integration" xml:space="preserve">INTEGRATION</x:String>
<x:String x:Key="Text.Preference.Shell" xml:space="preserve">SHELL/TERMINAL</x:String>
<x:String x:Key="Text.Preference.Shell.Type" xml:space="preserve">Shell/Terminal</x:String>
<x:String x:Key="Text.Preference.Shell.Path" xml:space="preserve">Chemin</x:String>
<x:String x:Key="Text.PruneRemote" xml:space="preserve">Élaguer une branche distant</x:String> <!-- If it is indeed about a branch -->
<x:String x:Key="Text.PruneRemote.Target" xml:space="preserve">Cible :</x:String>
<x:String x:Key="Text.PruneWorktrees" xml:space="preserve">Élaguer les Worktrees</x:String>
@ -417,87 +489,91 @@
<x:String x:Key="Text.Pull.LocalChanges.DoNothing" xml:space="preserve">Ne rien faire</x:String>
<x:String x:Key="Text.Pull.LocalChanges.StashAndReply" xml:space="preserve">Stash &amp; Réappliquer</x:String>
<x:String x:Key="Text.Pull.NoTags" xml:space="preserve">Fetch sans les tags</x:String>
<x:String x:Key="Text.Pull.Remote" xml:space="preserve">Distant :</x:String> <!-- Branch ?-->
<x:String x:Key="Text.Pull.Remote" xml:space="preserve">Dépôt distant :</x:String>
<x:String x:Key="Text.Pull.Title" xml:space="preserve">Pull (Fetch &amp; Merge)</x:String>
<x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">Use rebase instead of merge</x:String>
<x:String x:Key="Text.Pull.UseRebase" xml:space="preserve">Utiliser rebase au lieu de merge</x:String>
<x:String x:Key="Text.Push" xml:space="preserve">Push</x:String>
<x:String x:Key="Text.Push.CheckSubmodules" xml:space="preserve">Make sure submodules have been pushed</x:String>
<x:String x:Key="Text.Push.CheckSubmodules" xml:space="preserve">Assurez-vous que les submodules ont été poussés</x:String>
<x:String x:Key="Text.Push.Force" xml:space="preserve">Force push</x:String>
<x:String x:Key="Text.Push.Local" xml:space="preserve">Local Branch:</x:String>
<x:String x:Key="Text.Push.Remote" xml:space="preserve">Remote:</x:String>
<x:String x:Key="Text.Push.Title" xml:space="preserve">Push Changes To Remote</x:String>
<x:String x:Key="Text.Push.To" xml:space="preserve">Remote Branch:</x:String>
<x:String x:Key="Text.Push.Tracking" xml:space="preserve">Set as tracking branch</x:String>
<x:String x:Key="Text.Push.WithAllTags" xml:space="preserve">Push all tags</x:String>
<x:String x:Key="Text.Push.Local" xml:space="preserve">Branche locale :</x:String>
<x:String x:Key="Text.Push.Remote" xml:space="preserve">Dépôt distant :</x:String>
<x:String x:Key="Text.Push.Title" xml:space="preserve">Pousser les changements vers le dépôt distant</x:String>
<x:String x:Key="Text.Push.To" xml:space="preserve">Branche distante :</x:String>
<x:String x:Key="Text.Push.Tracking" xml:space="preserve">Définir comme branche de suivi</x:String>
<x:String x:Key="Text.Push.WithAllTags" xml:space="preserve">Push tous les tags</x:String>
<x:String x:Key="Text.PushTag" xml:space="preserve">Push Tag To Remote</x:String>
<x:String x:Key="Text.PushTag.PushAllRemotes" xml:space="preserve">Push to all remotes</x:String>
<x:String x:Key="Text.PushTag.Remote" xml:space="preserve">Remote:</x:String>
<x:String x:Key="Text.PushTag.Tag" xml:space="preserve">Tag:</x:String>
<x:String x:Key="Text.Quit" xml:space="preserve">Quit</x:String>
<x:String x:Key="Text.Rebase" xml:space="preserve">Rebase Current Branch</x:String>
<x:String x:Key="Text.Rebase.AutoStash" xml:space="preserve">Stash &amp; reapply local changes</x:String>
<x:String x:Key="Text.Rebase.On" xml:space="preserve">On:</x:String>
<x:String x:Key="Text.Rebase.Target" xml:space="preserve">Rebase:</x:String>
<x:String x:Key="Text.RefetchAvatar" xml:space="preserve">Refresh</x:String>
<x:String x:Key="Text.Remote.AddTitle" xml:space="preserve">Add Remote</x:String>
<x:String x:Key="Text.Remote.EditTitle" xml:space="preserve">Edit Remote</x:String>
<x:String x:Key="Text.Remote.Name" xml:space="preserve">Name:</x:String>
<x:String x:Key="Text.Remote.Name.Placeholder" xml:space="preserve">Remote name</x:String>
<x:String x:Key="Text.Remote.URL" xml:space="preserve">Repository URL:</x:String>
<x:String x:Key="Text.Remote.URL.Placeholder" xml:space="preserve">Remote git repository URL</x:String>
<x:String x:Key="Text.RemoteCM.CopyURL" xml:space="preserve">Copy URL</x:String>
<x:String x:Key="Text.RemoteCM.Delete" xml:space="preserve">Delete...</x:String>
<x:String x:Key="Text.RemoteCM.Edit" xml:space="preserve">Edit...</x:String>
<x:String x:Key="Text.PushTag.PushAllRemotes" xml:space="preserve">Push tous les dépôts distants</x:String>
<x:String x:Key="Text.PushTag.Remote" xml:space="preserve">Dépôt distant :</x:String>
<x:String x:Key="Text.PushTag.Tag" xml:space="preserve">Tag :</x:String>
<x:String x:Key="Text.Quit" xml:space="preserve">Quitter</x:String>
<x:String x:Key="Text.Rebase" xml:space="preserve">Rebase la branche actuelle</x:String>
<x:String x:Key="Text.Rebase.AutoStash" xml:space="preserve">Stash &amp; réappliquer changements locaux</x:String>
<x:String x:Key="Text.Rebase.On" xml:space="preserve">Sur :</x:String>
<x:String x:Key="Text.Rebase.Target" xml:space="preserve">Rebase :</x:String>
<x:String x:Key="Text.RefetchAvatar" xml:space="preserve">Rafraîchir</x:String>
<x:String x:Key="Text.Remote.AddTitle" xml:space="preserve">Ajouter dépôt distant</x:String>
<x:String x:Key="Text.Remote.EditTitle" xml:space="preserve">Modifier dépôt distant</x:String>
<x:String x:Key="Text.Remote.Name" xml:space="preserve">Nom :</x:String>
<x:String x:Key="Text.Remote.Name.Placeholder" xml:space="preserve">Nom du dépôt distant</x:String>
<x:String x:Key="Text.Remote.URL" xml:space="preserve">URL du repository :</x:String>
<x:String x:Key="Text.Remote.URL.Placeholder" xml:space="preserve">URL du dépôt distant </x:String>
<x:String x:Key="Text.RemoteCM.CopyURL" xml:space="preserve">Copier l'URL</x:String>
<x:String x:Key="Text.RemoteCM.Delete" xml:space="preserve">Supprimer...</x:String>
<x:String x:Key="Text.RemoteCM.Edit" xml:space="preserve">Editer...</x:String>
<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.OpenInBrowser" xml:space="preserve">Ouvrir dans le navigateur</x:String>
<x:String x:Key="Text.RemoteCM.Prune" xml:space="preserve">Prune</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>
<x:String x:Key="Text.RenameBranch" xml:space="preserve">Rename Branch</x:String>
<x:String x:Key="Text.RenameBranch.Name" xml:space="preserve">New Name:</x:String>
<x:String x:Key="Text.RenameBranch.Name.Placeholder" xml:space="preserve">Unique name for this branch</x:String>
<x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">Branch:</x:String>
<x:String x:Key="Text.RemoveWorktree" xml:space="preserve">Confirmer la suppression du Worktree</x:String>
<x:String x:Key="Text.RemoveWorktree.Force" xml:space="preserve">Activer l'option `--force`</x:String>
<x:String x:Key="Text.RemoveWorktree.Target" xml:space="preserve">Cible :</x:String>
<x:String x:Key="Text.RenameBranch" xml:space="preserve"> la branche</x:String>
<x:String x:Key="Text.RenameBranch.Name" xml:space="preserve">Nouveau nom :</x:String>
<x:String x:Key="Text.RenameBranch.Name.Placeholder" xml:space="preserve">Nom unique pour cette branche</x:String>
<x:String x:Key="Text.RenameBranch.Target" xml:space="preserve">Branche :</x:String>
<x:String x:Key="Text.Repository.Abort" xml:space="preserve">ABORT</x:String>
<x:String x:Key="Text.Repository.Clean" xml:space="preserve">Cleanup(GC &amp; Prune)</x:String>
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">Run `git gc` command for this repository.</x:String>
<x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">Clear all</x:String>
<x:String x:Key="Text.Repository.Configure" xml:space="preserve">Configure this repository</x:String>
<x:String x:Key="Text.Repository.Continue" xml:space="preserve">CONTINUE</x:String>
<x:String x:Key="Text.Repository.AutoFetching" xml:space="preserve">Fetch automatique des changements depuis les dépôts...</x:String>
<x:String x:Key="Text.Repository.Clean" xml:space="preserve">Nettoyage(GC &amp; Prune)</x:String>
<x:String x:Key="Text.Repository.CleanTips" xml:space="preserve">Lancer `git gc` pour ce repository.</x:String>
<x:String x:Key="Text.Repository.ClearAllCommitsFilter" xml:space="preserve">Tout effacer</x:String>
<x:String x:Key="Text.Repository.Configure" xml:space="preserve">Configurer ce repository</x:String>
<x:String x:Key="Text.Repository.Continue" xml:space="preserve">CONTINUER</x:String>
<x:String x:Key="Text.Repository.Explore" xml:space="preserve">Ouvrir dans l'explorateur Windows</x:String>
<x:String x:Key="Text.Repository.Filter" xml:space="preserve">Search Branches/Tags/Submodules</x:String>
<x:String x:Key="Text.Repository.FilterCommitPrefix" xml:space="preserve">FILTERED BY:</x:String>
<x:String x:Key="Text.Repository.LocalBranches" xml:space="preserve">LOCAL BRANCHES</x:String>
<x:String x:Key="Text.Repository.NavigateToCurrentHead" xml:space="preserve">Navigate To HEAD</x:String>
<x:String x:Key="Text.Repository.FirstParentFilterToggle" xml:space="preserve">Enable '--first-parent' Option</x:String>
<x:String x:Key="Text.Repository.NewBranch" xml:space="preserve">Create Branch</x:String>
<x:String x:Key="Text.Repository.OpenIn" xml:space="preserve">Open In {0}</x:String>
<x:String x:Key="Text.Repository.OpenWithExternalTools" xml:space="preserve">Open In External Tools</x:String>
<x:String x:Key="Text.Repository.Refresh" xml:space="preserve">Refresh</x:String>
<x:String x:Key="Text.Repository.Remotes" xml:space="preserve">REMOTES</x:String>
<x:String x:Key="Text.Repository.Remotes.Add" xml:space="preserve">ADD REMOTE</x:String>
<x:String x:Key="Text.Repository.Resolve" xml:space="preserve">RESOLVE</x:String>
<x:String x:Key="Text.Repository.Search" xml:space="preserve">Search Commit</x:String>
<x:String x:Key="Text.Repository.Search.ByFile" xml:space="preserve">File</x:String>
<x:String x:Key="Text.Repository.CustomActions.Empty" xml:space="preserve">Pas d'actions personnalisées</x:String>
<x:String x:Key="Text.Repository.EnableReflog" xml:space="preserve">Activer l'option '--reflog'</x:String>
<x:String x:Key="Text.Repository.Explore" xml:space="preserve">Ouvrir dans l'explorateur de fichiers</x:String>
<x:String x:Key="Text.Repository.Filter" xml:space="preserve">Rechercher Branches/Tags/Submodules</x:String>
<x:String x:Key="Text.Repository.LocalBranches" xml:space="preserve">BRANCHES LOCALES</x:String>
<x:String x:Key="Text.Repository.NavigateToCurrentHead" xml:space="preserve">Naviguer vers le HEAD</x:String>
<x:String x:Key="Text.Repository.FirstParentFilterToggle" xml:space="preserve">Activer l'option '--first-parent'</x:String>
<x:String x:Key="Text.Repository.NewBranch" xml:space="preserve">Créer une branche</x:String>
<x:String x:Key="Text.Repository.OpenIn" xml:space="preserve">Ouvrir dans {0}</x:String>
<x:String x:Key="Text.Repository.OpenWithExternalTools" xml:space="preserve">Ouvrir dans un outil externe</x:String>
<x:String x:Key="Text.Repository.Refresh" xml:space="preserve">Rafraîchir</x:String>
<x:String x:Key="Text.Repository.Remotes" xml:space="preserve">DEPOTS DISTANTS</x:String>
<x:String x:Key="Text.Repository.Remotes.Add" xml:space="preserve">AJOUTER DEPOT DISTANT</x:String>
<x:String x:Key="Text.Repository.Resolve" xml:space="preserve">RESOUDRE</x:String>
<x:String x:Key="Text.Repository.Search" xml:space="preserve">Rechercher un commit</x:String>
<x:String x:Key="Text.Repository.Search.ByFile" xml:space="preserve">Fichier</x:String>
<x:String x:Key="Text.Repository.Search.ByMessage" xml:space="preserve">Message</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">Author &amp; Committer</x:String>
<x:String x:Key="Text.Repository.ShowTagsAsTree" xml:space="preserve">Show Tags as Tree</x:String>
<x:String x:Key="Text.Repository.Statistics" xml:space="preserve">Statistics</x:String>
<x:String x:Key="Text.Repository.Search.ByUser" xml:space="preserve">Auteur &amp; Committer</x:String>
<x:String x:Key="Text.Repository.Search.InCurrentBranch" xml:space="preserve">Branche actuelle</x:String>
<x:String x:Key="Text.Repository.ShowTagsAsTree" xml:space="preserve">Voir les Tags en tant qu'arbre</x:String>
<x:String x:Key="Text.Repository.Statistics" xml:space="preserve">Statistiques</x:String>
<x:String x:Key="Text.Repository.Submodules" xml:space="preserve">SUBMODULES</x:String>
<x:String x:Key="Text.Repository.Submodules.Add" xml:space="preserve">ADD SUBMODULE</x:String>
<x:String x:Key="Text.Repository.Submodules.Update" xml:space="preserve">UPDATE SUBMODULE</x:String>
<x:String x:Key="Text.Repository.Submodules.Add" xml:space="preserve">AJOUTER SUBMODULE</x:String>
<x:String x:Key="Text.Repository.Submodules.Update" xml:space="preserve">METTRE A JOUR SUBMODULE</x:String>
<x:String x:Key="Text.Repository.Tags" xml:space="preserve">TAGS</x:String>
<x:String x:Key="Text.Repository.Tags.Add" xml:space="preserve">NEW TAG</x:String>
<x:String x:Key="Text.Repository.Tags.Add" xml:space="preserve">NOUVEAU TAG</x:String>
<x:String x:Key="Text.Repository.Terminal" xml:space="preserve">Ouvrir dans un 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">ADD WORKTREE</x:String>
<x:String x:Key="Text.Repository.Worktrees.Add" xml:space="preserve">AJOUTER WORKTREE</x:String>
<x:String x:Key="Text.Repository.Worktrees.Prune" xml:space="preserve">PRUNE</x:String>
<x:String x:Key="Text.RepositoryURL" xml:space="preserve">Git Repository URL</x:String>
<x:String x:Key="Text.Reset" xml:space="preserve">Reset Current Branch To Revision</x:String>
<x:String x:Key="Text.RepositoryURL" xml:space="preserve">URL du repository Git</x:String>
<x:String x:Key="Text.Reset" xml:space="preserve">Reset branche actuelle à la révision</x:String>
<x:String x:Key="Text.Reset.Mode" xml:space="preserve">Reset Mode:</x:String>
<x:String x:Key="Text.Reset.MoveTo" xml:space="preserve">Move To:</x:String>
<x:String x:Key="Text.Reset.Target" xml:space="preserve">Current Branch:</x:String>
<x:String x:Key="Text.Reset.MoveTo" xml:space="preserve">Déplacer vers :</x:String>
<x:String x:Key="Text.Reset.Target" xml:space="preserve">Branche actuelle :</x:String>
<x:String x:Key="Text.RevealFile" xml:space="preserve">Ouvrir dans l'explorateur de fichier</x:String>
<x:String x:Key="Text.Revert" xml:space="preserve">Revert le Commit</x:String>
<x:String x:Key="Text.Revert.Commit" xml:space="preserve">Commit :</x:String>
@ -509,6 +585,8 @@
<x:String x:Key="Text.SaveAs" xml:space="preserve">Sauvegarder en tant que...</x:String>
<x:String x:Key="Text.SaveAsPatchSuccess" xml:space="preserve">Le patch a été sauvegardé !</x:String>
<x:String x:Key="Text.SelfUpdate" xml:space="preserve">Vérifier les mises à jour...</x:String>
<x:String x:Key="Text.ScanRepositories.RootDir" xml:space="preserve">Dossier racine :</x:String>
<x:String x:Key="Text.SelfUpdate" xml:space="preserve">Rechercher des mises à jour...</x:String>
<x:String x:Key="Text.SelfUpdate.Available" xml:space="preserve">Une nouvelle version du logiciel est disponible :</x:String>
<x:String x:Key="Text.SelfUpdate.Error" xml:space="preserve">La vérification de mise à jour à échouée !</x:String>
<x:String x:Key="Text.SelfUpdate.GotoDownload" xml:space="preserve">Télécharger</x:String>
@ -516,13 +594,17 @@
<x:String x:Key="Text.SelfUpdate.Title" xml:space="preserve">Mise à jour du logiciel</x:String>
<x:String x:Key="Text.SelfUpdate.UpToDate" xml:space="preserve">Il n'y a pas de mise à jour pour le moment.</x:String>
<x:String x:Key="Text.Squash" xml:space="preserve">Squash Commits</x:String>
<x:String x:Key="Text.Squash.Into" xml:space="preserve">Dans :</x:String>
<x:String x:Key="Text.SSHKey" xml:space="preserve">SSH Private Key:</x:String>
<x:String x:Key="Text.SSHKey.Placeholder" xml:space="preserve">Private SSH key store path</x:String>
<x:String x:Key="Text.Start" xml:space="preserve">START</x:String>
<x:String x:Key="Text.Stash" xml:space="preserve">Stash</x:String>
<x:String x:Key="Text.Stash.IncludeUntracked" xml:space="preserve">Include untracked files</x:String>
<x:String x:Key="Text.Stash.Message" xml:space="preserve">Message:</x:String>
<x:String x:Key="Text.Stash.KeepIndex" xml:space="preserve">Garder les fichiers staged</x:String>
<x:String x:Key="Text.Stash.Message" xml:space="preserve">Message :</x:String>
<x:String x:Key="Text.Stash.Message.Placeholder" xml:space="preserve">Optionnel. Nom de ce stash</x:String>
<x:String x:Key="Text.Stash.OnlyStagedChanges" xml:space="preserve">Seulement les changements staged</x:String>
<x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">Les modifications staged et unstaged des fichiers sélectionnés seront stockées!!!</x:String>
<x:String x:Key="Text.Stash.Title" xml:space="preserve">Stash les changements locaux</x:String>
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">Appliquer</x:String>
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">Effacer</x:String>
@ -539,6 +621,7 @@
<x:String x:Key="Text.Statistics.ThisWeek" xml:space="preserve">WEEK</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">AUTHORS: </x:String>
<x:String x:Key="Text.Statistics.Overview" xml:space="preserve">APERCU</x:String>
<x:String x:Key="Text.Submodule" xml:space="preserve">SUBMODULES</x:String>
<x:String x:Key="Text.Submodule.Add" xml:space="preserve">Add Submodule</x:String>
<x:String x:Key="Text.Submodule.CopyPath" xml:space="preserve">Copy Relative Path</x:String>
@ -549,6 +632,7 @@
<x:String x:Key="Text.Submodule.Remove" xml:space="preserve">Delete Submodule</x:String>
<x:String x:Key="Text.Sure" xml:space="preserve">OK</x:String>
<x:String x:Key="Text.TagCM.Copy" xml:space="preserve">Copy Tag Name</x:String>
<x:String x:Key="Text.TagCM.CopyMessage" xml:space="preserve">Copier le message du tag</x:String>
<x:String x:Key="Text.TagCM.Delete" xml:space="preserve">Delete ${0}$...</x:String>
<x:String x:Key="Text.TagCM.Merge" xml:space="preserve">Fusionner ${0}$ dans ${1}$...</x:String>
<x:String x:Key="Text.TagCM.Push" xml:space="preserve">Push ${0}$...</x:String>
@ -567,9 +651,11 @@
<x:String x:Key="Text.Welcome.Delete" xml:space="preserve">Supprimer</x:String>
<x:String x:Key="Text.Welcome.DragDropTip" xml:space="preserve">GLISSER / DEPOSER DE DOSSIER SUPPORTÉ. GROUPAGE PERSONNALISÉ SUPPORTÉ.</x:String>
<x:String x:Key="Text.Welcome.Edit" xml:space="preserve">Éditer</x:String>
<x:String x:Key="Text.Welcome.Move" xml:space="preserve">Déplacer vers un autre groupe</x:String>
<x:String x:Key="Text.Welcome.OpenAllInNode" xml:space="preserve">Ouvrir tous les dépôts</x:String>
<x:String x:Key="Text.Welcome.OpenOrInit" xml:space="preserve">Ouvrir un dépôt</x:String>
<x:String x:Key="Text.Welcome.OpenTerminal" xml:space="preserve">Ouvrir le terminal</x:String>
<x:String x:Key="Text.Welcome.ScanDefaultCloneDir" xml:space="preserve">Réanalyser les repositories dans le dossier de clonage par défaut</x:String>
<x:String x:Key="Text.Welcome.Search" xml:space="preserve">Chercher des dépôts...</x:String>
<x:String x:Key="Text.Welcome.Sort" xml:space="preserve">Trier</x:String>
<x:String x:Key="Text.WorkingCopy" xml:space="preserve">Changements</x:String>
@ -583,6 +669,9 @@
<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">Modèles/Historiques</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 tous les changements et commit</x:String>
<x:String x:Key="Text.WorkingCopy.ConfirmCommitWithoutFiles" xml:space="preserve">Un commit vide a été détecté ! Voulez-vous continuer (--allow-empty) ?</x:String>
<x:String x:Key="Text.WorkingCopy.Conflicts" xml:space="preserve">CONFLITS DÉTECTÉS</x:String>
<x:String x:Key="Text.WorkingCopy.Conflicts.Resolved" xml:space="preserve">LES CONFLITS DE FICHIER SONT RÉSOLUS</x:String>
<x:String x:Key="Text.WorkingCopy.IncludeUntracked" xml:space="preserve">INCLURE LES FICHIERS NON-SUIVIS</x:String>
@ -597,6 +686,8 @@
<x:String x:Key="Text.WorkingCopy.Unstaged.ViewAssumeUnchaged" xml:space="preserve">VOIR LES FICHIERS PRÉSUMÉS INCHANGÉS</x:String>
<x:String x:Key="Text.WorkingCopy.UseCommitTemplate" xml:space="preserve">Modèle: ${0}$</x:String>
<x:String x:Key="Text.WorkingCopy.ResolveTip" xml:space="preserve">Faites un clique droit sur les fichiers sélectionnés et faites vos choix pour la résoluion des conflits.</x:String>
<x:String x:Key="Text.Workspace" xml:space="preserve">ESPACE DE TRAVAIL : </x:String>
<x:String x:Key="Text.Workspace.Configure" xml:space="preserve">Configurer les espaces de travail...</x:String>
<x:String x:Key="Text.Worktree" xml:space="preserve">WORKTREE</x:String>
<x:String x:Key="Text.Worktree.CopyPath" xml:space="preserve">Copier le chemin</x:String>
<x:String x:Key="Text.Worktree.Lock" xml:space="preserve">Verrouiller</x:String>

View file

@ -317,7 +317,6 @@
<x:String x:Key="Text.FileHistory" xml:space="preserve">Histórico de Arquivos</x:String>
<x:String x:Key="Text.FileHistory.FileContent" xml:space="preserve">CONTEUDO</x:String>
<x:String x:Key="Text.FileHistory.FileChange" xml:space="preserve">MUDANÇA</x:String>
<x:String x:Key="Text.Filter" xml:space="preserve">FILTRO</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>
@ -566,7 +565,6 @@
<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>

View file

@ -293,7 +293,6 @@
<x:String x:Key="Text.FileHistory" xml:space="preserve">История файлов</x:String>
<x:String x:Key="Text.FileHistory.FileContent" xml:space="preserve">СОДЕРЖИМОЕ</x:String>
<x:String x:Key="Text.FileHistory.FileChange" xml:space="preserve">ИЗМЕНИТЬ</x:String>
<x:String x:Key="Text.Filter" xml:space="preserve">ФИЛЬТР</x:String>
<x:String x:Key="Text.GitFlow" xml:space="preserve">Git-поток</x:String>
<x:String x:Key="Text.GitFlow.DevelopBranch" xml:space="preserve">Ветка разработчика:</x:String>
<x:String x:Key="Text.GitFlow.Feature" xml:space="preserve">Свойство:</x:String>
@ -545,7 +544,6 @@
<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>
<x:String x:Key="Text.Repository.LocalBranches" xml:space="preserve">ЛОКАЛЬНЫЕ ВЕТКИ</x:String>
<x:String x:Key="Text.Repository.NavigateToCurrentHead" xml:space="preserve">Навигация по заголовку</x:String>
<x:String x:Key="Text.Repository.FirstParentFilterToggle" xml:space="preserve">Включить опцию --first-parent</x:String>

View file

@ -292,7 +292,6 @@
<x:String x:Key="Text.FileHistory" xml:space="preserve">文件历史</x:String>
<x:String x:Key="Text.FileHistory.FileContent" xml:space="preserve">文件内容</x:String>
<x:String x:Key="Text.FileHistory.FileChange" xml:space="preserve">文件变更</x:String>
<x:String x:Key="Text.Filter" xml:space="preserve">过滤</x:String>
<x:String x:Key="Text.GitFlow" xml:space="preserve">GIT工作流</x:String>
<x:String x:Key="Text.GitFlow.DevelopBranch" xml:space="preserve">开发分支 </x:String>
<x:String x:Key="Text.GitFlow.Feature" xml:space="preserve">特性分支 </x:String>
@ -545,7 +544,9 @@
<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>
<x:String x:Key="Text.Repository.FilterCommits.Default" xml:space="preserve">不指定</x:String>
<x:String x:Key="Text.Repository.FilterCommits.Exclude" xml:space="preserve">在提交列表中隐藏</x:String>
<x:String x:Key="Text.Repository.FilterCommits.Include" xml:space="preserve">使用其对提交列表过滤</x:String>
<x:String x:Key="Text.Repository.LocalBranches" xml:space="preserve">本地分支</x:String>
<x:String x:Key="Text.Repository.NavigateToCurrentHead" xml:space="preserve">定位HEAD</x:String>
<x:String x:Key="Text.Repository.FirstParentFilterToggle" xml:space="preserve">启用 --first-parent 过滤选项</x:String>

View file

@ -292,7 +292,6 @@
<x:String x:Key="Text.FileHistory" xml:space="preserve">檔案歷史</x:String>
<x:String x:Key="Text.FileHistory.FileContent" xml:space="preserve">檔案内容</x:String>
<x:String x:Key="Text.FileHistory.FileChange" xml:space="preserve">檔案變更</x:String>
<x:String x:Key="Text.Filter" xml:space="preserve">篩選</x:String>
<x:String x:Key="Text.GitFlow" xml:space="preserve">Git 工作流</x:String>
<x:String x:Key="Text.GitFlow.DevelopBranch" xml:space="preserve">開發分支:</x:String>
<x:String x:Key="Text.GitFlow.Feature" xml:space="preserve">功能分支:</x:String>
@ -544,7 +543,9 @@
<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>
<x:String x:Key="Text.Repository.FilterCommits.Default" xml:space="preserve">不指定</x:String>
<x:String x:Key="Text.Repository.FilterCommits.Exclude" xml:space="preserve">在提交清單中隱藏</x:String>
<x:String x:Key="Text.Repository.FilterCommits.Include" xml:space="preserve">使用其來篩選提交清單</x:String>
<x:String x:Key="Text.Repository.LocalBranches" xml:space="preserve">本機分支</x:String>
<x:String x:Key="Text.Repository.NavigateToCurrentHead" xml:space="preserve">回到 HEAD</x:String>
<x:String x:Key="Text.Repository.FirstParentFilterToggle" xml:space="preserve">啟用 [--first-parent] 選項</x:String>

View file

@ -512,6 +512,12 @@
<Style Selector="Button.flat.primary ToolTip TextBlock">
<Setter Property="Foreground" Value="{DynamicResource Brush.FG1}"/>
</Style>
<Style Selector="Button.flat:disabled /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="Transparent"/>
</Style>
<Style Selector="Button.flat:disabled">
<Setter Property="Background" Value="{DynamicResource Brush.FlatButton.Background}"/>
</Style>
<Style Selector="aes|SearchPanel">
<Setter Property="Template">
@ -1038,35 +1044,6 @@
<Setter Property="Background" Value="Transparent"/>
</Style>
<Style Selector="ToggleButton.filter">
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="Template">
<ControlTemplate>
<Border Background="Transparent">
<Path x:Name="PART_IndicatorIcon"
Width="12"
Data="{StaticResource Icons.Filter}"
Fill="Transparent"
StrokeThickness="1"
Stroke="{DynamicResource Brush.FG2}"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter>
</Style>
<Style Selector="ToggleButton.filter:pressed">
<Setter Property="RenderTransform" Value="scale(1)"/>
</Style>
<Style Selector="ToggleButton.filter:checked /template/ Path#PART_IndicatorIcon">
<Setter Property="Fill" Value="{DynamicResource Brush.FG2}"/>
</Style>
<Style Selector="ToggleButton.filter:pointerover /template/ Path#PART_IndicatorIcon">
<Setter Property="Stroke" Value="{DynamicResource Brush.Accent}"/>
</Style>
<Style Selector="ToggleButton.tree_expander">
<Setter Property="Margin" Value="0" />
<Setter Property="Width" Value="9" />

View file

@ -1,9 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using Avalonia;
using Avalonia.Collections;
using Avalonia.Media;
using CommunityToolkit.Mvvm.ComponentModel;
@ -13,15 +11,16 @@ namespace SourceGit.ViewModels
public class BranchTreeNode : ObservableObject
{
public string Name { get; private set; } = string.Empty;
public string Path { get; private set; } = string.Empty;
public object Backend { get; private set; } = null;
public int Depth { get; set; } = 0;
public bool IsSelected { get; set; } = false;
public List<BranchTreeNode> Children { get; private set; } = new List<BranchTreeNode>();
public bool IsFiltered
public Models.FilterMode FilterMode
{
get => _isFiltered;
set => SetProperty(ref _isFiltered, value);
get => _filterMode;
set => SetProperty(ref _filterMode, value);
}
public bool IsExpanded
@ -51,7 +50,7 @@ namespace SourceGit.ViewModels
get => Backend is Models.Branch b ? b.FriendlyName : null;
}
private bool _isFiltered = false;
private Models.FilterMode _filterMode = Models.FilterMode.None;
private bool _isExpanded = false;
private CornerRadius _cornerRadius = new CornerRadius(4);
@ -66,10 +65,11 @@ namespace SourceGit.ViewModels
foreach (var remote in remotes)
{
var path = $"remote/{remote.Name}";
var path = $"refs/remotes/{remote.Name}";
var node = new BranchTreeNode()
{
Name = remote.Name,
Path = path,
Backend = remote,
IsExpanded = bForceExpanded || _expanded.Contains(path),
};
@ -80,16 +80,15 @@ namespace SourceGit.ViewModels
foreach (var branch in branches)
{
var isFiltered = _filters.Contains(branch.FullName);
if (branch.IsLocal)
{
MakeBranchNode(branch, _locals, folders, "local", isFiltered, bForceExpanded);
MakeBranchNode(branch, _locals, folders, "refs/heads", bForceExpanded);
}
else
{
var remote = _remotes.Find(x => x.Name == branch.Remote);
if (remote != null)
MakeBranchNode(branch, remote.Children, folders, $"remote/{remote.Name}", isFiltered, bForceExpanded);
MakeBranchNode(branch, remote.Children, folders, $"refs/remotes/{remote.Name}", bForceExpanded);
}
}
@ -98,42 +97,32 @@ namespace SourceGit.ViewModels
SortNodes(_remotes);
}
public void SetFilters(AvaloniaList<string> filters)
{
_filters.AddRange(filters);
}
public void CollectExpandedNodes(List<BranchTreeNode> nodes, bool isLocal)
{
CollectExpandedNodes(nodes, isLocal ? "local" : "remote");
}
private void CollectExpandedNodes(List<BranchTreeNode> nodes, string prefix)
public void CollectExpandedNodes(List<BranchTreeNode> nodes)
{
foreach (var node in nodes)
{
if (node.Backend is Models.Branch)
continue;
var path = prefix + "/" + node.Name;
if (node.IsExpanded)
_expanded.Add(path);
_expanded.Add(node.Path);
CollectExpandedNodes(node.Children, path);
CollectExpandedNodes(node.Children);
}
}
private void MakeBranchNode(Models.Branch branch, List<BranchTreeNode> roots, Dictionary<string, BranchTreeNode> folders, string prefix, bool isFiltered, bool bForceExpanded)
private void MakeBranchNode(Models.Branch branch, List<BranchTreeNode> roots, Dictionary<string, BranchTreeNode> folders, string prefix, bool bForceExpanded)
{
var fullpath = $"{prefix}/{branch.Name}";
var sepIdx = branch.Name.IndexOf('/', StringComparison.Ordinal);
if (sepIdx == -1 || branch.IsDetachedHead)
{
roots.Add(new BranchTreeNode()
{
Name = branch.Name,
Path = fullpath,
Backend = branch,
IsExpanded = false,
IsFiltered = isFiltered,
});
return;
}
@ -156,6 +145,7 @@ namespace SourceGit.ViewModels
lastFolder = new BranchTreeNode()
{
Name = name,
Path = folder,
IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder),
};
roots.Add(lastFolder);
@ -166,6 +156,7 @@ namespace SourceGit.ViewModels
var cur = new BranchTreeNode()
{
Name = name,
Path = folder,
IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder),
};
lastFolder.Children.Add(cur);
@ -179,10 +170,10 @@ namespace SourceGit.ViewModels
lastFolder?.Children.Add(new BranchTreeNode()
{
Name = Path.GetFileName(branch.Name),
Name = System.IO.Path.GetFileName(branch.Name),
Path = fullpath,
Backend = branch,
IsExpanded = false,
IsFiltered = isFiltered,
});
}
@ -206,7 +197,6 @@ namespace SourceGit.ViewModels
private readonly List<BranchTreeNode> _locals = new List<BranchTreeNode>();
private readonly List<BranchTreeNode> _remotes = new List<BranchTreeNode>();
private readonly HashSet<string> _expanded = new HashSet<string>();
private readonly List<string> _filters = new List<string>();
}
}
}

View file

@ -65,7 +65,7 @@ namespace SourceGit.ViewModels
{
var b = _repo.Branches.Find(x => x.IsLocal && x.Name == Branch);
if (b != null)
_repo.AutoAddBranchFilterPostCheckout(b);
_repo.UpdateHistoriesFilterAfterCheckout(b);
_repo.MarkBranchesDirtyManually();
_repo.SetWatcherEnabled(true);

View file

@ -127,7 +127,7 @@ namespace SourceGit.ViewModels
{
if (CheckoutAfterCreated)
{
_repo.AutoAddBranchFilterPostCheckout(new Models.Branch()
_repo.UpdateHistoriesFilterAfterCheckout(new Models.Branch()
{
FullName = $"refs/heads/{_name}",
Upstream = BasedOn is Models.Branch { IsLocal: false } remoteBranch ? remoteBranch.FullName : string.Empty,

View file

@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
using System;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
namespace SourceGit.ViewModels
@ -57,10 +58,17 @@ namespace SourceGit.ViewModels
var succ = Commands.Branch.Rename(_repo.FullPath, Target.Name, _name);
CallUIThread(() =>
{
if (succ && _repo.Settings.Filters.Contains(oldName))
if (succ)
{
_repo.Settings.Filters.Remove(oldName);
_repo.Settings.Filters.Add($"refs/heads/{_name}");
foreach (var filter in _repo.Settings.HistoriesFilters)
{
if (filter.Type == Models.FilterType.LocalBranch &&
filter.Pattern.Equals(oldName, StringComparison.Ordinal))
{
filter.Pattern = $"refs/heads/{_name}";
break;
}
}
}
_repo.MarkBranchesDirtyManually();

View file

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
@ -335,14 +336,7 @@ namespace SourceGit.ViewModels
public InProgressContext InProgressContext
{
get => _inProgressContext;
private set => SetProperty(ref _inProgressContext, value);
}
public bool HasUnsolvedConflicts
{
get => _hasUnsolvedConflicts;
private set => SetProperty(ref _hasUnsolvedConflicts, value);
get => _workingCopy?.InProgressContext;
}
public Models.Commit SearchResultSelectedCommit
@ -394,8 +388,6 @@ namespace SourceGit.ViewModels
_stashesPage = new StashesPage(this);
_selectedView = _histories;
_selectedViewIndex = 0;
_inProgressContext = null;
_hasUnsolvedConflicts = false;
_autoFetchTimer = new Timer(AutoFetchImpl, null, 5000, 5000);
RefreshAll();
@ -428,7 +420,6 @@ namespace SourceGit.ViewModels
_histories = null;
_workingCopy = null;
_stashesPage = null;
_inProgressContext = null;
_localChangesCount = 0;
_stashesCount = 0;
@ -455,13 +446,9 @@ namespace SourceGit.ViewModels
_hasAllowedSignersFile = !string.IsNullOrEmpty(allowedSignersFile);
});
Task.Run(() =>
{
RefreshBranches();
RefreshTags();
RefreshCommits();
});
Task.Run(RefreshBranches);
Task.Run(RefreshTags);
Task.Run(RefreshCommits);
Task.Run(RefreshSubmodules);
Task.Run(RefreshWorktrees);
Task.Run(RefreshWorkingCopyChanges);
@ -587,18 +574,6 @@ namespace SourceGit.ViewModels
Filter = string.Empty;
}
public void ClearHistoriesFilter()
{
_settings.Filters.Clear();
Task.Run(() =>
{
RefreshBranches();
RefreshTags();
RefreshCommits();
});
}
public void ClearSearchCommitFilter()
{
SearchCommitFilter = string.Empty;
@ -653,12 +628,8 @@ namespace SourceGit.ViewModels
{
if (_watcher == null)
{
Task.Run(() =>
{
RefreshBranches();
RefreshCommits();
});
Task.Run(RefreshBranches);
Task.Run(RefreshCommits);
Task.Run(RefreshWorkingCopyChanges);
Task.Run(RefreshWorktrees);
}
@ -696,53 +667,52 @@ namespace SourceGit.ViewModels
NavigateToCommit(_currentBranch.Head);
}
public void AutoAddBranchFilterPostCheckout(Models.Branch local)
public void ClearHistoriesFilter()
{
if (_settings.Filters.Count == 0 || _settings.Filters.Contains(local.FullName))
return;
var hasLeft = false;
foreach (var b in _branches)
{
if (!b.FullName.Equals(local.FullName, StringComparison.Ordinal) &&
!b.FullName.Equals(local.Upstream, StringComparison.Ordinal) &&
!_settings.Filters.Contains(b.FullName))
{
hasLeft = true;
break;
}
}
if (!hasLeft)
_settings.Filters.Clear();
else if (string.IsNullOrEmpty(local.Upstream) || _settings.Filters.Contains(local.Upstream))
_settings.Filters.Add(local.FullName);
else
_settings.Filters.AddRange([local.FullName, local.Upstream]);
_settings.HistoriesFilters.Clear();
ResetBranchTreeFilterMode(LocalBranchTrees);
ResetBranchTreeFilterMode(RemoteBranchTrees);
ResetTagFilterMode();
Task.Run(RefreshCommits);
}
public void UpdateFilters(List<string> filters, bool toggle)
public void MarkHistoriesFilterDirty()
{
var changed = false;
if (toggle)
UpdateBranchTreeFilterMode(LocalBranchTrees, true);
UpdateBranchTreeFilterMode(RemoteBranchTrees, false);
UpdateTagFilterMode();
Task.Run(RefreshCommits);
}
public void UpdateHistoriesFilterAfterCheckout(Models.Branch local)
{
var hasIncludedBranch = false;
foreach (var filter in _settings.HistoriesFilters)
{
foreach (var filter in filters)
if (filter.Type == Models.FilterType.LocalBranch)
{
if (!_settings.Filters.Contains(filter))
{
_settings.Filters.Add(filter);
changed = true;
}
if (filter.Pattern.Equals(local.FullName, StringComparison.Ordinal))
return;
hasIncludedBranch |= filter.Mode == Models.FilterMode.Included;
}
else if (filter.Type == Models.FilterType.LocalBranchFolder)
{
if (local.FullName.StartsWith(filter.Pattern, StringComparison.Ordinal))
return;
hasIncludedBranch |= filter.Mode == Models.FilterMode.Included;
}
else if (filter.Type == Models.FilterType.RemoteBranch || filter.Type == Models.FilterType.RemoteBranchFolder)
{
hasIncludedBranch |= filter.Mode == Models.FilterMode.Included;
}
}
else
{
foreach (var filter in filters)
changed |= _settings.Filters.Remove(filter);
}
if (changed)
Task.Run(RefreshCommits);
if (!hasIncludedBranch)
return;
_settings.UpdateHistoriesFilter(local.FullName, Models.FilterType.LocalBranch, Models.FilterMode.Included);
}
public void StashAll(bool autoStart)
@ -756,40 +726,9 @@ namespace SourceGit.ViewModels
SelectedViewIndex = 1;
}
public async void ContinueMerge()
public void AbortMerge()
{
if (_inProgressContext != null)
{
SetWatcherEnabled(false);
var succ = await Task.Run(_inProgressContext.Continue);
if (succ && _workingCopy != null)
{
_workingCopy.CommitMessage = string.Empty;
}
SetWatcherEnabled(true);
}
else
{
MarkWorkingCopyDirtyManually();
}
}
public async void AbortMerge()
{
if (_inProgressContext != null)
{
SetWatcherEnabled(false);
var succ = await Task.Run(_inProgressContext.Abort);
if (succ && _workingCopy != null)
{
_workingCopy.CommitMessage = string.Empty;
}
SetWatcherEnabled(true);
}
else
{
MarkWorkingCopyDirtyManually();
}
_workingCopy?.AbortMerge();
}
public void RefreshBranches()
@ -834,7 +773,7 @@ namespace SourceGit.ViewModels
{
var tags = new Commands.QueryTags(_fullpath).Result();
foreach (var tag in tags)
tag.IsFiltered = _settings.Filters.Contains(tag.Name);
tag.FilterMode = _settings.GetHistoriesFilterMode(tag.Name, Models.FilterType.Tag);
Dispatcher.UIThread.Invoke(() =>
{
@ -847,49 +786,21 @@ namespace SourceGit.ViewModels
{
Dispatcher.UIThread.Invoke(() => _histories.IsLoading = true);
var limits = $"-{Preference.Instance.MaxHistoryCommits} ";
var builder = new StringBuilder();
builder.Append($"-{Preference.Instance.MaxHistoryCommits} ");
if (_enableReflog)
limits += "--reflog ";
builder.Append("--reflog ");
if (_enableFirstParentInHistories)
limits += "--first-parent ";
builder.Append("--first-parent ");
var validFilters = new List<string>();
foreach (var filter in _settings.Filters)
{
if (filter.StartsWith("refs/", StringComparison.Ordinal))
{
if (_branches.FindIndex(x => x.FullName == filter) >= 0)
validFilters.Add(filter);
}
else
{
if (_tags.FindIndex(t => t.Name == filter) >= 0)
validFilters.Add(filter);
}
}
if (validFilters.Count > 0)
{
limits += string.Join(" ", validFilters);
if (_settings.Filters.Count != validFilters.Count)
{
Dispatcher.UIThread.Invoke(() =>
{
_settings.Filters.Clear();
_settings.Filters.AddRange(validFilters);
});
}
}
var invalidFilters = new List<Models.Filter>();
var filters = _settings.BuildHistoriesFilter();
if (string.IsNullOrEmpty(filters))
builder.Append("--branches --remotes --tags");
else
{
if (_settings.Filters.Count != 0)
Dispatcher.UIThread.Invoke(() => _settings.Filters.Clear());
builder.Append(filters);
limits += "--exclude=refs/stash --all";
}
var commits = new Commands.QueryCommits(_fullpath, limits).Result();
var commits = new Commands.QueryCommits(_fullpath, builder.ToString()).Result();
var graph = Models.CommitGraph.Parse(commits, _enableFirstParentInHistories);
Dispatcher.UIThread.Invoke(() =>
@ -921,23 +832,12 @@ namespace SourceGit.ViewModels
if (_workingCopy == null)
return;
var hasUnsolvedConflict = _workingCopy.SetData(changes);
var inProgress = null as InProgressContext;
if (File.Exists(Path.Combine(_gitDir, "CHERRY_PICK_HEAD")))
inProgress = new CherryPickInProgress(_fullpath);
else if (File.Exists(Path.Combine(_gitDir, "REBASE_HEAD")) && Directory.Exists(Path.Combine(_gitDir, "rebase-merge")))
inProgress = new RebaseInProgress(this);
else if (File.Exists(Path.Combine(_gitDir, "REVERT_HEAD")))
inProgress = new RevertInProgress(_fullpath);
else if (File.Exists(Path.Combine(_gitDir, "MERGE_HEAD")))
inProgress = new MergeInProgress(_fullpath);
_workingCopy.SetData(changes);
Dispatcher.UIThread.Invoke(() =>
{
InProgressContext = inProgress;
HasUnsolvedConflicts = hasUnsolvedConflict;
LocalChangesCount = changes.Count;
OnPropertyChanged(nameof(InProgressContext));
});
}
@ -2062,12 +1962,10 @@ namespace SourceGit.ViewModels
private BranchTreeNode.Builder BuildBranchTree(List<Models.Branch> branches, List<Models.Remote> remotes)
{
var builder = new BranchTreeNode.Builder();
builder.SetFilters(_settings.Filters);
if (string.IsNullOrEmpty(_filter))
{
builder.CollectExpandedNodes(_localBranchTrees, true);
builder.CollectExpandedNodes(_remoteBranchTrees, false);
builder.CollectExpandedNodes(_localBranchTrees);
builder.CollectExpandedNodes(_remoteBranchTrees);
builder.Run(branches, remotes, false);
}
else
@ -2082,6 +1980,8 @@ namespace SourceGit.ViewModels
builder.Run(visibles, remotes, true);
}
UpdateBranchTreeFilterMode(builder.Locals, true);
UpdateBranchTreeFilterMode(builder.Remotes, false);
return builder;
}
@ -2101,6 +2001,7 @@ namespace SourceGit.ViewModels
}
}
UpdateTagFilterMode();
return visible;
}
@ -2122,6 +2023,44 @@ namespace SourceGit.ViewModels
return visible;
}
private void UpdateBranchTreeFilterMode(List<BranchTreeNode> nodes, bool isLocal)
{
foreach (var node in nodes)
{
if (node.IsBranch)
{
node.FilterMode = _settings.GetHistoriesFilterMode(node.Path, isLocal ? Models.FilterType.LocalBranch : Models.FilterType.RemoteBranch);
}
else
{
node.FilterMode = _settings.GetHistoriesFilterMode(node.Path, isLocal ? Models.FilterType.LocalBranchFolder : Models.FilterType.RemoteBranchFolder);
UpdateBranchTreeFilterMode(node.Children, isLocal);
}
}
}
private void UpdateTagFilterMode()
{
foreach (var tag in _tags)
tag.FilterMode = _settings.GetHistoriesFilterMode(tag.Name, Models.FilterType.Tag);
}
private void ResetBranchTreeFilterMode(List<BranchTreeNode> nodes)
{
foreach (var node in nodes)
{
node.FilterMode = Models.FilterMode.None;
if (!node.IsBranch)
ResetBranchTreeFilterMode(node.Children);
}
}
private void ResetTagFilterMode()
{
foreach (var tag in _tags)
tag.FilterMode = Models.FilterMode.None;
}
private void UpdateCurrentRevisionFilesForSearchSuggestion()
{
_revisionFiles.Clear();
@ -2227,10 +2166,7 @@ namespace SourceGit.ViewModels
private List<Models.Submodule> _visibleSubmodules = new List<Models.Submodule>();
private bool _includeUntracked = true;
private InProgressContext _inProgressContext = null;
private bool _hasUnsolvedConflicts = false;
private Models.Commit _searchResultSelectedCommit = null;
private Timer _autoFetchTimer = null;
private DateTime _lastFetchTime = DateTime.MinValue;
}

View file

@ -22,16 +22,6 @@ namespace SourceGit.ViewModels
get => Tag == null;
}
public bool IsFiltered
{
get => Tag?.IsFiltered ?? false;
set
{
if (Tag != null)
Tag.IsFiltered = value;
}
}
public bool IsExpanded
{
get => _isExpanded;

View file

@ -56,6 +56,18 @@ namespace SourceGit.ViewModels
}
}
public bool HasUnsolvedConflicts
{
get => _hasUnsolvedConflicts;
set => SetProperty(ref _hasUnsolvedConflicts, value);
}
public InProgressContext InProgressContext
{
get => _inProgressContext;
private set => SetProperty(ref _inProgressContext, value);
}
public bool IsStaging
{
get => _isStaging;
@ -191,6 +203,7 @@ namespace SourceGit.ViewModels
public void Cleanup()
{
_repo = null;
_inProgressContext = null;
_selectedUnstaged.Clear();
OnPropertyChanged(nameof(SelectedUnstaged));
@ -208,7 +221,7 @@ namespace SourceGit.ViewModels
_commitMessage = string.Empty;
}
public bool SetData(List<Models.Change> changes)
public void SetData(List<Models.Change> changes)
{
if (!IsChanged(_cached, changes))
{
@ -221,9 +234,22 @@ namespace SourceGit.ViewModels
SetDetail(_selectedStaged[0], false);
else
SetDetail(null, false);
var inProgress = null as InProgressContext;
if (File.Exists(Path.Combine(_repo.GitDir, "CHERRY_PICK_HEAD")))
inProgress = new CherryPickInProgress(_repo.FullPath);
else if (File.Exists(Path.Combine(_repo.GitDir, "REBASE_HEAD")) && Directory.Exists(Path.Combine(_repo.GitDir, "rebase-merge")))
inProgress = new RebaseInProgress(_repo);
else if (File.Exists(Path.Combine(_repo.GitDir, "REVERT_HEAD")))
inProgress = new RevertInProgress(_repo.FullPath);
else if (File.Exists(Path.Combine(_repo.GitDir, "MERGE_HEAD")))
inProgress = new MergeInProgress(_repo.FullPath);
HasUnsolvedConflicts = _cached.Find(x => x.IsConflit) != null;
InProgressContext = inProgress;
});
return _cached.Find(x => x.IsConflit) != null;
return;
}
_cached = changes;
@ -268,6 +294,7 @@ namespace SourceGit.ViewModels
Dispatcher.UIThread.Invoke(() =>
{
_isLoadingData = true;
HasUnsolvedConflicts = hasConflict;
Unstaged = unstaged;
Staged = staged;
SelectedUnstaged = selectedUnstaged;
@ -281,6 +308,18 @@ namespace SourceGit.ViewModels
else
SetDetail(null, false);
var inProgress = null as InProgressContext;
if (File.Exists(Path.Combine(_repo.GitDir, "CHERRY_PICK_HEAD")))
inProgress = new CherryPickInProgress(_repo.FullPath);
else if (File.Exists(Path.Combine(_repo.GitDir, "REBASE_HEAD")) && Directory.Exists(Path.Combine(_repo.GitDir, "rebase-merge")))
inProgress = new RebaseInProgress(_repo);
else if (File.Exists(Path.Combine(_repo.GitDir, "REVERT_HEAD")))
inProgress = new RevertInProgress(_repo.FullPath);
else if (File.Exists(Path.Combine(_repo.GitDir, "MERGE_HEAD")))
inProgress = new MergeInProgress(_repo.FullPath);
InProgressContext = inProgress;
// Try to load merge message from MERGE_MSG
if (string.IsNullOrEmpty(_commitMessage))
{
@ -289,8 +328,6 @@ namespace SourceGit.ViewModels
CommitMessage = File.ReadAllText(mergeMsgFile);
}
});
return hasConflict;
}
public void OpenAssumeUnchanged()
@ -403,6 +440,52 @@ namespace SourceGit.ViewModels
}
}
public void ContinueMerge()
{
if (_inProgressContext != null)
{
_repo.SetWatcherEnabled(false);
Task.Run(() =>
{
var succ = _inProgressContext.Continue();
Dispatcher.UIThread.Invoke(() =>
{
if (succ)
CommitMessage = string.Empty;
_repo.SetWatcherEnabled(true);
});
});
}
else
{
_repo.MarkWorkingCopyDirtyManually();
}
}
public void AbortMerge()
{
if (_inProgressContext != null)
{
_repo.SetWatcherEnabled(false);
Task.Run(() =>
{
var succ = _inProgressContext.Abort();
Dispatcher.UIThread.Invoke(() =>
{
if (succ)
CommitMessage = string.Empty;
_repo.SetWatcherEnabled(true);
});
});
}
else
{
_repo.MarkWorkingCopyDirtyManually();
}
}
public void Commit()
{
DoCommit(false, false, false);
@ -1475,5 +1558,8 @@ namespace SourceGit.ViewModels
private int _count = 0;
private object _detailContext = null;
private string _commitMessage = string.Empty;
private bool _hasUnsolvedConflicts = false;
private InProgressContext _inProgressContext = null;
}
}

View file

@ -24,6 +24,10 @@
<Style Selector="ListBoxItem" x:DataType="vm:BranchTreeNode">
<Setter Property="CornerRadius" Value="{Binding CornerRadius}"/>
</Style>
<Style Selector="ListBoxItem:pointerover v|FilterModeSwitchButton">
<Setter Property="IsNoneVisible" Value="True"/>
</Style>
</ListBox.Styles>
<ListBox.ItemTemplate>
@ -67,15 +71,10 @@
Foreground="{DynamicResource Brush.BadgeFG}"
Background="{DynamicResource Brush.Badge}"/>
<!-- Filter Toggle Button -->
<ToggleButton Grid.Column="3"
Classes="filter"
Margin="0,0,8,0"
Background="Transparent"
IsVisible="{Binding IsBranch}"
IsChecked="{Binding IsFiltered}"
Click="OnToggleFilterClicked"
ToolTip.Tip="{DynamicResource Text.Filter}"/>
<!-- Filter Mode Switcher -->
<v:FilterModeSwitchButton Grid.Column="3"
Margin="0,0,8,0"
Mode="{Binding FilterMode}"/>
</Grid>
</Grid>
</DataTemplate>

View file

@ -428,28 +428,6 @@ namespace SourceGit.Views
}
}
private void OnToggleFilterClicked(object sender, RoutedEventArgs e)
{
if (DataContext is ViewModels.Repository repo &&
sender is ToggleButton toggle &&
toggle.DataContext is ViewModels.BranchTreeNode { Backend: Models.Branch branch } node)
{
bool filtered = toggle.IsChecked == true;
List<string> filters = [branch.FullName];
if (branch.IsLocal && !string.IsNullOrEmpty(branch.Upstream))
{
filters.Add(branch.Upstream);
node.IsFiltered = filtered;
UpdateUpstreamFilterState(repo.RemoteBranchTrees, branch.Upstream, filtered);
}
repo.UpdateFilters(filters, filtered);
}
e.Handled = true;
}
private void MakeRows(List<ViewModels.BranchTreeNode> rows, List<ViewModels.BranchTreeNode> nodes, int depth)
{
foreach (var node in nodes)
@ -477,23 +455,6 @@ namespace SourceGit.Views
CollectBranchesInNode(outs, sub);
}
private bool UpdateUpstreamFilterState(List<ViewModels.BranchTreeNode> collection, string upstream, bool isFiltered)
{
foreach (var node in collection)
{
if (node.Backend is Models.Branch b && b.FullName == upstream)
{
node.IsFiltered = isFiltered;
return true;
}
if (node.Backend is Models.Remote r && upstream.StartsWith($"refs/remotes/{r.Name}/", StringComparison.Ordinal))
return UpdateUpstreamFilterState(node.Children, upstream, isFiltered);
}
return false;
}
private bool _disableSelectionChangingEvent = false;
}
}

View file

@ -0,0 +1,32 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="using:SourceGit.Models"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.FilterModeSwitchButton"
x:Name="ThisControl">
<Button Classes="icon_button"
Width="12" Height="12"
Padding="0"
Background="Transparent"
VerticalContentAlignment="Center"
Click="OnChangeFilterModeButtonClicked">
<Grid>
<Path Width="12" Height="12"
Data="{StaticResource Icons.Eye}"
Fill="{DynamicResource Brush.FG2}"
IsVisible="{Binding #ThisControl.Mode, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:FilterMode.None}}"/>
<Path Width="12" Height="12"
Data="{StaticResource Icons.Filter}"
Fill="{DynamicResource Brush.Accent}"
IsVisible="{Binding #ThisControl.Mode, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:FilterMode.Included}}"/>
<Path Width="12" Height="12"
Data="{StaticResource Icons.EyeClose}"
Fill="{DynamicResource Brush.Accent}"
IsVisible="{Binding #ThisControl.Mode, Converter={x:Static ObjectConverters.Equal}, ConverterParameter={x:Static m:FilterMode.Excluded}}"/>
</Grid>
</Button>
</UserControl>

View file

@ -0,0 +1,277 @@
using System;
using System.Collections.Generic;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.VisualTree;
namespace SourceGit.Views
{
public partial class FilterModeSwitchButton : UserControl
{
public static readonly StyledProperty<Models.FilterMode> ModeProperty =
AvaloniaProperty.Register<FilterModeSwitchButton, Models.FilterMode>(nameof(Mode));
public Models.FilterMode Mode
{
get => GetValue(ModeProperty);
set => SetValue(ModeProperty, value);
}
public static readonly StyledProperty<bool> IsNoneVisibleProperty =
AvaloniaProperty.Register<FilterModeSwitchButton, bool>(nameof(IsNoneVisible));
public bool IsNoneVisible
{
get => GetValue(IsNoneVisibleProperty);
set => SetValue(IsNoneVisibleProperty, value);
}
public static readonly StyledProperty<bool> IsContextMenuOpeningProperty =
AvaloniaProperty.Register<FilterModeSwitchButton, bool>(nameof(IsContextMenuOpening));
public bool IsContextMenuOpening
{
get => GetValue(IsContextMenuOpeningProperty);
set => SetValue(IsContextMenuOpeningProperty, value);
}
public FilterModeSwitchButton()
{
IsVisible = false;
InitializeComponent();
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property == ModeProperty ||
change.Property == IsNoneVisibleProperty ||
change.Property == IsContextMenuOpeningProperty)
{
var visible = (Mode != Models.FilterMode.None || IsNoneVisible || IsContextMenuOpening);
SetCurrentValue(IsVisibleProperty, visible);
}
}
private void OnChangeFilterModeButtonClicked(object sender, RoutedEventArgs e)
{
var repoView = this.FindAncestorOfType<Repository>();
if (repoView == null)
return;
var repo = repoView.DataContext as ViewModels.Repository;
if (repo == null)
return;
var button = sender as Button;
if (button == null)
return;
var menu = new ContextMenu();
var mode = Models.FilterMode.None;
if (DataContext is Models.Tag tag)
{
mode = tag.FilterMode;
if (mode != Models.FilterMode.None)
{
var unset = new MenuItem();
unset.Header = App.Text("Repository.FilterCommits.Default");
unset.Click += (_, ev) =>
{
UpdateTagFilterMode(repo, tag, Models.FilterMode.None);
ev.Handled = true;
};
menu.Items.Add(unset);
menu.Items.Add(new MenuItem() { Header = "-" });
}
var include = new MenuItem();
include.Icon = App.CreateMenuIcon("Icons.Filter");
include.Header = App.Text("Repository.FilterCommits.Include");
include.IsEnabled = mode != Models.FilterMode.Included;
include.Click += (_, ev) =>
{
UpdateTagFilterMode(repo, tag, Models.FilterMode.Included);
ev.Handled = true;
};
var exclude = new MenuItem();
exclude.Icon = App.CreateMenuIcon("Icons.EyeClose");
exclude.Header = App.Text("Repository.FilterCommits.Exclude");
exclude.IsEnabled = mode != Models.FilterMode.Excluded;
exclude.Click += (_, ev) =>
{
UpdateTagFilterMode(repo, tag, Models.FilterMode.Excluded);
ev.Handled = true;
};
menu.Items.Add(include);
menu.Items.Add(exclude);
}
else if (DataContext is ViewModels.BranchTreeNode node)
{
mode = node.FilterMode;
if (mode != Models.FilterMode.None)
{
var unset = new MenuItem();
unset.Header = App.Text("Repository.FilterCommits.Default");
unset.Click += (_, ev) =>
{
UpdateBranchFilterMode(repo, node, Models.FilterMode.None);
ev.Handled = true;
};
menu.Items.Add(unset);
menu.Items.Add(new MenuItem() { Header = "-" });
}
var include = new MenuItem();
include.Icon = App.CreateMenuIcon("Icons.Filter");
include.Header = App.Text("Repository.FilterCommits.Include");
include.IsEnabled = mode != Models.FilterMode.Included;
include.Click += (_, ev) =>
{
UpdateBranchFilterMode(repo, node, Models.FilterMode.Included);
ev.Handled = true;
};
var exclude = new MenuItem();
exclude.Icon = App.CreateMenuIcon("Icons.EyeClose");
exclude.Header = App.Text("Repository.FilterCommits.Exclude");
exclude.IsEnabled = mode != Models.FilterMode.Excluded;
exclude.Click += (_, ev) =>
{
UpdateBranchFilterMode(repo, node, Models.FilterMode.Excluded);
ev.Handled = true;
};
menu.Items.Add(include);
menu.Items.Add(exclude);
}
if (mode == Models.FilterMode.None)
{
IsContextMenuOpening = true;
menu.Closed += (_, _) => IsContextMenuOpening = false;
}
menu.Open(button);
e.Handled = true;
}
private void UpdateTagFilterMode(ViewModels.Repository repo, Models.Tag tag, Models.FilterMode mode)
{
var changed = repo.Settings.UpdateHistoriesFilter(tag.Name, Models.FilterType.Tag, mode);
repo.MarkHistoriesFilterDirty();
}
private void UpdateBranchFilterMode(ViewModels.Repository repo, ViewModels.BranchTreeNode node, Models.FilterMode mode)
{
var isLocal = node.Path.StartsWith("refs/heads/", StringComparison.Ordinal);
var type = isLocal ? Models.FilterType.LocalBranch : Models.FilterType.RemoteBranch;
var tree = isLocal ? repo.LocalBranchTrees : repo.RemoteBranchTrees;
if (node.Backend is Models.Branch branch)
{
var changed = repo.Settings.UpdateHistoriesFilter(node.Path, type, mode);
if (!changed)
return;
// Try to update its upstream.
if (isLocal && !string.IsNullOrEmpty(branch.Upstream) && mode != Models.FilterMode.Excluded)
{
var upstream = branch.Upstream;
var canUpdateUpstream = true;
foreach (var filter in repo.Settings.HistoriesFilters)
{
bool matched = false;
if (filter.Type == Models.FilterType.RemoteBranch)
matched = filter.Pattern.Equals(upstream, StringComparison.Ordinal);
else if (filter.Type == Models.FilterType.RemoteBranchFolder)
matched = upstream.StartsWith(filter.Pattern, StringComparison.Ordinal);
if (matched && filter.Mode == Models.FilterMode.Excluded)
{
canUpdateUpstream = false;
break;
}
}
if (canUpdateUpstream)
repo.Settings.UpdateHistoriesFilter(upstream, Models.FilterType.RemoteBranch, mode);
}
}
else
{
var changed = repo.Settings.UpdateHistoriesFilter(node.Path, isLocal ? Models.FilterType.LocalBranchFolder : Models.FilterType.RemoteBranchFolder, mode);
if (!changed)
return;
ResetChildrenBranchNodeFilterMode(repo, node, isLocal);
}
var parentType = isLocal ? Models.FilterType.LocalBranchFolder : Models.FilterType.RemoteBranchFolder;
var cur = node;
do
{
var lastSepIdx = cur.Path.LastIndexOf('/');
if (lastSepIdx <= 0)
break;
var parentPath = cur.Path.Substring(0, lastSepIdx);
var parent = FindBranchNode(tree, parentPath);
if (parent == null)
break;
repo.Settings.UpdateHistoriesFilter(parent.Path, parentType, Models.FilterMode.None);
cur = parent;
} while (true);
repo.MarkHistoriesFilterDirty();
}
private void ResetChildrenBranchNodeFilterMode(ViewModels.Repository repo, ViewModels.BranchTreeNode node, bool isLocal)
{
foreach (var child in node.Children)
{
if (child.IsBranch)
{
var type = isLocal ? Models.FilterType.LocalBranch : Models.FilterType.RemoteBranch;
repo.Settings.UpdateHistoriesFilter(child.Path, type, Models.FilterMode.None);
}
else
{
var type = isLocal ? Models.FilterType.LocalBranchFolder : Models.FilterType.RemoteBranchFolder;
repo.Settings.UpdateHistoriesFilter(child.Path, type, Models.FilterMode.None);
ResetChildrenBranchNodeFilterMode(repo, child, isLocal);
}
}
}
private ViewModels.BranchTreeNode FindBranchNode(List<ViewModels.BranchTreeNode> nodes, string path)
{
foreach (var node in nodes)
{
if (node.Path.Equals(path, StringComparison.Ordinal))
return node;
if (path.StartsWith(node.Path, StringComparison.Ordinal))
{
var founded = FindBranchNode(node.Children, path);
if (founded != null)
return founded;
}
}
return null;
}
}
}

View file

@ -524,7 +524,7 @@
<!-- Right -->
<Grid Grid.Column="2" RowDefinitions="Auto,Auto,*">
<Grid Grid.Row="0" Height="28" ColumnDefinitions="*,Auto,Auto,Auto" Background="{DynamicResource Brush.Conflict}" IsVisible="{Binding InProgressContext, Converter={x:Static ObjectConverters.IsNotNull}}">
<Grid Grid.Row="0" Height="28" ColumnDefinitions="*,Auto,Auto" Background="{DynamicResource Brush.Conflict}" IsVisible="{Binding InProgressContext, Converter={x:Static ObjectConverters.IsNotNull}}">
<ContentControl Grid.Column="0" Margin="8,0" Content="{Binding InProgressContext}">
<ContentControl.DataTemplates>
<DataTemplate DataType="vm:CherryPickInProgress">
@ -557,14 +557,6 @@
</Button.IsVisible>
</Button>
<Button Grid.Column="2"
Classes="flat primary"
FontWeight="Regular"
BorderThickness="0"
Content="{DynamicResource Text.Repository.Continue}"
Padding="8,0" Margin="4,0"
Command="{Binding ContinueMerge}"
IsVisible="{Binding !HasUnsolvedConflicts}"/>
<Button Grid.Column="3"
Classes="flat"
FontWeight="Regular"
BorderThickness="0"
@ -577,14 +569,18 @@
<Border.IsVisible>
<MultiBinding Converter="{x:Static BoolConverters.And}">
<Binding Path="SelectedViewIndex" Converter="{x:Static c:IntConverters.IsZero}"/>
<Binding Path="Settings.Filters.Count" Converter="{x:Static c:IntConverters.IsGreaterThanZero}"/>
<Binding Path="Settings.HistoriesFilters.Count" Converter="{x:Static c:IntConverters.IsGreaterThanZero}"/>
</MultiBinding>
</Border.IsVisible>
<Grid Height="28" ColumnDefinitions="Auto,*,Auto">
<TextBlock Grid.Column="0" Margin="8,0,0,0" Classes="table_header" Text="{DynamicResource Text.Repository.FilterCommitPrefix}"/>
<ItemsControl Grid.Column="1" Margin="8,0,0,0" ItemsSource="{Binding Settings.Filters}">
<Path Grid.Column="0"
x:Name="HistoriesFilterModeIcon"
Margin="8,0,0,0"
Width="14" Height="14"
Fill="{DynamicResource Brush.FG2}"/>
<ItemsControl Grid.Column="1" Margin="8,0,0,0" ItemsSource="{Binding Settings.HistoriesFilters}" LayoutUpdated="OnHistoriesFiltersLayoutUpdated">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" VerticalAlignment="Center"/>
@ -592,9 +588,17 @@
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Height="20" Margin="0,0,6,0" BorderThickness="1" BorderBrush="{DynamicResource Brush.Border2}" CornerRadius="12">
<TextBlock Classes="primary" Text="{Binding Converter={x:Static c:StringConverters.TrimRefsPrefix}}" Margin="8,0"/>
<DataTemplate DataType="m:Filter">
<Border Height="20"
Margin="0,0,6,0"
CornerRadius="12"
BorderThickness="1"
BorderBrush="{Binding Mode, Converter={x:Static c:FilterModeConverters.ToBorderBrush}}">
<StackPanel Orientation="Horizontal" Margin="8,0">
<Path Width="10" Height="10" Data="{StaticResource Icons.Branch}" IsVisible="{Binding IsBranch}"/>
<Path Width="10" Height="10" Data="{StaticResource Icons.Tag}" IsVisible="{Binding !IsBranch}"/>
<TextBlock Classes="primary" Text="{Binding Pattern, Converter={x:Static c:StringConverters.TrimRefsPrefix}}" Margin="4,0,0,0"/>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>

View file

@ -395,5 +395,40 @@ namespace SourceGit.Views
}
e.Handled = true;
}
private void OnHistoriesFiltersLayoutUpdated(object sender, EventArgs e)
{
var repo = DataContext as ViewModels.Repository;
if (repo == null)
return;
var filters = repo.Settings.HistoriesFilters;
if (filters.Count == 0)
return;
var mode = filters[0].Mode;
if (mode == _lastFilterMode)
return;
_lastFilterMode = mode;
var icon = null as StreamGeometry;
switch (mode)
{
case Models.FilterMode.Included:
icon = this.FindResource("Icons.Filter") as StreamGeometry;
break;
case Models.FilterMode.Excluded:
icon = this.FindResource("Icons.EyeClose") as StreamGeometry;
break;
default:
break;
}
if (icon != null)
HistoriesFilterModeIcon.Data = icon;
}
private Models.FilterMode _lastFilterMode = Models.FilterMode.None;
}
}

View file

@ -12,6 +12,10 @@
<Style Selector="ListBoxItem">
<Setter Property="CornerRadius" Value="4"/>
</Style>
<Style Selector="ListBoxItem:pointerover v|FilterModeSwitchButton">
<Setter Property="IsNoneVisible" Value="True"/>
</Style>
</UserControl.Styles>
<UserControl.DataTemplates>
@ -43,15 +47,14 @@
Classes="primary"
Text="{Binding FullPath, Converter={x:Static c:PathConverters.PureFileName}}"
Margin="8,0,0,0"/>
<ToggleButton Grid.Column="3"
Classes="filter"
Margin="0,0,8,0"
Background="Transparent"
Click="OnToggleFilterClicked"
IsChecked="{Binding IsFiltered, Mode=TwoWay}"
IsVisible="{Binding !IsFolder}"
ToolTip.Tip="{DynamicResource Text.Filter}"/>
<ContentControl Grid.Column="3" Content="{Binding Tag}">
<ContentControl.DataTemplates>
<DataTemplate DataType="m:Tag">
<v:FilterModeSwitchButton Mode="{Binding FilterMode}"/>
</DataTemplate>
</ContentControl.DataTemplates>
</ContentControl>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
@ -60,33 +63,28 @@
<DataTemplate DataType="vm:TagCollectionAsList">
<ListBox Classes="repo_left_content_list"
Margin="12,0,0,0"
Margin="8,0,0,0"
ItemsSource="{Binding Tags}"
SelectionMode="Single"
SelectionChanged="OnRowSelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate DataType="m:Tag">
<Grid ColumnDefinitions="Auto,*,Auto"
<Grid ColumnDefinitions="Auto,*,20"
Background="Transparent"
ContextRequested="OnRowContextRequested"
ToolTip.Tip="{Binding Message}">
<Path Grid.Column="0"
Margin="4,0,0,0"
Margin="8,0,0,0"
Width="12" Height="12"
Data="{StaticResource Icons.Tag}"/>
<TextBlock Grid.Column="1"
Classes="primary"
Text="{Binding Name}"
Margin="8,0,0,0"/>
Margin="8,0,0,0"
TextTrimming="CharacterEllipsis"/>
<ToggleButton Grid.Column="2"
Classes="filter"
Margin="0,0,8,0"
Background="Transparent"
Click="OnToggleFilterClicked"
IsChecked="{Binding IsFiltered, Mode=TwoWay}"
ToolTip.Tip="{DynamicResource Text.Filter}"/>
<v:FilterModeSwitchButton Grid.Column="2" Mode="{Binding FilterMode}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>

View file

@ -247,23 +247,6 @@ namespace SourceGit.Views
}
}
private void OnToggleFilterClicked(object sender, RoutedEventArgs e)
{
if (sender is ToggleButton toggle && DataContext is ViewModels.Repository repo)
{
var target = null as Models.Tag;
if (toggle.DataContext is ViewModels.TagTreeNode node)
target = node.Tag;
else if (toggle.DataContext is Models.Tag tag)
target = tag;
if (target != null)
repo.UpdateFilters([target.Name], toggle.IsChecked == true);
}
e.Handled = true;
}
private void MakeTreeRows(List<ViewModels.TagTreeNode> rows, List<ViewModels.TagTreeNode> nodes)
{
foreach (var node in nodes)

View file

@ -239,10 +239,21 @@
Margin="8,0,0,0"
HorizontalAlignment="Left"
IsChecked="{Binding UseAmend, Mode=TwoWay}"
IsVisible="{Binding InProgressContext, Converter={x:Static ObjectConverters.IsNull}}"
Content="{DynamicResource Text.WorkingCopy.Amend}"/>
<v:LoadingIcon Grid.Column="5" Width="18" Height="18" IsVisible="{Binding IsCommitting}"/>
<Button Grid.Column="6"
Classes="flat primary"
Content="{DynamicResource Text.Repository.Continue}"
Height="28"
Margin="8,0,0,0"
Padding="8,0"
Command="{Binding ContinueMerge}"
IsVisible="{Binding InProgressContext, Converter={x:Static ObjectConverters.IsNotNull}}"
IsEnabled="{Binding !HasUnsolvedConflicts}"/>
<Button Grid.Column="6"
Classes="flat primary"
Content="{DynamicResource Text.WorkingCopy.Commit}"
@ -251,6 +262,7 @@
Padding="8,0"
Command="{Binding Commit}"
HotKey="{OnPlatform Ctrl+Enter, macOS=⌘+Enter}"
IsVisible="{Binding InProgressContext, Converter={x:Static ObjectConverters.IsNull}}"
ToolTip.Placement="Top"
ToolTip.VerticalOffset="0">
<ToolTip.Tip>