diff --git a/src/Commands/QuerySubmodules.cs b/src/Commands/QuerySubmodules.cs index 81fb1f34..c6dac1f5 100644 --- a/src/Commands/QuerySubmodules.cs +++ b/src/Commands/QuerySubmodules.cs @@ -70,6 +70,7 @@ namespace SourceGit.Commands { var modules = new Dictionary(); lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries); + foreach (var line in lines) { var match = REG_FORMAT_MODULE_INFO().Match(line); @@ -81,21 +82,39 @@ namespace SourceGit.Commands if (!modules.TryGetValue(name, out var m)) { - m = new ModuleInfo(); - modules.Add(name, m); + // Find name alias. + foreach (var kv in modules) + { + if (kv.Value.Path.Equals(name, StringComparison.Ordinal)) + { + m = kv.Value; + break; + } + } + + if (m == null) + { + m = new ModuleInfo(); + modules.Add(name, m); + } } if (key.Equals("path", StringComparison.Ordinal)) m.Path = val; else if (key.Equals("url", StringComparison.Ordinal)) m.URL = val; + else if (key.Equals("branch", StringComparison.Ordinal)) + m.Branch = val; } } foreach (var kv in modules) { if (map.TryGetValue(kv.Value.Path, out var m)) + { m.URL = kv.Value.URL; + m.Branch = kv.Value.Branch; + } } } } @@ -138,6 +157,7 @@ namespace SourceGit.Commands { public string Path { get; set; } = string.Empty; public string URL { get; set; } = string.Empty; + public string Branch { get; set; } = string.Empty; } } } diff --git a/src/Commands/Submodule.cs b/src/Commands/Submodule.cs index 2c0d7147..ce93e017 100644 --- a/src/Commands/Submodule.cs +++ b/src/Commands/Submodule.cs @@ -27,12 +27,22 @@ namespace SourceGit.Commands return await ExecAsync().ConfigureAwait(false); } - public async Task SetURL(string path, string url) + public async Task SetURLAsync(string path, string url) { Args = $"submodule set-url -- \"{path}\" \"{url}\""; return await ExecAsync().ConfigureAwait(false); } + public async Task SetBranchAsync(string path, string branch) + { + if (string.IsNullOrEmpty(branch)) + Args = $"submodule set-branch -d -- \"{path}\""; + else + Args = $"submodule set-branch -b \"{branch}\" -- \"{path}\""; + + return await ExecAsync().ConfigureAwait(false); + } + public async Task UpdateAsync(List modules, bool init, bool recursive, bool useRemote = false) { var builder = new StringBuilder(); diff --git a/src/Models/Submodule.cs b/src/Models/Submodule.cs index ca73a8de..17080713 100644 --- a/src/Models/Submodule.cs +++ b/src/Models/Submodule.cs @@ -14,6 +14,7 @@ public string Path { get; set; } = string.Empty; public string SHA { get; set; } = string.Empty; public string URL { get; set; } = string.Empty; + public string Branch { get; set; } = string.Empty; public SubmoduleStatus Status { get; set; } = SubmoduleStatus.Normal; public bool IsDirty => Status > SubmoduleStatus.NotInited; } diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 7b7b0738..03e52b94 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -704,6 +704,11 @@ Skip This Version Software Update There are currently no updates available. + Set Submodule's Branch + Submodule: + Current: + Change To: + Optional. Set to default when it is empty. Set Tracking Branch Branch: Unset upstream @@ -742,6 +747,7 @@ COMMITS: SUBMODULES Add Submodule + Branch Relative Path De-initialize Fetch nested submodules @@ -751,6 +757,7 @@ Relative Path: Relative folder to store this module. Delete + Set Branch Change URL STATUS modified diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index b72f4600..e7803940 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -708,6 +708,11 @@ 忽略此版本 软件更新 当前已是最新版本。 + 修改子模块追踪分支 + 子模块 : + 当前追踪分支 : + 修改为 : + 可选。当不填写时,恢复默认追踪分支。 切换上游分支 本地分支 : 取消追踪 @@ -746,6 +751,7 @@ 提交次数: 子模块 添加子模块 + 跟踪分支 相对路径 取消初始化 拉取子孙模块 @@ -755,6 +761,7 @@ 相对仓库路径 : 本地存放的相对路径。 删除 + 修改跟踪分支 修改远程地址 状态 未提交修改 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index a38e8173..8aa2d108 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -708,6 +708,11 @@ 忽略此版本 軟體更新 目前已是最新版本。 + 設定子模組的追蹤分支 + 子模組: + 目前追蹤分支: + 變更為: + 選購。為空時設定為預設值。 切換上游分支 本機分支: 取消設定上游分支 @@ -746,6 +751,7 @@ 提交次數: 子模組 新增子模組 + 追蹤分支 相對路徑 取消初始化 提取子模組 @@ -755,6 +761,7 @@ 相對存放庫路徑: 本機存放的相對路徑。 刪除 + 更改追蹤分支 更改遠端網址 狀態 未提交變更 diff --git a/src/ViewModels/ChangeSubmoduleUrl.cs b/src/ViewModels/ChangeSubmoduleUrl.cs index e7ceb4a3..f356234b 100644 --- a/src/ViewModels/ChangeSubmoduleUrl.cs +++ b/src/ViewModels/ChangeSubmoduleUrl.cs @@ -47,7 +47,7 @@ namespace SourceGit.ViewModels var succ = await new Commands.Submodule(_repo.FullPath) .Use(log) - .SetURL(Submodule.Path, _url); + .SetURLAsync(Submodule.Path, _url); log.Complete(); _repo.SetWatcherEnabled(true); diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index cf1881e9..908da1c0 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -1272,8 +1272,9 @@ namespace SourceGit.ViewModels } hasChanged = !exist.SHA.Equals(module.SHA, StringComparison.Ordinal) || - !exist.URL.Equals(module.URL, StringComparison.Ordinal) || - exist.Status != module.Status; + !exist.Branch.Equals(module.Branch, StringComparison.Ordinal) || + !exist.URL.Equals(module.URL, StringComparison.Ordinal) || + exist.Status != module.Status; if (hasChanged) break; @@ -2584,6 +2585,16 @@ namespace SourceGit.ViewModels ev.Handled = true; }; + var setBranch = new MenuItem(); + setBranch.Header = App.Text("Submodule.SetBranch"); + setBranch.Icon = App.CreateMenuIcon("Icons.Track"); + setBranch.Click += (_, ev) => + { + if (CanCreatePopup()) + ShowPopup(new SetSubmoduleBranch(this, submodule)); + ev.Handled = true; + }; + var deinit = new MenuItem(); deinit.Header = App.Text("Submodule.Deinit"); deinit.Icon = App.CreateMenuIcon("Icons.Undo"); @@ -2641,10 +2652,20 @@ namespace SourceGit.ViewModels ev.Handled = true; }; + var copyBranch = new MenuItem(); + copyBranch.Header = App.Text("Submodule.Branch"); + copyBranch.Icon = App.CreateMenuIcon("Icons.Branch"); + copyBranch.Click += async (_, ev) => + { + await App.CopyTextAsync(submodule.Branch); + ev.Handled = true; + }; + var copy = new MenuItem(); copy.Header = App.Text("Copy"); copy.Icon = App.CreateMenuIcon("Icons.Copy"); copy.Items.Add(copySHA); + copy.Items.Add(copyBranch); copy.Items.Add(copyRelativePath); copy.Items.Add(copyURL); @@ -2653,6 +2674,7 @@ namespace SourceGit.ViewModels menu.Items.Add(new MenuItem() { Header = "-" }); menu.Items.Add(update); menu.Items.Add(setURL); + menu.Items.Add(setBranch); menu.Items.Add(move); menu.Items.Add(deinit); menu.Items.Add(rm); diff --git a/src/ViewModels/SetSubmoduleBranch.cs b/src/ViewModels/SetSubmoduleBranch.cs new file mode 100644 index 00000000..5abeec87 --- /dev/null +++ b/src/ViewModels/SetSubmoduleBranch.cs @@ -0,0 +1,49 @@ +using System; +using System.Threading.Tasks; + +namespace SourceGit.ViewModels +{ + public class SetSubmoduleBranch : Popup + { + public Models.Submodule Submodule + { + get; + } + + public string ChangeTo + { + get => _changeTo; + set => SetProperty(ref _changeTo, value); + } + + public SetSubmoduleBranch(Repository repo, Models.Submodule submodule) + { + _repo = repo; + _changeTo = submodule.Branch; + Submodule = submodule; + } + + public override async Task Sure() + { + ProgressDescription = "Set submodule's branch ..."; + + if (_changeTo.Equals(Submodule.Branch, StringComparison.Ordinal)) + return true; + + var log = _repo.CreateLog("Set Submodule's Branch"); + _repo.SetWatcherEnabled(false); + Use(log); + + var succ = await new Commands.Submodule(_repo.FullPath) + .Use(log) + .SetBranchAsync(Submodule.Path, _changeTo); + + log.Complete(); + _repo.SetWatcherEnabled(true); + return succ; + } + + private readonly Repository _repo; + private string _changeTo; + } +} diff --git a/src/Views/SetSubmoduleBranch.axaml b/src/Views/SetSubmoduleBranch.axaml new file mode 100644 index 00000000..5fb0281f --- /dev/null +++ b/src/Views/SetSubmoduleBranch.axaml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Views/SetSubmoduleBranch.axaml.cs b/src/Views/SetSubmoduleBranch.axaml.cs new file mode 100644 index 00000000..ecc06b2a --- /dev/null +++ b/src/Views/SetSubmoduleBranch.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia.Controls; + +namespace SourceGit.Views +{ + public partial class SetSubmoduleBranch : UserControl + { + public SetSubmoduleBranch() + { + InitializeComponent(); + } + } +} + diff --git a/src/Views/SubmodulesView.axaml b/src/Views/SubmodulesView.axaml index b8147384..a1e01c66 100644 --- a/src/Views/SubmodulesView.axaml +++ b/src/Views/SubmodulesView.axaml @@ -147,14 +147,31 @@ - + + Text="{DynamicResource Text.Submodule.Branch}"/> + + + + + + + + @@ -190,12 +207,12 @@ - - - -