diff --git a/.editorconfig b/.editorconfig
index 3ad9d05b..83b15884 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -293,6 +293,10 @@ end_of_line = lf
[*.{cmd,bat}]
end_of_line = crlf
+# Package manifests
+[{*.spec,control}]
+end_of_line = lf
+
# YAML files
[*.{yml,yaml}]
indent_size = 2
diff --git a/.gitattributes b/.gitattributes
index 7410eb08..bd1dfea9 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -3,10 +3,12 @@
*.png binary
*.ico binary
*.sh text eol=lf
+*.spec text eol=lf
+control text eol=lf
*.bat text eol=crlf
*.cmd text eol=crlf
*.ps1 text eol=crlf
*.json text
.gitattributes export-ignore
-.gitignore export-ignore
\ No newline at end of file
+.gitignore export-ignore
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index ad62efb6..d4117364 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -32,7 +32,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
- dotnet-version: 8.0.x
+ dotnet-version: 9.0.x
- name: Configure arm64 packages
if: ${{ matrix.runtime == 'linux-arm64' }}
run: |
diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml
index 53affe3d..e973c1ab 100644
--- a/.github/workflows/package.yml
+++ b/.github/workflows/package.yml
@@ -3,7 +3,7 @@ on:
workflow_call:
inputs:
version:
- description: Source Git package version
+ description: SourceGit package version
required: true
type: string
jobs:
diff --git a/README.md b/README.md
index e464f74c..d49fb1e4 100644
--- a/README.md
+++ b/README.md
@@ -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-98.70%25-yellow)](TRANSLATION.md) [![es__ES](https://img.shields.io/badge/es__ES-100.00%25-brightgreen)](TRANSLATION.md) [![fr__FR](https://img.shields.io/badge/fr__FR-86.58%25-yellow)](TRANSLATION.md) [![pt__BR](https://img.shields.io/badge/pt__BR-100.00%25-brightgreen)](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-100.00%25-brightgreen)](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-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)
## How to Use
diff --git a/SourceGit.sln b/SourceGit.sln
index 9799a09e..9c5fcdb1 100644
--- a/SourceGit.sln
+++ b/SourceGit.sln
@@ -13,6 +13,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{F45A
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{67B6D05F-A000-40BA-ADB4-C9065F880D7B}"
ProjectSection(SolutionItems) = preProject
+ .github\workflows\build.yml = .github\workflows\build.yml
.github\workflows\ci.yml = .github\workflows\ci.yml
.github\workflows\package.yml = .github\workflows\package.yml
.github\workflows\release.yml = .github\workflows\release.yml
diff --git a/TRANSLATION.md b/TRANSLATION.md
index 587ba99a..5967d21e 100644
--- a/TRANSLATION.md
+++ b/TRANSLATION.md
@@ -1,22 +1,4 @@
-### de_DE.axaml: 98.70%
-
-
-
-Missing Keys
-
-- Text.Diff.SaveAsPatch
-- Text.Diff.VisualLines.All
-- Text.Hotkeys.Repo.CreateBranchOnCommit
-- Text.Hotkeys.Repo.Fetch
-- Text.Hotkeys.Repo.Pull
-- Text.Hotkeys.Repo.Push
-- Text.IssueLinkCM.OpenInBrowser
-- Text.IssueLinkCM.CopyLink
-- Text.Preference.Appearance.EditorFontSize
-
-
-
-### es_ES.axaml: 100.00%
+### de_DE.axaml: 100.00%
@@ -26,115 +8,53 @@
-### fr_FR.axaml: 86.58%
+### es_ES.axaml: 99.14%
+
+
+
+Missing Keys
+
+- 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
+
+
+
+### fr_FR.axaml: 98.42%
Missing Keys
-- 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.EditorFontSize
-- Text.Preference.General.ShowAuthorTime
-- Text.Preference.Integration
-- Text.Preference.Shell
-- Text.Preference.Shell.Type
-- Text.Preference.Shell.Path
-- Text.Repository.AutoFetching
+- Text.Preference.Appearance.FontSize
+- Text.Preference.Appearance.FontSize.Default
+- Text.Preference.Appearance.FontSize.Editor
- 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
-### pt_BR.axaml: 100.00%
+### pt_BR.axaml: 99.14%
Missing Keys
-
+- 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
diff --git a/VERSION b/VERSION
index 833d11c8..fb6559a3 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-8.38
\ No newline at end of file
+8.39
\ No newline at end of file
diff --git a/build/resources/_common/applications/sourcegit.desktop b/build/resources/_common/applications/sourcegit.desktop
index ff7ef135..bcf9c813 100644
--- a/build/resources/_common/applications/sourcegit.desktop
+++ b/build/resources/_common/applications/sourcegit.desktop
@@ -1,5 +1,5 @@
[Desktop Entry]
-Name=Source Git
+Name=SourceGit
Comment=Open-source & Free Git GUI Client
Exec=/opt/sourcegit/sourcegit
Icon=/usr/share/icons/sourcegit.png
diff --git a/build/resources/rpm/SPECS/build.spec b/build/resources/rpm/SPECS/build.spec
index 9dda5f96..d31b6587 100644
--- a/build/resources/rpm/SPECS/build.spec
+++ b/build/resources/rpm/SPECS/build.spec
@@ -5,8 +5,8 @@ Summary: Open-source & Free Git Gui Client
License: MIT
URL: https://sourcegit-scm.github.io/
Source: https://github.com/sourcegit-scm/sourcegit/archive/refs/tags/v%_version.tar.gz
-Requires: (libX11 or libX11-6)
-Requires: (libSM or libSM6)
+Requires: libX11.so.6()(%{__isa_bits}bit)
+Requires: libSM.so.6()(%{__isa_bits}bit)
%define _build_id_links none
diff --git a/build/scripts/package.linux.sh b/build/scripts/package.linux.sh
index 5ffd5a27..5abb058b 100755
--- a/build/scripts/package.linux.sh
+++ b/build/scripts/package.linux.sh
@@ -5,16 +5,6 @@ set -o
set -u
set pipefail
-if [[ -z "$VERSION" ]]; then
- echo "Provide the version as environment variable VERSION"
- exit 1
-fi
-
-if [[ -z "$RUNTIME" ]]; then
- echo "Provide the runtime as environment variable RUNTIME"
- exit 1
-fi
-
arch=
appimage_arch=
target=
diff --git a/build/scripts/package.osx-app.sh b/build/scripts/package.osx-app.sh
index 4a50a860..2d43e24a 100755
--- a/build/scripts/package.osx-app.sh
+++ b/build/scripts/package.osx-app.sh
@@ -5,16 +5,6 @@ set -o
set -u
set pipefail
-if [[ -z "$VERSION" ]]; then
- echo "Provide the version as environment variable VERSION"
- exit 1
-fi
-
-if [[ -z "$RUNTIME" ]]; then
- echo "Provide the runtime as environment variable RUNTIME"
- exit 1
-fi
-
cd build
mkdir -p SourceGit.app/Contents/Resources
diff --git a/build/scripts/package.windows-portable.sh b/build/scripts/package.windows-portable.sh
index 9ba29216..6bd3879b 100755
--- a/build/scripts/package.windows-portable.sh
+++ b/build/scripts/package.windows-portable.sh
@@ -5,16 +5,6 @@ set -o
set -u
set pipefail
-if [[ -z "$VERSION" ]]; then
- echo "Provide the version as environment variable VERSION"
- exit 1
-fi
-
-if [[ -z "$RUNTIME" ]]; then
- echo "Provide the runtime as environment variable RUNTIME"
- exit 1
-fi
-
cd build
rm -rf SourceGit/*.pdb
diff --git a/global.json b/global.json
index b5b37b60..a27a2b82 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
- "version": "8.0.0",
+ "version": "9.0.0",
"rollForward": "latestMajor",
"allowPrerelease": false
}
diff --git a/src/App.axaml.cs b/src/App.axaml.cs
index dfec763b..0615724a 100644
--- a/src/App.axaml.cs
+++ b/src/App.axaml.cs
@@ -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;
}
diff --git a/src/Commands/Branch.cs b/src/Commands/Branch.cs
index 890b54ee..4ec8da82 100644
--- a/src/Commands/Branch.cs
+++ b/src/Commands/Branch.cs
@@ -48,8 +48,18 @@
var cmd = new Command();
cmd.WorkingDirectory = repo;
cmd.Context = repo;
- cmd.SSHKey = new Config(repo).Get($"remote.{remote}.sshkey");
- cmd.Args = $"push {remote} --delete {name}";
+
+ bool exists = new Remote(repo).HasBranch(remote, name);
+ if (exists)
+ {
+ cmd.SSHKey = new Config(repo).Get($"remote.{remote}.sshkey");
+ cmd.Args = $"push {remote} --delete {name}";
+ }
+ else
+ {
+ cmd.Args = $"branch -D -r {remote}/{name}";
+ }
+
return cmd.Exec();
}
}
diff --git a/src/Commands/Diff.cs b/src/Commands/Diff.cs
index 04103d68..dea15592 100644
--- a/src/Commands/Diff.cs
+++ b/src/Commands/Diff.cs
@@ -28,9 +28,9 @@ namespace SourceGit.Commands
Context = repo;
if (ignoreWhitespace)
- Args = $"diff --patch --ignore-cr-at-eol --ignore-all-space --unified={unified} {opt}";
+ Args = $"diff --no-ext-diff --patch --ignore-cr-at-eol --ignore-all-space --unified={unified} {opt}";
else
- Args = $"diff --patch --ignore-cr-at-eol --unified={unified} {opt}";
+ Args = $"diff --no-ext-diff --patch --ignore-cr-at-eol --unified={unified} {opt}";
}
public Models.DiffResult Result()
@@ -129,7 +129,7 @@ namespace SourceGit.Commands
_oldLine = int.Parse(match.Groups[1].Value);
_newLine = int.Parse(match.Groups[2].Value);
_result.TextDiff.Lines.Add(new Models.TextDiffLine(Models.TextDiffLineType.Indicator, line, 0, 0));
- }
+ }
}
else
{
diff --git a/src/Commands/ExecuteCustomAction.cs b/src/Commands/ExecuteCustomAction.cs
index f5fec82c..4981b2f9 100644
--- a/src/Commands/ExecuteCustomAction.cs
+++ b/src/Commands/ExecuteCustomAction.cs
@@ -44,7 +44,7 @@ namespace SourceGit.Commands
{
outputHandler?.Invoke(e.Data);
builder.AppendLine(e.Data);
- }
+ }
};
try
diff --git a/src/Commands/Fetch.cs b/src/Commands/Fetch.cs
index 08d2d1c6..834cd7fc 100644
--- a/src/Commands/Fetch.cs
+++ b/src/Commands/Fetch.cs
@@ -16,7 +16,7 @@ namespace SourceGit.Commands
if (noTags)
Args += "--no-tags ";
else
- Args += "--force ";
+ Args += "--tags ";
if (prune)
Args += "--prune ";
diff --git a/src/Commands/Remote.cs b/src/Commands/Remote.cs
index f2e8d09e..beaf412b 100644
--- a/src/Commands/Remote.cs
+++ b/src/Commands/Remote.cs
@@ -45,5 +45,14 @@
Args = "remote set-url" + (isPush ? " --push " : " ") + $"{name} {url}";
return Exec();
}
+
+ public bool HasBranch(string remote, string branch)
+ {
+ SSHKey = new Config(WorkingDirectory).Get($"remote.{remote}.sshkey");
+ Args = $"ls-remote {remote} {branch}";
+
+ var rs = ReadToEnd();
+ return rs.IsSuccess && rs.StdOut.Trim().Length > 0;
+ }
}
}
diff --git a/src/Commands/Statistics.cs b/src/Commands/Statistics.cs
index adfcc574..511c43e8 100644
--- a/src/Commands/Statistics.cs
+++ b/src/Commands/Statistics.cs
@@ -4,11 +4,11 @@ namespace SourceGit.Commands
{
public class Statistics : Command
{
- public Statistics(string repo)
+ public Statistics(string repo, int max)
{
WorkingDirectory = repo;
Context = repo;
- Args = $"log --date-order --branches --remotes -40000 --pretty=format:\"%ct$%aN\"";
+ Args = $"log --date-order --branches --remotes -{max} --pretty=format:\"%ct$%aN\"";
}
public Models.Statistics Result()
diff --git a/src/Converters/FilterModeConverters.cs b/src/Converters/FilterModeConverters.cs
new file mode 100644
index 00000000..c486af5e
--- /dev/null
+++ b/src/Converters/FilterModeConverters.cs
@@ -0,0 +1,22 @@
+using Avalonia.Data.Converters;
+using Avalonia.Media;
+
+namespace SourceGit.Converters
+{
+ public static class FilterModeConverters
+ {
+ public static readonly FuncValueConverter ToBorderBrush =
+ new FuncValueConverter(v =>
+ {
+ switch (v)
+ {
+ case Models.FilterMode.Included:
+ return Brushes.Green;
+ case Models.FilterMode.Excluded:
+ return Brushes.Red;
+ default:
+ return Brushes.Transparent;
+ }
+ });
+ }
+}
diff --git a/src/Models/ExternalMerger.cs b/src/Models/ExternalMerger.cs
index b5398835..a09f808c 100644
--- a/src/Models/ExternalMerger.cs
+++ b/src/Models/ExternalMerger.cs
@@ -39,7 +39,7 @@ namespace SourceGit.Models
new ExternalMerger(4, "tortoise_merge", "Tortoise Merge", "TortoiseMerge.exe;TortoiseGitMerge.exe", "-base:\"$BASE\" -theirs:\"$REMOTE\" -mine:\"$LOCAL\" -merged:\"$MERGED\"", "-base:\"$LOCAL\" -theirs:\"$REMOTE\""),
new ExternalMerger(5, "kdiff3", "KDiff3", "kdiff3.exe", "\"$REMOTE\" -b \"$BASE\" \"$LOCAL\" -o \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""),
new ExternalMerger(6, "beyond_compare", "Beyond Compare", "BComp.exe", "\"$REMOTE\" \"$LOCAL\" \"$BASE\" \"$MERGED\"", "\"$LOCAL\" \"$REMOTE\""),
- new ExternalMerger(7, "win_merge", "WinMerge", "WinMergeU.exe", "-u -e \"$REMOTE\" \"$LOCAL\" \"$MERGED\"", "-u -e \"$LOCAL\" \"$REMOTE\""),
+ new ExternalMerger(7, "win_merge", "WinMerge", "WinMergeU.exe", "\"$MERGED\"", "-u -e \"$LOCAL\" \"$REMOTE\""),
new ExternalMerger(8, "codium", "VSCodium", "VSCodium.exe", "-n --wait \"$MERGED\"", "-n --wait --diff \"$LOCAL\" \"$REMOTE\""),
new ExternalMerger(9, "p4merge", "P4Merge", "p4merge.exe", "-tw 4 \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"", "-tw 4 \"$LOCAL\" \"$REMOTE\""),
};
diff --git a/src/Models/Filter.cs b/src/Models/Filter.cs
new file mode 100644
index 00000000..af4569fa
--- /dev/null
+++ b/src/Models/Filter.cs
@@ -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;
+ }
+}
diff --git a/src/Models/OpenAI.cs b/src/Models/OpenAI.cs
index e9c7b5ed..c5ca7449 100644
--- a/src/Models/OpenAI.cs
+++ b/src/Models/OpenAI.cs
@@ -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
diff --git a/src/Models/RepositorySettings.cs b/src/Models/RepositorySettings.cs
index 77c58ee7..f6796198 100644
--- a/src/Models/RepositorySettings.cs
+++ b/src/Models/RepositorySettings.cs
@@ -1,4 +1,8 @@
-using Avalonia.Collections;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using Avalonia.Collections;
namespace SourceGit.Models
{
@@ -76,11 +80,11 @@ namespace SourceGit.Models
set;
} = true;
- public AvaloniaList Filters
+ public AvaloniaList HistoriesFilters
{
get;
set;
- } = new AvaloniaList();
+ } = new AvaloniaList();
public AvaloniaList CommitTemplates
{
@@ -148,6 +152,208 @@ namespace SourceGit.Models
set;
} = "---";
+ public Dictionary CollectHistoriesFilters()
+ {
+ var map = new Dictionary();
+ foreach (var filter in HistoriesFilters)
+ map.Add(filter.Pattern, filter.Mode);
+ return map;
+ }
+
+ 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 void RemoveChildrenBranchFilters(string pattern)
+ {
+ var dirty = new List();
+ var prefix = $"{pattern}/";
+
+ foreach (var filter in HistoriesFilters)
+ {
+ if (filter.Type == FilterType.Tag)
+ continue;
+
+ if (filter.Pattern.StartsWith(prefix, StringComparison.Ordinal))
+ dirty.Add(filter);
+ }
+
+ foreach (var filter in dirty)
+ HistoriesFilters.Remove(filter);
+ }
+
+ public string BuildHistoriesFilter()
+ {
+ var excludedBranches = new List();
+ var excludedRemotes = new List();
+ var excludedTags = new List();
+ var includedBranches = new List();
+ var includedRemotes = new List();
+ var includedTags = new List();
+ 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);
+ }
+ }
+
+ bool hasIncluded = includedBranches.Count > 0 || includedRemotes.Count > 0 || includedTags.Count > 0;
+ bool hasExcluded = excludedBranches.Count > 0 || excludedRemotes.Count > 0 || excludedTags.Count > 0;
+
+ var builder = new StringBuilder();
+ if (hasIncluded)
+ {
+ foreach (var b in includedBranches)
+ {
+ builder.Append("--branches=");
+ builder.Append(b);
+ builder.Append(' ');
+ }
+
+ foreach (var r in includedRemotes)
+ {
+ builder.Append("--remotes=");
+ builder.Append(r);
+ builder.Append(' ');
+ }
+
+ foreach (var t in includedTags)
+ {
+ builder.Append("--tags=");
+ builder.Append(t);
+ builder.Append(' ');
+ }
+ }
+ else if (hasExcluded)
+ {
+ if (excludedBranches.Count > 0)
+ {
+ foreach (var b in excludedBranches)
+ {
+ builder.Append("--exclude=");
+ builder.Append(b);
+ builder.Append(' ');
+ }
+ }
+
+ builder.Append("--exclude=HEA[D] --branches ");
+
+ if (excludedRemotes.Count > 0)
+ {
+ foreach (var r in excludedRemotes)
+ {
+ builder.Append("--exclude=");
+ builder.Append(r);
+ builder.Append(' ');
+ }
+ }
+
+ builder.Append("--exclude=origin/HEA[D] --remotes ");
+
+ if (excludedTags.Count > 0)
+ {
+ foreach (var t in excludedTags)
+ {
+ builder.Append("--exclude=");
+ builder.Append(t);
+ builder.Append(' ');
+ }
+ }
+
+ builder.Append("--tags ");
+ }
+
+ return builder.ToString();
+ }
+
public void PushCommitMessage(string message)
{
var existIdx = CommitMessages.IndexOf(message);
diff --git a/src/Models/ResetMode.cs b/src/Models/ResetMode.cs
index 735533c2..827ccaa9 100644
--- a/src/Models/ResetMode.cs
+++ b/src/Models/ResetMode.cs
@@ -6,23 +6,25 @@ namespace SourceGit.Models
{
public static readonly ResetMode[] Supported =
[
- new ResetMode("Soft", "Keep all changes. Stage differences", "--soft", Brushes.Green),
- new ResetMode("Mixed", "Keep all changes. Unstage differences", "--mixed", Brushes.Orange),
- new ResetMode("Merge", "Reset while keeping unmerged changes", "--merge", Brushes.Purple),
- new ResetMode("Keep", "Reset while keeping local modifications", "--keep", Brushes.Purple),
- new ResetMode("Hard", "Discard all changes", "--hard", Brushes.Red),
+ new ResetMode("Soft", "Keep all changes. Stage differences", "--soft", "S", Brushes.Green),
+ new ResetMode("Mixed", "Keep all changes. Unstage differences", "--mixed", "M", Brushes.Orange),
+ new ResetMode("Merge", "Reset while keeping unmerged changes", "--merge", "G", Brushes.Purple),
+ new ResetMode("Keep", "Reset while keeping local modifications", "--keep", "K", Brushes.Purple),
+ new ResetMode("Hard", "Discard all changes", "--hard", "H", Brushes.Red),
];
public string Name { get; set; }
public string Desc { get; set; }
public string Arg { get; set; }
+ public string Key { get; set; }
public IBrush Color { get; set; }
- public ResetMode(string n, string d, string a, IBrush b)
+ public ResetMode(string n, string d, string a, string k, IBrush b)
{
Name = n;
Desc = d;
Arg = a;
+ Key = k;
Color = b;
}
}
diff --git a/src/Models/Statistics.cs b/src/Models/Statistics.cs
index b669eb55..969d3945 100644
--- a/src/Models/Statistics.cs
+++ b/src/Models/Statistics.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using LiveChartsCore;
using LiveChartsCore.Defaults;
@@ -138,7 +139,8 @@ namespace SourceGit.Models
public Statistics()
{
_today = DateTime.Now.ToLocalTime().Date;
- _thisWeekStart = _today.AddSeconds(-(int)_today.DayOfWeek * 3600 * 24);
+ var weekOffset = (7 + (int)_today.DayOfWeek - (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek) % 7;
+ _thisWeekStart = _today.AddDays(-weekOffset);
_thisMonthStart = _today.AddDays(1 - _today.Day);
All = new StatisticsReport(StaticsticsMode.All, DateTime.MinValue);
diff --git a/src/Models/Tag.cs b/src/Models/Tag.cs
index 2ec9e093..2e8f2c8e 100644
--- a/src/Models/Tag.cs
+++ b/src/Models/Tag.cs
@@ -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;
}
}
diff --git a/src/Models/Watcher.cs b/src/Models/Watcher.cs
index 6665250c..710b307d 100644
--- a/src/Models/Watcher.cs
+++ b/src/Models/Watcher.cs
@@ -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);
}
diff --git a/src/Resources/Locales/de_DE.axaml b/src/Resources/Locales/de_DE.axaml
index d1f43695..200d3638 100644
--- a/src/Resources/Locales/de_DE.axaml
+++ b/src/Resources/Locales/de_DE.axaml
@@ -58,7 +58,7 @@
Lösche alle ausgewählten {0} Branches
Alle Änderungen verwerfen
Fast-Forward zu ${0}$
- Fetche ${0}$ nach ${1}$...
+ Fetche ${0}$ in ${1}$ hinein...
Git Flow - Abschließen ${0}$
Merge ${0}$ in ${1}$ hinein...
Pull ${0}$
@@ -73,7 +73,7 @@
ABBRECHEN
Auf diese Revision zurücksetzen
Auf Vorgänger-Revision zurücksetzen
- Generiere Commit-Nachricht
+ Generiere Commit-Nachricht
ANZEIGE MODUS ÄNDERN
Zeige als Datei- und Ordnerliste
Zeige als Pfadliste
@@ -162,8 +162,8 @@
TICKETSYSTEM
Beispiel für Github-Regel hinzufügen
Beispiel für Jira-Regel hinzufügen
- Beispiel für eine Gitlab Issue Regel einfügen
- Beispiel für einen Gitlab Merge Request einfügen
+ Beispiel für Gitlab Issue Regel einfügen
+ Beispiel für Gitlab Merge Request einfügen
Neue Regel
Ticketnummer Regex-Ausdruck:
Name:
@@ -171,7 +171,7 @@
Verwende bitte $1, $2 um auf Regex-Gruppenwerte zuzugreifen.
OPEN AI
Bevorzugter Service:
- Wenn der 'Bevorzugte Service' aktiviert ist, wird SourceGit nur dieses Repository nutzen. Ansonsten wird, wenn mehrere Services verfügbar sind, eine Kontextmenü zur Auswahl angezeigt.
+ Der ausgewählte 'Bevorzugte Service' wird nur in diesem Repository gesetzt und verwendet. Wenn keiner gesetzt ist und mehrere Servies verfügbar sind wird ein Kontextmenü zur Auswahl angezeigt.
HTTP Proxy
HTTP Proxy für dieses Repository
Benutzername
@@ -240,6 +240,7 @@
Nächste Änderung
KEINE ÄNDERUNG ODER NUR ZEILEN-ENDE ÄNDERUNGEN
Vorherige Änderung
+ Als Patch speichern
Zeige versteckte Symbole
Nebeneinander
SUBMODUL
@@ -248,6 +249,7 @@
Syntax Hervorhebung
Zeilenumbruch
Öffne in Merge Tool
+ Alle Zeilen anzeigen
Weniger Zeilen anzeigen
Mehr Zeilen anzeigen
WÄHLE EINE DATEI AUS UM ÄNDERUNGEN ANZUZEIGEN
@@ -263,7 +265,7 @@
Ziel:
Ausgewählte Gruppe bearbeiten
Ausgewähltes Repository bearbeiten
- Führe benutzerte Aktion aus
+ Führe benutzerdefinierte Aktion aus
Name der Aktion:
Fast-Forward (ohne Auschecken)
Fetch
@@ -290,7 +292,6 @@
Datei Historie
INHALT
ÄNDERUNGEN
- FILTER
Git-Flow
Development-Branch:
Feature:
@@ -364,8 +365,12 @@
Gestagte Änderungen committen
Gestagte Änderungen committen und pushen
Alle Änderungen stagen und committen
+ Neuen Branch basierend auf ausgewählten Commit erstellen
Ausgewählte Änderungen verwerfen
+ Fetch, wird direkt ausgeführt
Dashboard Modus (Standard)
+ Pull, wird direkt ausgeführt
+ Push, wird direkt ausgeführt
Erzwinge Neuladen des Repositorys
Ausgewählte Änderungen stagen/unstagen
Commit-Suchmodus
@@ -389,6 +394,8 @@
Interaktiver Rebase
Ziel Branch:
Auf:
+ In Browser öffnen
+ Link kopieren
FEHLER
INFO
Branch mergen
@@ -429,7 +436,9 @@
Modell
DARSTELLUNG
Standardschriftart
- Standardschriftgröße
+ Schriftgröße
+ Standard
+ Texteditor
Monospace-Schriftart
Verwende die Monospace-Schriftart nur im Texteditor
Design
@@ -526,7 +535,7 @@
Änderungen automatisch von Remote fetchen...
Aufräumen (GC & Prune)
Führt `git gc` auf diesem Repository aus.
- Alles löschen
+ Filter aufheben
Repository Einstellungen
WEITER
Benutzerdefinierte Aktionen
@@ -534,7 +543,9 @@
Aktiviere '--reflog' Option
Öffne im Datei-Browser
Suche Branches/Tags/Submodule
- GEFILTERT:
+ Aufheben
+ Im Graph ausblenden
+ Im Graph filtern
LOKALE BRANCHES
Zum HEAD wechseln
Aktiviere '--first-parent' Option
@@ -593,7 +604,7 @@
START
Stash
Inklusive nicht-verfolgter Dateien
- Behalte Dateien des Stages
+ Behalte gestagte Dateien
Name:
Optional. Name dieses Stashes
Nur gestagte Änderungen
diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml
index 3803bd39..55fb04d8 100644
--- a/src/Resources/Locales/en_US.axaml
+++ b/src/Resources/Locales/en_US.axaml
@@ -289,7 +289,6 @@
File History
CONTENT
CHANGE
- FILTER
Git-Flow
Development Branch:
Feature:
@@ -434,8 +433,9 @@
Server
APPEARANCE
Default Font
- Default Font Size
- Editor Font Size
+ Font Size
+ Default
+ Editor
Monospace Font
Only use monospace font in text editor
Theme
@@ -540,7 +540,9 @@
Enable '--reflog' Option
Open in File Browser
Search Branches/Tags/Submodules
- FILTERED BY:
+ Unset
+ Hide in commit graph
+ Filter in commit graph
LOCAL BRANCHES
Navigate to HEAD
Enable '--first-parent' Option
diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml
index 6bc96dd1..f69fc934 100644
--- a/src/Resources/Locales/es_ES.axaml
+++ b/src/Resources/Locales/es_ES.axaml
@@ -294,7 +294,6 @@
Historial de Archivos
CONTENIDO
CAMBIO
- FILTRO
Git-Flow
Rama de Desarrollo:
Feature:
@@ -438,8 +437,6 @@
Servidor
APARIENCIA
Fuente por defecto
- Tamaño de fuente por defecto
- Tamaño de fuente del editor
Fuente Monospace
Usar solo fuente monospace en el editor de texto
Tema
@@ -544,7 +541,6 @@
Habilitar Opción '--reflog'
Abrir en el Explorador
Buscar Ramas/Etiquetas/Submódulos
- FILTRAR POR:
RAMAS LOCALES
Navegar a HEAD
Habilitar Opción '--first-parent'
diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml
index 043e8f97..75cd4d58 100644
--- a/src/Resources/Locales/fr_FR.axaml
+++ b/src/Resources/Locales/fr_FR.axaml
@@ -3,23 +3,26 @@
À propos
+ À propos de SourceGit
• Compilé avec
+ • Le graphique est rendu par
© 2024 sourcegit-scm
• TextEditor de
• Les polices Monospace proviennent de
- À propos de SourceGit
• Le code source est disponible sur
Client Git Open Source et Gratuit
Ajouter un Worktree
+ What to Checkout:
+ Créer une nouvelle branche
+ Branche existante
Emplacement :
Chemin vers ce worktree. Relatif supporté.
Nom de branche:
Optionnel. Nom du dossier de destination par défaut.
Suivre la branche :
Suivi de la branche distante
- What to Checkout:
- Créer une nouvelle branche
- Branche existante
+ Assistant IA
+ Utiliser l'IA pour générer un message de commit
Appliquer
Erreur
Soulever les erreurs et refuser d'appliquer le patch
@@ -55,6 +58,7 @@
Supprimer {0} branches sélectionnées
Rejeter tous les changements
Fast-Forward vers ${0}$
+ Fetch ${0}$ vers ${1}$...
Git Flow - Terminer ${0}$
Fusionner ${0}$ dans ${1}$...
Tirer ${0}$
@@ -69,6 +73,7 @@
ANNULER
Réinitialiser à la révision parente
Réinitialiser à cette révision
+ Générer un message de commit
CHANGER LE MODE D'AFFICHAGE
Afficher comme liste de dossiers/fichiers
Afficher comme liste de chemins
@@ -77,24 +82,25 @@
Checkout ce commit
Commit :
Avertissement: un checkout vers un commit aboutiera vers un HEAD détaché
+ Branche :
Changements locaux :
Annuler
Ne rien faire
Mettre en stash et réappliquer
- Branche :
Cherry-Pick de ce commit
Commit :
Commit tous les changements
+ Ligne principale :
Cherry Pick
Supprimer les stashes
Vous essayez de supprimer tous les stashes. Êtes-vous sûr de vouloir continuer ?
+ Cloner repository distant
Paramètres supplémentaires :
Arguments additionnels au clônage. Optionnel.
Nom local :
Nom de dépôt. Optionnel.
Dossier parent :
URL du dépôt :
- Cloner le dépôt distant
FERMER
Éditeur
Changer de commit
@@ -103,6 +109,7 @@
Comparer avec le worktree
Copier les informations
Copier le SHA
+ Action personnalisée
Rebase interactif de ${0}$ ici
Rebaser ${0}$ ici
Réinitialiser ${0}$ ici
@@ -110,6 +117,7 @@
Reformuler
Enregistrer en tant que patch...
Squash dans le parent
+ Squash les commits enfants ici
CHANGEMENTS
Rechercher les changements...
FICHIERS
@@ -126,29 +134,56 @@
PARENTS
REFS
SHA
- Description
+ Ouvrir dans le navigateur
Entrez le message du commit
+ Description
Configurer le dépôt
MODÈLE DE COMMIT
- Contenu de modèle:
Nom de modèle:
+ Contenu de modèle:
+ ACTION PERSONNALISÉE
+ Arguments :
+ ${REPO} - Chemin du repository; ${SHA} - SHA du commit sélectionné
+ Fichier exécutable :
+ Nom :
+ Portée :
+ Commit
+ Repository
Adresse e-mail
Adresse e-mail
GIT
Fetch les dépôts distants automatiquement
minute(s)
+ Dépôt par défaut
+ Activer --prune pour fetch
+ Activer --signoff pour commit
SUIVI DES PROBLÈMES
Ajouter une règle d'exemple Github
Ajouter une règle d'exemple Jira
+ Ajouter une règle d'exemple pour Incidents GitLab
+ Ajouter une règle d'exemple pour Merge Request GitLab
Nouvelle règle
Issue Regex Expression:
Nom de règle :
- Veuillez utiliser $1, $2 pour accéder aux valeurs des groupes regex.
URL résultant:
+ Veuillez utiliser $1, $2 pour accéder aux valeurs des groupes regex.
+ IA
+ Service préféré:
+ 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é.
Proxy HTTP
Proxy HTTP utilisé par ce dépôt
Nom d'utilisateur
Nom d'utilisateur pour ce dépôt
+ Espaces de travail
+ Couleur
+ Restaurer les onglets au démarrage
+ Assistant Commits Conventionnels
+ Changement Radical :
+ Incident Clos :
+ Détail des Modifications :
+ Portée :
+ Courte Description :
+ Type de Changement :
Copier
Copier tout le texte
Copier le nom de fichier
@@ -198,10 +233,12 @@
ANCIEN
Copier
Mode de fichier changé
+ Ignorer les changements d'espaces
CHANGEMENT D'OBJET LFS
Différence suivante
PAS DE CHANGEMENT OU SEULEMENT EN FIN DE LIGNE
Différence précédente
+ Enregistrer en tant que patch
Afficher les caractères invisibles
Diff côte-à-côte
SOUS-MODULE
@@ -210,6 +247,7 @@
Coloration syntaxique
Retour à la ligne
Ouvrir dans l'outil de fusion
+ Voir toutes les lignes
Réduit le nombre de ligne visibles
Augmente le nombre de ligne visibles
SÉLECTIONNEZ UN FICHIER POUR VOIR LES CHANGEMENTS
@@ -217,6 +255,7 @@
Rejeter les changements
Tous les changements dans la copie de travail.
Changements :
+ Inclure les fichiers ignorés
{0} changements seront rejetés
Vous ne pouvez pas annuler cette action !!!
Signet :
@@ -224,6 +263,8 @@
Cible :
Éditer le groupe sélectionné
Éditer le dépôt sélectionné
+ Lancer action personnalisée
+ Nom de l'action :
Fast-Forward (sans checkout)
Fetch
Fetch toutes les branches distantes
@@ -248,63 +289,68 @@
Utiliser les leurs (checkout --theirs)
Historique du fichier
CONTENU
- FILTRER
+ MODIFICATION
Git-Flow
- Development Branch:
+ Branche de développement :
Feature:
Feature Prefix:
- FLOW - Finish Feature
- FLOW - Finish Hotfix
- FLOW - Finish Release
- Target:
+ FLOW - Terminer Feature
+ FLOW - Terminer Hotfix
+ FLOW - Terminer Release
+ Cible:
Hotfix:
Hotfix Prefix:
- Initialize Git-Flow
- Keep branch
- Production Branch:
- Release:
- Release Prefix:
- Start Feature...
- FLOW - Start Feature
- Start Hotfix...
- FLOW - Start Hotfix
- Enter name
- Start Release...
- FLOW - Start Release
- Version Tag Prefix:
+ Initialiser Git-Flow
+ Garder la branche
+ Branche de production :
+ Release :
+ Release Prefix :
+ Commencer Feature...
+ FLOW - Commencer Feature
+ Commencer Hotfix...
+ FLOW - Commencer Hotfix
+ Saisir le nom
+ Commencer Release...
+ FLOW - Commencer Release
+ Préfixe Tag de Version :
Git LFS
- Add Track Pattern...
- Pattern is file name
- Custom Pattern:
- Add Track Pattern to Git LFS
+ Ajouter un pattern de suivi...
+ Le pattern est un nom de fichier
+ Pattern personnalisé :
+ Ajouter un pattern de suivi à Git LFS
Fetch
- Fetch LFS Objects
- Run `git lfs fetch` to download Git LFS objects. This does not update the working copy.
- Install Git LFS hooks
- Show Locks
- No Locked Files
- Lock
- LFS Locks
- Unlock
- Force Unlock
+ Fetch les objets LFS
+ Lancer `git lfs fetch` pour télécharger les objets Git LFS. Cela ne met pas à jour la copie de travail.
+ Installer les hooks Git LFS
+ Afficher les verrous
+ Pas de fichiers verrouillés
+ Verrouiller
+ Afficher seulement mes verrous
+ Verrous LFS
+ Déverouiller
+ Forcer le déverouillage
Prune
- Run `git lfs prune` to delete old LFS files from local storage
+ Lancer `git lfs prune` pour supprimer les anciens fichier LFS du stockage local
Pull
- Pull LFS Objects
- Run `git lfs pull` to download all Git LFS files for current ref & checkout
+ Pull les objets LFS
+ Lancer `git lfs pull` pour télécharger tous les fichier Git LFS de la référence actuelle & checkout
Push
- Push LFS Objects
- Push queued large files to the Git LFS endpoint
- Remote:
- Track files named '{0}'
- Track all *{0} files
+ Push les objets LFS
+ Transférer les fichiers volumineux en file d'attente vers le point de terminaison Git LFS
+ Dépôt :
+ Suivre les fichiers appelés '{0}'
+ Suivre tous les fichiers *{0}
Historique
Basculer entre dispositions Horizontal/Vertical
AUTEUR
+ HEURE DE L'AUTEUR
GRAPHE & SUJET
SHA
HEURE DE COMMIT
{0} COMMITS SÉLECTIONNÉS
+ Maintenir 'Ctrl' ou 'Shift' enfoncée pour sélectionner plusieurs commits.
+ Maintenir ⌘ ou ⇧ enfoncée pour sélectionner plusieurs commits.
+ CONSEILS:
Référence des raccourcis clavier
GLOBAL
Annuler le popup en cours
@@ -316,7 +362,13 @@
DÉPÔT
Commit les changements de l'index
Commit et pousser les changements de l'index
+ Ajouter tous les changements et commit
+ Créer une nouvelle branche basée sur le commit actuel
+ Rejeter les changements sélectionnés
+ Fetch, démarre directement
Mode tableau de bord (Défaut)
+ Pull, démarre directement
+ Push, démarre directement
Forcer le rechargement du dépôt
Ajouter/Retirer les changements sélectionnés de l'index
Recherche de commit
@@ -331,26 +383,30 @@
Stage
Retirer de l'index
Rejeter
- Initialize Repository
- Path:
- Cherry-Pick in progress. Press 'Abort' to restore original HEAD.
- Merge request in progress. Press 'Abort' to restore original HEAD.
- Rebase in progress. Press 'Abort' to restore original HEAD.
- Revert in progress. Press 'Abort' to restore original HEAD.
- Interactive Rebase
- Target Branch:
- On:
- ERROR
+ Initialiser le repository
+ Chemin :
+ Cherry-Pick en cours. Appuyer sur 'Abort' pour restaurer le HEAD d'origine.
+ Merge request in progress. Appuyer sur 'Abort' pour restaurer le HEAD d'origine.
+ Rebase in progress. Appuyer sur 'Abort' pour restaurer le HEAD d'origine.
+ Revert in progress. Appuyer sur 'Abort' pour restaurer le HEAD d'origine.
+ Rebase interactif
+ Branche cible :
+ Sur :
+ Ouvrir dans le navigateur
+ Copier le lien
+ ERREUR
NOTICE
- Merge Branch
- Into:
- Merge Option:
- Source Branch:
+ Merger la branche
+ Dans :
+ Option de merge:
+ Branche source :
+ Déplacer le noeud du repository
+ Sélectionnier le noeud parent pour :
Nom :
Git n'a PAS été configuré. Veuillez d'abord le faire dans le menu Préférence.
Ouvrir le dossier AppData
- Open With...
- Optional.
+ Ouvrir avec...
+ Optionnel.
Créer un nouvel onglet
Bookmark
Fermer l'onglet
@@ -369,9 +425,17 @@
L'an dernier
il y a {0} ans
Préférences
+ IA
+ Analyser Diff Prompt
+ Clé d'API
+ Générer le sujet de Prompt
+ Modèle
+ Nom
+ Serveur
APPARENCE
Police par défaut
Taille de police par défaut
+ Taille de police de l'éditeur
Police monospace
N'utiliser que des polices monospace pour l'éditeur de texte
Thème
@@ -386,6 +450,7 @@
Vérifier les mises à jour au démarrage
Language
Historique de commits
+ Afficher l'heure de l'auteur au lieu de l'heure de validation dans le graphique
Guide de longueur du sujet
GIT
Activer auto CRLF
@@ -405,6 +470,10 @@
Saisir le chemin d'installation vers le programme GPG
Clé de signature de l'utilisateur
Clé de signature GPG de l'utilisateur
+ INTEGRATION
+ SHELL/TERMINAL
+ Shell/Terminal
+ Chemin
Élaguer une branche distant
Cible :
Élaguer les Worktrees
@@ -418,87 +487,90 @@
Ne rien faire
Stash & Réappliquer
Fetch sans les tags
- Distant :
+ Dépôt distant :
Pull (Fetch & Merge)
- Use rebase instead of merge
+ Utiliser rebase au lieu de merge
Push
- Make sure submodules have been pushed
+ Assurez-vous que les submodules ont été poussés
Force push
- Local Branch:
- Remote:
- Push Changes To Remote
- Remote Branch:
- Set as tracking branch
- Push all tags
+ Branche locale :
+ Dépôt distant :
+ Pousser les changements vers le dépôt distant
+ Branche distante :
+ Définir comme branche de suivi
+ Push tous les tags
Push Tag To Remote
- Push to all remotes
- Remote:
- Tag:
- Quit
- Rebase Current Branch
- Stash & reapply local changes
- On:
- Rebase:
- Refresh
- Add Remote
- Edit Remote
- Name:
- Remote name
- Repository URL:
- Remote git repository URL
- Copy URL
- Delete...
- Edit...
+ Push tous les dépôts distants
+ Dépôt distant :
+ Tag :
+ Quitter
+ Rebase la branche actuelle
+ Stash & réappliquer changements locaux
+ Sur :
+ Rebase :
+ Rafraîchir
+ Ajouter dépôt distant
+ Modifier dépôt distant
+ Nom :
+ Nom du dépôt distant
+ URL du repository :
+ URL du dépôt distant
+ Copier l'URL
+ Supprimer...
+ Editer...
Fetch
- Open In Browser
+ Ouvrir dans le navigateur
Prune
- Confirm to Remove Worktree
- Enable `--force` Option
- Target:
- Rename Branch
- New Name:
- Unique name for this branch
- Branch:
+ Confirmer la suppression du Worktree
+ Activer l'option `--force`
+ Cible :
+ la branche
+ Nouveau nom :
+ Nom unique pour cette branche
+ Branche :
ABORT
- Cleanup(GC & Prune)
- Run `git gc` command for this repository.
- Clear all
- Configure this repository
- CONTINUE
- Ouvrir dans l'explorateur Windows
- Search Branches/Tags/Submodules
- FILTERED BY:
- LOCAL BRANCHES
- Navigate To HEAD
- Enable '--first-parent' Option
- Create Branch
- Open In {0}
- Open In External Tools
- Refresh
- REMOTES
- ADD REMOTE
- RESOLVE
- Search Commit
- File
+ Fetch automatique des changements depuis les dépôts...
+ Nettoyage(GC & Prune)
+ Lancer `git gc` pour ce repository.
+ Tout effacer
+ Configurer ce repository
+ CONTINUER
+ Pas d'actions personnalisées
+ Activer l'option '--reflog'
+ Ouvrir dans l'explorateur de fichiers
+ Rechercher Branches/Tags/Submodules
+ BRANCHES LOCALES
+ Naviguer vers le HEAD
+ Activer l'option '--first-parent'
+ Créer une branche
+ Ouvrir dans {0}
+ Ouvrir dans un outil externe
+ Rafraîchir
+ DEPOTS DISTANTS
+ AJOUTER DEPOT DISTANT
+ RESOUDRE
+ Rechercher un commit
+ Fichier
Message
SHA
- Author & Committer
- Show Tags as Tree
- Statistics
+ Auteur & Committer
+ Branche actuelle
+ Voir les Tags en tant qu'arbre
+ Statistiques
SUBMODULES
- ADD SUBMODULE
- UPDATE SUBMODULE
+ AJOUTER SUBMODULE
+ METTRE A JOUR SUBMODULE
TAGS
- NEW TAG
+ NOUVEAU TAG
Ouvrir dans un terminal
WORKTREES
- ADD WORKTREE
+ AJOUTER WORKTREE
PRUNE
- Git Repository URL
- Reset Current Branch To Revision
+ URL du repository Git
+ Reset branche actuelle à la révision
Reset Mode:
- Move To:
- Current Branch:
+ Déplacer vers :
+ Branche actuelle :
Ouvrir dans l'explorateur de fichier
Revert le Commit
Commit :
@@ -509,7 +581,8 @@
SAUVEGARDER
Sauvegarder en tant que...
Le patch a été sauvegardé !
- Vérifier les mises à jour...
+ Dossier racine :
+ Rechercher des mises à jour...
Une nouvelle version du logiciel est disponible :
La vérification de mise à jour à échouée !
Télécharger
@@ -517,13 +590,17 @@
Mise à jour du logiciel
Il n'y a pas de mise à jour pour le moment.
Squash Commits
+ Dans :
SSH Private Key:
Private SSH key store path
START
Stash
Include untracked files
- Message:
+ Garder les fichiers staged
+ Message :
Optionnel. Nom de ce stash
+ Seulement les changements staged
+ Les modifications staged et unstaged des fichiers sélectionnés seront stockées!!!
Stash les changements locaux
Appliquer
Effacer
@@ -540,6 +617,7 @@
WEEK
COMMITS:
AUTHORS:
+ APERCU
SUBMODULES
Add Submodule
Copy Relative Path
@@ -550,6 +628,7 @@
Delete Submodule
OK
Copy Tag Name
+ Copier le message du tag
Delete ${0}$...
Fusionner ${0}$ dans ${1}$...
Push ${0}$...
@@ -568,9 +647,11 @@
Supprimer
GLISSER / DEPOSER DE DOSSIER SUPPORTÉ. GROUPAGE PERSONNALISÉ SUPPORTÉ.
Éditer
+ Déplacer vers un autre groupe
Ouvrir tous les dépôts
Ouvrir un dépôt
Ouvrir le terminal
+ Réanalyser les repositories dans le dossier de clonage par défaut
Chercher des dépôts...
Trier
Changements
@@ -584,6 +665,9 @@
COMMIT
COMMIT & PUSH
Modèles/Historiques
+ Trigger click event
+ Stage tous les changements et commit
+ Un commit vide a été détecté ! Voulez-vous continuer (--allow-empty) ?
CONFLITS DÉTECTÉS
LES CONFLITS DE FICHIER SONT RÉSOLUS
INCLURE LES FICHIERS NON-SUIVIS
@@ -598,6 +682,8 @@
VOIR LES FICHIERS PRÉSUMÉS INCHANGÉS
Modèle: ${0}$
Faites un clique droit sur les fichiers sélectionnés et faites vos choix pour la résoluion des conflits.
+ ESPACE DE TRAVAIL :
+ Configurer les espaces de travail...
WORKTREE
Copier le chemin
Verrouiller
diff --git a/src/Resources/Locales/pt_BR.axaml b/src/Resources/Locales/pt_BR.axaml
index 61ded334..a4f20310 100644
--- a/src/Resources/Locales/pt_BR.axaml
+++ b/src/Resources/Locales/pt_BR.axaml
@@ -176,7 +176,6 @@
Repositório
Endereço de email
Endereço de email
- Endereço de Email
Buscar remotos automaticamente
Minuto(s)
Remoto padrão
@@ -317,7 +316,6 @@
Histórico de Arquivos
CONTEUDO
MUDANÇA
- FILTRO
Branch de Desenvolvimento:
Feature:
Prefixo da Feature:
@@ -460,8 +458,6 @@
Servidor
INTELIGÊNCIA ARTIFICIAL
Fonte Padrão
- Tamanho da fonte padrão
- Tamanho da fonte do editor
Fonte Monoespaçada
Usar fonte monoespaçada apenas no editor de texto
Tema
@@ -568,7 +564,6 @@
Habilitar opção '--reflog'
Abrir no Navegador de Arquivos
Pesquisar Branches/Tags/Submódulos
- FILTRADO POR:
Habilitar opção '--first-parent'
BRANCHES LOCAIS
Navegar para HEAD
diff --git a/src/Resources/Locales/ru_RU.axaml b/src/Resources/Locales/ru_RU.axaml
index 3ea6a922..3d03e850 100644
--- a/src/Resources/Locales/ru_RU.axaml
+++ b/src/Resources/Locales/ru_RU.axaml
@@ -62,7 +62,7 @@
Поток Git - Завершение ${0}$
Слить ${0}$ в ${1}$...
Забрать ${0}$
- Перетащить ${0}$ в ${1}$...
+ Забрать ${0}$ в ${1}$...
Выложить ${0}$
Переместить ${0}$ на ${1}$...
Переименовать ${0}$...
@@ -213,7 +213,7 @@
Вид:
Аннотированный
Лёгкий
- Удерживайте Ctrl, чтобы начать непосредственно
+ Удерживайте Ctrl, чтобы начать сразу
Вырезать
Удалить ветку
Ветка:
@@ -293,7 +293,6 @@
История файлов
СОДЕРЖИМОЕ
ИЗМЕНИТЬ
- ФИЛЬТР
Git-поток
Ветка разработчика:
Свойство:
@@ -369,11 +368,11 @@
Подготовить все изменения и зафиксировать
Создать новую ветку на основе выбранной ветки
Отклонить выбранные изменения
- Извлечение, запускается непосредственно
+ Извлечение, запускается сразу
Режим доски (по-умолчанию)
Принудительно перезагрузить этот хранилище
- Забрать, запускается непосредственно
- Выложить, запускается непосредственно
+ Забрать, запускается сразу
+ Выложить, запускается сразу
Подготовленные/Неподготовленные выбранные изменения
Режим поиска фиксаций
Переключить на «Изменения»
@@ -438,8 +437,9 @@
Сервер
ВИД
Шрифт по-умолчанию
- Размер шрифта по-умолчанию
- Размер шрифта редактора
+ Размер шрифта
+ По-умолчанию
+ Редактор
Моноширный шрифт
В текстовом редакторе используется только моноширный шрифт
Тема
@@ -544,7 +544,10 @@
Разрешить опцию --reflog
Открыть в файловом менеджере
Поиск веток, меток и подмодулей
- ОТФИЛЬТРОВАНО:
+ Не установлен (По-умолчанию)
+ Скрыть в графе фиксации
+ Фильтр в графе фиксации
+ ОТФИЛЬТРОВАНО:
ЛОКАЛЬНЫЕ ВЕТКИ
Навигация по заголовку
Включить опцию --first-parent
diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml
index 3df54899..1ab661be 100644
--- a/src/Resources/Locales/zh_CN.axaml
+++ b/src/Resources/Locales/zh_CN.axaml
@@ -292,7 +292,6 @@
文件历史
文件内容
文件变更
- 过滤
GIT工作流
开发分支 :
特性分支 :
@@ -437,7 +436,9 @@
服务地址
外观配置
缺省字体
- 默认字体大小
+ 字体大小
+ 默认
+ 代码编辑器
代码字体大小
等宽字体
仅在文本编辑器中使用等宽字体
@@ -543,7 +544,9 @@
启用 --reflog 选项
在文件浏览器中打开
快速查找分支/标签/子模块
- 过滤规则 :
+ 不指定
+ 在提交列表中隐藏
+ 使用其对提交列表过滤
本地分支
定位HEAD
启用 --first-parent 过滤选项
diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml
index 4dcb31aa..5452fef6 100644
--- a/src/Resources/Locales/zh_TW.axaml
+++ b/src/Resources/Locales/zh_TW.axaml
@@ -292,7 +292,6 @@
檔案歷史
檔案内容
檔案變更
- 篩選
Git 工作流
開發分支:
功能分支:
@@ -437,8 +436,9 @@
產生提交訊息提示詞
外觀設定
預設字型
- 預設字型大小
- 程式碼字型大小
+ 字型大小
+ 預設
+ 程式碼
等寬字型
僅在文字編輯器中使用等寬字型
佈景主題
@@ -543,7 +543,9 @@
啟用 [--reflog] 選項
在檔案瀏覽器中開啟
快速搜尋分支/標籤/子模組
- 篩選規則:
+ 不指定
+ 在提交清單中隱藏
+ 使用其來篩選提交清單
本機分支
回到 HEAD
啟用 [--first-parent] 選項
diff --git a/src/Resources/Styles.axaml b/src/Resources/Styles.axaml
index 50f4d830..82970549 100644
--- a/src/Resources/Styles.axaml
+++ b/src/Resources/Styles.axaml
@@ -168,12 +168,13 @@
-
+
@@ -511,6 +512,12 @@
+
+
-
-
-
-
+
+
@@ -67,15 +71,10 @@
Foreground="{DynamicResource Brush.BadgeFG}"
Background="{DynamicResource Brush.Badge}"/>
-
-
+
+
diff --git a/src/Views/BranchTree.axaml.cs b/src/Views/BranchTree.axaml.cs
index e96b2594..92c2b043 100644
--- a/src/Views/BranchTree.axaml.cs
+++ b/src/Views/BranchTree.axaml.cs
@@ -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 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 rows, List nodes, int depth)
{
foreach (var node in nodes)
@@ -477,23 +455,6 @@ namespace SourceGit.Views
CollectBranchesInNode(outs, sub);
}
- private bool UpdateUpstreamFilterState(List 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;
}
}
diff --git a/src/Views/CommitBaseInfo.axaml b/src/Views/CommitBaseInfo.axaml
index 76ea0227..d8b77a18 100644
--- a/src/Views/CommitBaseInfo.axaml
+++ b/src/Views/CommitBaseInfo.axaml
@@ -117,7 +117,28 @@
TextDecorations="Underline"
Cursor="Hand"
Margin="0,0,16,0"
- PointerPressed="OnSHAPressed"/>
+ PointerEntered="OnSHAPointerEntered"
+ PointerPressed="OnSHAPressed">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Views/CommitBaseInfo.axaml.cs b/src/Views/CommitBaseInfo.axaml.cs
index 228fbe8e..8f480745 100644
--- a/src/Views/CommitBaseInfo.axaml.cs
+++ b/src/Views/CommitBaseInfo.axaml.cs
@@ -1,3 +1,5 @@
+using System.Threading.Tasks;
+
using Avalonia;
using Avalonia.Collections;
using Avalonia.Controls;
@@ -113,6 +115,29 @@ namespace SourceGit.Views
e.Handled = true;
}
+ private async void OnSHAPointerEntered(object sender, PointerEventArgs e)
+ {
+ if (DataContext is ViewModels.CommitDetail detail && sender is Control { DataContext: string sha } ctl)
+ {
+ var tooltip = ToolTip.GetTip(ctl);
+ if (tooltip is Models.Commit commit && commit.SHA == sha)
+ {
+ ToolTip.SetIsOpen(ctl, true);
+ }
+ else
+ {
+ var c = await Task.Run(() => detail.GetParent(sha));
+ if (c != null)
+ {
+ ToolTip.SetTip(ctl, c);
+ ToolTip.SetIsOpen(ctl, ctl.IsPointerOver);
+ }
+ }
+ }
+
+ e.Handled = true;
+ }
+
private void OnSHAPressed(object sender, PointerPressedEventArgs e)
{
if (DataContext is ViewModels.CommitDetail detail && sender is Control { DataContext: string sha })
diff --git a/src/Views/CommitRefsPresenter.cs b/src/Views/CommitRefsPresenter.cs
index fc3233a5..e8a66da0 100644
--- a/src/Views/CommitRefsPresenter.cs
+++ b/src/Views/CommitRefsPresenter.cs
@@ -38,7 +38,7 @@ namespace SourceGit.Views
}
public static readonly StyledProperty BackgroundProperty =
- AvaloniaProperty.Register(nameof(Background), null);
+ AvaloniaProperty.Register(nameof(Background), Brushes.Transparent);
public IBrush Background
{
@@ -56,7 +56,7 @@ namespace SourceGit.Views
}
public static readonly StyledProperty UseGraphColorProperty =
- AvaloniaProperty.Register(nameof(UseGraphColor), false);
+ AvaloniaProperty.Register(nameof(UseGraphColor));
public bool UseGraphColor
{
@@ -96,7 +96,6 @@ namespace SourceGit.Views
var x = 1.0;
foreach (var item in _items)
{
- var iconRect = new RoundedRect(new Rect(x, 0, 16, 16), new CornerRadius(2, 0, 0, 2));
var entireRect = new RoundedRect(new Rect(x, 0, item.Width, 16), new CornerRadius(2));
if (item.IsHead)
diff --git a/src/Views/DiffView.axaml b/src/Views/DiffView.axaml
index 06525abd..e0627ad8 100644
--- a/src/Views/DiffView.axaml
+++ b/src/Views/DiffView.axaml
@@ -34,8 +34,24 @@
+
+
+
+
@@ -81,9 +94,7 @@
@@ -97,14 +108,14 @@
@@ -112,16 +123,14 @@
-
diff --git a/src/Views/DiffView.axaml.cs b/src/Views/DiffView.axaml.cs
index 860627d3..7184ec44 100644
--- a/src/Views/DiffView.axaml.cs
+++ b/src/Views/DiffView.axaml.cs
@@ -1,4 +1,6 @@
using Avalonia.Controls;
+using Avalonia.Interactivity;
+using Avalonia.VisualTree;
namespace SourceGit.Views
{
@@ -8,5 +10,31 @@ namespace SourceGit.Views
{
InitializeComponent();
}
+
+ private void OnGotoPrevChange(object _, RoutedEventArgs e)
+ {
+ var textDiff = this.FindDescendantOfType();
+ if (textDiff == null)
+ return;
+
+ textDiff.GotoPrevChange();
+ if (textDiff is SingleSideTextDiffPresenter presenter)
+ presenter.ForceSyncScrollOffset();
+
+ e.Handled = true;
+ }
+
+ private void OnGotoNextChange(object _, RoutedEventArgs e)
+ {
+ var textDiff = this.FindDescendantOfType();
+ if (textDiff == null)
+ return;
+
+ textDiff.GotoNextChange();
+ if (textDiff is SingleSideTextDiffPresenter presenter)
+ presenter.ForceSyncScrollOffset();
+
+ e.Handled = true;
+ }
}
}
diff --git a/src/Views/FilterModeSwitchButton.axaml b/src/Views/FilterModeSwitchButton.axaml
new file mode 100644
index 00000000..0fbbbf8e
--- /dev/null
+++ b/src/Views/FilterModeSwitchButton.axaml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Views/FilterModeSwitchButton.axaml.cs b/src/Views/FilterModeSwitchButton.axaml.cs
new file mode 100644
index 00000000..f68e9166
--- /dev/null
+++ b/src/Views/FilterModeSwitchButton.axaml.cs
@@ -0,0 +1,167 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Interactivity;
+using Avalonia.VisualTree;
+
+namespace SourceGit.Views
+{
+ public partial class FilterModeSwitchButton : UserControl
+ {
+ public static readonly StyledProperty ModeProperty =
+ AvaloniaProperty.Register(nameof(Mode));
+
+ public Models.FilterMode Mode
+ {
+ get => GetValue(ModeProperty);
+ set => SetValue(ModeProperty, value);
+ }
+
+ public static readonly StyledProperty IsNoneVisibleProperty =
+ AvaloniaProperty.Register(nameof(IsNoneVisible));
+
+ public bool IsNoneVisible
+ {
+ get => GetValue(IsNoneVisibleProperty);
+ set => SetValue(IsNoneVisibleProperty, value);
+ }
+
+ public static readonly StyledProperty IsContextMenuOpeningProperty =
+ AvaloniaProperty.Register(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();
+ 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) =>
+ {
+ repo.SetTagFilterMode(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) =>
+ {
+ repo.SetTagFilterMode(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) =>
+ {
+ repo.SetTagFilterMode(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) =>
+ {
+ repo.SetBranchFilterMode(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) =>
+ {
+ repo.SetBranchFilterMode(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) =>
+ {
+ repo.SetBranchFilterMode(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;
+ }
+ }
+}
+
+
diff --git a/src/Views/Histories.axaml.cs b/src/Views/Histories.axaml.cs
index 9f436346..7edcb295 100644
--- a/src/Views/Histories.axaml.cs
+++ b/src/Views/Histories.axaml.cs
@@ -192,35 +192,26 @@ namespace SourceGit.Views
if (string.IsNullOrEmpty(subject))
return;
- var offset = 0;
var keywordMatch = REG_KEYWORD_FORMAT1().Match(subject);
if (!keywordMatch.Success)
keywordMatch = REG_KEYWORD_FORMAT2().Match(subject);
- if (keywordMatch.Success)
- {
- var keyword = new Run(subject.Substring(0, keywordMatch.Length));
- keyword.FontWeight = FontWeight.Bold;
- Inlines.Add(keyword);
-
- offset = keywordMatch.Length;
- subject = subject.Substring(offset);
- }
-
- var rules = IssueTrackerRules;
- if (rules == null || rules.Count == 0)
- {
- Inlines.Add(new Run(subject));
- return;
- }
-
+ var rules = IssueTrackerRules ?? [];
var matches = new List();
foreach (var rule in rules)
rule.Matches(matches, subject);
if (matches.Count == 0)
{
- Inlines.Add(new Run(subject));
+ if (keywordMatch.Success)
+ {
+ Inlines.Add(new Run(subject.Substring(0, keywordMatch.Length)) { FontWeight = FontWeight.Bold });
+ Inlines.Add(new Run(subject.Substring(keywordMatch.Length)));
+ }
+ else
+ {
+ Inlines.Add(new Run(subject));
+ }
return;
}
@@ -232,18 +223,44 @@ namespace SourceGit.Views
foreach (var match in matches)
{
if (match.Start > pos)
- inlines.Add(new Run(subject.Substring(pos, match.Start - pos)));
+ {
+ if (keywordMatch.Success && pos < keywordMatch.Length)
+ {
+ if (keywordMatch.Length < match.Start)
+ {
+ inlines.Add(new Run(subject.Substring(pos, keywordMatch.Length - pos)) { FontWeight = FontWeight.Bold });
+ inlines.Add(new Run(subject.Substring(keywordMatch.Length, match.Start - keywordMatch.Length)));
+ }
+ else
+ {
+ inlines.Add(new Run(subject.Substring(pos, match.Start - pos)) { FontWeight = FontWeight.Bold });
+ }
+ }
+ else
+ {
+ inlines.Add(new Run(subject.Substring(pos, match.Start - pos)));
+ }
+ }
var link = new Run(subject.Substring(match.Start, match.Length));
link.Classes.Add("issue_link");
inlines.Add(link);
pos = match.Start + match.Length;
- match.Start += offset; // Because we use this index of whole subject to detect mouse event.
}
if (pos < subject.Length)
- inlines.Add(new Run(subject.Substring(pos)));
+ {
+ if (keywordMatch.Success && pos < keywordMatch.Length)
+ {
+ inlines.Add(new Run(subject.Substring(pos, keywordMatch.Length - pos)) { FontWeight = FontWeight.Bold });
+ inlines.Add(new Run(subject.Substring(keywordMatch.Length)));
+ }
+ else
+ {
+ inlines.Add(new Run(subject.Substring(pos)));
+ }
+ }
Inlines.AddRange(inlines);
}
@@ -713,9 +730,12 @@ namespace SourceGit.Views
private void OnCommitListDoubleTapped(object sender, TappedEventArgs e)
{
- if (DataContext is ViewModels.Histories histories && sender is ListBox { SelectedItems: { Count: 1 } selected })
+ if (DataContext is ViewModels.Histories histories && sender is ListBox { SelectedItems: { Count: 1 } })
{
- histories.DoubleTapped(selected[0] as Models.Commit);
+ var source = e.Source as Control;
+ var item = source.FindAncestorOfType();
+ if (item is { DataContext: Models.Commit commit })
+ histories.DoubleTapped(commit);
}
e.Handled = true;
}
diff --git a/src/Views/LauncherPage.axaml b/src/Views/LauncherPage.axaml
index e75fd936..be2b339f 100644
--- a/src/Views/LauncherPage.axaml
+++ b/src/Views/LauncherPage.axaml
@@ -109,7 +109,7 @@
-
+
diff --git a/src/Views/Preference.axaml b/src/Views/Preference.axaml
index 73be0f7c..9b84604a 100644
--- a/src/Views/Preference.axaml
+++ b/src/Views/Preference.axaml
@@ -121,7 +121,7 @@
-
+
-
+
+ Value="{Binding DefaultFontSize, Mode=TwoWay}">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
@@ -196,16 +205,16 @@
-
-
-
-
+
@@ -557,14 +557,6 @@
-
-
+
-
-
-
+
+
+
+
@@ -592,16 +595,24 @@
-
-
-
+
+
+
+
+
+
+
-
-
+
+
diff --git a/src/Views/RepositoryToolbar.axaml.cs b/src/Views/RepositoryToolbar.axaml.cs
index e2c7df8c..afc8ac5a 100644
--- a/src/Views/RepositoryToolbar.axaml.cs
+++ b/src/Views/RepositoryToolbar.axaml.cs
@@ -52,7 +52,7 @@ namespace SourceGit.Views
var startDirectly = launcher.HasKeyModifier(KeyModifiers.Control);
if (!startDirectly && OperatingSystem.IsMacOS())
startDirectly = launcher.HasKeyModifier(KeyModifiers.Meta);
-
+
repo.Fetch(startDirectly);
e.Handled = true;
}
@@ -66,7 +66,7 @@ namespace SourceGit.Views
var startDirectly = launcher.HasKeyModifier(KeyModifiers.Control);
if (!startDirectly && OperatingSystem.IsMacOS())
startDirectly = launcher.HasKeyModifier(KeyModifiers.Meta);
-
+
repo.Pull(startDirectly);
e.Handled = true;
}
@@ -80,7 +80,7 @@ namespace SourceGit.Views
var startDirectly = launcher.HasKeyModifier(KeyModifiers.Control);
if (!startDirectly && OperatingSystem.IsMacOS())
startDirectly = launcher.HasKeyModifier(KeyModifiers.Meta);
-
+
repo.Push(startDirectly);
e.Handled = true;
}
diff --git a/src/Views/Reset.axaml b/src/Views/Reset.axaml
index c703ac1d..b3a18e49 100644
--- a/src/Views/Reset.axaml
+++ b/src/Views/Reset.axaml
@@ -37,16 +37,19 @@
Margin="0,0,8,0"
Text="{DynamicResource Text.Reset.Mode}"/>
+ SelectedItem="{Binding SelectedMode, Mode=TwoWay}"
+ KeyDown="OnResetModeKeyDown">
-
-
+
+
+
diff --git a/src/Views/Reset.axaml.cs b/src/Views/Reset.axaml.cs
index cc4b9b58..8c380538 100644
--- a/src/Views/Reset.axaml.cs
+++ b/src/Views/Reset.axaml.cs
@@ -1,4 +1,6 @@
using Avalonia.Controls;
+using Avalonia.Input;
+using Avalonia.Interactivity;
namespace SourceGit.Views
{
@@ -8,5 +10,29 @@ namespace SourceGit.Views
{
InitializeComponent();
}
+
+ protected override void OnLoaded(RoutedEventArgs e)
+ {
+ base.OnLoaded(e);
+
+ ResetMode.Focus();
+ }
+
+ private void OnResetModeKeyDown(object sender, KeyEventArgs e)
+ {
+ if (sender is ComboBox comboBox)
+ {
+ var key = e.Key.ToString();
+ for (int i = 0; i < Models.ResetMode.Supported.Length; i++)
+ {
+ if (key.Equals(Models.ResetMode.Supported[i].Key, System.StringComparison.OrdinalIgnoreCase))
+ {
+ comboBox.SelectedIndex = i;
+ e.Handled = true;
+ return;
+ }
+ }
+ }
+ }
}
}
diff --git a/src/Views/TagsView.axaml b/src/Views/TagsView.axaml
index a30f63de..5dedb661 100644
--- a/src/Views/TagsView.axaml
+++ b/src/Views/TagsView.axaml
@@ -12,6 +12,10 @@
+
+
@@ -43,15 +47,14 @@
Classes="primary"
Text="{Binding FullPath, Converter={x:Static c:PathConverters.PureFileName}}"
Margin="8,0,0,0"/>
-
-
+
+
+
+
+
+
+
+
@@ -60,32 +63,28 @@
-
+ Margin="8,0,0,0"
+ TextTrimming="CharacterEllipsis"/>
-
+
diff --git a/src/Views/TagsView.axaml.cs b/src/Views/TagsView.axaml.cs
index 8d4168b2..c83cfd28 100644
--- a/src/Views/TagsView.axaml.cs
+++ b/src/Views/TagsView.axaml.cs
@@ -65,7 +65,7 @@ namespace SourceGit.Views
}
if (node.Tag != null)
- CreateContent(new Thickness(0, 2, 0, 0), "Icons.Tag");
+ CreateContent(new Thickness(0, 0, 0, 0), "Icons.Tag");
else if (node.IsExpanded)
CreateContent(new Thickness(0, 2, 0, 0), "Icons.Folder.Open");
else
@@ -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 rows, List nodes)
{
foreach (var node in nodes)
diff --git a/src/Views/TextDiffView.axaml b/src/Views/TextDiffView.axaml
index 57427321..f2a5beaf 100644
--- a/src/Views/TextDiffView.axaml
+++ b/src/Views/TextDiffView.axaml
@@ -13,27 +13,39 @@
-
+
+
+
+
+
+
+
-
+
+
+
+
+
diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs
index 913a6340..242f8c4c 100644
--- a/src/Views/TextDiffView.axaml.cs
+++ b/src/Views/TextDiffView.axaml.cs
@@ -45,6 +45,18 @@ namespace SourceGit.Views
}
}
+ public record TextDiffViewRange
+ {
+ public int StartIdx { get; set; } = 0;
+ public int EndIdx { get; set; } = 0;
+
+ public TextDiffViewRange(int startIdx, int endIdx)
+ {
+ StartIdx = startIdx;
+ EndIdx = endIdx;
+ }
+ }
+
public class ThemedTextDiffPresenter : TextEditor
{
public class VerticalSeperatorMargin : AbstractMargin
@@ -210,7 +222,6 @@ namespace SourceGit.Views
if (presenter == null)
return new Size(0, 0);
- var maxLineNumber = presenter.GetMaxLineNumber();
var typeface = TextView.CreateTypeface();
var test = new FormattedText(
$"-",
@@ -465,6 +476,15 @@ namespace SourceGit.Views
get => GetValue(SelectedChunkProperty);
set => SetValue(SelectedChunkProperty, value);
}
+
+ public static readonly StyledProperty DisplayRangeProperty =
+ AvaloniaProperty.Register(nameof(DisplayRange), new TextDiffViewRange(0, 0));
+
+ public TextDiffViewRange DisplayRange
+ {
+ get => GetValue(DisplayRangeProperty);
+ set => SetValue(DisplayRangeProperty, value);
+ }
protected override Type StyleKeyOverride => typeof(TextEditor);
@@ -498,6 +518,78 @@ namespace SourceGit.Views
{
}
+ public void GotoPrevChange()
+ {
+ var firstLineIdx = DisplayRange.StartIdx;
+ if (firstLineIdx <= 1)
+ return;
+
+ var lines = GetLines();
+ var firstLineType = lines[firstLineIdx].Type;
+ var prevLineType = lines[firstLineIdx - 1].Type;
+ var isChangeFirstLine = firstLineType != Models.TextDiffLineType.Normal && firstLineType != Models.TextDiffLineType.Indicator;
+ var isChangePrevLine = prevLineType != Models.TextDiffLineType.Normal && prevLineType != Models.TextDiffLineType.Indicator;
+ if (isChangeFirstLine && isChangePrevLine)
+ {
+ for (var i = firstLineIdx - 2; i >= 0; i--)
+ {
+ var prevType = lines[i].Type;
+ if (prevType == Models.TextDiffLineType.Normal || prevType == Models.TextDiffLineType.Indicator)
+ {
+ ScrollToLine(i + 2);
+ return;
+ }
+ }
+ }
+
+ var findChange = false;
+ for (var i = firstLineIdx - 1; i >= 0; i--)
+ {
+ var prevType = lines[i].Type;
+ if (prevType == Models.TextDiffLineType.Normal || prevType == Models.TextDiffLineType.Indicator)
+ {
+ if (findChange)
+ {
+ ScrollToLine(i + 2);
+ return;
+ }
+ }
+ else if (!findChange)
+ {
+ findChange = true;
+ }
+ }
+ }
+
+ public void GotoNextChange()
+ {
+ var lines = GetLines();
+ var lastLineIdx = DisplayRange.EndIdx;
+ if (lastLineIdx >= lines.Count - 1)
+ return;
+
+ var lastLineType = lines[lastLineIdx].Type;
+ var findNormalLine = lastLineType == Models.TextDiffLineType.Normal || lastLineType == Models.TextDiffLineType.Indicator;
+ for (var idx = lastLineIdx + 1; idx < lines.Count; idx++)
+ {
+ var nextType = lines[idx].Type;
+ if (nextType == Models.TextDiffLineType.None ||
+ nextType == Models.TextDiffLineType.Added ||
+ nextType == Models.TextDiffLineType.Deleted)
+ {
+ if (findNormalLine)
+ {
+ ScrollToLine(idx + 1);
+ return;
+ }
+ }
+ else if (!findNormalLine)
+ {
+ findNormalLine = true;
+ }
+ }
+ }
+
public override void Render(DrawingContext context)
{
base.Render(context);
@@ -524,6 +616,7 @@ namespace SourceGit.Views
TextArea.TextView.PointerEntered += OnTextViewPointerChanged;
TextArea.TextView.PointerMoved += OnTextViewPointerChanged;
TextArea.TextView.PointerWheelChanged += OnTextViewPointerWheelChanged;
+ TextArea.TextView.VisualLinesChanged += OnTextViewVisualLinesChanged;
UpdateTextMate();
}
@@ -536,6 +629,7 @@ namespace SourceGit.Views
TextArea.TextView.PointerEntered -= OnTextViewPointerChanged;
TextArea.TextView.PointerMoved -= OnTextViewPointerChanged;
TextArea.TextView.PointerWheelChanged -= OnTextViewPointerWheelChanged;
+ TextArea.TextView.VisualLinesChanged -= OnTextViewVisualLinesChanged;
if (_textMate != null)
{
@@ -643,6 +737,34 @@ namespace SourceGit.Views
}
}
+ private void OnTextViewVisualLinesChanged(object sender, EventArgs e)
+ {
+ if (!TextArea.TextView.VisualLinesValid)
+ {
+ SetCurrentValue(DisplayRangeProperty, new TextDiffViewRange(0, 0));
+ return;
+ }
+
+ var lines = GetLines();
+ var start = int.MaxValue;
+ var count = 0;
+ foreach (var line in TextArea.TextView.VisualLines)
+ {
+ if (line.IsDisposed || line.FirstDocumentLine == null || line.FirstDocumentLine.IsDeleted)
+ continue;
+
+ var index = line.FirstDocumentLine.LineNumber - 1;
+ if (index >= lines.Count)
+ continue;
+
+ count++;
+ if (start > index)
+ start = index;
+ }
+
+ SetCurrentValue(DisplayRangeProperty, new TextDiffViewRange(start, start + count));
+ }
+
protected void TrySetChunk(TextDiffViewChunk chunk)
{
var old = SelectedChunk;
@@ -950,12 +1072,8 @@ namespace SourceGit.Views
private void OnTextViewScrollGotFocus(object sender, GotFocusEventArgs e)
{
- if (EnableChunkSelection && sender is ScrollViewer viewer)
- {
- var area = viewer.FindDescendantOfType