diff --git a/src/Commands/Branch.cs b/src/Commands/Branch.cs index 55c27843..0d1b1f8f 100644 --- a/src/Commands/Branch.cs +++ b/src/Commands/Branch.cs @@ -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(); diff --git a/src/Commands/Checkout.cs b/src/Commands/Checkout.cs index 6f63ae60..aa386c2f 100644 --- a/src/Commands/Checkout.cs +++ b/src/Commands/Checkout.cs @@ -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(); } diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index cff83f1a..c12396ec 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -217,6 +217,7 @@ Enter branch name. Spaces will be replaced with dashes. Create Local Branch + Overwrite existing branch Create Tag... New Tag At: GPG signing diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 627c7725..00939656 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -221,6 +221,7 @@ 填写分支名称。 空格将被替换为'-'符号 创建本地分支 + 允许重置已存在的分支 新建标签 ... 标签位于 : 使用GPG签名 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 065ac49d..026a41ed 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -221,6 +221,7 @@ 輸入分支名稱。 空格將以英文破折號取代 建立本機分支 + 允許覆寫現有分支 新增標籤... 標籤位於: 使用 GPG 簽章 diff --git a/src/ViewModels/CreateBranch.cs b/src/ViewModels/CreateBranch.cs index ce751a2f..e518e977 100644 --- a/src/ViewModels/CreateBranch.cs +++ b/src/ViewModels/CreateBranch.cs @@ -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 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; } } diff --git a/src/ViewModels/InitGitFlow.cs b/src/ViewModels/InitGitFlow.cs index 5188b773..dec587b0 100644 --- a/src/ViewModels/InitGitFlow.cs +++ b/src/ViewModels/InitGitFlow.cs @@ -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(); diff --git a/src/ViewModels/ResetWithoutCheckout.cs b/src/ViewModels/ResetWithoutCheckout.cs index da2dbeaf..3a9582ef 100644 --- a/src/ViewModels/ResetWithoutCheckout.cs +++ b/src/ViewModels/ResetWithoutCheckout.cs @@ -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; diff --git a/src/Views/CreateBranch.axaml b/src/Views/CreateBranch.axaml index e77f8751..3266e312 100644 --- a/src/Views/CreateBranch.axaml +++ b/src/Views/CreateBranch.axaml @@ -14,7 +14,7 @@ - + + + -