Skip to content

Commit af75815

Browse files
committed
feature: add quick action entry for interactive rebase (#1572)
Signed-off-by: leo <longshuang@msn.cn>
1 parent 4d37e73 commit af75815

File tree

5 files changed

+140
-21
lines changed

5 files changed

+140
-21
lines changed

src/Resources/Locales/en_US.axaml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,13 @@
127127
<x:String x:Key="Text.CommitCM.CopySHA" xml:space="preserve">SHA</x:String>
128128
<x:String x:Key="Text.CommitCM.CopySubject" xml:space="preserve">Subject</x:String>
129129
<x:String x:Key="Text.CommitCM.CustomAction" xml:space="preserve">Custom Action</x:String>
130-
<x:String x:Key="Text.CommitCM.InteractiveRebase" xml:space="preserve">Interactively Rebase ${0}$ on ${1}$</x:String>
130+
<x:String x:Key="Text.CommitCM.InteractiveRebase" xml:space="preserve">Interactive Rebase</x:String>
131+
<x:String x:Key="Text.CommitCM.InteractiveRebase.Drop" xml:space="preserve">Drop...</x:String>
132+
<x:String x:Key="Text.CommitCM.InteractiveRebase.Edit" xml:space="preserve">Edit...</x:String>
133+
<x:String x:Key="Text.CommitCM.InteractiveRebase.Fixup" xml:space="preserve">Fixup into Parent...</x:String>
134+
<x:String x:Key="Text.CommitCM.InteractiveRebase.Manually" xml:space="preserve">Interactively Rebase ${0}$ on ${1}$</x:String>
135+
<x:String x:Key="Text.CommitCM.InteractiveRebase.Reword" xml:space="preserve">Reword...</x:String>
136+
<x:String x:Key="Text.CommitCM.InteractiveRebase.Squash" xml:space="preserve">Squash into Parent...</x:String>
131137
<x:String x:Key="Text.CommitCM.Merge" xml:space="preserve">Merge to ${0}$</x:String>
132138
<x:String x:Key="Text.CommitCM.MergeMultiple" xml:space="preserve">Merge ...</x:String>
133139
<x:String x:Key="Text.CommitCM.PushRevision" xml:space="preserve">Push ${0}$ to ${1}$</x:String>

src/Resources/Locales/zh_CN.axaml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,13 @@
131131
<x:String x:Key="Text.CommitCM.CopySHA" xml:space="preserve">提交指纹</x:String>
132132
<x:String x:Key="Text.CommitCM.CopySubject" xml:space="preserve">主题</x:String>
133133
<x:String x:Key="Text.CommitCM.CustomAction" xml:space="preserve">自定义操作</x:String>
134-
<x:String x:Key="Text.CommitCM.InteractiveRebase" xml:space="preserve">交互式变基(rebase -i) ${0}$ 到 ${1}$</x:String>
134+
<x:String x:Key="Text.CommitCM.InteractiveRebase" xml:space="preserve">交互式变基(rebase -i)</x:String>
135+
<x:String x:Key="Text.CommitCM.InteractiveRebase.Drop" xml:space="preserve">丢弃...</x:String>
136+
<x:String x:Key="Text.CommitCM.InteractiveRebase.Edit" xml:space="preserve">编辑...</x:String>
137+
<x:String x:Key="Text.CommitCM.InteractiveRebase.Fixup" xml:space="preserve">修复至父提交...</x:String>
138+
<x:String x:Key="Text.CommitCM.InteractiveRebase.Manually" xml:space="preserve">交互式变基 ${0}$ 到 ${1}$</x:String>
139+
<x:String x:Key="Text.CommitCM.InteractiveRebase.Reword" xml:space="preserve">修改提交信息...</x:String>
140+
<x:String x:Key="Text.CommitCM.InteractiveRebase.Squash" xml:space="preserve">合并至父提交...</x:String>
135141
<x:String x:Key="Text.CommitCM.Merge" xml:space="preserve">合并(merge)此提交至 ${0}$</x:String>
136142
<x:String x:Key="Text.CommitCM.MergeMultiple" xml:space="preserve">合并(merge)...</x:String>
137143
<x:String x:Key="Text.CommitCM.PushRevision" xml:space="preserve">推送(push) ${0}$ 到 ${1}$</x:String>

src/Resources/Locales/zh_TW.axaml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,13 @@
131131
<x:String x:Key="Text.CommitCM.CopySHA" xml:space="preserve">提交編號</x:String>
132132
<x:String x:Key="Text.CommitCM.CopySubject" xml:space="preserve">標題</x:String>
133133
<x:String x:Key="Text.CommitCM.CustomAction" xml:space="preserve">自訂動作</x:String>
134-
<x:String x:Key="Text.CommitCM.InteractiveRebase" xml:space="preserve">互動式重定基底 (rebase -i) ${0}$ 至 ${1}$</x:String>
134+
<x:String x:Key="Text.CommitCM.InteractiveRebase" xml:space="preserve">互動式重定基底 (rebase -i)</x:String>
135+
<x:String x:Key="Text.CommitCM.InteractiveRebase.Drop" xml:space="preserve">捨棄...</x:String>
136+
<x:String x:Key="Text.CommitCM.InteractiveRebase.Edit" xml:space="preserve">編輯...</x:String>
137+
<x:String x:Key="Text.CommitCM.InteractiveRebase.Fixup" xml:space="preserve">修正至父提交...</x:String>
138+
<x:String x:Key="Text.CommitCM.InteractiveRebase.Manually" xml:space="preserve">互動式重定基底 ${0}$ 至 ${1}$</x:String>
139+
<x:String x:Key="Text.CommitCM.InteractiveRebase.Reword" xml:space="preserve">編輯提交訊息...</x:String>
140+
<x:String x:Key="Text.CommitCM.InteractiveRebase.Squash" xml:space="preserve">合併至父提交...</x:String>
135141
<x:String x:Key="Text.CommitCM.Merge" xml:space="preserve">合併 (merge) 此提交到 ${0}$</x:String>
136142
<x:String x:Key="Text.CommitCM.MergeMultiple" xml:space="preserve">合併 (merge)...</x:String>
137143
<x:String x:Key="Text.CommitCM.PushRevision" xml:space="preserve">推送(push) ${0}$ 至 ${1}$</x:String>

src/ViewModels/Histories.cs

Lines changed: 96 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -630,19 +630,105 @@ public ContextMenu CreateContextMenuForSelectedCommits(List<Models.Commit> selec
630630
_repo.ShowPopup(new CheckoutCommit(_repo, commit));
631631
e.Handled = true;
632632
};
633+
menu.Items.Add(checkoutCommit);
633634

634-
var interactiveRebase = new MenuItem();
635-
interactiveRebase.Header = App.Text("CommitCM.InteractiveRebase", current.Name, target);
636-
interactiveRebase.Icon = App.CreateMenuIcon("Icons.InteractiveRebase");
637-
interactiveRebase.Click += async (_, e) =>
635+
if (commit.IsMerged && commit.Parents.Count > 0)
638636
{
639-
await App.ShowDialog(new InteractiveRebase(_repo, current, commit));
640-
e.Handled = true;
641-
};
637+
var interactiveRebase = new MenuItem();
638+
interactiveRebase.Header = App.Text("CommitCM.InteractiveRebase");
639+
interactiveRebase.Icon = App.CreateMenuIcon("Icons.InteractiveRebase");
642640

643-
menu.Items.Add(checkoutCommit);
644-
menu.Items.Add(new MenuItem() { Header = "-" });
645-
menu.Items.Add(interactiveRebase);
641+
var manually = new MenuItem();
642+
manually.Header = App.Text("CommitCM.InteractiveRebase.Manually", current.Name, target);
643+
manually.Click += async (_, e) =>
644+
{
645+
await App.ShowDialog(new InteractiveRebase(_repo, commit));
646+
e.Handled = true;
647+
};
648+
649+
var reword = new MenuItem();
650+
reword.Header = App.Text("CommitCM.InteractiveRebase.Reword");
651+
reword.Click += async (_, e) =>
652+
{
653+
var prefill = new InteractiveRebasePrefill(commit.SHA, Models.InteractiveRebaseAction.Reword);
654+
var on = await new Commands.QuerySingleCommit(_repo.FullPath, $"{commit.SHA}~").GetResultAsync();
655+
await App.ShowDialog(new InteractiveRebase(_repo, on, prefill));
656+
e.Handled = true;
657+
};
658+
659+
var edit = new MenuItem();
660+
edit.Header = App.Text("CommitCM.InteractiveRebase.Edit");
661+
edit.Click += async (_, e) =>
662+
{
663+
var prefill = new InteractiveRebasePrefill(commit.SHA, Models.InteractiveRebaseAction.Edit);
664+
var on = await new Commands.QuerySingleCommit(_repo.FullPath, $"{commit.SHA}~").GetResultAsync();
665+
await App.ShowDialog(new InteractiveRebase(_repo, on, prefill));
666+
e.Handled = true;
667+
};
668+
669+
var squash = new MenuItem();
670+
squash.Header = App.Text("CommitCM.InteractiveRebase.Squash");
671+
squash.Click += async (_, e) =>
672+
{
673+
var prefill = new InteractiveRebasePrefill(commit.SHA, Models.InteractiveRebaseAction.Squash);
674+
var on = await new Commands.QuerySingleCommit(_repo.FullPath, $"{commit.SHA}~~").GetResultAsync();
675+
if (on != null)
676+
await App.ShowDialog(new InteractiveRebase(_repo, on, prefill));
677+
else
678+
App.RaiseException(_repo.FullPath, $"Can not squash current commit into parent!");
679+
680+
e.Handled = true;
681+
};
682+
683+
var fixup = new MenuItem();
684+
fixup.Header = App.Text("CommitCM.InteractiveRebase.Fixup");
685+
fixup.Click += async (_, e) =>
686+
{
687+
var prefill = new InteractiveRebasePrefill(commit.SHA, Models.InteractiveRebaseAction.Fixup);
688+
var on = await new Commands.QuerySingleCommit(_repo.FullPath, $"{commit.SHA}~~").GetResultAsync();
689+
if (on != null)
690+
await App.ShowDialog(new InteractiveRebase(_repo, on, prefill));
691+
else
692+
App.RaiseException(_repo.FullPath, $"Can not fixup current commit into parent!");
693+
694+
e.Handled = true;
695+
};
696+
697+
var drop = new MenuItem();
698+
drop.Header = App.Text("CommitCM.InteractiveRebase.Drop");
699+
drop.Click += async (_, e) =>
700+
{
701+
var prefill = new InteractiveRebasePrefill(commit.SHA, Models.InteractiveRebaseAction.Drop);
702+
var on = await new Commands.QuerySingleCommit(_repo.FullPath, $"{commit.SHA}~").GetResultAsync();
703+
await App.ShowDialog(new InteractiveRebase(_repo, on, prefill));
704+
e.Handled = true;
705+
};
706+
707+
interactiveRebase.Items.Add(manually);
708+
interactiveRebase.Items.Add(new MenuItem() { Header = "-" });
709+
interactiveRebase.Items.Add(reword);
710+
interactiveRebase.Items.Add(edit);
711+
interactiveRebase.Items.Add(squash);
712+
interactiveRebase.Items.Add(fixup);
713+
interactiveRebase.Items.Add(drop);
714+
715+
menu.Items.Add(new MenuItem() { Header = "-" });
716+
menu.Items.Add(interactiveRebase);
717+
}
718+
else
719+
{
720+
var interactiveRebase = new MenuItem();
721+
interactiveRebase.Header = App.Text("CommitCM.InteractiveRebase.Manually", current.Name, target);
722+
interactiveRebase.Icon = App.CreateMenuIcon("Icons.InteractiveRebase");
723+
interactiveRebase.Click += async (_, e) =>
724+
{
725+
await App.ShowDialog(new InteractiveRebase(_repo, commit));
726+
e.Handled = true;
727+
};
728+
729+
menu.Items.Add(new MenuItem() { Header = "-" });
730+
menu.Items.Add(interactiveRebase);
731+
}
646732
}
647733

648734
menu.Items.Add(new MenuItem() { Header = "-" });

src/ViewModels/InteractiveRebase.cs

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
23
using System.IO;
34
using System.Text.Json;
45
using System.Threading.Tasks;
@@ -10,6 +11,12 @@
1011

1112
namespace SourceGit.ViewModels
1213
{
14+
public record InteractiveRebasePrefill(string sha, Models.InteractiveRebaseAction action)
15+
{
16+
public string SHA { get; } = sha;
17+
public Models.InteractiveRebaseAction Action { get; } = action;
18+
}
19+
1320
public class InteractiveRebaseItem : ObservableObject
1421
{
1522
public Models.Commit Commit
@@ -123,19 +130,17 @@ public CommitDetail DetailContext
123130
private set;
124131
}
125132

126-
public InteractiveRebase(Repository repo, Models.Branch current, Models.Commit on)
133+
public InteractiveRebase(Repository repo, Models.Commit on, InteractiveRebasePrefill prefill = null)
127134
{
128-
var repoPath = repo.FullPath;
129135
_repo = repo;
130-
131-
Current = current;
136+
Current = repo.CurrentBranch;
132137
On = on;
133138
IsLoading = true;
134139
DetailContext = new CommitDetail(repo, false);
135140

136141
Task.Run(async () =>
137142
{
138-
var commits = await new Commands.QueryCommitsForInteractiveRebase(repoPath, on.SHA)
143+
var commits = await new Commands.QueryCommitsForInteractiveRebase(_repo.FullPath, on.SHA)
139144
.GetResultAsync()
140145
.ConfigureAwait(false);
141146

@@ -146,11 +151,21 @@ public InteractiveRebase(Repository repo, Models.Branch current, Models.Commit o
146151
list.Add(new InteractiveRebaseItem(c.Commit, c.Message, i < commits.Count - 1));
147152
}
148153

154+
InteractiveRebaseItem selected = list.Count > 0 ? list[0] : null;
155+
if (prefill != null)
156+
{
157+
var item = list.Find(x => x.Commit.SHA.Equals(prefill.SHA, StringComparison.Ordinal));
158+
if (item != null)
159+
{
160+
item.Action = prefill.Action;
161+
selected = item;
162+
}
163+
}
164+
149165
Dispatcher.UIThread.Post(() =>
150166
{
151167
Items.AddRange(list);
152-
if (list.Count > 0)
153-
SelectedItem = list[0];
168+
SelectedItem = selected;
154169
IsLoading = false;
155170
});
156171
});

0 commit comments

Comments
 (0)