mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-23 20:47:25 -08:00
enhance: tag creation & pushing (#141)
* supports creating lightweight tags * supports GPG signed tags * add option to push selected tag to all remotes
This commit is contained in:
parent
0dea7ed0e2
commit
b556feb3d3
11 changed files with 122 additions and 42 deletions
|
@ -5,12 +5,22 @@ namespace SourceGit.Commands
|
|||
{
|
||||
public static class Tag
|
||||
{
|
||||
public static bool Add(string repo, string name, string basedOn, string message)
|
||||
public static bool Add(string repo, string name, string basedOn)
|
||||
{
|
||||
var cmd = new Command();
|
||||
cmd.WorkingDirectory = repo;
|
||||
cmd.Context = repo;
|
||||
cmd.Args = $"tag -a {name} {basedOn} ";
|
||||
cmd.Args = $"tag {name} {basedOn}";
|
||||
return cmd.Exec();
|
||||
}
|
||||
|
||||
public static bool Add(string repo, string name, string basedOn, string message, bool sign)
|
||||
{
|
||||
var param = sign ? "-s -a" : "-a";
|
||||
var cmd = new Command();
|
||||
cmd.WorkingDirectory = repo;
|
||||
cmd.Context = repo;
|
||||
cmd.Args = $"tag {param} {name} {basedOn} ";
|
||||
|
||||
if (!string.IsNullOrEmpty(message))
|
||||
{
|
||||
|
|
|
@ -114,10 +114,14 @@
|
|||
<x:String x:Key="Text.CreateBranch.Title" xml:space="preserve">Create Local Branch</x:String>
|
||||
<x:String x:Key="Text.CreateTag" xml:space="preserve">Create Tag</x:String>
|
||||
<x:String x:Key="Text.CreateTag.BasedOn" xml:space="preserve">New Tag At :</x:String>
|
||||
<x:String x:Key="Text.CreateTag.GPGSign" xml:space="preserve">Enable GPG signing</x:String>
|
||||
<x:String x:Key="Text.CreateTag.Message" xml:space="preserve">Tag Message :</x:String>
|
||||
<x:String x:Key="Text.CreateTag.Message.Placeholder" xml:space="preserve">Optional.</x:String>
|
||||
<x:String x:Key="Text.CreateTag.Name" xml:space="preserve">Tag Name :</x:String>
|
||||
<x:String x:Key="Text.CreateTag.Name.Placeholder" xml:space="preserve">Recommended format :v1.0.0-alpha</x:String>
|
||||
<x:String x:Key="Text.CreateTag.Type" xml:space="preserve">Kind :</x:String>
|
||||
<x:String x:Key="Text.CreateTag.Type.Annotated" xml:space="preserve">annotated</x:String>
|
||||
<x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">lightweight</x:String>
|
||||
<x:String x:Key="Text.Cut" xml:space="preserve">Cut</x:String>
|
||||
<x:String x:Key="Text.DeleteBranch" xml:space="preserve">Delete Branch</x:String>
|
||||
<x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">Branch :</x:String>
|
||||
|
@ -312,6 +316,7 @@
|
|||
<x:String x:Key="Text.Push.To" xml:space="preserve">Remote Branch :</x:String>
|
||||
<x:String x:Key="Text.Push.WithAllTags" xml:space="preserve">Push all tags</x:String>
|
||||
<x:String x:Key="Text.PushTag" xml:space="preserve">Push Tag To Remote</x:String>
|
||||
<x:String x:Key="Text.PushTag.PushAllRemotes" xml:space="preserve">Push to all remotes</x:String>
|
||||
<x:String x:Key="Text.PushTag.Remote" xml:space="preserve">Remote :</x:String>
|
||||
<x:String x:Key="Text.PushTag.Tag" xml:space="preserve">Tag :</x:String>
|
||||
<x:String x:Key="Text.Quit" xml:space="preserve">Quit</x:String>
|
||||
|
|
|
@ -114,10 +114,14 @@
|
|||
<x:String x:Key="Text.CreateBranch.Title" xml:space="preserve">创建本地分支</x:String>
|
||||
<x:String x:Key="Text.CreateTag" xml:space="preserve">新建标签</x:String>
|
||||
<x:String x:Key="Text.CreateTag.BasedOn" xml:space="preserve">标签位于 :</x:String>
|
||||
<x:String x:Key="Text.CreateTag.GPGSign" xml:space="preserve">使用GPG签名</x:String>
|
||||
<x:String x:Key="Text.CreateTag.Message" xml:space="preserve">标签描述 :</x:String>
|
||||
<x:String x:Key="Text.CreateTag.Message.Placeholder" xml:space="preserve">选填。</x:String>
|
||||
<x:String x:Key="Text.CreateTag.Name" xml:space="preserve">标签名 :</x:String>
|
||||
<x:String x:Key="Text.CreateTag.Name.Placeholder" xml:space="preserve">推荐格式 :v1.0.0-alpha</x:String>
|
||||
<x:String x:Key="Text.CreateTag.Type" xml:space="preserve">类型 :</x:String>
|
||||
<x:String x:Key="Text.CreateTag.Type.Annotated" xml:space="preserve">附注标签</x:String>
|
||||
<x:String x:Key="Text.CreateTag.Type.Lightweight" xml:space="preserve">轻量标签</x:String>
|
||||
<x:String x:Key="Text.Cut" xml:space="preserve">剪切</x:String>
|
||||
<x:String x:Key="Text.DeleteBranch" xml:space="preserve">删除分支确认</x:String>
|
||||
<x:String x:Key="Text.DeleteBranch.Branch" xml:space="preserve">分支名 :</x:String>
|
||||
|
@ -312,6 +316,7 @@
|
|||
<x:String x:Key="Text.Push.To" xml:space="preserve">远程分支 :</x:String>
|
||||
<x:String x:Key="Text.Push.WithAllTags" xml:space="preserve">同时推送标签</x:String>
|
||||
<x:String x:Key="Text.PushTag" xml:space="preserve">推送标签到远程仓库</x:String>
|
||||
<x:String x:Key="Text.PushTag.PushAllRemotes" xml:space="preserve">推送到所有远程仓库</x:String>
|
||||
<x:String x:Key="Text.PushTag.Remote" xml:space="preserve">远程仓库 :</x:String>
|
||||
<x:String x:Key="Text.PushTag.Tag" xml:space="preserve">标签 :</x:String>
|
||||
<x:String x:Key="Text.Quit" xml:space="preserve">退出</x:String>
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SourceGit.ViewModels
|
||||
{
|
||||
public class CreateTag : Popup
|
||||
{
|
||||
public object BasedOn
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Required(ErrorMessage = "Tag name is required!")]
|
||||
[RegularExpression(@"^[\w\-\.]+$", ErrorMessage = "Bad tag name format!")]
|
||||
[CustomValidation(typeof(CreateTag), nameof(ValidateTagName))]
|
||||
|
@ -22,11 +26,17 @@ namespace SourceGit.ViewModels
|
|||
set;
|
||||
}
|
||||
|
||||
public object BasedOn
|
||||
public bool Annotated
|
||||
{
|
||||
get => _annotated;
|
||||
set => SetProperty(ref _annotated, value);
|
||||
}
|
||||
|
||||
public bool SignTag
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
set;
|
||||
} = false;
|
||||
|
||||
public CreateTag(Repository repo, Models.Branch branch)
|
||||
{
|
||||
|
@ -65,7 +75,11 @@ namespace SourceGit.ViewModels
|
|||
|
||||
return Task.Run(() =>
|
||||
{
|
||||
Commands.Tag.Add(_repo.FullPath, TagName, _basedOn, Message);
|
||||
if (_annotated)
|
||||
Commands.Tag.Add(_repo.FullPath, _tagName, _basedOn, Message, SignTag);
|
||||
else
|
||||
Commands.Tag.Add(_repo.FullPath, _tagName, _basedOn);
|
||||
|
||||
CallUIThread(() => _repo.SetWatcherEnabled(true));
|
||||
return true;
|
||||
});
|
||||
|
@ -73,6 +87,7 @@ namespace SourceGit.ViewModels
|
|||
|
||||
private readonly Repository _repo = null;
|
||||
private string _tagName = string.Empty;
|
||||
private bool _annotated = true;
|
||||
private readonly string _basedOn = string.Empty;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,12 @@ namespace SourceGit.ViewModels
|
|||
set;
|
||||
}
|
||||
|
||||
public bool PushAllRemotes
|
||||
{
|
||||
get => _pushAllRemotes;
|
||||
set => SetProperty(ref _pushAllRemotes, value);
|
||||
}
|
||||
|
||||
public PushTag(Repository repo, Models.Tag target)
|
||||
{
|
||||
_repo = repo;
|
||||
|
@ -37,12 +43,27 @@ namespace SourceGit.ViewModels
|
|||
|
||||
return Task.Run(() =>
|
||||
{
|
||||
var succ = new Commands.Push(_repo.FullPath, SelectedRemote.Name, Target.Name, false).Exec();
|
||||
bool succ = true;
|
||||
if (_pushAllRemotes)
|
||||
{
|
||||
foreach (var remote in _repo.Remotes)
|
||||
{
|
||||
succ = new Commands.Push(_repo.FullPath, remote.Name, Target.Name, false).Exec();
|
||||
if (!succ)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
succ = new Commands.Push(_repo.FullPath, SelectedRemote.Name, Target.Name, false).Exec();
|
||||
}
|
||||
|
||||
CallUIThread(() => _repo.SetWatcherEnabled(true));
|
||||
return succ;
|
||||
});
|
||||
}
|
||||
|
||||
private readonly Repository _repo = null;
|
||||
private bool _pushAllRemotes = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel;
|
||||
|
||||
using Avalonia.Controls;
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<TextBlock FontSize="18"
|
||||
Classes="bold"
|
||||
Text="{DynamicResource Text.CreateTag}"/>
|
||||
<Grid Margin="0,16,8,0" RowDefinitions="32,32,64" ColumnDefinitions="150,*">
|
||||
<Grid Margin="0,16,8,0" RowDefinitions="32,32,32,Auto,Auto" ColumnDefinitions="150,*">
|
||||
<TextBlock Grid.Column="0"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Margin="0,0,8,0"
|
||||
|
@ -49,16 +49,37 @@
|
|||
v:AutoFocusBehaviour.IsEnabled="True"/>
|
||||
|
||||
<TextBlock Grid.Row="2" Grid.Column="0"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Margin="0,0,8,0"
|
||||
Text="{DynamicResource Text.CreateTag.Type}"/>
|
||||
<StackPanel Grid.Row="2" Grid.Column="1" Orientation="Horizontal">
|
||||
<RadioButton Content="{DynamicResource Text.CreateTag.Type.Annotated}"
|
||||
GroupName="TagKind"
|
||||
IsChecked="{Binding Annotated, Mode=TwoWay}"/>
|
||||
<RadioButton Content="{DynamicResource Text.CreateTag.Type.Lightweight}"
|
||||
GroupName="TagKind"
|
||||
Margin="8,0,0,0"/>
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock Grid.Row="3" Grid.Column="0"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Top"
|
||||
Margin="0,6,8,0"
|
||||
Text="{DynamicResource Text.CreateTag.Message}"/>
|
||||
<TextBox Grid.Row="2" Grid.Column="1"
|
||||
Height="56"
|
||||
Text="{DynamicResource Text.CreateTag.Message}"
|
||||
IsVisible="{Binding Annotated}"/>
|
||||
<TextBox Grid.Row="3" Grid.Column="1"
|
||||
Height="64"
|
||||
AcceptsReturn="True" AcceptsTab="False"
|
||||
VerticalAlignment="Center" VerticalContentAlignment="Top"
|
||||
CornerRadius="2"
|
||||
Watermark="{DynamicResource Text.CreateTag.Message.Placeholder}"
|
||||
Text="{Binding Message, Mode=TwoWay}"/>
|
||||
Text="{Binding Message, Mode=TwoWay}"
|
||||
IsVisible="{Binding Annotated}"/>
|
||||
|
||||
<CheckBox Grid.Row="4" Grid.Column="1"
|
||||
Height="32"
|
||||
Content="{DynamicResource Text.CreateTag.GPGSign}"
|
||||
IsChecked="{Binding SignTag, Mode=TwoWay}"
|
||||
IsVisible="{Binding Annotated}"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
|
|
|
@ -396,17 +396,10 @@
|
|||
|
||||
<Grid Margin="8" RowDefinitions="32,32,32" ColumnDefinitions="Auto,*">
|
||||
<TextBlock Grid.Row="0" Grid.Column="0"
|
||||
Text="{DynamicResource Text.Preference.GPG.Enabled}"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="0,0,16,0"/>
|
||||
<CheckBox Grid.Row="0" Grid.Column="1"
|
||||
IsChecked="{Binding #me.EnableGPGSigning, Mode=TwoWay}"/>
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="0"
|
||||
Text="{DynamicResource Text.Preference.GPG.Path}"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="0,0,16,0"/>
|
||||
<TextBox Grid.Row="1" Grid.Column="1"
|
||||
<TextBox Grid.Row="0" Grid.Column="1"
|
||||
Height="28"
|
||||
CornerRadius="3"
|
||||
Text="{Binding #me.GPGExecutableFile, Mode=TwoWay}">
|
||||
|
@ -417,15 +410,19 @@
|
|||
</TextBox.InnerRightContent>
|
||||
</TextBox>
|
||||
|
||||
<TextBlock Grid.Row="2" Grid.Column="0"
|
||||
<TextBlock Grid.Row="1" Grid.Column="0"
|
||||
Text="{DynamicResource Text.Preference.GPG.UserKey}"
|
||||
HorizontalAlignment="Right"
|
||||
Margin="0,0,16,0"/>
|
||||
<TextBox Grid.Row="2" Grid.Column="1"
|
||||
<TextBox Grid.Row="1" Grid.Column="1"
|
||||
Height="28"
|
||||
CornerRadius="3"
|
||||
Text="{Binding #me.GPGUserKey, Mode=TwoWay}"
|
||||
Watermark="{DynamicResource Text.Preference.GPG.UserKey.Placeholder}"/>
|
||||
|
||||
<CheckBox Grid.Row="2" Grid.Column="1"
|
||||
Content="{DynamicResource Text.Preference.GPG.Enabled}"
|
||||
IsChecked="{Binding #me.EnableGPGSigning, Mode=TwoWay}"/>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
|
||||
|
|
|
@ -207,10 +207,17 @@ namespace SourceGit.Views
|
|||
|
||||
private async void SelectGPGExecutable(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var pattern = OperatingSystem.IsWindows() ? "gpg.exe" : "gpg";
|
||||
var patterns = new List<string>();
|
||||
if (OperatingSystem.IsWindows())
|
||||
patterns.Add("gpg.exe");
|
||||
else if (OperatingSystem.IsLinux())
|
||||
patterns.AddRange(new string[] { "gpg", "gpg2" });
|
||||
else
|
||||
patterns.Add("gpg");
|
||||
|
||||
var options = new FilePickerOpenOptions()
|
||||
{
|
||||
FileTypeFilter = [new FilePickerFileType("GPG Executable") { Patterns = [pattern] }],
|
||||
FileTypeFilter = [new FilePickerFileType("GPG Executable") { Patterns = patterns }],
|
||||
AllowMultiple = false,
|
||||
};
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<TextBlock FontSize="18"
|
||||
Classes="bold"
|
||||
Text="{DynamicResource Text.PushTag}"/>
|
||||
<Grid Margin="0,16,0,0" RowDefinitions="32,32" ColumnDefinitions="150,*">
|
||||
<Grid Margin="0,16,0,0" RowDefinitions="32,32,32" ColumnDefinitions="150,*">
|
||||
<TextBlock Grid.Column="0"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Margin="0,0,8,0"
|
||||
|
@ -31,7 +31,8 @@
|
|||
Height="28" Padding="8,0"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Stretch"
|
||||
ItemsSource="{Binding Remotes}"
|
||||
SelectedItem="{Binding SelectedRemote, Mode=TwoWay}">
|
||||
SelectedItem="{Binding SelectedRemote, Mode=TwoWay}"
|
||||
IsEnabled="{Binding !PushAllRemotes}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="{x:Type m:Remote}">
|
||||
<StackPanel Orientation="Horizontal" Height="20" VerticalAlignment="Center">
|
||||
|
@ -41,6 +42,10 @@
|
|||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<CheckBox Grid.Row="2" Grid.Column="1"
|
||||
Content="{DynamicResource Text.PushTag.PushAllRemotes}"
|
||||
IsChecked="{Binding PushAllRemotes, Mode=TwoWay}"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
|
|
|
@ -47,23 +47,18 @@
|
|||
Text="{Binding HttpProxy, Mode=TwoWay}"/>
|
||||
|
||||
<TextBlock Grid.Row="3" Grid.Column="0"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Margin="0,0,8,0"
|
||||
Text="{DynamicResource Text.Preference.GPG.Enabled}"/>
|
||||
<CheckBox Grid.Row="3" Grid.Column="1"
|
||||
x:Name="chkGPGSigningEnabled"
|
||||
IsChecked="{Binding GPGSigningEnabled, Mode=TwoWay}"/>
|
||||
|
||||
<TextBlock Grid.Row="4" Grid.Column="0"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Margin="0,0,8,0"
|
||||
Text="{DynamicResource Text.Preference.GPG.UserKey}"/>
|
||||
<TextBox Grid.Row="4" Grid.Column="1"
|
||||
<TextBox Grid.Row="3" Grid.Column="1"
|
||||
Height="28"
|
||||
CornerRadius="3"
|
||||
Watermark="{DynamicResource Text.Preference.GPG.UserKey.Placeholder}"
|
||||
Text="{Binding GPGUserSigningKey, Mode=TwoWay}"
|
||||
IsEnabled="{Binding #chkGPGSigningEnabled.IsChecked}"/>
|
||||
Text="{Binding GPGUserSigningKey, Mode=TwoWay}"/>
|
||||
|
||||
<CheckBox Grid.Row="4" Grid.Column="1"
|
||||
Content="{DynamicResource Text.Preference.GPG.Enabled}"
|
||||
IsChecked="{Binding GPGSigningEnabled, Mode=TwoWay}"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
|
|
Loading…
Reference in a new issue