Skip to content

Commit 0c37957

Browse files
committed
feature: support git stash branch <branch_name> <stash> command (#2227)
Signed-off-by: leo <longshuang@msn.cn>
1 parent ca9f5e1 commit 0c37957

File tree

9 files changed

+164
-0
lines changed

9 files changed

+164
-0
lines changed

src/Commands/Stash.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ public async Task<bool> ApplyAsync(string name, bool restoreIndex)
7676
return await ExecAsync().ConfigureAwait(false);
7777
}
7878

79+
public async Task<bool> CheckoutBranchAsync(string name, string branch)
80+
{
81+
Args = $"stash branch {branch.Quoted()} {name.Quoted()}";
82+
return await ExecAsync().ConfigureAwait(false);
83+
}
84+
7985
public async Task<bool> PopAsync(string name)
8086
{
8187
Args = $"stash pop -q --index {name.Quoted()}";

src/Resources/Locales/en_US.axaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@
115115
<x:String x:Key="Text.Checkout.WarnUpdatingSubmodules" xml:space="preserve">The following submodules need to be updated:{0}Do you want to update them?</x:String>
116116
<x:String x:Key="Text.Checkout.WithFastForward" xml:space="preserve">Checkout &amp; Fast-Forward</x:String>
117117
<x:String x:Key="Text.Checkout.WithFastForward.Upstream" xml:space="preserve">Fast-Forward to:</x:String>
118+
<x:String x:Key="Text.CheckoutBranchFromStash" xml:space="preserve">Checkout Branch From Stash</x:String>
119+
<x:String x:Key="Text.CheckoutBranchFromStash.Branch" xml:space="preserve">New Branch:</x:String>
120+
<x:String x:Key="Text.CheckoutBranchFromStash.Stash" xml:space="preserve">Stash:</x:String>
118121
<x:String x:Key="Text.CherryPick" xml:space="preserve">Cherry Pick</x:String>
119122
<x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">Append source to commit message</x:String>
120123
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">Commit(s):</x:String>
@@ -858,6 +861,7 @@
858861
<x:String x:Key="Text.Stash.Title" xml:space="preserve">Stash Local Changes</x:String>
859862
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">Apply</x:String>
860863
<x:String x:Key="Text.StashCM.ApplyFileChanges" xml:space="preserve">Apply Changes</x:String>
864+
<x:String x:Key="Text.StashCM.Branch" xml:space="preserve">Checkout New Branch</x:String>
861865
<x:String x:Key="Text.StashCM.CopyMessage" xml:space="preserve">Copy Message</x:String>
862866
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">Drop</x:String>
863867
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">Save as Patch...</x:String>

src/Resources/Locales/zh_CN.axaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@
119119
<x:String x:Key="Text.Checkout.WarnUpdatingSubmodules" xml:space="preserve">以下子模块需要更新:{0}是否立即更新?</x:String>
120120
<x:String x:Key="Text.Checkout.WithFastForward" xml:space="preserve">检出分支并快进</x:String>
121121
<x:String x:Key="Text.Checkout.WithFastForward.Upstream" xml:space="preserve">上游分支 :</x:String>
122+
<x:String x:Key="Text.CheckoutBranchFromStash" xml:space="preserve">从所选贮藏检出分支</x:String>
123+
<x:String x:Key="Text.CheckoutBranchFromStash.Branch" xml:space="preserve">新分支 :</x:String>
124+
<x:String x:Key="Text.CheckoutBranchFromStash.Stash" xml:space="preserve">所选贮藏 :</x:String>
122125
<x:String x:Key="Text.CherryPick" xml:space="preserve">挑选提交</x:String>
123126
<x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">提交信息中追加来源信息</x:String>
124127
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">提交列表 :</x:String>
@@ -862,6 +865,7 @@
862865
<x:String x:Key="Text.Stash.Title" xml:space="preserve">贮藏本地变更</x:String>
863866
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">应用(apply)</x:String>
864867
<x:String x:Key="Text.StashCM.ApplyFileChanges" xml:space="preserve">应用(apply)选中变更</x:String>
868+
<x:String x:Key="Text.StashCM.Branch" xml:space="preserve">检出新分支</x:String>
865869
<x:String x:Key="Text.StashCM.CopyMessage" xml:space="preserve">复制描述信息</x:String>
866870
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">删除(drop)</x:String>
867871
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">另存为补丁...</x:String>

src/Resources/Locales/zh_TW.axaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@
119119
<x:String x:Key="Text.Checkout.WarnUpdatingSubmodules" xml:space="preserve">以下子模組需要更新: {0},您要立即更新嗎?</x:String>
120120
<x:String x:Key="Text.Checkout.WithFastForward" xml:space="preserve">簽出分支並快轉</x:String>
121121
<x:String x:Key="Text.Checkout.WithFastForward.Upstream" xml:space="preserve">上游分支: </x:String>
122+
<x:String x:Key="Text.CheckoutBranchFromStash" xml:space="preserve">從所選擱置簽出分支</x:String>
123+
<x:String x:Key="Text.CheckoutBranchFromStash.Branch" xml:space="preserve">新分支:</x:String>
124+
<x:String x:Key="Text.CheckoutBranchFromStash.Stash" xml:space="preserve">所選擱置:</x:String>
122125
<x:String x:Key="Text.CherryPick" xml:space="preserve">揀選提交</x:String>
123126
<x:String x:Key="Text.CherryPick.AppendSourceToMessage" xml:space="preserve">提交資訊中追加來源資訊</x:String>
124127
<x:String x:Key="Text.CherryPick.Commit" xml:space="preserve">提交列表:</x:String>
@@ -862,6 +865,7 @@
862865
<x:String x:Key="Text.Stash.Title" xml:space="preserve">擱置本機變更</x:String>
863866
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">套用 (apply)</x:String>
864867
<x:String x:Key="Text.StashCM.ApplyFileChanges" xml:space="preserve">套用 (apply) 所選變更</x:String>
868+
<x:String x:Key="Text.StashCM.Branch" xml:space="preserve">簽出分支</x:String>
865869
<x:String x:Key="Text.StashCM.CopyMessage" xml:space="preserve">複製描述訊息</x:String>
866870
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">刪除 (drop)</x:String>
867871
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">另存為修補檔 (patch)...</x:String>
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
using System;
2+
using System.ComponentModel.DataAnnotations;
3+
using System.Threading.Tasks;
4+
5+
namespace SourceGit.ViewModels
6+
{
7+
public class CheckoutBranchFromStash : Popup
8+
{
9+
public Models.Stash Target
10+
{
11+
get;
12+
}
13+
14+
[Required(ErrorMessage = "Branch name is required!")]
15+
[RegularExpression(@"^[\w\-/\.#\+]+$", ErrorMessage = "Bad branch name format!")]
16+
[CustomValidation(typeof(CheckoutBranchFromStash), nameof(ValidateBranchName))]
17+
public string BranchName
18+
{
19+
get => _branchName;
20+
set => SetProperty(ref _branchName, value, true);
21+
}
22+
23+
public CheckoutBranchFromStash(Repository repo, Models.Stash stash)
24+
{
25+
_repo = repo;
26+
Target = stash;
27+
}
28+
29+
public static ValidationResult ValidateBranchName(string name, ValidationContext ctx)
30+
{
31+
if (ctx.ObjectInstance is CheckoutBranchFromStash caller)
32+
{
33+
foreach (var b in caller._repo.Branches)
34+
{
35+
if (b.FriendlyName.Equals(name, StringComparison.Ordinal))
36+
return new ValidationResult("A branch with same name already exists!");
37+
}
38+
39+
return ValidationResult.Success;
40+
}
41+
42+
return new ValidationResult("Missing runtime context to create branch!");
43+
}
44+
45+
public override async Task<bool> Sure()
46+
{
47+
using var lockWatcher = _repo.LockWatcher();
48+
ProgressDescription = "Checkout branch from stash...";
49+
50+
var log = _repo.CreateLog($"Checkout Branch '{_branchName}'");
51+
Use(log);
52+
53+
var succ = await new Commands.Stash(_repo.FullPath)
54+
.Use(log)
55+
.CheckoutBranchAsync(Target.Name, _branchName);
56+
57+
if (succ)
58+
{
59+
_repo.MarkWorkingCopyDirtyManually();
60+
_repo.MarkStashesDirtyManually();
61+
}
62+
63+
log.Complete();
64+
return true;
65+
}
66+
67+
private readonly Repository _repo;
68+
private string _branchName = string.Empty;
69+
}
70+
}

src/ViewModels/StashesPage.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,12 @@ public void Apply(Models.Stash stash)
153153
_repo.ShowPopup(new ApplyStash(_repo, stash));
154154
}
155155

156+
public void CheckoutBranch(Models.Stash stash)
157+
{
158+
if (_repo.CanCreatePopup())
159+
_repo.ShowPopup(new CheckoutBranchFromStash(_repo, stash));
160+
}
161+
156162
public void Drop(Models.Stash stash)
157163
{
158164
if (_repo.CanCreatePopup())
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<UserControl xmlns="https://github.com/avaloniaui"
2+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
3+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
4+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
5+
xmlns:vm="using:SourceGit.ViewModels"
6+
xmlns:v="using:SourceGit.Views"
7+
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
8+
x:Class="SourceGit.Views.CheckoutBranchFromStash"
9+
x:DataType="vm:CheckoutBranchFromStash">
10+
<StackPanel Orientation="Vertical" Margin="8,0,0,0">
11+
<StackPanel Orientation="Horizontal">
12+
<Path Width="16" Height="16"
13+
Data="{StaticResource Icons.Branch.Add}"/>
14+
15+
<TextBlock FontSize="18"
16+
Margin="8,0,0,0"
17+
Classes="bold"
18+
Text="{DynamicResource Text.CheckoutBranchFromStash}"/>
19+
</StackPanel>
20+
21+
<Grid Margin="0,16,8,0" RowDefinitions="32,32" ColumnDefinitions="120,*">
22+
<TextBlock Grid.Row="0" Grid.Column="0"
23+
HorizontalAlignment="Right" VerticalAlignment="Center"
24+
Margin="0,0,8,0"
25+
Text="{DynamicResource Text.CheckoutBranchFromStash.Stash}"/>
26+
<Grid Grid.Row="0" Grid.Column="1" ColumnDefinitions="Auto,Auto,*">
27+
<Path Grid.Column="0"
28+
Width="12" Height="12"
29+
Margin="2,0,8,0"
30+
HorizontalAlignment="Left" VerticalAlignment="Center"
31+
Data="{StaticResource Icons.Stashes}"/>
32+
33+
<TextBlock Grid.Column="1" VerticalAlignment="Center" Text="{Binding Target.Name}" Foreground="DarkOrange"/>
34+
<TextBlock Grid.Column="2" VerticalAlignment="Center" Text="{Binding Target.Subject}" TextTrimming="CharacterEllipsis" Margin="4,0,0,0"/>
35+
</Grid>
36+
37+
<TextBlock Grid.Row="1" Grid.Column="0"
38+
HorizontalAlignment="Right" VerticalAlignment="Center"
39+
Margin="0,0,8,0"
40+
Text="{DynamicResource Text.CheckoutBranchFromStash.Branch}"/>
41+
<v:BranchOrTagNameTextBox Grid.Row="1" Grid.Column="1"
42+
Height="26"
43+
VerticalAlignment="Center"
44+
CornerRadius="3"
45+
Text="{Binding BranchName, Mode=TwoWay}"/>
46+
</Grid>
47+
</StackPanel>
48+
</UserControl>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using Avalonia.Controls;
2+
3+
namespace SourceGit.Views
4+
{
5+
public partial class CheckoutBranchFromStash : UserControl
6+
{
7+
public CheckoutBranchFromStash()
8+
{
9+
InitializeComponent();
10+
}
11+
}
12+
}

src/Views/StashesPage.axaml.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,15 @@ private void OnStashContextRequested(object sender, ContextRequestedEventArgs e)
5959
ev.Handled = true;
6060
};
6161

62+
var branch = new MenuItem();
63+
branch.Header = App.Text("StashCM.Branch");
64+
branch.Icon = App.CreateMenuIcon("Icons.Branch.Add");
65+
branch.Click += (_, ev) =>
66+
{
67+
vm.CheckoutBranch(stash);
68+
ev.Handled = true;
69+
};
70+
6271
var drop = new MenuItem();
6372
drop.Header = App.Text("StashCM.Drop");
6473
drop.Icon = App.CreateMenuIcon("Icons.Clear");
@@ -109,6 +118,7 @@ private void OnStashContextRequested(object sender, ContextRequestedEventArgs e)
109118

110119
var menu = new ContextMenu();
111120
menu.Items.Add(apply);
121+
menu.Items.Add(branch);
112122
menu.Items.Add(drop);
113123
menu.Items.Add(new MenuItem { Header = "-" });
114124
menu.Items.Add(patch);

0 commit comments

Comments
 (0)