mirror of
https://github.com/sourcegit-scm/sourcegit
synced 2025-05-31 09:04:59 +00:00
feature: supports to overwrite existing branch while creating new branch (#1349)
Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
parent
594ffc0d1a
commit
76a197aae7
9 changed files with 74 additions and 36 deletions
|
@ -1,4 +1,6 @@
|
|||
namespace SourceGit.Commands
|
||||
using System.Text;
|
||||
|
||||
namespace SourceGit.Commands
|
||||
{
|
||||
public static class Branch
|
||||
{
|
||||
|
@ -11,12 +13,20 @@
|
|||
return cmd.ReadToEnd().StdOut.Trim();
|
||||
}
|
||||
|
||||
public static bool Create(string repo, string name, string basedOn, Models.ICommandLog log)
|
||||
public static bool Create(string repo, string name, string basedOn, bool force, Models.ICommandLog log)
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
builder.Append("branch ");
|
||||
if (force)
|
||||
builder.Append("-f ");
|
||||
builder.Append(name);
|
||||
builder.Append(" ");
|
||||
builder.Append(basedOn);
|
||||
|
||||
var cmd = new Command();
|
||||
cmd.WorkingDirectory = repo;
|
||||
cmd.Context = repo;
|
||||
cmd.Args = $"branch {name} {basedOn}";
|
||||
cmd.Args = builder.ToString();
|
||||
cmd.Log = log;
|
||||
return cmd.Exec();
|
||||
}
|
||||
|
@ -31,16 +41,6 @@
|
|||
return cmd.Exec();
|
||||
}
|
||||
|
||||
public static bool ResetWithoutCheckout(string repo, string name, string to, Models.ICommandLog log)
|
||||
{
|
||||
var cmd = new Command();
|
||||
cmd.WorkingDirectory = repo;
|
||||
cmd.Context = repo;
|
||||
cmd.Args = $"branch -f {name} {to}";
|
||||
cmd.Log = log;
|
||||
return cmd.Exec();
|
||||
}
|
||||
|
||||
public static bool SetUpstream(string repo, string name, string upstream, Models.ICommandLog log)
|
||||
{
|
||||
var cmd = new Command();
|
||||
|
|
|
@ -13,15 +13,28 @@ namespace SourceGit.Commands
|
|||
|
||||
public bool Branch(string branch, bool force)
|
||||
{
|
||||
var option = force ? "--force" : string.Empty;
|
||||
Args = $"checkout {option} --progress {branch}";
|
||||
var builder = new StringBuilder();
|
||||
builder.Append("checkout --progress ");
|
||||
if (force)
|
||||
builder.Append("--force ");
|
||||
builder.Append(branch);
|
||||
|
||||
Args = builder.ToString();
|
||||
return Exec();
|
||||
}
|
||||
|
||||
public bool Branch(string branch, string basedOn, bool force)
|
||||
public bool Branch(string branch, string basedOn, bool force, bool allowOverwrite)
|
||||
{
|
||||
var option = force ? "--force" : string.Empty;
|
||||
Args = $"checkout --progress -b {branch} {basedOn}";
|
||||
var builder = new StringBuilder();
|
||||
builder.Append("checkout --progress ");
|
||||
builder.Append(allowOverwrite ? "-B " : "-b ");
|
||||
if (force)
|
||||
builder.Append("--force ");
|
||||
builder.Append(branch);
|
||||
builder.Append(" ");
|
||||
builder.Append(basedOn);
|
||||
|
||||
Args = builder.ToString();
|
||||
return Exec();
|
||||
}
|
||||
|
||||
|
|
|
@ -217,6 +217,7 @@
|
|||
<x:String x:Key="Text.CreateBranch.Name.Placeholder" xml:space="preserve">Enter branch name.</x:String>
|
||||
<x:String x:Key="Text.CreateBranch.Name.WarnSpace" xml:space="preserve">Spaces will be replaced with dashes.</x:String>
|
||||
<x:String x:Key="Text.CreateBranch.Title" xml:space="preserve">Create Local Branch</x:String>
|
||||
<x:String x:Key="Text.CreateBranch.OverwriteExisting" xml:space="preserve">Overwrite existing 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">GPG signing</x:String>
|
||||
|
|
|
@ -221,6 +221,7 @@
|
|||
<x:String x:Key="Text.CreateBranch.Name.Placeholder" xml:space="preserve">填写分支名称。</x:String>
|
||||
<x:String x:Key="Text.CreateBranch.Name.WarnSpace" xml:space="preserve">空格将被替换为'-'符号</x:String>
|
||||
<x:String x:Key="Text.CreateBranch.Title" xml:space="preserve">创建本地分支</x:String>
|
||||
<x:String x:Key="Text.CreateBranch.OverwriteExisting" 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>
|
||||
|
|
|
@ -221,6 +221,7 @@
|
|||
<x:String x:Key="Text.CreateBranch.Name.Placeholder" xml:space="preserve">輸入分支名稱。</x:String>
|
||||
<x:String x:Key="Text.CreateBranch.Name.WarnSpace" xml:space="preserve">空格將以英文破折號取代</x:String>
|
||||
<x:String x:Key="Text.CreateBranch.Title" xml:space="preserve">建立本機分支</x:String>
|
||||
<x:String x:Key="Text.CreateBranch.OverwriteExisting" 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>
|
||||
|
|
|
@ -43,6 +43,16 @@ namespace SourceGit.ViewModels
|
|||
get => _repo.IsBare;
|
||||
}
|
||||
|
||||
public bool AllowOverwrite
|
||||
{
|
||||
get => _allowOverwrite;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _allowOverwrite, value))
|
||||
ValidateProperty(_name, nameof(Name));
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsRecurseSubmoduleVisible
|
||||
{
|
||||
get => _repo.Submodules.Count > 0;
|
||||
|
@ -88,18 +98,24 @@ namespace SourceGit.ViewModels
|
|||
|
||||
public static ValidationResult ValidateBranchName(string name, ValidationContext ctx)
|
||||
{
|
||||
var creator = ctx.ObjectInstance as CreateBranch;
|
||||
if (creator == null)
|
||||
return new ValidationResult("Missing runtime context to create branch!");
|
||||
|
||||
var fixedName = creator.FixName(name);
|
||||
foreach (var b in creator._repo.Branches)
|
||||
if (ctx.ObjectInstance is CreateBranch creator)
|
||||
{
|
||||
if (b.FriendlyName == fixedName)
|
||||
return new ValidationResult("A branch with same name already exists!");
|
||||
}
|
||||
if (!creator._allowOverwrite)
|
||||
{
|
||||
var fixedName = creator.FixName(name);
|
||||
foreach (var b in creator._repo.Branches)
|
||||
{
|
||||
if (b.FriendlyName == fixedName)
|
||||
return new ValidationResult("A branch with same name already exists!");
|
||||
}
|
||||
}
|
||||
|
||||
return ValidationResult.Success;
|
||||
return ValidationResult.Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ValidationResult("Missing runtime context to create branch!");
|
||||
}
|
||||
}
|
||||
|
||||
public override Task<bool> Sure()
|
||||
|
@ -119,7 +135,7 @@ namespace SourceGit.ViewModels
|
|||
var needPopStash = false;
|
||||
if (DiscardLocalChanges)
|
||||
{
|
||||
succ = new Commands.Checkout(_repo.FullPath).Use(log).Branch(fixedName, _baseOnRevision, true);
|
||||
succ = new Commands.Checkout(_repo.FullPath).Use(log).Branch(fixedName, _baseOnRevision, true, _allowOverwrite);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -137,7 +153,7 @@ namespace SourceGit.ViewModels
|
|||
needPopStash = true;
|
||||
}
|
||||
|
||||
succ = new Commands.Checkout(_repo.FullPath).Use(log).Branch(fixedName, _baseOnRevision, false);
|
||||
succ = new Commands.Checkout(_repo.FullPath).Use(log).Branch(fixedName, _baseOnRevision, false, _allowOverwrite);
|
||||
}
|
||||
|
||||
if (succ)
|
||||
|
@ -155,7 +171,7 @@ namespace SourceGit.ViewModels
|
|||
}
|
||||
else
|
||||
{
|
||||
succ = Commands.Branch.Create(_repo.FullPath, fixedName, _baseOnRevision, log);
|
||||
succ = Commands.Branch.Create(_repo.FullPath, fixedName, _baseOnRevision, _allowOverwrite, log);
|
||||
}
|
||||
|
||||
log.Complete();
|
||||
|
@ -201,5 +217,6 @@ namespace SourceGit.ViewModels
|
|||
private readonly Repository _repo = null;
|
||||
private string _name = null;
|
||||
private readonly string _baseOnRevision = null;
|
||||
private bool _allowOverwrite = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ namespace SourceGit.ViewModels
|
|||
var masterBranch = _repo.Branches.Find(x => x.IsLocal && x.Name.Equals(_master, StringComparison.Ordinal));
|
||||
if (masterBranch == null)
|
||||
{
|
||||
succ = Commands.Branch.Create(_repo.FullPath, _master, current.Head, log);
|
||||
succ = Commands.Branch.Create(_repo.FullPath, _master, current.Head, true, log);
|
||||
if (!succ)
|
||||
{
|
||||
log.Complete();
|
||||
|
@ -128,7 +128,7 @@ namespace SourceGit.ViewModels
|
|||
var developBranch = _repo.Branches.Find(x => x.IsLocal && x.Name.Equals(_develop, StringComparison.Ordinal));
|
||||
if (developBranch == null)
|
||||
{
|
||||
succ = Commands.Branch.Create(_repo.FullPath, _develop, current.Head, log);
|
||||
succ = Commands.Branch.Create(_repo.FullPath, _develop, current.Head, true, log);
|
||||
if (!succ)
|
||||
{
|
||||
log.Complete();
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace SourceGit.ViewModels
|
|||
|
||||
return Task.Run(() =>
|
||||
{
|
||||
var succ = Commands.Branch.ResetWithoutCheckout(_repo.FullPath, Target.Name, _revision, log);
|
||||
var succ = Commands.Branch.Create(_repo.FullPath, Target.Name, _revision, true, log);
|
||||
log.Complete();
|
||||
CallUIThread(() => _repo.SetWatcherEnabled(true));
|
||||
return succ;
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<TextBlock FontSize="18"
|
||||
Classes="bold"
|
||||
Text="{DynamicResource Text.CreateBranch.Title}"/>
|
||||
<Grid Margin="0,16,0,0" RowDefinitions="32,32,Auto,Auto,Auto,Auto" ColumnDefinitions="140,*">
|
||||
<Grid Margin="0,16,0,0" RowDefinitions="32,32,Auto,32,Auto,Auto,Auto" ColumnDefinitions="140,*">
|
||||
<TextBlock Grid.Row="0" Grid.Column="0"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Margin="0,0,8,0"
|
||||
|
@ -80,11 +80,16 @@
|
|||
</Border>
|
||||
|
||||
<CheckBox Grid.Row="4" Grid.Column="1"
|
||||
Content="{DynamicResource Text.CreateBranch.OverwriteExisting}"
|
||||
IsChecked="{Binding AllowOverwrite, Mode=TwoWay}"
|
||||
ToolTip.Tip="checkout -B or branch -f"/>
|
||||
|
||||
<CheckBox Grid.Row="5" Grid.Column="1"
|
||||
Content="{DynamicResource Text.CreateBranch.Checkout}"
|
||||
IsChecked="{Binding CheckoutAfterCreated, Mode=TwoWay}"
|
||||
IsVisible="{Binding !IsBareRepository}"/>
|
||||
|
||||
<CheckBox Grid.Row="5" Grid.Column="1"
|
||||
<CheckBox Grid.Row="6" Grid.Column="1"
|
||||
Content="{DynamicResource Text.Checkout.RecurseSubmodules}"
|
||||
IsChecked="{Binding RecurseSubmodules, Mode=TwoWay}"
|
||||
ToolTip.Tip="--recurse-submodules">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue