refactor: rewrite git-flow integration

Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
leo 2025-05-20 21:08:00 +08:00
parent 6fa454ace8
commit 4d5be9f280
No known key found for this signature in database
9 changed files with 197 additions and 166 deletions

View file

@ -9,9 +9,11 @@ namespace SourceGit.ViewModels
get;
}
public bool IsFeature => _type == "feature";
public bool IsRelease => _type == "release";
public bool IsHotfix => _type == "hotfix";
public Models.GitFlowBranchType Type
{
get;
private set;
}
public bool Squash
{
@ -31,27 +33,27 @@ namespace SourceGit.ViewModels
set;
} = false;
public GitFlowFinish(Repository repo, Models.Branch branch, string type, string prefix)
public GitFlowFinish(Repository repo, Models.Branch branch, Models.GitFlowBranchType type)
{
_repo = repo;
_type = type;
_prefix = prefix;
Branch = branch;
Type = type;
}
public override Task<bool> Sure()
{
_repo.SetWatcherEnabled(false);
ProgressDescription = $"Git Flow - Finish {Branch.Name} ...";
var name = Branch.Name.StartsWith(_prefix) ? Branch.Name.Substring(_prefix.Length) : Branch.Name;
ProgressDescription = $"Git Flow - finishing {_type} {name} ...";
var log = _repo.CreateLog("Gitflow - Finish");
var log = _repo.CreateLog("GitFlow - Finish");
Use(log);
var prefix = _repo.GitFlow.GetPrefix(Type);
var name = Branch.Name.StartsWith(prefix) ? Branch.Name.Substring(prefix.Length) : Branch.Name;
return Task.Run(() =>
{
var succ = Commands.GitFlow.Finish(_repo.FullPath, _type, name, Squash, AutoPush, KeepBranch, log);
var succ = Commands.GitFlow.Finish(_repo.FullPath, Type, name, Squash, AutoPush, KeepBranch, log);
log.Complete();
CallUIThread(() => _repo.SetWatcherEnabled(true));
return succ;
@ -59,7 +61,5 @@ namespace SourceGit.ViewModels
}
private readonly Repository _repo;
private readonly string _type;
private readonly string _prefix;
}
}

View file

@ -5,6 +5,18 @@ namespace SourceGit.ViewModels
{
public class GitFlowStart : Popup
{
public Models.GitFlowBranchType Type
{
get;
private set;
}
public string Prefix
{
get;
private set;
}
[Required(ErrorMessage = "Name is required!!!")]
[RegularExpression(@"^[\w\-/\.#]+$", ErrorMessage = "Bad branch name format!")]
[CustomValidation(typeof(GitFlowStart), nameof(ValidateBranchName))]
@ -14,27 +26,19 @@ namespace SourceGit.ViewModels
set => SetProperty(ref _name, value, true);
}
public string Prefix
{
get => _prefix;
}
public bool IsFeature => _type == "feature";
public bool IsRelease => _type == "release";
public bool IsHotfix => _type == "hotfix";
public GitFlowStart(Repository repo, string type)
public GitFlowStart(Repository repo, Models.GitFlowBranchType type)
{
_repo = repo;
_type = type;
_prefix = Commands.GitFlow.GetPrefix(repo.FullPath, type);
Type = type;
Prefix = _repo.GitFlow.GetPrefix(type);
}
public static ValidationResult ValidateBranchName(string name, ValidationContext ctx)
{
if (ctx.ObjectInstance is GitFlowStart starter)
{
var check = $"{starter._prefix}{name}";
var check = $"{starter.Prefix}{name}";
foreach (var b in starter._repo.Branches)
{
if (b.FriendlyName == check)
@ -48,14 +52,14 @@ namespace SourceGit.ViewModels
public override Task<bool> Sure()
{
_repo.SetWatcherEnabled(false);
ProgressDescription = $"Git Flow - starting {_type} {_name} ...";
ProgressDescription = $"Git Flow - Start {Prefix}{_name} ...";
var log = _repo.CreateLog("Gitflow - Start");
var log = _repo.CreateLog("GitFlow - Start");
Use(log);
return Task.Run(() =>
{
var succ = Commands.GitFlow.Start(_repo.FullPath, _type, _name, log);
var succ = Commands.GitFlow.Start(_repo.FullPath, Type, _name, log);
log.Complete();
CallUIThread(() => _repo.SetWatcherEnabled(true));
return succ;
@ -63,8 +67,6 @@ namespace SourceGit.ViewModels
}
private readonly Repository _repo;
private readonly string _type;
private readonly string _prefix;
private string _name = null;
}
}

View file

@ -975,8 +975,8 @@ namespace SourceGit.ViewModels
if (!_repo.IsBare)
{
var detect = Commands.GitFlow.DetectType(_repo.FullPath, _repo.Branches, current.Name);
if (detect.IsGitFlowBranch)
var type = _repo.GetGitFlowType(current);
if (type != Models.GitFlowBranchType.None)
{
var finish = new MenuItem();
finish.Header = App.Text("BranchCM.Finish", current.Name);
@ -984,7 +984,7 @@ namespace SourceGit.ViewModels
finish.Click += (_, e) =>
{
if (_repo.CanCreatePopup())
_repo.ShowPopup(new GitFlowFinish(_repo, current, detect.Type, detect.Prefix));
_repo.ShowPopup(new GitFlowFinish(_repo, current, type));
e.Handled = true;
};
submenu.Items.Add(finish);
@ -1063,8 +1063,8 @@ namespace SourceGit.ViewModels
if (!_repo.IsBare)
{
var detect = Commands.GitFlow.DetectType(_repo.FullPath, _repo.Branches, branch.Name);
if (detect.IsGitFlowBranch)
var type = _repo.GetGitFlowType(branch);
if (type != Models.GitFlowBranchType.None)
{
var finish = new MenuItem();
finish.Header = App.Text("BranchCM.Finish", branch.Name);
@ -1072,7 +1072,7 @@ namespace SourceGit.ViewModels
finish.Click += (_, e) =>
{
if (_repo.CanCreatePopup())
_repo.ShowPopup(new GitFlowFinish(_repo, branch, detect.Type, detect.Prefix));
_repo.ShowPopup(new GitFlowFinish(_repo, branch, type));
e.Handled = true;
};
submenu.Items.Add(finish);

View file

@ -121,7 +121,23 @@ namespace SourceGit.ViewModels
log);
log.Complete();
CallUIThread(() => _repo.SetWatcherEnabled(true));
CallUIThread(() =>
{
if (succ)
{
var gitflow = new Models.GitFlow();
gitflow.Master = _master;
gitflow.Develop = _develop;
gitflow.FeaturePrefix = _featurePrefix;
gitflow.ReleasePrefix = _releasePrefix;
gitflow.HotfixPrefix = _hotfixPrefix;
_repo.GitFlow = gitflow;
}
_repo.SetWatcherEnabled(true);
});
return succ;
});
}

View file

@ -51,6 +51,12 @@ namespace SourceGit.ViewModels
get => _settings;
}
public Models.GitFlow GitFlow
{
get;
set;
} = new Models.GitFlow();
public Models.FilterMode HistoriesFilterMode
{
get => _historiesFilterMode;
@ -595,6 +601,28 @@ namespace SourceGit.ViewModels
GetOwnerPage()?.StartPopup(popup);
}
public bool IsGitFlowEnabled()
{
return GitFlow is { IsValid: true } &&
_branches.Find(x => x.IsLocal && x.Name.Equals(GitFlow.Master, StringComparison.Ordinal)) != null &&
_branches.Find(x => x.IsLocal && x.Name.Equals(GitFlow.Develop, StringComparison.Ordinal)) != null;
}
public Models.GitFlowBranchType GetGitFlowType(Models.Branch b)
{
if (!IsGitFlowEnabled())
return Models.GitFlowBranchType.None;
var name = b.Name;
if (name.StartsWith(GitFlow.FeaturePrefix, StringComparison.Ordinal))
return Models.GitFlowBranchType.Feature;
if (name.StartsWith(GitFlow.ReleasePrefix, StringComparison.Ordinal))
return Models.GitFlowBranchType.Release;
if (name.StartsWith(GitFlow.HotfixPrefix, StringComparison.Ordinal))
return Models.GitFlowBranchType.Hotfix;
return Models.GitFlowBranchType.None;
}
public CommandLog CreateLog(string name)
{
var log = new CommandLog(name);
@ -606,8 +634,19 @@ namespace SourceGit.ViewModels
{
Task.Run(() =>
{
var allowedSignersFile = new Commands.Config(_fullpath).Get("gpg.ssh.allowedSignersFile");
_hasAllowedSignersFile = !string.IsNullOrEmpty(allowedSignersFile);
var config = new Commands.Config(_fullpath).ListAll();
_hasAllowedSignersFile = config.TryGetValue("gpg.ssh.allowedSignersFile", out var allowedSignersFile) && !string.IsNullOrEmpty(allowedSignersFile);
if (config.TryGetValue("gitflow.branch.master", out var masterName))
GitFlow.Master = masterName;
if (config.TryGetValue("gitflow.branch.develop", out var developName))
GitFlow.Develop = developName;
if (config.TryGetValue("gitflow.prefix.feature", out var featurePrefix))
GitFlow.FeaturePrefix = featurePrefix;
if (config.TryGetValue("gitflow.prefix.release", out var releasePrefix))
GitFlow.ReleasePrefix = releasePrefix;
if (config.TryGetValue("gitflow.prefix.hotfix", out var hotfixPrefix))
GitFlow.HotfixPrefix = hotfixPrefix;
});
Task.Run(RefreshBranches);
@ -1377,8 +1416,7 @@ namespace SourceGit.ViewModels
var menu = new ContextMenu();
menu.Placement = PlacementMode.BottomEdgeAlignedLeft;
var isGitFlowEnabled = Commands.GitFlow.IsEnabled(_fullpath, _branches);
if (isGitFlowEnabled)
if (IsGitFlowEnabled())
{
var startFeature = new MenuItem();
startFeature.Header = App.Text("GitFlow.StartFeature");
@ -1386,7 +1424,7 @@ namespace SourceGit.ViewModels
startFeature.Click += (_, e) =>
{
if (CanCreatePopup())
ShowPopup(new GitFlowStart(this, "feature"));
ShowPopup(new GitFlowStart(this, Models.GitFlowBranchType.Feature));
e.Handled = true;
};
@ -1396,7 +1434,7 @@ namespace SourceGit.ViewModels
startRelease.Click += (_, e) =>
{
if (CanCreatePopup())
ShowPopup(new GitFlowStart(this, "release"));
ShowPopup(new GitFlowStart(this, Models.GitFlowBranchType.Release));
e.Handled = true;
};
@ -1406,7 +1444,7 @@ namespace SourceGit.ViewModels
startHotfix.Click += (_, e) =>
{
if (CanCreatePopup())
ShowPopup(new GitFlowStart(this, "hotfix"));
ShowPopup(new GitFlowStart(this, Models.GitFlowBranchType.Hotfix));
e.Handled = true;
};
@ -1867,8 +1905,8 @@ namespace SourceGit.ViewModels
if (!IsBare)
{
var detect = Commands.GitFlow.DetectType(_fullpath, _branches, branch.Name);
if (detect.IsGitFlowBranch)
var type = GetGitFlowType(branch);
if (type != Models.GitFlowBranchType.None)
{
var finish = new MenuItem();
finish.Header = App.Text("BranchCM.Finish", branch.Name);
@ -1876,7 +1914,7 @@ namespace SourceGit.ViewModels
finish.Click += (_, e) =>
{
if (CanCreatePopup())
ShowPopup(new GitFlowFinish(this, branch, detect.Type, detect.Prefix));
ShowPopup(new GitFlowFinish(this, branch, type));
e.Handled = true;
};
menu.Items.Add(new MenuItem() { Header = "-" });