From 5fef6e93b9471b6415aa5ec4fb3ace9bcddb64f1 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 14 Oct 2024 15:18:29 +0800 Subject: [PATCH] enhance: cherry-pick (#563) * supports to cherry-pick a merge commit * add option to enable the `-x` parameter --- src/Commands/CherryPick.cs | 13 ++++-- src/Resources/Locales/en_US.axaml | 3 ++ src/Resources/Locales/zh_CN.axaml | 3 ++ src/Resources/Locales/zh_TW.axaml | 3 ++ src/ViewModels/CherryPick.cs | 68 ++++++++++++++++++++++++++++--- src/ViewModels/Histories.cs | 23 ++++++++++- src/Views/CherryPick.axaml | 50 ++++++++++++++++++----- 7 files changed, 144 insertions(+), 19 deletions(-) diff --git a/src/Commands/CherryPick.cs b/src/Commands/CherryPick.cs index 95b56655..0c82b9fd 100644 --- a/src/Commands/CherryPick.cs +++ b/src/Commands/CherryPick.cs @@ -2,12 +2,19 @@ { public class CherryPick : Command { - public CherryPick(string repo, string commits, bool noCommit) + public CherryPick(string repo, string commits, bool noCommit, bool appendSourceToMessage, string extraParams) { - var mode = noCommit ? "-n" : "--ff"; WorkingDirectory = repo; Context = repo; - Args = $"cherry-pick {mode} {commits}"; + + Args = "cherry-pick "; + if (noCommit) + Args += "-n "; + if (appendSourceToMessage) + Args += "-x "; + if (!string.IsNullOrEmpty(extraParams)) + Args += $"{extraParams} "; + Args += commits; } } } diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 22a1cde2..4534e0b5 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -83,8 +83,11 @@ Do Nothing Stash & Reapply Cherry Pick + Append source to commit message Commit(s): Commit all changes + Mainline: + Usually you cannot cherry-pick a merge because you do not know which side of the merge should be considered the mainline. This option allows cherry-pick to replay the change relative to the specified parent. Clear Stashes You are trying to clear all stashes. Are you sure to continue? Clone Remote Repository diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index b95a85e8..32bcb958 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -86,8 +86,11 @@ 不做处理 贮藏并自动恢复 挑选提交 + 提交信息中追加来源信息 提交列表 : 提交变化 + 作为对比的父提交 : + 通常你不能对一个合并进行挑选,因为你不知道合并的哪一边应该被视为主线。这个选项指定了作为主线的父提交,允许挑选相对于该提交的修改。 丢弃贮藏确认 您正在丢弃所有的贮藏,一经操作,无法回退,是否继续? 克隆远程仓库 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 2e0fcd3f..b49ee242 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -86,8 +86,11 @@ 不做處理 擱置變更並自動復原 揀選提交 + 提交資訊中追加來源資訊 提交列表: 提交變更 + 作為對比的父提交: + 通常你不能對一個合併進行揀選,因為你不知道合併的哪一邊應該被視為主線。這個選項指定了作為主線的父提交,允許揀選相對於該提交的修改。 捨棄擱置變更確認 您正在捨棄所有的擱置變更,一經操作便無法復原,是否繼續? 複製 (clone) 遠端存放庫 diff --git a/src/ViewModels/CherryPick.cs b/src/ViewModels/CherryPick.cs index 9f8fe882..e4058309 100644 --- a/src/ViewModels/CherryPick.cs +++ b/src/ViewModels/CherryPick.cs @@ -12,6 +12,30 @@ namespace SourceGit.ViewModels private set; } + public bool IsMergeCommit + { + get; + private set; + } + + public List ParentsForMergeCommit + { + get; + private set; + } + + public int MainlineForMergeCommit + { + get; + set; + } + + public bool AppendSourceToMessage + { + get; + set; + } + public bool AutoCommit { get; @@ -22,6 +46,22 @@ namespace SourceGit.ViewModels { _repo = repo; Targets = targets; + IsMergeCommit = false; + ParentsForMergeCommit = []; + MainlineForMergeCommit = 0; + AppendSourceToMessage = true; + AutoCommit = true; + View = new Views.CherryPick() { DataContext = this }; + } + + public CherryPick(Repository repo, Models.Commit merge, List parents) + { + _repo = repo; + Targets = [merge]; + IsMergeCommit = true; + ParentsForMergeCommit = parents; + MainlineForMergeCommit = 0; + AppendSourceToMessage = true; AutoCommit = true; View = new Views.CherryPick() { DataContext = this }; } @@ -33,12 +73,30 @@ namespace SourceGit.ViewModels return Task.Run(() => { - // Get commit SHAs reverted - var builder = new StringBuilder(); - for (int i = Targets.Count - 1; i >= 0; i--) - builder.Append($"{Targets[i].SHA} "); + var succ = false; + if (IsMergeCommit) + { + succ = new Commands.CherryPick( + _repo.FullPath, + Targets[0].SHA, + !AutoCommit, + AppendSourceToMessage, + $"-m {MainlineForMergeCommit+1}").Exec(); + } + else + { + var builder = new StringBuilder(); + for (int i = Targets.Count - 1; i >= 0; i--) + builder.Append($"{Targets[i].SHA} "); - var succ = new Commands.CherryPick(_repo.FullPath, builder.ToString(), !AutoCommit).Exec(); + succ = new Commands.CherryPick( + _repo.FullPath, + builder.ToString(), + !AutoCommit, + AppendSourceToMessage, + string.Empty).Exec(); + } + CallUIThread(() => _repo.SetWatcherEnabled(true)); return succ; }); diff --git a/src/ViewModels/Histories.cs b/src/ViewModels/Histories.cs index 10f4b60a..d03d13c2 100644 --- a/src/ViewModels/Histories.cs +++ b/src/ViewModels/Histories.cs @@ -424,7 +424,28 @@ namespace SourceGit.ViewModels cherryPick.Click += (_, e) => { if (PopupHost.CanCreatePopup()) - PopupHost.ShowPopup(new CherryPick(_repo, [commit])); + { + if (commit.Parents.Count <= 1) + { + PopupHost.ShowPopup(new CherryPick(_repo, [commit])); + } + else + { + var parents = new List(); + foreach (var sha in commit.Parents) + { + var parent = _commits.Find(x => x.SHA == sha); + if (parent == null) + parent = new Commands.QuerySingleCommit(_repo.FullPath, sha).Result(); + + if (parent != null) + parents.Add(parent); + } + + PopupHost.ShowPopup(new CherryPick(_repo, commit, parents)); + } + } + e.Handled = true; }; menu.Items.Add(cherryPick); diff --git a/src/Views/CherryPick.axaml b/src/Views/CherryPick.axaml index ba672b13..1ba62ff7 100644 --- a/src/Views/CherryPick.axaml +++ b/src/Views/CherryPick.axaml @@ -12,17 +12,11 @@ - - - - - - + - - + - + + + + + + + + + + + + + + + + + + + +