sourcegit/src/ViewModels/Push.cs

174 lines
6.4 KiB
C#

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
namespace SourceGit.ViewModels {
public class Push : Popup {
public bool HasSpecifiedLocalBranch {
get;
private set;
}
[Required(ErrorMessage = "Local branch is required!!!")]
public Models.Branch SelectedLocalBranch {
get => _selectedLocalBranch;
set {
if (SetProperty(ref _selectedLocalBranch, value)) {
// If selected local branch has upstream branch. Try to find it's remote.
if (!string.IsNullOrEmpty(value.Upstream)) {
var branch = _repo.Branches.Find(x => x.FullName == value.Upstream);
if (branch != null) {
var remote = _repo.Remotes.Find(x => x.Name == branch.Remote);
if (remote != null && remote != _selectedRemote) {
SelectedRemote = remote;
return;
}
}
}
// Re-generate remote branches and auto-select remote branches.
AutoSelectBranchByRemote();
}
}
}
public List<Models.Branch> LocalBranches {
get;
private set;
}
public List<Models.Remote> Remotes {
get => _repo.Remotes;
}
[Required(ErrorMessage = "Remote is required!!!")]
public Models.Remote SelectedRemote {
get => _selectedRemote;
set {
if (SetProperty(ref _selectedRemote, value)) AutoSelectBranchByRemote();
}
}
public List<Models.Branch> RemoteBranches {
get => _remoteBranches;
private set => SetProperty(ref _remoteBranches, value);
}
[Required(ErrorMessage = "Remote branch is required!!!")]
public Models.Branch SelectedRemoteBranch {
get => _selectedRemoteBranch;
set => SetProperty(ref _selectedRemoteBranch, value);
}
public bool PushAllTags {
get;
set;
}
public bool ForcePush {
get;
set;
}
public Push(Repository repo, Models.Branch localBranch) {
_repo = repo;
// Gather all local branches and find current branch.
LocalBranches = new List<Models.Branch>();
var current = null as Models.Branch;
foreach (var branch in _repo.Branches) {
if (branch.IsLocal) LocalBranches.Add(branch);
if (branch.IsCurrent) current = branch;
}
// Set default selected local branch.
if (localBranch != null) {
_selectedLocalBranch = localBranch;
HasSpecifiedLocalBranch = true;
} else {
_selectedLocalBranch = current;
HasSpecifiedLocalBranch = false;
}
// Find preferred remote if selected local branch has upstream.
if (!string.IsNullOrEmpty(_selectedLocalBranch.Upstream)) {
foreach (var branch in repo.Branches) {
if (!branch.IsLocal && _selectedLocalBranch.Upstream == branch.FullName) {
_selectedRemote = repo.Remotes.Find(x => x.Name == branch.Remote);
break;
}
}
}
// Set default remote to the first if haven't been set.
if (_selectedRemote == null) _selectedRemote = repo.Remotes[0];
// Auto select preferred remote branch.
AutoSelectBranchByRemote();
View = new Views.Push() { DataContext = this };
}
public override Task<bool> Sure() {
_repo.SetWatcherEnabled(false);
return Task.Run(() => {
var remoteBranchName = _selectedRemoteBranch.Name.Replace(" (new)", "");
SetProgressDescription($"Push {_selectedLocalBranch.Name} -> {_selectedRemote.Name}/{remoteBranchName} ...");
var succ = new Commands.Push(
_repo.FullPath,
_selectedLocalBranch.Name,
_selectedRemote.Name,
remoteBranchName,
PushAllTags,
ForcePush,
string.IsNullOrEmpty(_selectedLocalBranch.Upstream),
SetProgressDescription).Exec();
CallUIThread(() => _repo.SetWatcherEnabled(true));
return succ;
});
}
private void AutoSelectBranchByRemote() {
// Gather branches.
var branches = new List<Models.Branch>();
foreach (var branch in _repo.Branches) {
if (branch.Remote == _selectedRemote.Name) branches.Add(branch);
}
// If selected local branch has upstream branch. Try to find it in current remote branches.
if (!string.IsNullOrEmpty(_selectedLocalBranch.Upstream)) {
foreach (var branch in branches) {
if (_selectedLocalBranch.Upstream == branch.FullName) {
RemoteBranches = branches;
SelectedRemoteBranch = branch;
return;
}
}
}
// Find best remote branch by name.
foreach (var branch in branches) {
if (_selectedLocalBranch.Name == branch.Name) {
RemoteBranches = branches;
SelectedRemoteBranch = branch;
return;
}
}
// Add a fake new branch.
var fake = new Models.Branch() {
Name = $"{_selectedLocalBranch.Name} (new)",
Remote = _selectedRemote.Name,
};
branches.Add(fake);
RemoteBranches = branches;
SelectedRemoteBranch = fake;
}
private Repository _repo = null;
private Models.Branch _selectedLocalBranch = null;
private Models.Remote _selectedRemote = null;
private List<Models.Branch> _remoteBranches = new List<Models.Branch>();
private Models.Branch _selectedRemoteBranch = null;
}
}