From 1fef7a7baacb48735b8fe77ecb9454239f11f0ff Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 21 May 2025 17:49:39 +0800 Subject: [PATCH] perf: only update uninited or outdated submodules Signed-off-by: leo --- src/Commands/QueryUpdatableSubmodules.cs | 40 ++++++++++++++++++++++++ src/Commands/Submodule.cs | 20 ++---------- src/ViewModels/Checkout.cs | 4 +-- src/ViewModels/CheckoutCommit.cs | 4 +-- src/ViewModels/Clone.cs | 4 +-- src/ViewModels/CreateBranch.cs | 4 +-- src/ViewModels/Pull.cs | 4 +-- src/ViewModels/UpdateSubmodules.cs | 11 ++----- 8 files changed, 55 insertions(+), 36 deletions(-) create mode 100644 src/Commands/QueryUpdatableSubmodules.cs diff --git a/src/Commands/QueryUpdatableSubmodules.cs b/src/Commands/QueryUpdatableSubmodules.cs new file mode 100644 index 00000000..03f4a24d --- /dev/null +++ b/src/Commands/QueryUpdatableSubmodules.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace SourceGit.Commands +{ + public partial class QueryUpdatableSubmodules : Command + { + [GeneratedRegex(@"^([U\-\+ ])([0-9a-f]+)\s(.*?)(\s\(.*\))?$")] + private static partial Regex REG_FORMAT_STATUS(); + + public QueryUpdatableSubmodules(string repo) + { + WorkingDirectory = repo; + Context = repo; + Args = "submodule status"; + } + + public List Result() + { + var submodules = new List(); + var rs = ReadToEnd(); + + var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries); + foreach (var line in lines) + { + var match = REG_FORMAT_STATUS().Match(line); + if (match.Success) + { + var stat = match.Groups[1].Value; + var path = match.Groups[3].Value; + if (!stat.StartsWith(' ')) + submodules.Add(path); + } + } + + return submodules; + } + } +} diff --git a/src/Commands/Submodule.cs b/src/Commands/Submodule.cs index 7d88ca5b..20cc845c 100644 --- a/src/Commands/Submodule.cs +++ b/src/Commands/Submodule.cs @@ -29,23 +29,7 @@ namespace SourceGit.Commands } } - public bool Update(string module, bool init, bool recursive, bool useRemote) - { - Args = "submodule update"; - - if (init) - Args += " --init"; - if (recursive) - Args += " --recursive"; - if (useRemote) - Args += " --remote"; - if (!string.IsNullOrEmpty(module)) - Args += $" -- \"{module}\""; - - return Exec(); - } - - public bool Update(List modules, bool init, bool recursive, bool useRemote) + public bool Update(List modules, bool init, bool recursive, bool useRemote = false) { var builder = new StringBuilder(); builder.Append("submodule update"); @@ -60,7 +44,7 @@ namespace SourceGit.Commands { builder.Append(" --"); foreach (var module in modules) - builder.Append($" \"{module.Path}\""); + builder.Append($" \"{module}\""); } Args = builder.ToString(); diff --git a/src/ViewModels/Checkout.cs b/src/ViewModels/Checkout.cs index 5cdf4de5..630a97a5 100644 --- a/src/ViewModels/Checkout.cs +++ b/src/ViewModels/Checkout.cs @@ -74,9 +74,9 @@ namespace SourceGit.ViewModels { if (updateSubmodules) { - var submodules = new Commands.QuerySubmodules(_repo.FullPath).Result(); + var submodules = new Commands.QueryUpdatableSubmodules(_repo.FullPath).Result(); if (submodules.Count > 0) - new Commands.Submodule(_repo.FullPath).Use(log).Update(submodules, true, true, false); + new Commands.Submodule(_repo.FullPath).Use(log).Update(submodules, true, true); } if (needPopStash) diff --git a/src/ViewModels/CheckoutCommit.cs b/src/ViewModels/CheckoutCommit.cs index 57aadf65..c41fd2ce 100644 --- a/src/ViewModels/CheckoutCommit.cs +++ b/src/ViewModels/CheckoutCommit.cs @@ -74,9 +74,9 @@ namespace SourceGit.ViewModels { if (updateSubmodules) { - var submodules = new Commands.QuerySubmodules(_repo.FullPath).Result(); + var submodules = new Commands.QueryUpdatableSubmodules(_repo.FullPath).Result(); if (submodules.Count > 0) - new Commands.Submodule(_repo.FullPath).Use(log).Update(submodules, true, true, false); + new Commands.Submodule(_repo.FullPath).Use(log).Update(submodules, true, true); } if (needPop) diff --git a/src/ViewModels/Clone.cs b/src/ViewModels/Clone.cs index dd9cf86b..032551a2 100644 --- a/src/ViewModels/Clone.cs +++ b/src/ViewModels/Clone.cs @@ -140,9 +140,9 @@ namespace SourceGit.ViewModels if (InitAndUpdateSubmodules) { - var submodules = new Commands.QuerySubmodules(path).Result(); + var submodules = new Commands.QueryUpdatableSubmodules(path).Result(); if (submodules.Count > 0) - new Commands.Submodule(path).Use(log).Update(submodules, true, true, false); + new Commands.Submodule(path).Use(log).Update(submodules, true, true); } log.Complete(); diff --git a/src/ViewModels/CreateBranch.cs b/src/ViewModels/CreateBranch.cs index e5d1eea8..ce751a2f 100644 --- a/src/ViewModels/CreateBranch.cs +++ b/src/ViewModels/CreateBranch.cs @@ -144,9 +144,9 @@ namespace SourceGit.ViewModels { if (updateSubmodules) { - var submodules = new Commands.QuerySubmodules(_repo.FullPath).Result(); + var submodules = new Commands.QueryUpdatableSubmodules(_repo.FullPath).Result(); if (submodules.Count > 0) - new Commands.Submodule(_repo.FullPath).Use(log).Update(submodules, true, true, false); + new Commands.Submodule(_repo.FullPath).Use(log).Update(submodules, true, true); } if (needPopStash) diff --git a/src/ViewModels/Pull.cs b/src/ViewModels/Pull.cs index b19ed9a5..1756ea06 100644 --- a/src/ViewModels/Pull.cs +++ b/src/ViewModels/Pull.cs @@ -153,9 +153,9 @@ namespace SourceGit.ViewModels { if (updateSubmodules) { - var submodules = new Commands.QuerySubmodules(_repo.FullPath).Result(); + var submodules = new Commands.QueryUpdatableSubmodules(_repo.FullPath).Result(); if (submodules.Count > 0) - new Commands.Submodule(_repo.FullPath).Use(log).Update(submodules, true, true, false); + new Commands.Submodule(_repo.FullPath).Use(log).Update(submodules, true, true); } if (needPopStash) diff --git a/src/ViewModels/UpdateSubmodules.cs b/src/ViewModels/UpdateSubmodules.cs index c2f23133..df2d5565 100644 --- a/src/ViewModels/UpdateSubmodules.cs +++ b/src/ViewModels/UpdateSubmodules.cs @@ -65,14 +65,9 @@ namespace SourceGit.ViewModels return Task.Run(() => { - foreach (var submodule in targets) - { - new Commands.Submodule(_repo.FullPath).Use(log).Update( - submodule, - EnableInit, - EnableRecursive, - EnableRemote); - } + new Commands.Submodule(_repo.FullPath) + .Use(log) + .Update(targets, EnableInit, EnableRecursive, EnableRemote); log.Complete(); CallUIThread(() => _repo.SetWatcherEnabled(true));