Skip to content

Commit 5fef6e9

Browse files
committed
enhance: cherry-pick (#563)
* supports to cherry-pick a merge commit * add option to enable the `-x` parameter
1 parent 688f10e commit 5fef6e9

File tree

7 files changed

+144
-19
lines changed

7 files changed

+144
-19
lines changed

src/Commands/CherryPick.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,19 @@
22
{
33
public class CherryPick : Command
44
{
5-
public CherryPick(string repo, string commits, bool noCommit)
5+
public CherryPick(string repo, string commits, bool noCommit, bool appendSourceToMessage, string extraParams)
66
{
7-
var mode = noCommit ? "-n" : "--ff";
87
WorkingDirectory = repo;
98
Context = repo;
10-
Args = $"cherry-pick {mode} {commits}";
9+
10+
Args = "cherry-pick ";
11+
if (noCommit)
12+
Args += "-n ";
13+
if (appendSourceToMessage)
14+
Args += "-x ";
15+
if (!string.IsNullOrEmpty(extraParams))
16+
Args += $"{extraParams} ";
17+
Args += commits;
1118
}
1219
}
1320
}

src/Resources/Locales/en_US.axaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,11 @@
8383
<x:String x:Key="Text.Checkout.LocalChanges.DoNothing" xml:space="preserve">Do Nothing</x:String>
8484
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">Stash &amp; Reapply</x:String>
8585
<x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry Pick</x:String>
86+
<x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">Append source to commit message</x:String>
8687
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">Commit(s):</x:String>
8788
<x:String x:Key="Text.CherryPick.CommitChanges" xml:space="preserve">Commit all changes</x:String>
89+
<x:String x:Key="Text.CherryPick.Mainline" xml:space="preserve">Mainline:</x:String>
90+
<x:String x:Key="Text.CherryPick.Mainline.Tips" xml:space="preserve">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.</x:String>
8891
<x:String x:Key="Text.ClearStashes" xml:space="preserve">Clear Stashes</x:String>
8992
<x:String x:Key="Text.ClearStashes.Message" xml:space="preserve">You are trying to clear all stashes. Are you sure to continue?</x:String>
9093
<x:String x:Key="Text.Clone" xml:space="preserve">Clone Remote Repository</x:String>

src/Resources/Locales/zh_CN.axaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,11 @@
8686
<x:String x:Key="Text.Checkout.LocalChanges.DoNothing" xml:space="preserve">不做处理</x:String>
8787
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">贮藏并自动恢复</x:String>
8888
<x:String x:Key="Text.CherryPick" xml:space="preserve">挑选提交</x:String>
89+
<x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">提交信息中追加来源信息</x:String>
8990
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">提交列表 :</x:String>
9091
<x:String x:Key="Text.CherryPick.CommitChanges" xml:space="preserve">提交变化</x:String>
92+
<x:String x:Key="Text.CherryPick.Mainline" xml:space="preserve">作为对比的父提交 :</x:String>
93+
<x:String x:Key="Text.CherryPick.Mainline.Tips" xml:space="preserve">通常你不能对一个合并进行挑选,因为你不知道合并的哪一边应该被视为主线。这个选项指定了作为主线的父提交,允许挑选相对于该提交的修改。</x:String>
9194
<x:String x:Key="Text.ClearStashes" xml:space="preserve">丢弃贮藏确认</x:String>
9295
<x:String x:Key="Text.ClearStashes.Message" xml:space="preserve">您正在丢弃所有的贮藏,一经操作,无法回退,是否继续?</x:String>
9396
<x:String x:Key="Text.Clone" xml:space="preserve">克隆远程仓库</x:String>

src/Resources/Locales/zh_TW.axaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,11 @@
8686
<x:String x:Key="Text.Checkout.LocalChanges.DoNothing" xml:space="preserve">不做處理</x:String>
8787
<x:String x:Key="Text.Checkout.LocalChanges.StashAndReply" xml:space="preserve">擱置變更並自動復原</x:String>
8888
<x:String x:Key="Text.CherryPick" xml:space="preserve">揀選提交</x:String>
89+
<x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">提交資訊中追加來源資訊</x:String>
8990
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">提交列表:</x:String>
9091
<x:String x:Key="Text.CherryPick.CommitChanges" xml:space="preserve">提交變更</x:String>
92+
<x:String x:Key="Text.CherryPick.Mainline" xml:space="preserve">作為對比的父提交:</x:String>
93+
<x:String x:Key="Text.CherryPick.Mainline.Tips" xml:space="preserve">通常你不能對一個合併進行揀選,因為你不知道合併的哪一邊應該被視為主線。這個選項指定了作為主線的父提交,允許揀選相對於該提交的修改。</x:String>
9194
<x:String x:Key="Text.ClearStashes" xml:space="preserve">捨棄擱置變更確認</x:String>
9295
<x:String x:Key="Text.ClearStashes.Message" xml:space="preserve">您正在捨棄所有的擱置變更,一經操作便無法復原,是否繼續?</x:String>
9396
<x:String x:Key="Text.Clone" xml:space="preserve">複製 (clone) 遠端存放庫</x:String>

src/ViewModels/CherryPick.cs

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,30 @@ public List<Models.Commit> Targets
1212
private set;
1313
}
1414

15+
public bool IsMergeCommit
16+
{
17+
get;
18+
private set;
19+
}
20+
21+
public List<Models.Commit> ParentsForMergeCommit
22+
{
23+
get;
24+
private set;
25+
}
26+
27+
public int MainlineForMergeCommit
28+
{
29+
get;
30+
set;
31+
}
32+
33+
public bool AppendSourceToMessage
34+
{
35+
get;
36+
set;
37+
}
38+
1539
public bool AutoCommit
1640
{
1741
get;
@@ -22,6 +46,22 @@ public CherryPick(Repository repo, List<Models.Commit> targets)
2246
{
2347
_repo = repo;
2448
Targets = targets;
49+
IsMergeCommit = false;
50+
ParentsForMergeCommit = [];
51+
MainlineForMergeCommit = 0;
52+
AppendSourceToMessage = true;
53+
AutoCommit = true;
54+
View = new Views.CherryPick() { DataContext = this };
55+
}
56+
57+
public CherryPick(Repository repo, Models.Commit merge, List<Models.Commit> parents)
58+
{
59+
_repo = repo;
60+
Targets = [merge];
61+
IsMergeCommit = true;
62+
ParentsForMergeCommit = parents;
63+
MainlineForMergeCommit = 0;
64+
AppendSourceToMessage = true;
2565
AutoCommit = true;
2666
View = new Views.CherryPick() { DataContext = this };
2767
}
@@ -33,12 +73,30 @@ public override Task<bool> Sure()
3373

3474
return Task.Run(() =>
3575
{
36-
// Get commit SHAs reverted
37-
var builder = new StringBuilder();
38-
for (int i = Targets.Count - 1; i >= 0; i--)
39-
builder.Append($"{Targets[i].SHA} ");
76+
var succ = false;
77+
if (IsMergeCommit)
78+
{
79+
succ = new Commands.CherryPick(
80+
_repo.FullPath,
81+
Targets[0].SHA,
82+
!AutoCommit,
83+
AppendSourceToMessage,
84+
$"-m {MainlineForMergeCommit+1}").Exec();
85+
}
86+
else
87+
{
88+
var builder = new StringBuilder();
89+
for (int i = Targets.Count - 1; i >= 0; i--)
90+
builder.Append($"{Targets[i].SHA} ");
4091

41-
var succ = new Commands.CherryPick(_repo.FullPath, builder.ToString(), !AutoCommit).Exec();
92+
succ = new Commands.CherryPick(
93+
_repo.FullPath,
94+
builder.ToString(),
95+
!AutoCommit,
96+
AppendSourceToMessage,
97+
string.Empty).Exec();
98+
}
99+
42100
CallUIThread(() => _repo.SetWatcherEnabled(true));
43101
return succ;
44102
});

src/ViewModels/Histories.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,28 @@ public ContextMenu MakeContextMenu(ListBox list)
424424
cherryPick.Click += (_, e) =>
425425
{
426426
if (PopupHost.CanCreatePopup())
427-
PopupHost.ShowPopup(new CherryPick(_repo, [commit]));
427+
{
428+
if (commit.Parents.Count <= 1)
429+
{
430+
PopupHost.ShowPopup(new CherryPick(_repo, [commit]));
431+
}
432+
else
433+
{
434+
var parents = new List<Models.Commit>();
435+
foreach (var sha in commit.Parents)
436+
{
437+
var parent = _commits.Find(x => x.SHA == sha);
438+
if (parent == null)
439+
parent = new Commands.QuerySingleCommit(_repo.FullPath, sha).Result();
440+
441+
if (parent != null)
442+
parents.Add(parent);
443+
}
444+
445+
PopupHost.ShowPopup(new CherryPick(_repo, commit, parents));
446+
}
447+
}
448+
428449
e.Handled = true;
429450
};
430451
menu.Items.Add(cherryPick);

src/Views/CherryPick.axaml

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,11 @@
1212
<TextBlock FontSize="18"
1313
Classes="bold"
1414
Text="{DynamicResource Text.CherryPick}"/>
15-
<Grid Margin="0,16,0,0" ColumnDefinitions="100,*">
16-
<Grid.RowDefinitions>
17-
<RowDefinition Height="Auto"/>
18-
<RowDefinition Height="32"/>
19-
</Grid.RowDefinitions>
20-
15+
<Grid Margin="0,16,0,0" RowDefinitions="Auto,Auto,32,32" ColumnDefinitions="100,*">
2116
<TextBlock Grid.Row="0" Grid.Column="0"
22-
HorizontalAlignment="Right" VerticalAlignment="Top"
17+
HorizontalAlignment="Right" VerticalAlignment="Center"
2318
Margin="0,0,8,0"
2419
Text="{DynamicResource Text.CherryPick.Commit}"/>
25-
2620
<ListBox Grid.Row="0" Grid.Column="1"
2721
MinHeight="32" MaxHeight="100"
2822
ItemsSource="{Binding Targets}"
@@ -56,11 +50,47 @@
5650
</Grid>
5751
</DataTemplate>
5852
</ListBox.ItemTemplate>
59-
</ListBox>
53+
</ListBox>
54+
55+
<TextBlock Grid.Row="1" Grid.Column="0"
56+
HorizontalAlignment="Right" VerticalAlignment="Center"
57+
Margin="0,0,8,0"
58+
Text="{DynamicResource Text.CherryPick.Mainline}"
59+
IsVisible="{Binding IsMergeCommit}"/>
60+
<Grid Grid.Row="1" Grid.Column="1" Height="32" ColumnDefinitions="*,24" IsVisible="{Binding IsMergeCommit}">
61+
<ComboBox Grid.Column="0"
62+
Height="28" Padding="4,0"
63+
VerticalAlignment="Center" HorizontalAlignment="Stretch"
64+
ItemsSource="{Binding ParentsForMergeCommit}"
65+
SelectedIndex="{Binding MainlineForMergeCommit, Mode=TwoWay}">
66+
<ComboBox.ItemTemplate>
67+
<DataTemplate x:DataType="{x:Type m:Commit}">
68+
<Grid ColumnDefinitions="Auto,*">
69+
<TextBlock Grid.Column="0" FontFamily="{DynamicResource Fonts.Monospace}" VerticalAlignment="Center" Text="{Binding SHA, Converter={x:Static c:StringConverters.ToShortSHA}}" Foreground="DarkOrange" Margin="6,0,4,0"/>
70+
<TextBlock Grid.Column="1" VerticalAlignment="Center" Text="{Binding Subject}" TextTrimming="CharacterEllipsis"/>
71+
</Grid>
72+
</DataTemplate>
73+
</ComboBox.ItemTemplate>
74+
</ComboBox>
6075

61-
<CheckBox Grid.Row="1" Grid.Column="1"
76+
<Border Grid.Column="1"
77+
Background="Transparent"
78+
ToolTip.Tip="{DynamicResource Text.CherryPick.Mainline.Tips}">
79+
<Path Grid.Column="1"
80+
Width="14" Height="14"
81+
Data="{StaticResource Icons.Info}"/>
82+
</Border>
83+
</Grid>
84+
85+
<CheckBox Grid.Row="2" Grid.Column="1"
6286
Content="{DynamicResource Text.CherryPick.CommitChanges}"
6387
IsChecked="{Binding AutoCommit, Mode=TwoWay}"/>
88+
89+
<CheckBox Grid.Row="3" Grid.Column="1"
90+
Content="{DynamicResource Text.CherryPick.AppendSourceToMessage}"
91+
IsChecked="{Binding AppendSourceToMessage, Mode=TwoWay}"
92+
IsEnabled="{Binding AutoCommit}"
93+
ToolTip.Tip="-x"/>
6494
</Grid>
6595
</StackPanel>
6696
</UserControl>

0 commit comments

Comments
 (0)