From 888bf543038da1dc8268bdc7b47b4c258784ff50 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 22 Jul 2024 16:41:35 +0800 Subject: [PATCH 01/55] code_style: remove unused code --- src/Commands/QueryBranches.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Commands/QueryBranches.cs b/src/Commands/QueryBranches.cs index 7b42878d..e598ee08 100644 --- a/src/Commands/QueryBranches.cs +++ b/src/Commands/QueryBranches.cs @@ -1,18 +1,14 @@ using System; using System.Collections.Generic; -using System.Text.RegularExpressions; namespace SourceGit.Commands { - public partial class QueryBranches : Command + public class QueryBranches : Command { private const string PREFIX_LOCAL = "refs/heads/"; private const string PREFIX_REMOTE = "refs/remotes/"; private const string PREFIX_DETACHED = "(HEAD detached at"; - [GeneratedRegex(@"^(\d+)\s(\d+)$")] - private static partial Regex REG_AHEAD_BEHIND(); - public QueryBranches(string repo) { WorkingDirectory = repo; From d8af6bd75f2555f61f52b4987fee5fda77cd3876 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 22 Jul 2024 18:24:08 +0800 Subject: [PATCH 02/55] feature: change minimal system requirement for macOS to 11.0 (#275) --- build/resources/app/App.plist | 50 +++++++++++++++++------------------ src/SourceGit.csproj | 4 +++ 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/build/resources/app/App.plist b/build/resources/app/App.plist index 3ccf7335..a9852019 100644 --- a/build/resources/app/App.plist +++ b/build/resources/app/App.plist @@ -2,30 +2,30 @@ - CFBundleIconFile - App.icns - CFBundleIdentifier - com.sourcegit-scm.sourcegit - CFBundleName - SourceGit - CFBundleVersion - SOURCE_GIT_VERSION.0 - LSMinimumSystemVersion - 10.12 - LSEnvironment - - PATH - /opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin - - CFBundleExecutable - SourceGit - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - APPL - CFBundleShortVersionString - SOURCE_GIT_VERSION - NSHighResolutionCapable - + CFBundleIconFile + App.icns + CFBundleIdentifier + com.sourcegit-scm.sourcegit + CFBundleName + SourceGit + CFBundleVersion + SOURCE_GIT_VERSION.0 + LSMinimumSystemVersion + 11.0 + LSEnvironment + + PATH + /opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin + + CFBundleExecutable + SourceGit + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleShortVersionString + SOURCE_GIT_VERSION + NSHighResolutionCapable + diff --git a/src/SourceGit.csproj b/src/SourceGit.csproj index 657b49f3..ca840c83 100644 --- a/src/SourceGit.csproj +++ b/src/SourceGit.csproj @@ -44,4 +44,8 @@ + + + + From eecea3529a1340c46fab49c33b9790d44df515c4 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 23 Jul 2024 10:22:33 +0800 Subject: [PATCH 03/55] ux: lower contrast colors in diff view --- src/Resources/Themes.axaml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Resources/Themes.axaml b/src/Resources/Themes.axaml index 3dc7943f..4bcd0826 100644 --- a/src/Resources/Themes.axaml +++ b/src/Resources/Themes.axaml @@ -27,11 +27,11 @@ White #FF1F1F1F #FF6F6F6F - #3C000000 - #3C00FF00 - #3CFF0000 - #5A00FF00 - #50FF0000 + #10000000 + #80BFE6C1 + #80FF9797 + #A7E1A7 + #F19B9D @@ -43,7 +43,7 @@ #FF1F1F1F #FF2C2C2C #FF2B2B2B - #FF1B1B1B + #FF1C1C1C #FF8F8F8F #FFDDDDDD #FF505050 @@ -61,10 +61,10 @@ #FFDDDDDD #40F1F1F1 #3C000000 - #3C00FF00 - #3CFF0000 - #5A00FF00 - #50FF0000 + #C03A5C3F + #C0633F3E + #A0308D3C + #A09F4247 From ef0cf7657183a1ddf20387bcd262be7f52e89b8c Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 23 Jul 2024 11:45:54 +0800 Subject: [PATCH 04/55] project: upgrade AvaloniaUI to 11.1.0 --- src/SourceGit.csproj | 12 ++++++------ src/Views/Histories.axaml | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/SourceGit.csproj b/src/SourceGit.csproj index ca840c83..6ddadd46 100644 --- a/src/SourceGit.csproj +++ b/src/SourceGit.csproj @@ -29,12 +29,12 @@ - - - - + + + + - + @@ -48,4 +48,4 @@ - + \ No newline at end of file diff --git a/src/Views/Histories.axaml b/src/Views/Histories.axaml index fd2f0936..8865bcf1 100644 --- a/src/Views/Histories.axaml +++ b/src/Views/Histories.axaml @@ -39,12 +39,12 @@ BorderBrush="{DynamicResource Brush.Border0}" BorderThickness="0,0,0,1"> - + Date: Tue, 23 Jul 2024 12:07:39 +0800 Subject: [PATCH 05/55] fix: `IntelliJ IDEA Ultimate` and `IntelliJ IDEA Community` fallbacks to JetBrains common icon (#279) --- src/Models/ExternalTool.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Models/ExternalTool.cs b/src/Models/ExternalTool.cs index dc164f59..401fb987 100644 --- a/src/Models/ExternalTool.cs +++ b/src/Models/ExternalTool.cs @@ -128,7 +128,7 @@ namespace SourceGit.Models public void FindJetBrainsFromToolbox(Func platformFinder) { var exclude = new List { "fleet", "dotmemory", "dottrace", "resharper-u", "androidstudio" }; - var supported_icons = new List { "CL", "DB", "DL", "DS", "GO", "IC", "IU", "JB", "PC", "PS", "PY", "QA", "QD", "RD", "RM", "RR", "WRS", "WS" }; + var supported_icons = new List { "CL", "DB", "DL", "DS", "GO", "JB", "PC", "PS", "PY", "QA", "QD", "RD", "RM", "RR", "WRS", "WS" }; var state = Path.Combine(platformFinder(), "state.json"); if (File.Exists(state)) { From e0319e3f9b36d8bd2116fe1d5ceb5e2a8cddc8e7 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 23 Jul 2024 13:48:52 +0800 Subject: [PATCH 06/55] fix: ssh-askpass not working (#272) --- src/App.axaml.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/App.axaml.cs b/src/App.axaml.cs index 6d09fe00..70b140d1 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -501,10 +501,15 @@ namespace SourceGit private bool TryLaunchedAsAskpass(IClassicDesktopStyleApplicationLifetime desktop) { var args = desktop.Args; - if (args == null || args.Length != 1 || !args[0].StartsWith("Enter passphrase", StringComparison.Ordinal)) + if (args == null || args.Length != 1) return false; - desktop.MainWindow = new Views.Askpass(args[0]); + var param = args[0]; + if (!param.StartsWith("enter passphrase", StringComparison.OrdinalIgnoreCase) && + !param.Contains(" password", StringComparison.OrdinalIgnoreCase)) + return false; + + desktop.MainWindow = new Views.Askpass(param); return true; } From 40d5a7c7f30b99d597c8fb0186f2b75a7c4e0bbc Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 23 Jul 2024 13:58:57 +0800 Subject: [PATCH 07/55] code_style: run `dotnet format` to apply rules --- src/App.axaml.cs | 10 +++++----- src/Commands/Diff.cs | 3 ++- src/Commands/QuerySingleCommit.cs | 2 -- src/Commands/QueryTrackStatus.cs | 2 +- src/Views/Histories.axaml.cs | 2 +- src/Views/TextDiffView.axaml.cs | 12 ++++++------ 6 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/App.axaml.cs b/src/App.axaml.cs index 70b140d1..b4f93e38 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -92,7 +92,7 @@ namespace SourceGit var toplevel = GetTopLevel() as Window; if (toplevel == null) return; - + var dialog = new Views.Preference(); dialog.ShowDialog(toplevel); }); @@ -102,7 +102,7 @@ namespace SourceGit var toplevel = GetTopLevel() as Window; if (toplevel == null) return; - + var dialog = new Views.Hotkeys(); dialog.ShowDialog(toplevel); }); @@ -112,7 +112,7 @@ namespace SourceGit var toplevel = GetTopLevel() as Window; if (toplevel == null) return; - + var dialog = new Views.About(); dialog.ShowDialog(toplevel); }); @@ -247,7 +247,7 @@ namespace SourceGit var geo = Current?.FindResource(key) as StreamGeometry; if (geo != null) icon.Data = geo; - + return icon; } @@ -257,7 +257,7 @@ namespace SourceGit { return desktop.MainWindow; } - + return null; } diff --git a/src/Commands/Diff.cs b/src/Commands/Diff.cs index 56c924e5..2d7a8ec2 100644 --- a/src/Commands/Diff.cs +++ b/src/Commands/Diff.cs @@ -14,7 +14,8 @@ namespace SourceGit.Commands public Diff(string repo, Models.DiffOption opt, int unified) { - _result.TextDiff = new Models.TextDiff() { + _result.TextDiff = new Models.TextDiff() + { Repo = repo, Option = opt, }; diff --git a/src/Commands/QuerySingleCommit.cs b/src/Commands/QuerySingleCommit.cs index eef08b7e..6c242631 100644 --- a/src/Commands/QuerySingleCommit.cs +++ b/src/Commands/QuerySingleCommit.cs @@ -38,7 +38,5 @@ namespace SourceGit.Commands return null; } - - } } diff --git a/src/Commands/QueryTrackStatus.cs b/src/Commands/QueryTrackStatus.cs index ce8e4d0e..abd5d5f4 100644 --- a/src/Commands/QueryTrackStatus.cs +++ b/src/Commands/QueryTrackStatus.cs @@ -4,7 +4,7 @@ namespace SourceGit.Commands { public class QueryTrackStatus : Command { - public QueryTrackStatus(string repo, string local, string upstream) + public QueryTrackStatus(string repo, string local, string upstream) { WorkingDirectory = repo; Context = repo; diff --git a/src/Views/Histories.axaml.cs b/src/Views/Histories.axaml.cs index 9e1bae46..86102d43 100644 --- a/src/Views/Histories.axaml.cs +++ b/src/Views/Histories.axaml.cs @@ -106,7 +106,7 @@ namespace SourceGit.Views if (ShowAsDateTime) StopTimer(); else - StartTimer(); + StartTimer(); } } diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index d8972c80..cfc392f1 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -37,9 +37,9 @@ namespace SourceGit.Views if (old == null) return true; - return Math.Abs(Y - old.Y) > 0.001 || - Math.Abs(Height - old.Height) > 0.001 || - StartIdx != old.StartIdx || + return Math.Abs(Y - old.Y) > 0.001 || + Math.Abs(Height - old.Height) > 0.001 || + StartIdx != old.StartIdx || EndIdx != old.EndIdx || Combined != Combined || IsOldSide != IsOldSide; @@ -1217,7 +1217,7 @@ namespace SourceGit.Views } } - private void OnDiscardChunk(object sender, RoutedEventArgs e) + private void OnDiscardChunk(object sender, RoutedEventArgs e) { var chunk = SelectedChunk; if (chunk == null) @@ -1260,12 +1260,12 @@ namespace SourceGit.Views if (change.Index == Models.ChangeState.Added) { diff.GenerateNewPatchFromSelection(change, null, selection, true, tmpFile); - } + } else if (chunk.Combined) { var treeGuid = new Commands.QueryStagedFileBlobGuid(diff.Repo, change.Path).Result(); diff.GeneratePatchFromSelection(change, treeGuid, selection, true, tmpFile); - } + } else { var treeGuid = new Commands.QueryStagedFileBlobGuid(diff.Repo, change.Path).Result(); From 183cb8a658cb9313799aa72e135661be728e3ec6 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 23 Jul 2024 14:36:27 +0800 Subject: [PATCH 08/55] enhance: supports checking updates with hotfix version --- src/Commands/AssumeUnchanged.cs | 10 +++++----- src/Commands/QueryStashChanges.cs | 1 - src/Models/Version.cs | 22 ++++++++++------------ 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/Commands/AssumeUnchanged.cs b/src/Commands/AssumeUnchanged.cs index f4cfe32b..1898122a 100644 --- a/src/Commands/AssumeUnchanged.cs +++ b/src/Commands/AssumeUnchanged.cs @@ -5,11 +5,11 @@ namespace SourceGit.Commands { public partial class AssumeUnchanged { - partial class ViewCommand : Command - { - [GeneratedRegex(@"^(\w)\s+(.+)$")] - private static partial Regex REG(); + [GeneratedRegex(@"^(\w)\s+(.+)$")] + private static partial Regex REG_PARSE(); + class ViewCommand : Command + { public ViewCommand(string repo) { WorkingDirectory = repo; @@ -25,7 +25,7 @@ namespace SourceGit.Commands protected override void OnReadline(string line) { - var match = REG().Match(line); + var match = REG_PARSE().Match(line); if (!match.Success) return; diff --git a/src/Commands/QueryStashChanges.cs b/src/Commands/QueryStashChanges.cs index bf61ca2d..3b8d2db6 100644 --- a/src/Commands/QueryStashChanges.cs +++ b/src/Commands/QueryStashChanges.cs @@ -5,7 +5,6 @@ namespace SourceGit.Commands { public partial class QueryStashChanges : Command { - [GeneratedRegex(@"^(\s?[\w\?]{1,4})\s+(.+)$")] private static partial Regex REG_FORMAT(); diff --git a/src/Models/Version.cs b/src/Models/Version.cs index aca1f0fc..35c21778 100644 --- a/src/Models/Version.cs +++ b/src/Models/Version.cs @@ -1,10 +1,9 @@ using System.Reflection; using System.Text.Json.Serialization; -using System.Text.RegularExpressions; namespace SourceGit.Models { - public partial class Version + public class Version { [JsonPropertyName("name")] public string Name { get; set; } @@ -15,21 +14,20 @@ namespace SourceGit.Models [JsonPropertyName("body")] public string Body { get; set; } - [GeneratedRegex(@"^v(\d+)\.(\d+)$")] - private static partial Regex REG_VERSION_TAG(); - public bool IsNewVersion { get { - var match = REG_VERSION_TAG().Match(TagName); - if (!match.Success) + try + { + System.Version version = new System.Version(TagName.Substring(1)); + System.Version current = Assembly.GetExecutingAssembly().GetName().Version!; + return current.CompareTo(version) < 0; + } + catch + { return false; - - var major = int.Parse(match.Groups[1].Value); - var minor = int.Parse(match.Groups[2].Value); - var ver = Assembly.GetExecutingAssembly().GetName().Version!; - return ver.Major < major || (ver.Major == major && ver.Minor < minor); + } } } } From fa9990c38cc9033604863546e64669b14329d097 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 23 Jul 2024 14:52:25 +0800 Subject: [PATCH 09/55] code_style: move `SourceGit.ViewModels.RepositorySettings` to `SourceGit.Models.RepositorySettings` --- src/App.JsonCodeGen.cs | 2 +- src/Models/RepositorySettings.cs | 91 ++++++++++++++++++++++++++++++ src/ViewModels/Repository.cs | 96 ++------------------------------ 3 files changed, 96 insertions(+), 93 deletions(-) create mode 100644 src/Models/RepositorySettings.cs diff --git a/src/App.JsonCodeGen.cs b/src/App.JsonCodeGen.cs index ffc74262..f6e3cd88 100644 --- a/src/App.JsonCodeGen.cs +++ b/src/App.JsonCodeGen.cs @@ -62,7 +62,7 @@ namespace SourceGit [JsonSerializable(typeof(Models.JetBrainsState))] [JsonSerializable(typeof(Models.ThemeOverrides))] [JsonSerializable(typeof(Models.Version))] + [JsonSerializable(typeof(Models.RepositorySettings))] [JsonSerializable(typeof(ViewModels.Preference))] - [JsonSerializable(typeof(ViewModels.RepositorySettings))] internal partial class JsonCodeGen : JsonSerializerContext { } } diff --git a/src/Models/RepositorySettings.cs b/src/Models/RepositorySettings.cs new file mode 100644 index 00000000..98926500 --- /dev/null +++ b/src/Models/RepositorySettings.cs @@ -0,0 +1,91 @@ +using Avalonia.Collections; + +namespace SourceGit.Models +{ + public class RepositorySettings + { + public DealWithLocalChanges DealWithLocalChangesOnCheckoutBranch + { + get; + set; + } = DealWithLocalChanges.DoNothing; + + public bool FetchWithoutTags + { + get; + set; + } = false; + + public DealWithLocalChanges DealWithLocalChangesOnPull + { + get; + set; + } = DealWithLocalChanges.DoNothing; + + public bool PreferRebaseInsteadOfMerge + { + get; + set; + } = true; + + public bool FetchWithoutTagsOnPull + { + get; + set; + } = false; + + public bool PushAllTags + { + get; + set; + } = false; + + public DealWithLocalChanges DealWithLocalChangesOnCreateBranch + { + get; + set; + } = DealWithLocalChanges.DoNothing; + + public bool CheckoutBranchOnCreateBranch + { + get; + set; + } = true; + + public bool AutoStageBeforeCommit + { + get; + set; + } = false; + + public AvaloniaList Filters + { + get; + set; + } = new AvaloniaList(); + + public AvaloniaList CommitMessages + { + get; + set; + } = new AvaloniaList(); + + public void PushCommitMessage(string message) + { + var existIdx = CommitMessages.IndexOf(message); + if (existIdx == 0) + return; + + if (existIdx > 0) + { + CommitMessages.Move(existIdx, 0); + return; + } + + if (CommitMessages.Count > 9) + CommitMessages.RemoveRange(9, CommitMessages.Count - 9); + + CommitMessages.Insert(0, message); + } + } +} diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 709b0f2b..f6ad023d 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -4,7 +4,6 @@ using System.IO; using System.Text.Json; using System.Threading.Tasks; -using Avalonia.Collections; using Avalonia.Controls; using Avalonia.Media; using Avalonia.Media.Imaging; @@ -14,93 +13,6 @@ using CommunityToolkit.Mvvm.ComponentModel; namespace SourceGit.ViewModels { - public class RepositorySettings - { - public Models.DealWithLocalChanges DealWithLocalChangesOnCheckoutBranch - { - get; - set; - } = Models.DealWithLocalChanges.DoNothing; - - public bool FetchWithoutTags - { - get; - set; - } = false; - - public Models.DealWithLocalChanges DealWithLocalChangesOnPull - { - get; - set; - } = Models.DealWithLocalChanges.DoNothing; - - public bool PreferRebaseInsteadOfMerge - { - get; - set; - } = true; - - public bool FetchWithoutTagsOnPull - { - get; - set; - } = false; - - public bool PushAllTags - { - get; - set; - } = false; - - public Models.DealWithLocalChanges DealWithLocalChangesOnCreateBranch - { - get; - set; - } = Models.DealWithLocalChanges.DoNothing; - - public bool CheckoutBranchOnCreateBranch - { - get; - set; - } = true; - - public bool AutoStageBeforeCommit - { - get; - set; - } = false; - - public AvaloniaList Filters - { - get; - set; - } = new AvaloniaList(); - - public AvaloniaList CommitMessages - { - get; - set; - } = new AvaloniaList(); - - public void PushCommitMessage(string message) - { - var existIdx = CommitMessages.IndexOf(message); - if (existIdx == 0) - return; - - if (existIdx > 0) - { - CommitMessages.Move(existIdx, 0); - return; - } - - if (CommitMessages.Count > 9) - CommitMessages.RemoveRange(9, CommitMessages.Count - 9); - - CommitMessages.Insert(0, message); - } - } - public class Repository : ObservableObject, Models.IRepository { public string FullPath @@ -126,7 +38,7 @@ namespace SourceGit.ViewModels set => SetProperty(ref _gitDir, value); } - public RepositorySettings Settings + public Models.RepositorySettings Settings { get => _settings; } @@ -341,12 +253,12 @@ namespace SourceGit.ViewModels } catch { - _settings = new RepositorySettings(); + _settings = new Models.RepositorySettings(); } } else { - _settings = new RepositorySettings(); + _settings = new Models.RepositorySettings(); } _watcher = new Models.Watcher(this); @@ -1985,7 +1897,7 @@ namespace SourceGit.ViewModels private string _fullpath = string.Empty; private string _gitDir = string.Empty; - private RepositorySettings _settings = null; + private Models.RepositorySettings _settings = null; private Models.Watcher _watcher = null; private Histories _histories = null; From cd1eed4356e5a4f95429e3fdecaa53a0fe7ce521 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 23 Jul 2024 15:14:30 +0800 Subject: [PATCH 10/55] fix: column header vertical seperator missing in some cases --- src/Views/Histories.axaml | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/Views/Histories.axaml b/src/Views/Histories.axaml index 8865bcf1..3f160d60 100644 --- a/src/Views/Histories.axaml +++ b/src/Views/Histories.axaml @@ -37,22 +37,13 @@ - - + - - - From 5cc30f7d104902909f7dcbc6667a75e92f85fcdf Mon Sep 17 00:00:00 2001 From: Giuseppe Lippolis Date: Tue, 23 Jul 2024 11:41:33 +0200 Subject: [PATCH 11/55] feat: Allow Swap Commits in Revision Compare --- src/Models/Commit.cs | 2 +- src/Models/IObjectId.cs | 7 +++ src/Models/Object.cs | 2 +- src/Resources/Locales/en_US.axaml | 1 + src/Resources/Locales/zh_CN.axaml | 1 + src/Resources/Locales/zh_TW.axaml | 1 + src/ViewModels/RevisionCompare.cs | 58 ++++++++++---------- src/Views/RevisionCompare.axaml | 89 +++++++++++++++++-------------- 8 files changed, 91 insertions(+), 70 deletions(-) create mode 100644 src/Models/IObjectId.cs diff --git a/src/Models/Commit.cs b/src/Models/Commit.cs index 38436fe3..6a5dcc74 100644 --- a/src/Models/Commit.cs +++ b/src/Models/Commit.cs @@ -6,7 +6,7 @@ using Avalonia.Media; namespace SourceGit.Models { - public class Commit + public class Commit: IObjectId { public static double OpacityForNotMerged { diff --git a/src/Models/IObjectId.cs b/src/Models/IObjectId.cs new file mode 100644 index 00000000..a812f871 --- /dev/null +++ b/src/Models/IObjectId.cs @@ -0,0 +1,7 @@ +namespace SourceGit.Models +{ + public interface IObjectId + { + string SHA { get; } + } +} diff --git a/src/Models/Object.cs b/src/Models/Object.cs index 119177ee..c929b30c 100644 --- a/src/Models/Object.cs +++ b/src/Models/Object.cs @@ -9,7 +9,7 @@ Commit, } - public class Object + public class Object: IObjectId { public string SHA { get; set; } public ObjectType Type { get; set; } diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index b5c6a4d3..8172242e 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -189,6 +189,7 @@ Increase Number of Visible Lines SELECT FILE TO VIEW CHANGES Show hidden symbols + Reverse Commits Open In Merge Tool Discard Changes All local changes in working copy. diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 38592803..11015a88 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -192,6 +192,7 @@ 增加可见的行数 请选择需要对比的文件 显示隐藏符号 + 反向提交 使用外部比对工具查看 放弃更改确认 所有本地址未提交的修改。 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 0c34de95..da6d0a9d 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -192,6 +192,7 @@ 增加可見的行數 請選擇需要對比的檔案 顯示隱藏符號 + 反向提交 使用外部比對工具檢視 放棄更改確認 所有本地址未提交的修改。 diff --git a/src/ViewModels/RevisionCompare.cs b/src/ViewModels/RevisionCompare.cs index 98b185c0..d9940752 100644 --- a/src/ViewModels/RevisionCompare.cs +++ b/src/ViewModels/RevisionCompare.cs @@ -2,28 +2,26 @@ using System.Collections.Generic; using System.IO; using System.Threading.Tasks; - using Avalonia.Controls; using Avalonia.Threading; - using CommunityToolkit.Mvvm.ComponentModel; namespace SourceGit.ViewModels { - public class CompareTargetWorktree + public sealed class CompareTargetWorktree : Models.IObjectId { public string SHA => string.Empty; } public class RevisionCompare : ObservableObject { - public Models.Commit StartPoint + public Models.IObjectId StartPoint { get; private set; } - public object EndPoint + public Models.IObjectId EndPoint { get; private set; @@ -43,7 +41,7 @@ namespace SourceGit.ViewModels if (SetProperty(ref _selectedChanges, value)) { if (value != null && value.Count == 1) - DiffContext = new DiffContext(_repo, new Models.DiffOption(StartPoint.SHA, _endPoint, value[0]), _diffContext); + DiffContext = new DiffContext(_repo, new Models.DiffOption(StartPoint.SHA, EndPoint?.SHA ?? string.Empty, value[0]), _diffContext); else DiffContext = null; } @@ -76,31 +74,13 @@ namespace SourceGit.ViewModels if (endPoint == null) { EndPoint = new CompareTargetWorktree(); - _endPoint = string.Empty; } else { EndPoint = endPoint; - _endPoint = endPoint.SHA; } - Task.Run(() => - { - _changes = new Commands.CompareRevisions(_repo, startPoint.SHA, _endPoint).Result(); - - var visible = _changes; - if (!string.IsNullOrWhiteSpace(_searchFilter)) - { - visible = new List(); - foreach (var c in _changes) - { - if (c.Path.Contains(_searchFilter, StringComparison.OrdinalIgnoreCase)) - visible.Add(c); - } - } - - Dispatcher.UIThread.Invoke(() => VisibleChanges = visible); - }); + Task.Run(Refresh); } public void Cleanup() @@ -140,7 +120,7 @@ namespace SourceGit.ViewModels diffWithMerger.Icon = App.CreateMenuIcon("Icons.OpenWith"); diffWithMerger.Click += (_, ev) => { - var opt = new Models.DiffOption(StartPoint.SHA, _endPoint, change); + var opt = new Models.DiffOption(StartPoint.SHA, EndPoint?.SHA ?? string.Empty, change); var toolType = Preference.Instance.ExternalMergeToolType; var toolPath = Preference.Instance.ExternalMergeToolPath; @@ -209,8 +189,32 @@ namespace SourceGit.ViewModels } } + private void Refresh() + { + _changes = new Commands.CompareRevisions(_repo, StartPoint.SHA, EndPoint?.SHA ?? string.Empty).Result(); + + var visible = _changes; + if (!string.IsNullOrWhiteSpace(_searchFilter)) + { + visible = []; + foreach (var c in _changes) + { + if (c.Path.Contains(_searchFilter, StringComparison.OrdinalIgnoreCase)) + visible.Add(c); + } + } + + Dispatcher.UIThread.Invoke(() => VisibleChanges = visible); + } + + public void Swap() + { + (StartPoint, EndPoint) = (EndPoint, StartPoint); + OnPropertyChanged(string.Empty); + Task.Run(Refresh); + } + private string _repo; - private string _endPoint; private List _changes = null; private List _visibleChanges = null; private List _selectedChanges = null; diff --git a/src/Views/RevisionCompare.axaml b/src/Views/RevisionCompare.axaml index 630f9752..e25342bd 100644 --- a/src/Views/RevisionCompare.axaml +++ b/src/Views/RevisionCompare.axaml @@ -10,56 +10,63 @@ x:Class="SourceGit.Views.RevisionCompare" x:DataType="vm:RevisionCompare" Background="{DynamicResource Brush.Window}"> + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + - + - - - - - - - - - - - - - - - - - - - - - + + From 1583b088927846a022b39fa37635d0d7623c7b26 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 23 Jul 2024 19:13:32 +0800 Subject: [PATCH 12/55] code_review: PR (#280) * tooltip for swap button * move `Views.CompareTargetWorktree` to `Models.CompareTargetWorktree` * remove unused `Models.IObjectId` * fix swap not working when target is Worktree, because Commands.CompareRevisions's Args do not changed after swapping --- src/Commands/CompareRevisions.cs | 4 +- src/Models/Commit.cs | 2 +- src/Models/CompareTargetWorktree.cs | 6 +++ src/Models/IObjectId.cs | 7 ---- src/Models/Object.cs | 2 +- src/Resources/Locales/en_US.axaml | 2 +- src/Resources/Locales/zh_CN.axaml | 2 +- src/Resources/Locales/zh_TW.axaml | 2 +- src/ViewModels/RevisionCompare.cs | 58 +++++++++++++++-------------- src/Views/RevisionCompare.axaml | 30 ++++++--------- 10 files changed, 56 insertions(+), 59 deletions(-) create mode 100644 src/Models/CompareTargetWorktree.cs delete mode 100644 src/Models/IObjectId.cs diff --git a/src/Commands/CompareRevisions.cs b/src/Commands/CompareRevisions.cs index 860cd34a..c4674c8e 100644 --- a/src/Commands/CompareRevisions.cs +++ b/src/Commands/CompareRevisions.cs @@ -13,7 +13,9 @@ namespace SourceGit.Commands { WorkingDirectory = repo; Context = repo; - Args = $"diff --name-status {start} {end}"; + + var based = string.IsNullOrEmpty(start) ? "-R" : start; + Args = $"diff --name-status {based} {end}"; } public List Result() diff --git a/src/Models/Commit.cs b/src/Models/Commit.cs index 6a5dcc74..38436fe3 100644 --- a/src/Models/Commit.cs +++ b/src/Models/Commit.cs @@ -6,7 +6,7 @@ using Avalonia.Media; namespace SourceGit.Models { - public class Commit: IObjectId + public class Commit { public static double OpacityForNotMerged { diff --git a/src/Models/CompareTargetWorktree.cs b/src/Models/CompareTargetWorktree.cs new file mode 100644 index 00000000..6505f408 --- /dev/null +++ b/src/Models/CompareTargetWorktree.cs @@ -0,0 +1,6 @@ +namespace SourceGit.Models +{ + public class CompareTargetWorktree + { + } +} diff --git a/src/Models/IObjectId.cs b/src/Models/IObjectId.cs deleted file mode 100644 index a812f871..00000000 --- a/src/Models/IObjectId.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace SourceGit.Models -{ - public interface IObjectId - { - string SHA { get; } - } -} diff --git a/src/Models/Object.cs b/src/Models/Object.cs index c929b30c..119177ee 100644 --- a/src/Models/Object.cs +++ b/src/Models/Object.cs @@ -9,7 +9,7 @@ Commit, } - public class Object: IObjectId + public class Object { public string SHA { get; set; } public ObjectType Type { get; set; } diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 8172242e..9efcc0e1 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -189,7 +189,7 @@ Increase Number of Visible Lines SELECT FILE TO VIEW CHANGES Show hidden symbols - Reverse Commits + Swap Open In Merge Tool Discard Changes All local changes in working copy. diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 11015a88..cc4512cf 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -192,7 +192,7 @@ 增加可见的行数 请选择需要对比的文件 显示隐藏符号 - 反向提交 + 交换比对双方 使用外部比对工具查看 放弃更改确认 所有本地址未提交的修改。 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index da6d0a9d..a5a68398 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -192,7 +192,7 @@ 增加可見的行數 請選擇需要對比的檔案 顯示隱藏符號 - 反向提交 + 交換比對雙方 使用外部比對工具檢視 放棄更改確認 所有本地址未提交的修改。 diff --git a/src/ViewModels/RevisionCompare.cs b/src/ViewModels/RevisionCompare.cs index d9940752..5f008bad 100644 --- a/src/ViewModels/RevisionCompare.cs +++ b/src/ViewModels/RevisionCompare.cs @@ -2,29 +2,26 @@ using System.Collections.Generic; using System.IO; using System.Threading.Tasks; + using Avalonia.Controls; using Avalonia.Threading; + using CommunityToolkit.Mvvm.ComponentModel; namespace SourceGit.ViewModels { - public sealed class CompareTargetWorktree : Models.IObjectId - { - public string SHA => string.Empty; - } - public class RevisionCompare : ObservableObject { - public Models.IObjectId StartPoint + public object StartPoint { - get; - private set; + get => _startPoint; + private set => SetProperty(ref _startPoint, value); } - public Models.IObjectId EndPoint + public object EndPoint { - get; - private set; + get => _endPoint; + private set => SetProperty(ref _endPoint, value); } public List VisibleChanges @@ -41,9 +38,14 @@ namespace SourceGit.ViewModels if (SetProperty(ref _selectedChanges, value)) { if (value != null && value.Count == 1) - DiffContext = new DiffContext(_repo, new Models.DiffOption(StartPoint.SHA, EndPoint?.SHA ?? string.Empty, value[0]), _diffContext); + { + var option = new Models.DiffOption(GetSHA(_startPoint), GetSHA(_endPoint), value[0]); + DiffContext = new DiffContext(_repo, option, _diffContext); + } else + { DiffContext = null; + } } } } @@ -69,16 +71,8 @@ namespace SourceGit.ViewModels public RevisionCompare(string repo, Models.Commit startPoint, Models.Commit endPoint) { _repo = repo; - StartPoint = startPoint; - - if (endPoint == null) - { - EndPoint = new CompareTargetWorktree(); - } - else - { - EndPoint = endPoint; - } + _startPoint = (object)startPoint ?? new Models.CompareTargetWorktree(); + _endPoint = (object)endPoint ?? new Models.CompareTargetWorktree(); Task.Run(Refresh); } @@ -86,6 +80,8 @@ namespace SourceGit.ViewModels public void Cleanup() { _repo = null; + _startPoint = null; + _endPoint = null; if (_changes != null) _changes.Clear(); if (_visibleChanges != null) @@ -102,6 +98,12 @@ namespace SourceGit.ViewModels repo?.NavigateToCommit(commitSHA); } + public void Swap() + { + (StartPoint, EndPoint) = (_endPoint, _startPoint); + Task.Run(Refresh); + } + public void ClearSearchFilter() { SearchFilter = string.Empty; @@ -120,7 +122,7 @@ namespace SourceGit.ViewModels diffWithMerger.Icon = App.CreateMenuIcon("Icons.OpenWith"); diffWithMerger.Click += (_, ev) => { - var opt = new Models.DiffOption(StartPoint.SHA, EndPoint?.SHA ?? string.Empty, change); + var opt = new Models.DiffOption(GetSHA(_startPoint), GetSHA(_endPoint), change); var toolType = Preference.Instance.ExternalMergeToolType; var toolPath = Preference.Instance.ExternalMergeToolPath; @@ -191,7 +193,7 @@ namespace SourceGit.ViewModels private void Refresh() { - _changes = new Commands.CompareRevisions(_repo, StartPoint.SHA, EndPoint?.SHA ?? string.Empty).Result(); + _changes = new Commands.CompareRevisions(_repo, GetSHA(_startPoint), GetSHA(_endPoint)).Result(); var visible = _changes; if (!string.IsNullOrWhiteSpace(_searchFilter)) @@ -207,14 +209,14 @@ namespace SourceGit.ViewModels Dispatcher.UIThread.Invoke(() => VisibleChanges = visible); } - public void Swap() + private string GetSHA(object obj) { - (StartPoint, EndPoint) = (EndPoint, StartPoint); - OnPropertyChanged(string.Empty); - Task.Run(Refresh); + return obj is Models.Commit commit ? commit.SHA : string.Empty; } private string _repo; + private object _startPoint = null; + private object _endPoint = null; private List _changes = null; private List _visibleChanges = null; private List _selectedChanges = null; diff --git a/src/Views/RevisionCompare.axaml b/src/Views/RevisionCompare.axaml index e25342bd..bb101ae3 100644 --- a/src/Views/RevisionCompare.axaml +++ b/src/Views/RevisionCompare.axaml @@ -10,16 +10,12 @@ x:Class="SourceGit.Views.RevisionCompare" x:DataType="vm:RevisionCompare" Background="{DynamicResource Brush.Window}"> - - + + - + @@ -32,8 +28,8 @@ - + + @@ -41,7 +37,9 @@ + + @@ -51,17 +49,12 @@ - + @@ -72,6 +65,7 @@ + From b160f4e47a01e276cca3d6f45e970149e6dc58d1 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 23 Jul 2024 19:30:16 +0800 Subject: [PATCH 13/55] enhance: clear selection after swap compare targets --- src/ViewModels/RevisionCompare.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ViewModels/RevisionCompare.cs b/src/ViewModels/RevisionCompare.cs index 5f008bad..6bfcf566 100644 --- a/src/ViewModels/RevisionCompare.cs +++ b/src/ViewModels/RevisionCompare.cs @@ -101,6 +101,7 @@ namespace SourceGit.ViewModels public void Swap() { (StartPoint, EndPoint) = (_endPoint, _startPoint); + SelectedChanges = []; Task.Run(Refresh); } From 300c1c99bf57488f670a6c5186fa4763d937cdd2 Mon Sep 17 00:00:00 2001 From: RevenantX Date: Tue, 23 Jul 2024 21:00:54 +0300 Subject: [PATCH 14/55] Add copy info that copies "{Short SHA} - {commit subject}" into clipboard --- src/Resources/Locales/en_US.axaml | 1 + src/ViewModels/Histories.cs | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 9efcc0e1..85ac9f1b 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -97,6 +97,7 @@ Compare with HEAD Compare with Worktree Copy SHA + Copy Info Interactive Rebase ${0}$ to Here Rebase ${0}$ to Here Reset ${0}$ to Here diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs index 15549038..71f3b6f0 100644 --- a/src/ViewModels/Histories.cs +++ b/src/ViewModels/Histories.cs @@ -435,6 +435,17 @@ namespace SourceGit.ViewModels e.Handled = true; }; menu.Items.Add(copySHA); + + var copyInfo = new MenuItem(); + copyInfo.Header = App.Text("CommitCM.CopyInfo"); + copyInfo.Icon = App.CreateMenuIcon("Icons.Copy"); + copyInfo.Click += (_, e) => + { + App.CopyText($"{commit.SHA[..7]} - {commit.Subject}"); + e.Handled = true; + }; + menu.Items.Add(copyInfo); + return menu; } From 6038fecab4ba06dd1918174deda6f0b8ffd4028d Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 24 Jul 2024 10:42:58 +0800 Subject: [PATCH 15/55] code_review: PR (#282) * add translations for `Text.CommitCM.CopyInfo` * unify length of commit's short SHA --- src/Resources/Locales/en_US.axaml | 2 +- src/Resources/Locales/zh_CN.axaml | 1 + src/Resources/Locales/zh_TW.axaml | 1 + src/ViewModels/Histories.cs | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 85ac9f1b..e1220d5f 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -96,8 +96,8 @@ Checkout Commit Compare with HEAD Compare with Worktree - Copy SHA Copy Info + Copy SHA Interactive Rebase ${0}$ to Here Rebase ${0}$ to Here Reset ${0}$ to Here diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index cc4512cf..92cfe42f 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -99,6 +99,7 @@ 检出此提交 与当前HEAD比较 与本地工作树比较 + 复制简要信息 复制提交指纹 交互式变基(rebase -i) ${0}$ 到此处 变基(rebase) ${0}$ 到此处 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index a5a68398..56e26678 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -99,6 +99,7 @@ 檢出此提交 與當前HEAD比較 與本地工作樹比較 + 複製簡要資訊 複製提交指紋 互動式變基(rebase -i) ${0}$ 到此處 變基(rebase) ${0}$ 到此處 diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs index 71f3b6f0..e66f1415 100644 --- a/src/ViewModels/Histories.cs +++ b/src/ViewModels/Histories.cs @@ -441,7 +441,7 @@ namespace SourceGit.ViewModels copyInfo.Icon = App.CreateMenuIcon("Icons.Copy"); copyInfo.Click += (_, e) => { - App.CopyText($"{commit.SHA[..7]} - {commit.Subject}"); + App.CopyText($"{commit.SHA.Substring(0, 10)} - {commit.Subject}"); e.Handled = true; }; menu.Items.Add(copyInfo); From 0dee3a19691e07b781e3fa188e35328ddadf09cc Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 24 Jul 2024 11:16:28 +0800 Subject: [PATCH 16/55] refactor: use `Binding.TargetNullValue` instead of empty class `Models.CompareTargetWorktree` --- src/Models/CompareTargetWorktree.cs | 6 ---- src/ViewModels/RevisionCompare.cs | 4 +-- src/Views/RevisionCompare.axaml | 44 +++++++++++++++-------------- 3 files changed, 25 insertions(+), 29 deletions(-) delete mode 100644 src/Models/CompareTargetWorktree.cs diff --git a/src/Models/CompareTargetWorktree.cs b/src/Models/CompareTargetWorktree.cs deleted file mode 100644 index 6505f408..00000000 --- a/src/Models/CompareTargetWorktree.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace SourceGit.Models -{ - public class CompareTargetWorktree - { - } -} diff --git a/src/ViewModels/RevisionCompare.cs b/src/ViewModels/RevisionCompare.cs index 6bfcf566..8ac6f823 100644 --- a/src/ViewModels/RevisionCompare.cs +++ b/src/ViewModels/RevisionCompare.cs @@ -71,8 +71,8 @@ namespace SourceGit.ViewModels public RevisionCompare(string repo, Models.Commit startPoint, Models.Commit endPoint) { _repo = repo; - _startPoint = (object)startPoint ?? new Models.CompareTargetWorktree(); - _endPoint = (object)endPoint ?? new Models.CompareTargetWorktree(); + _startPoint = startPoint; + _endPoint = endPoint; Task.Run(Refresh); } diff --git a/src/Views/RevisionCompare.axaml b/src/Views/RevisionCompare.axaml index bb101ae3..41439b6b 100644 --- a/src/Views/RevisionCompare.axaml +++ b/src/Views/RevisionCompare.axaml @@ -10,9 +10,8 @@ x:Class="SourceGit.Views.RevisionCompare" x:DataType="vm:RevisionCompare" Background="{DynamicResource Brush.Window}"> - - - + + @@ -27,25 +26,23 @@ - - - - - - - - + - - - - - + + + + + + + + + + @@ -56,11 +53,16 @@ - - - - - + + + + + + + + + + From 9e048751ae0833254b4de2a152f84b5f6edeece6 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 24 Jul 2024 11:44:13 +0800 Subject: [PATCH 17/55] refactor: move non-observable object from `ViewModels` to `Models` * ViewModels.MergeMode -> Models.MergeMode * ViewModels.Notification -> Models.Notification * ViewModels.ResetMode -> Models.ResetMode * use `int` instead of `ViewModels.CountSelectedCommits` --- src/Models/MergeMode.cs | 24 +++++++++++++++ src/{ViewModels => Models}/Notification.cs | 2 +- src/Models/ResetMode.cs | 27 ++++++++++++++++ src/ViewModels/Histories.cs | 7 +---- src/ViewModels/Launcher.cs | 4 +-- src/ViewModels/LauncherPage.cs | 4 +-- src/ViewModels/Merge.cs | 33 ++------------------ src/ViewModels/Reset.cs | 36 ++-------------------- src/Views/Histories.axaml | 4 +-- src/Views/LauncherPage.axaml | 3 +- src/Views/LauncherPage.axaml.cs | 2 +- src/Views/Merge.axaml | 5 +-- src/Views/Reset.axaml | 5 +-- 13 files changed, 74 insertions(+), 82 deletions(-) create mode 100644 src/Models/MergeMode.cs rename src/{ViewModels => Models}/Notification.cs (87%) create mode 100644 src/Models/ResetMode.cs diff --git a/src/Models/MergeMode.cs b/src/Models/MergeMode.cs new file mode 100644 index 00000000..23ace5c5 --- /dev/null +++ b/src/Models/MergeMode.cs @@ -0,0 +1,24 @@ +namespace SourceGit.Models +{ + public class MergeMode + { + public static readonly MergeMode[] Supported = + [ + new MergeMode("Default", "Fast-forward if possible", ""), + new MergeMode("No Fast-forward", "Always create a merge commit", "--no-ff"), + new MergeMode("Squash", "Use '--squash'", "--squash"), + new MergeMode("Don't commit", "Merge without commit", "--no-commit"), + ]; + + public string Name { get; set; } + public string Desc { get; set; } + public string Arg { get; set; } + + public MergeMode(string n, string d, string a) + { + Name = n; + Desc = d; + Arg = a; + } + } +} diff --git a/src/ViewModels/Notification.cs b/src/Models/Notification.cs similarity index 87% rename from src/ViewModels/Notification.cs rename to src/Models/Notification.cs index e54c3790..2261e327 100644 --- a/src/ViewModels/Notification.cs +++ b/src/Models/Notification.cs @@ -1,4 +1,4 @@ -namespace SourceGit.ViewModels +namespace SourceGit.Models { public class Notification { diff --git a/src/Models/ResetMode.cs b/src/Models/ResetMode.cs new file mode 100644 index 00000000..bf608149 --- /dev/null +++ b/src/Models/ResetMode.cs @@ -0,0 +1,27 @@ +using Avalonia.Media; + +namespace SourceGit.Models +{ + public class ResetMode + { + 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("Hard", "Discard all changes", "--hard", Brushes.Red), + ]; + + public string Name { get; set; } + public string Desc { get; set; } + public string Arg { get; set; } + public IBrush Color { get; set; } + + public ResetMode(string n, string d, string a, IBrush b) + { + Name = n; + Desc = d; + Arg = a; + Color = b; + } + } +} diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs index e66f1415..59c03324 100644 --- a/src/ViewModels/Histories.cs +++ b/src/ViewModels/Histories.cs @@ -9,11 +9,6 @@ using CommunityToolkit.Mvvm.ComponentModel; namespace SourceGit.ViewModels { - public class CountSelectedCommits - { - public int Count { get; set; } - } - public class Histories : ObservableObject { public bool IsLoading @@ -143,7 +138,7 @@ namespace SourceGit.ViewModels else { _repo.SearchResultSelectedCommit = null; - DetailContext = new CountSelectedCommits() { Count = commits.Count }; + DetailContext = commits.Count; } } diff --git a/src/ViewModels/Launcher.cs b/src/ViewModels/Launcher.cs index 19c328c4..71584098 100644 --- a/src/ViewModels/Launcher.cs +++ b/src/ViewModels/Launcher.cs @@ -38,7 +38,7 @@ namespace SourceGit.ViewModels var root = new Commands.QueryRepositoryRootPath(startupRepo).Result(); if (string.IsNullOrEmpty(root)) { - Pages[0].Notifications.Add(new Notification + Pages[0].Notifications.Add(new Models.Notification { IsError = true, Message = $"Given path: '{startupRepo}' is NOT a valid repository!" @@ -272,7 +272,7 @@ namespace SourceGit.ViewModels public void DispatchNotification(string pageId, string message, bool isError) { - var notification = new Notification() + var notification = new Models.Notification() { IsError = isError, Message = message, diff --git a/src/ViewModels/LauncherPage.cs b/src/ViewModels/LauncherPage.cs index 27d84d10..65d5f7a5 100644 --- a/src/ViewModels/LauncherPage.cs +++ b/src/ViewModels/LauncherPage.cs @@ -18,11 +18,11 @@ namespace SourceGit.ViewModels set => SetProperty(ref _data, value); } - public AvaloniaList Notifications + public AvaloniaList Notifications { get; set; - } = new AvaloniaList(); + } = new AvaloniaList(); public LauncherPage() { diff --git a/src/ViewModels/Merge.cs b/src/ViewModels/Merge.cs index 37b537fc..48af8722 100644 --- a/src/ViewModels/Merge.cs +++ b/src/ViewModels/Merge.cs @@ -1,22 +1,7 @@ -using System.Collections.Generic; -using System.Threading.Tasks; +using System.Threading.Tasks; namespace SourceGit.ViewModels { - public class MergeMode - { - public string Name { get; set; } - public string Desc { get; set; } - public string Arg { get; set; } - - public MergeMode(string n, string d, string a) - { - Name = n; - Desc = d; - Arg = a; - } - } - public class Merge : Popup { public string Source @@ -31,13 +16,7 @@ namespace SourceGit.ViewModels private set; } - public List Modes - { - get; - private set; - } - - public MergeMode SelectedMode + public Models.MergeMode SelectedMode { get; set; @@ -48,13 +27,7 @@ namespace SourceGit.ViewModels _repo = repo; Source = source; Into = into; - Modes = new List() { - new MergeMode("Default", "Fast-forward if possible", ""), - new MergeMode("No Fast-forward", "Always create a merge commit", "--no-ff"), - new MergeMode("Squash", "Use '--squash'", "--squash"), - new MergeMode("Don't commit", "Merge without commit", "--no-commit"), - }; - SelectedMode = Modes[0]; + SelectedMode = Models.MergeMode.Supported[0]; View = new Views.Merge() { DataContext = this }; } diff --git a/src/ViewModels/Reset.cs b/src/ViewModels/Reset.cs index 30b89137..ba3a3794 100644 --- a/src/ViewModels/Reset.cs +++ b/src/ViewModels/Reset.cs @@ -1,26 +1,7 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -using Avalonia.Media; +using System.Threading.Tasks; namespace SourceGit.ViewModels { - public class ResetMode - { - public string Name { get; set; } - public string Desc { get; set; } - public string Arg { get; set; } - public IBrush Color { get; set; } - - public ResetMode(string n, string d, string a, IBrush b) - { - Name = n; - Desc = d; - Arg = a; - Color = b; - } - } - public class Reset : Popup { public Models.Branch Current @@ -35,13 +16,7 @@ namespace SourceGit.ViewModels private set; } - public List Modes - { - get; - private set; - } - - public ResetMode SelectedMode + public Models.ResetMode SelectedMode { get; set; @@ -52,12 +27,7 @@ namespace SourceGit.ViewModels _repo = repo; Current = current; To = to; - Modes = new List() { - new ResetMode("Soft", "Keep all changes. Stage differences", "--soft", Brushes.Green), - new ResetMode("Mixed", "Keep all changes. Unstage differences", "--mixed", Brushes.Orange), - new ResetMode("Hard", "Discard all changes", "--hard", Brushes.Red), - }; - SelectedMode = Modes[0]; + SelectedMode = Models.ResetMode.Supported[0]; View = new Views.Reset() { DataContext = this }; } diff --git a/src/Views/Histories.axaml b/src/Views/Histories.axaml index 3f160d60..74818238 100644 --- a/src/Views/Histories.axaml +++ b/src/Views/Histories.axaml @@ -215,7 +215,7 @@ - + + Text="{Binding Converter={x:Static c:StringConverters.FormatByResourceKey}, ConverterParameter='Histories.Selected'}"/> diff --git a/src/Views/LauncherPage.axaml b/src/Views/LauncherPage.axaml index f4cc3f8d..dda5b7ef 100644 --- a/src/Views/LauncherPage.axaml +++ b/src/Views/LauncherPage.axaml @@ -2,6 +2,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:m="using:SourceGit.Models" xmlns:v="using:SourceGit.Views" xmlns:vm="using:SourceGit.ViewModels" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" @@ -86,7 +87,7 @@ - + diff --git a/src/Views/LauncherPage.axaml.cs b/src/Views/LauncherPage.axaml.cs index 17331ec0..44a5351b 100644 --- a/src/Views/LauncherPage.axaml.cs +++ b/src/Views/LauncherPage.axaml.cs @@ -34,7 +34,7 @@ namespace SourceGit.Views private void OnDismissNotification(object sender, RoutedEventArgs e) { - if (sender is Button { DataContext: ViewModels.Notification notice } && + if (sender is Button { DataContext: Models.Notification notice } && DataContext is ViewModels.LauncherPage page) page.Notifications.Remove(notice); diff --git a/src/Views/Merge.axaml b/src/Views/Merge.axaml index 8ab08c2a..b63bfc04 100644 --- a/src/Views/Merge.axaml +++ b/src/Views/Merge.axaml @@ -2,6 +2,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:m="using:SourceGit.Models" xmlns:vm="using:SourceGit.ViewModels" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="SourceGit.Views.Merge" @@ -36,10 +37,10 @@ - + diff --git a/src/Views/Reset.axaml b/src/Views/Reset.axaml index 238a7849..3c9a78f8 100644 --- a/src/Views/Reset.axaml +++ b/src/Views/Reset.axaml @@ -2,6 +2,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:m="using:SourceGit.Models" xmlns:vm="using:SourceGit.ViewModels" xmlns:c="using:SourceGit.Converters" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" @@ -38,10 +39,10 @@ - + From 3ef703c65dff81ec2faf40bee46fc8cd6bfbfca8 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 24 Jul 2024 11:45:16 +0800 Subject: [PATCH 18/55] code_style: run `dotnet format` --- src/Models/ResetMode.cs | 2 +- src/ViewModels/Histories.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Models/ResetMode.cs b/src/Models/ResetMode.cs index bf608149..f2bfb5ef 100644 --- a/src/Models/ResetMode.cs +++ b/src/Models/ResetMode.cs @@ -4,7 +4,7 @@ namespace SourceGit.Models { public class ResetMode { - public static readonly ResetMode[] Supported = + 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), diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs index 59c03324..08701c48 100644 --- a/src/ViewModels/Histories.cs +++ b/src/ViewModels/Histories.cs @@ -430,7 +430,7 @@ namespace SourceGit.ViewModels e.Handled = true; }; menu.Items.Add(copySHA); - + var copyInfo = new MenuItem(); copyInfo.Header = App.Text("CommitCM.CopyInfo"); copyInfo.Icon = App.CreateMenuIcon("Icons.Copy"); @@ -440,7 +440,7 @@ namespace SourceGit.ViewModels e.Handled = true; }; menu.Items.Add(copyInfo); - + return menu; } From ad3eeabb833f679f116d432a3af464b74b1eae23 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 24 Jul 2024 12:17:44 +0800 Subject: [PATCH 19/55] feature: allow swap in branch compare --- src/ViewModels/BranchCompare.cs | 87 ++++++++++++++++++++------------- src/Views/BranchCompare.axaml | 5 +- src/Views/RevisionCompare.axaml | 4 +- 3 files changed, 60 insertions(+), 36 deletions(-) diff --git a/src/ViewModels/BranchCompare.cs b/src/ViewModels/BranchCompare.cs index d2463aca..1d19a229 100644 --- a/src/ViewModels/BranchCompare.cs +++ b/src/ViewModels/BranchCompare.cs @@ -14,14 +14,14 @@ namespace SourceGit.ViewModels { public Models.Branch Base { - get; - private set; + get => _based; + private set => SetProperty(ref _based, value); } public Models.Branch To { - get; - private set; + get => _to; + private set => SetProperty(ref _to, value); } public Models.Commit BaseHead @@ -50,7 +50,7 @@ namespace SourceGit.ViewModels if (SetProperty(ref _selectedChanges, value)) { if (value != null && value.Count == 1) - DiffContext = new DiffContext(_repo, new Models.DiffOption(Base.Head, To.Head, value[0]), _diffContext); + DiffContext = new DiffContext(_repo, new Models.DiffOption(_based.Head, _to.Head, value[0]), _diffContext); else DiffContext = null; } @@ -78,34 +78,10 @@ namespace SourceGit.ViewModels public BranchCompare(string repo, Models.Branch baseBranch, Models.Branch toBranch) { _repo = repo; + _based = baseBranch; + _to = toBranch; - Base = baseBranch; - To = toBranch; - - Task.Run(() => - { - var baseHead = new Commands.QuerySingleCommit(_repo, Base.Head).Result(); - var toHead = new Commands.QuerySingleCommit(_repo, To.Head).Result(); - _changes = new Commands.CompareRevisions(_repo, Base.Head, To.Head).Result(); - - var visible = _changes; - if (!string.IsNullOrWhiteSpace(_searchFilter)) - { - visible = new List(); - foreach (var c in _changes) - { - if (c.Path.Contains(_searchFilter, StringComparison.OrdinalIgnoreCase)) - visible.Add(c); - } - } - - Dispatcher.UIThread.Invoke(() => - { - BaseHead = baseHead; - ToHead = toHead; - VisibleChanges = visible; - }); - }); + Refresh(); } public void NavigateTo(string commitSHA) @@ -114,6 +90,17 @@ namespace SourceGit.ViewModels repo?.NavigateToCommit(commitSHA); } + public void Swap() + { + (Base, To) = (_to, _based); + SelectedChanges = []; + + if (_baseHead != null) + (BaseHead, ToHead) = (_toHead, _baseHead); + + Refresh(); + } + public void ClearSearchFilter() { SearchFilter = string.Empty; @@ -134,7 +121,7 @@ namespace SourceGit.ViewModels { var toolType = Preference.Instance.ExternalMergeToolType; var toolPath = Preference.Instance.ExternalMergeToolPath; - var opt = new Models.DiffOption(Base.Head, To.Head, change); + var opt = new Models.DiffOption(_based.Head, _to.Head, change); Task.Run(() => Commands.MergeTool.OpenForDiff(_repo, toolType, toolPath, opt)); ev.Handled = true; @@ -179,6 +166,38 @@ namespace SourceGit.ViewModels return menu; } + private void Refresh() + { + Task.Run(() => + { + if (_baseHead == null) + { + var baseHead = new Commands.QuerySingleCommit(_repo, _based.Head).Result(); + var toHead = new Commands.QuerySingleCommit(_repo, _to.Head).Result(); + Dispatcher.UIThread.Invoke(() => + { + BaseHead = baseHead; + ToHead = toHead; + }); + } + + _changes = new Commands.CompareRevisions(_repo, _based.Head, _to.Head).Result(); + + var visible = _changes; + if (!string.IsNullOrWhiteSpace(_searchFilter)) + { + visible = new List(); + foreach (var c in _changes) + { + if (c.Path.Contains(_searchFilter, StringComparison.OrdinalIgnoreCase)) + visible.Add(c); + } + } + + Dispatcher.UIThread.Invoke(() => VisibleChanges = visible); + }); + } + private void RefreshVisible() { if (_changes == null) @@ -202,6 +221,8 @@ namespace SourceGit.ViewModels } private string _repo; + private Models.Branch _based = null; + private Models.Branch _to = null; private Models.Commit _baseHead = null; private Models.Commit _toHead = null; private List _changes = null; diff --git a/src/Views/BranchCompare.axaml b/src/Views/BranchCompare.axaml index f8a1964f..759fd939 100644 --- a/src/Views/BranchCompare.axaml +++ b/src/Views/BranchCompare.axaml @@ -69,7 +69,10 @@ - + + diff --git a/src/Views/RevisionCompare.axaml b/src/Views/RevisionCompare.axaml index 41439b6b..52bd8d9e 100644 --- a/src/Views/RevisionCompare.axaml +++ b/src/Views/RevisionCompare.axaml @@ -47,8 +47,8 @@ - From f8caeceadebe68455eb30fca6f3295275acd1391 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 24 Jul 2024 14:32:27 +0800 Subject: [PATCH 20/55] refactor: remove unnecessary memebers --- src/App.axaml.cs | 5 ++++ src/ViewModels/Clone.cs | 48 +++++++++++++++++++++++---------------- src/ViewModels/Welcome.cs | 20 +++------------- src/Views/Blame.axaml | 1 - src/Views/Blame.axaml.cs | 6 ----- 5 files changed, 36 insertions(+), 44 deletions(-) diff --git a/src/App.axaml.cs b/src/App.axaml.cs index b4f93e38..3cb3909c 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -302,6 +302,11 @@ namespace SourceGit }); } + public static ViewModels.Launcher GetLauncer() + { + return Current is App app ? app._launcher : null; + } + public static ViewModels.Repository FindOpenedRepository(string repoPath) { if (Current is App app && app._launcher != null) diff --git a/src/ViewModels/Clone.cs b/src/ViewModels/Clone.cs index 7f03e0fd..641fd544 100644 --- a/src/ViewModels/Clone.cs +++ b/src/ViewModels/Clone.cs @@ -3,6 +3,8 @@ using System.ComponentModel.DataAnnotations; using System.IO; using System.Threading.Tasks; +using Avalonia.Threading; + namespace SourceGit.ViewModels { public class Clone : Popup @@ -51,28 +53,25 @@ namespace SourceGit.ViewModels set => SetProperty(ref _extraArgs, value); } - public Clone(Launcher launcher) + public Clone() { - _launcher = launcher; - _page = launcher.ActivePage; - View = new Views.Clone() { DataContext = this }; - App.GetClipboardTextAsync() - .ContinueWith(t => + + Task.Run(async () => + { + try { - if (t.IsFaulted) + var text = await App.GetClipboardTextAsync(); + if (Models.Remote.IsValidURL(text)) { - t.Exception.Handle(static _ => true); + Dispatcher.UIThread.Invoke(() => Remote = text); } - else if (t.IsCompleted) - { - var result = t.Result; - if (Models.Remote.IsValidURL(result)) - { - Remote = result; - } - } - }); + } + catch + { + // ignore + } + }); } public static ValidationResult ValidateRemote(string remote, ValidationContext _) @@ -131,15 +130,24 @@ namespace SourceGit.ViewModels { var normalizedPath = path.Replace("\\", "/"); var node = Preference.Instance.FindOrAddNodeByRepositoryPath(normalizedPath, null, true); - _launcher.OpenRepositoryInTab(node, _page); + var launcher = App.GetLauncer(); + var page = null as LauncherPage; + foreach (var one in launcher.Pages) + { + if (one.GetId() == HostPageId) + { + page = one; + break; + } + } + + launcher.OpenRepositoryInTab(node, page); }); return true; }); } - private readonly Launcher _launcher = null; - private readonly LauncherPage _page = null; private string _remote = string.Empty; private bool _useSSH = false; private string _sshKey = string.Empty; diff --git a/src/ViewModels/Welcome.cs b/src/ViewModels/Welcome.cs index a1bc0a46..8d6c423e 100644 --- a/src/ViewModels/Welcome.cs +++ b/src/ViewModels/Welcome.cs @@ -1,9 +1,7 @@ using System; -using Avalonia; using Avalonia.Collections; using Avalonia.Controls; -using Avalonia.Controls.ApplicationLifetimes; using CommunityToolkit.Mvvm.ComponentModel; @@ -50,23 +48,16 @@ namespace SourceGit.ViewModels return; } - if (PopupHost.CanCreatePopup() && - Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime { MainWindow: { DataContext: Launcher launcher } }) - { - PopupHost.ShowPopup(new Clone(launcher)); - } + if (PopupHost.CanCreatePopup()) + PopupHost.ShowPopup(new Clone()); } public void OpenTerminal() { if (!Preference.Instance.IsGitConfigured()) - { App.RaiseException(PopupHost.Active.GetId(), App.Text("NotConfigured")); - } else - { Native.OS.OpenTerminal(null); - } } public void ClearSearchFilter() @@ -96,12 +87,7 @@ namespace SourceGit.ViewModels openAll.Icon = App.CreateMenuIcon("Icons.Folder.Open"); openAll.Click += (_, e) => { - if (PopupHost.CanCreatePopup() && - Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime { MainWindow: { DataContext: Launcher launcher } }) - { - OpenAllInNode(launcher, node); - } - + OpenAllInNode(App.GetLauncer(), node); e.Handled = true; }; diff --git a/src/Views/Blame.axaml b/src/Views/Blame.axaml index 9265b0d6..b7b23e82 100644 --- a/src/Views/Blame.axaml +++ b/src/Views/Blame.axaml @@ -9,7 +9,6 @@ x:DataType="vm:Blame" Icon="/App.ico" Title="{DynamicResource Text.Blame}" - WindowStartupLocation="CenterOwner" MinWidth="1280" MinHeight="720"> diff --git a/src/Views/Blame.axaml.cs b/src/Views/Blame.axaml.cs index a8f74b95..ba539d68 100644 --- a/src/Views/Blame.axaml.cs +++ b/src/Views/Blame.axaml.cs @@ -4,7 +4,6 @@ using System.Globalization; using Avalonia; using Avalonia.Controls; -using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.Media; @@ -326,11 +325,6 @@ namespace SourceGit.Views { public Blame() { - if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) - { - Owner = desktop.MainWindow; - } - InitializeComponent(); } From 6f317039ab324a600f05d27559cc0d13717da79e Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 24 Jul 2024 15:36:26 +0800 Subject: [PATCH 21/55] feature: add `CurrentBranch` property to `ViewModels.Repository` --- src/ViewModels/Histories.cs | 2 +- src/ViewModels/Pull.cs | 2 +- src/ViewModels/Repository.cs | 121 +++++++++++++++++----------------- src/ViewModels/WorkingCopy.cs | 2 +- 4 files changed, 63 insertions(+), 64 deletions(-) diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs index 08701c48..61b33a9b 100644 --- a/src/ViewModels/Histories.cs +++ b/src/ViewModels/Histories.cs @@ -147,7 +147,7 @@ namespace SourceGit.ViewModels if (datagrid.SelectedItems.Count != 1) return null; - var current = _repo.Branches.Find(x => x.IsCurrent); + var current = _repo.CurrentBranch; if (current == null) return null; diff --git a/src/ViewModels/Pull.cs b/src/ViewModels/Pull.cs index 743315fa..2811f306 100644 --- a/src/ViewModels/Pull.cs +++ b/src/ViewModels/Pull.cs @@ -68,7 +68,7 @@ namespace SourceGit.ViewModels public Pull(Repository repo, Models.Branch specifiedRemoteBranch) { _repo = repo; - _current = repo.Branches.Find(x => x.IsCurrent); + _current = repo.CurrentBranch; if (specifiedRemoteBranch != null) { diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index f6ad023d..659df263 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -99,6 +99,12 @@ namespace SourceGit.ViewModels private set => SetProperty(ref _branches, value); } + public Models.Branch CurrentBranch + { + get => _currentBranch; + private set => SetProperty(ref _currentBranch, value); + } + public List LocalBranchTrees { get => _localBranchTrees; @@ -364,7 +370,7 @@ namespace SourceGit.ViewModels if (!PopupHost.CanCreatePopup()) return; - if (Remotes.Count == 0) + if (_remotes.Count == 0) { App.RaiseException(_fullpath, "No remotes added to this repository!!!"); return; @@ -378,7 +384,7 @@ namespace SourceGit.ViewModels if (!PopupHost.CanCreatePopup()) return; - if (Remotes.Count == 0) + if (_remotes.Count == 0) { App.RaiseException(_fullpath, "No remotes added to this repository!!!"); return; @@ -392,13 +398,13 @@ namespace SourceGit.ViewModels if (!PopupHost.CanCreatePopup()) return; - if (Remotes.Count == 0) + if (_remotes.Count == 0) { App.RaiseException(_fullpath, "No remotes added to this repository!!!"); return; } - if (Branches.Find(x => x.IsCurrent) == null) + if (_currentBranch == null) { App.RaiseException(_fullpath, "Can NOT found current branch!!!"); return; @@ -478,10 +484,10 @@ namespace SourceGit.ViewModels break; case 2: - visible = new Commands.QueryCommits(FullPath, 1000, _searchCommitFilter, false).Result(); + visible = new Commands.QueryCommits(_fullpath, 1000, _searchCommitFilter, false).Result(); break; case 3: - visible = new Commands.QueryCommits(FullPath, 1000, _searchCommitFilter, true).Result(); + visible = new Commands.QueryCommits(_fullpath, 1000, _searchCommitFilter, true).Result(); break; } @@ -527,9 +533,8 @@ namespace SourceGit.ViewModels public void NavigateToCurrentHead() { - var cur = Branches.Find(x => x.IsCurrent); - if (cur != null) - NavigateToCommit(cur.Head); + if (_currentBranch != null) + NavigateToCommit(_currentBranch.Head); } public void UpdateFilter(string filter, bool toggle) @@ -607,22 +612,20 @@ namespace SourceGit.ViewModels public void RefreshBranches() { - var branches = new Commands.QueryBranches(FullPath).Result(); - var remotes = new Commands.QueryRemotes(FullPath).Result(); + var branches = new Commands.QueryBranches(_fullpath).Result(); + var remotes = new Commands.QueryRemotes(_fullpath).Result(); var builder = BuildBranchTree(branches, remotes); Dispatcher.UIThread.Invoke(() => { Remotes = remotes; Branches = branches; + CurrentBranch = branches.Find(x => x.IsCurrent); LocalBranchTrees = builder.Locals; RemoteBranchTrees = builder.Remotes; if (_workingCopy != null) - { - var cur = Branches.Find(x => x.IsCurrent); - _workingCopy.CanCommitWithPush = cur != null && !string.IsNullOrEmpty(cur.Upstream); - } + _workingCopy.CanCommitWithPush = _currentBranch != null && !string.IsNullOrEmpty(_currentBranch.Upstream); }); } @@ -647,7 +650,7 @@ namespace SourceGit.ViewModels public void RefreshTags() { - var tags = new Commands.QueryTags(FullPath).Result(); + var tags = new Commands.QueryTags(_fullpath).Result(); foreach (var tag in tags) tag.IsFiltered = _settings.Filters.Contains(tag.Name); @@ -698,7 +701,7 @@ namespace SourceGit.ViewModels var canPushCommits = new HashSet(); var canPullCommits = new HashSet(); - var currentBranch = Branches.Find(x => x.IsCurrent); + var currentBranch = _branches.Find(x => x.IsCurrent); if (currentBranch != null) { foreach (var sha in currentBranch.TrackStatus.Ahead) @@ -724,13 +727,13 @@ namespace SourceGit.ViewModels public void RefreshSubmodules() { - var submodules = new Commands.QuerySubmodules(FullPath).Result(); + var submodules = new Commands.QuerySubmodules(_fullpath).Result(); Dispatcher.UIThread.Invoke(() => Submodules = submodules); } public void RefreshWorkingCopyChanges() { - var changes = new Commands.QueryLocalChanges(FullPath, _includeUntracked).Result(); + var changes = new Commands.QueryLocalChanges(_fullpath, _includeUntracked).Result(); if (_workingCopy == null) return; @@ -774,7 +777,7 @@ namespace SourceGit.ViewModels public void RefreshStashes() { - var stashes = new Commands.QueryStashes(FullPath).Result(); + var stashes = new Commands.QueryStashes(_fullpath).Result(); Dispatcher.UIThread.Invoke(() => { if (_stashesPage != null) @@ -785,15 +788,14 @@ namespace SourceGit.ViewModels public void CreateNewBranch() { - var current = Branches.Find(x => x.IsCurrent); - if (current == null) + if (_currentBranch == null) { App.RaiseException(_fullpath, "Git do not hold any branch until you do first commit."); return; } if (PopupHost.CanCreatePopup()) - PopupHost.ShowPopup(new CreateBranch(this, current)); + PopupHost.ShowPopup(new CreateBranch(this, _currentBranch)); } public void CheckoutBranch(Models.Branch branch) @@ -820,7 +822,7 @@ namespace SourceGit.ViewModels } else { - foreach (var b in Branches) + foreach (var b in _branches) { if (b.IsLocal && b.Upstream == branch.FullName) { @@ -843,15 +845,14 @@ namespace SourceGit.ViewModels public void CreateNewTag() { - var current = Branches.Find(x => x.IsCurrent); - if (current == null) + if (_currentBranch == null) { App.RaiseException(_fullpath, "Git do not hold any branch until you do first commit."); return; } if (PopupHost.CanCreatePopup()) - PopupHost.ShowPopup(new CreateTag(this, current)); + PopupHost.ShowPopup(new CreateTag(this, _currentBranch)); } public void AddRemote() @@ -1007,12 +1008,12 @@ namespace SourceGit.ViewModels var fetch = new MenuItem(); fetch.Header = App.Text("GitLFS.Fetch"); fetch.Icon = App.CreateMenuIcon("Icons.Fetch"); - fetch.IsEnabled = Remotes.Count > 0; + fetch.IsEnabled = _remotes.Count > 0; fetch.Click += (_, e) => { if (PopupHost.CanCreatePopup()) { - if (Remotes.Count == 1) + if (_remotes.Count == 1) PopupHost.ShowAndStartPopup(new LFSFetch(this)); else PopupHost.ShowPopup(new LFSFetch(this)); @@ -1025,12 +1026,12 @@ namespace SourceGit.ViewModels var pull = new MenuItem(); pull.Header = App.Text("GitLFS.Pull"); pull.Icon = App.CreateMenuIcon("Icons.Pull"); - pull.IsEnabled = Remotes.Count > 0; + pull.IsEnabled = _remotes.Count > 0; pull.Click += (_, e) => { if (PopupHost.CanCreatePopup()) { - if (Remotes.Count == 1) + if (_remotes.Count == 1) PopupHost.ShowAndStartPopup(new LFSPull(this)); else PopupHost.ShowPopup(new LFSPull(this)); @@ -1043,12 +1044,12 @@ namespace SourceGit.ViewModels var push = new MenuItem(); push.Header = App.Text("GitLFS.Push"); push.Icon = App.CreateMenuIcon("Icons.Push"); - push.IsEnabled = Remotes.Count > 0; + push.IsEnabled = _remotes.Count > 0; push.Click += (_, e) => { if (PopupHost.CanCreatePopup()) { - if (Remotes.Count == 1) + if (_remotes.Count == 1) PopupHost.ShowAndStartPopup(new LFSPush(this)); else PopupHost.ShowPopup(new LFSPush(this)); @@ -1074,8 +1075,8 @@ namespace SourceGit.ViewModels var locks = new MenuItem(); locks.Header = App.Text("GitLFS.Locks"); locks.Icon = App.CreateMenuIcon("Icons.Lock"); - locks.IsEnabled = Remotes.Count > 0; - if (Remotes.Count == 1) + locks.IsEnabled = _remotes.Count > 0; + if (_remotes.Count == 1) { locks.Click += (_, e) => { @@ -1083,14 +1084,14 @@ namespace SourceGit.ViewModels if (topLevel == null) return; - var dialog = new Views.LFSLocks() { DataContext = new LFSLocks(_fullpath, Remotes[0].Name) }; + var dialog = new Views.LFSLocks() { DataContext = new LFSLocks(_fullpath, _remotes[0].Name) }; dialog.Show(topLevel); e.Handled = true; }; } else { - foreach (var remote in Remotes) + foreach (var remote in _remotes) { var remoteName = remote.Name; var lockRemote = new MenuItem(); @@ -1138,7 +1139,7 @@ namespace SourceGit.ViewModels var push = new MenuItem(); push.Header = new Views.NameHighlightedTextBlock("BranchCM.Push", branch.Name); push.Icon = App.CreateMenuIcon("Icons.Push"); - push.IsEnabled = Remotes.Count > 0; + push.IsEnabled = _remotes.Count > 0; push.Click += (_, e) => { if (PopupHost.CanCreatePopup()) @@ -1201,8 +1202,6 @@ namespace SourceGit.ViewModels } else { - var current = Branches.Find(x => x.IsCurrent); - var checkout = new MenuItem(); checkout.Header = new Views.NameHighlightedTextBlock("BranchCM.Checkout", branch.Name); checkout.Icon = App.CreateMenuIcon("Icons.Check"); @@ -1213,7 +1212,7 @@ namespace SourceGit.ViewModels }; menu.Items.Add(checkout); - var upstream = Branches.Find(x => x.FullName == branch.Upstream); + var upstream = _branches.Find(x => x.FullName == branch.Upstream); if (upstream != null) { var fastForward = new MenuItem(); @@ -1235,22 +1234,22 @@ namespace SourceGit.ViewModels menu.Items.Add(push); var merge = new MenuItem(); - merge.Header = new Views.NameHighlightedTextBlock("BranchCM.Merge", branch.Name, current.Name); + merge.Header = new Views.NameHighlightedTextBlock("BranchCM.Merge", branch.Name, _currentBranch.Name); merge.Icon = App.CreateMenuIcon("Icons.Merge"); merge.Click += (_, e) => { if (PopupHost.CanCreatePopup()) - PopupHost.ShowPopup(new Merge(this, branch.Name, current.Name)); + PopupHost.ShowPopup(new Merge(this, branch.Name, _currentBranch.Name)); e.Handled = true; }; var rebase = new MenuItem(); - rebase.Header = new Views.NameHighlightedTextBlock("BranchCM.Rebase", current.Name, branch.Name); + rebase.Header = new Views.NameHighlightedTextBlock("BranchCM.Rebase", _currentBranch.Name, branch.Name); rebase.Icon = App.CreateMenuIcon("Icons.Rebase"); rebase.Click += (_, e) => { if (PopupHost.CanCreatePopup()) - PopupHost.ShowPopup(new Rebase(this, current, branch)); + PopupHost.ShowPopup(new Rebase(this, _currentBranch, branch)); e.Handled = true; }; @@ -1268,9 +1267,9 @@ namespace SourceGit.ViewModels if (_histories != null) { - var target = new Commands.QuerySingleCommit(FullPath, branch.Head).Result(); + var target = new Commands.QuerySingleCommit(_fullpath, branch.Head).Result(); _histories.AutoSelectedCommit = null; - _histories.DetailContext = new RevisionCompare(FullPath, target, null); + _histories.DetailContext = new RevisionCompare(_fullpath, target, null); } }; menu.Items.Add(new MenuItem() { Header = "-" }); @@ -1353,7 +1352,7 @@ namespace SourceGit.ViewModels menu.Items.Add(new MenuItem() { Header = "-" }); var remoteBranches = new List(); - foreach (var b in Branches) + foreach (var b in _branches) { if (!b.IsLocal) remoteBranches.Add(b); @@ -1505,7 +1504,6 @@ namespace SourceGit.ViewModels public ContextMenu CreateContextMenuForRemoteBranch(Models.Branch branch) { var menu = new ContextMenu(); - var current = Branches.Find(x => x.IsCurrent); var name = branch.FriendlyName; var checkout = new MenuItem(); @@ -1519,10 +1517,10 @@ namespace SourceGit.ViewModels menu.Items.Add(checkout); menu.Items.Add(new MenuItem() { Header = "-" }); - if (current != null) + if (_currentBranch != null) { var pull = new MenuItem(); - pull.Header = new Views.NameHighlightedTextBlock("BranchCM.PullInto", name, current.Name); + pull.Header = new Views.NameHighlightedTextBlock("BranchCM.PullInto", name, _currentBranch.Name); pull.Icon = App.CreateMenuIcon("Icons.Pull"); pull.Click += (_, e) => { @@ -1532,22 +1530,22 @@ namespace SourceGit.ViewModels }; var merge = new MenuItem(); - merge.Header = new Views.NameHighlightedTextBlock("BranchCM.Merge", name, current.Name); + merge.Header = new Views.NameHighlightedTextBlock("BranchCM.Merge", name, _currentBranch.Name); merge.Icon = App.CreateMenuIcon("Icons.Merge"); merge.Click += (_, e) => { if (PopupHost.CanCreatePopup()) - PopupHost.ShowPopup(new Merge(this, name, current.Name)); + PopupHost.ShowPopup(new Merge(this, name, _currentBranch.Name)); e.Handled = true; }; var rebase = new MenuItem(); - rebase.Header = new Views.NameHighlightedTextBlock("BranchCM.Rebase", current.Name, name); + rebase.Header = new Views.NameHighlightedTextBlock("BranchCM.Rebase", _currentBranch.Name, name); rebase.Icon = App.CreateMenuIcon("Icons.Rebase"); rebase.Click += (_, e) => { if (PopupHost.CanCreatePopup()) - PopupHost.ShowPopup(new Rebase(this, current, branch)); + PopupHost.ShowPopup(new Rebase(this, _currentBranch, branch)); e.Handled = true; }; @@ -1569,9 +1567,9 @@ namespace SourceGit.ViewModels if (_histories != null) { - var target = new Commands.QuerySingleCommit(FullPath, branch.Head).Result(); + var target = new Commands.QuerySingleCommit(_fullpath, branch.Head).Result(); _histories.AutoSelectedCommit = null; - _histories.DetailContext = new RevisionCompare(FullPath, target, null); + _histories.DetailContext = new RevisionCompare(_fullpath, target, null); } }; menu.Items.Add(compareWithWorktree); @@ -1663,7 +1661,7 @@ namespace SourceGit.ViewModels var pushTag = new MenuItem(); pushTag.Header = new Views.NameHighlightedTextBlock("TagCM.Push", tag.Name); pushTag.Icon = App.CreateMenuIcon("Icons.Push"); - pushTag.IsEnabled = Remotes.Count > 0; + pushTag.IsEnabled = _remotes.Count > 0; pushTag.Click += (_, ev) => { if (PopupHost.CanCreatePopup()) @@ -1813,14 +1811,14 @@ namespace SourceGit.ViewModels private MenuItem CreateMenuItemToCompareBranches(Models.Branch branch) { - if (Branches.Count == 1) + if (_branches.Count == 1) return null; var compare = new MenuItem(); compare.Header = App.Text("BranchCM.CompareWithBranch"); compare.Icon = App.CreateMenuIcon("Icons.Compare"); - foreach (var b in Branches) + foreach (var b in _branches) { if (b.FullName != branch.FullName) { @@ -1836,7 +1834,7 @@ namespace SourceGit.ViewModels var wnd = new Views.BranchCompare() { - DataContext = new BranchCompare(FullPath, branch, dup) + DataContext = new BranchCompare(_fullpath, branch, dup) }; wnd.Show(topLevel); @@ -1922,6 +1920,7 @@ namespace SourceGit.ViewModels private List _remotes = new List(); private List _branches = new List(); + private Models.Branch _currentBranch = null; private List _localBranchTrees = new List(); private List _remoteBranchTrees = new List(); private List _worktrees = new List(); diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 2980c46a..9f447394 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -90,7 +90,7 @@ namespace SourceGit.ViewModels { if (SetProperty(ref _useAmend, value) && value) { - var currentBranch = _repo.Branches.Find(x => x.IsCurrent); + var currentBranch = _repo.CurrentBranch; if (currentBranch == null) { App.RaiseException(_repo.FullPath, "No commits to amend!!!"); From e29d78e2aed6cbd4390a9431aff035f55236d4d3 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 24 Jul 2024 16:35:35 +0800 Subject: [PATCH 22/55] feature: show current branch on toolbar (#283) * re-arrange toolbar buttons * move `Navigate to HEAD` button to toolbar --- src/Views/Repository.axaml | 5 +-- src/Views/RepositoryToolbar.axaml | 51 ++++++++++++++++++++++++++----- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/Views/Repository.axaml b/src/Views/Repository.axaml index 24ed3c92..24b5232b 100644 --- a/src/Views/Repository.axaml +++ b/src/Views/Repository.axaml @@ -76,7 +76,7 @@ - + - diff --git a/src/Views/RepositoryToolbar.axaml b/src/Views/RepositoryToolbar.axaml index f301b384..b8860a62 100644 --- a/src/Views/RepositoryToolbar.axaml +++ b/src/Views/RepositoryToolbar.axaml @@ -2,6 +2,7 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:m="using:SourceGit.Models" xmlns:vm="using:SourceGit.ViewModels" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="SourceGit.Views.RepositoryToolbar" @@ -19,6 +20,19 @@ + + + + + + @@ -58,19 +72,40 @@ + + + + - + - + + + + + + + + - From 013b4285e4dee898604dd81eb5ce5cc1c2c00939 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 24 Jul 2024 16:39:18 +0800 Subject: [PATCH 23/55] ux: text displayed when current branch is valid --- src/Views/RepositoryToolbar.axaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Views/RepositoryToolbar.axaml b/src/Views/RepositoryToolbar.axaml index b8860a62..22151cdd 100644 --- a/src/Views/RepositoryToolbar.axaml +++ b/src/Views/RepositoryToolbar.axaml @@ -90,7 +90,7 @@ - + From 537ac3e2dfd250367db787dc08484a20880fdd82 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 24 Jul 2024 17:09:30 +0800 Subject: [PATCH 24/55] ux: toolbar button icon size --- src/Views/RepositoryToolbar.axaml | 10 +++++----- src/Views/WelcomeToolbar.axaml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Views/RepositoryToolbar.axaml b/src/Views/RepositoryToolbar.axaml index 22151cdd..e8765cf8 100644 --- a/src/Views/RepositoryToolbar.axaml +++ b/src/Views/RepositoryToolbar.axaml @@ -14,7 +14,7 @@ @@ -86,7 +86,7 @@ - + @@ -105,7 +105,7 @@ diff --git a/src/Views/WelcomeToolbar.axaml b/src/Views/WelcomeToolbar.axaml index 4d65ef2a..6455f14c 100644 --- a/src/Views/WelcomeToolbar.axaml +++ b/src/Views/WelcomeToolbar.axaml @@ -17,7 +17,7 @@ From 869ba7a4710b7f41ee69e2256c014ac45ef4a4bf Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 24 Jul 2024 17:41:20 +0800 Subject: [PATCH 25/55] ux: improve tooltip recognition --- src/Resources/Styles.axaml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/Resources/Styles.axaml b/src/Resources/Styles.axaml index 06b2a3bf..89df6a01 100644 --- a/src/Resources/Styles.axaml +++ b/src/Resources/Styles.axaml @@ -163,6 +163,27 @@