sourcegit/src/ViewModels/Push.cs
2024-07-15 00:30:31 +08:00

215 lines
6.6 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))
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
{
if (SetProperty(ref _selectedRemoteBranch, value))
IsSetTrackOptionVisible = value != null && _selectedLocalBranch.Upstream != value.FullName;
}
}
public bool PushAllTags
{
get => _repo.Settings.PushAllTags;
set => _repo.Settings.PushAllTags = value;
}
public bool IsSetTrackOptionVisible
{
get => _isSetTrackOptionVisible;
private set => SetProperty(ref _isSetTrackOptionVisible, value);
}
public bool Tracking
{
get;
set;
} = true;
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);
var remoteBranchName = _selectedRemoteBranch.Name.Replace(" (new)", "");
ProgressDescription = $"Push {_selectedLocalBranch.Name} -> {_selectedRemote.Name}/{remoteBranchName} ...";
return Task.Run(() =>
{
var succ = new Commands.Push(
_repo.FullPath,
_selectedLocalBranch.Name,
_selectedRemote.Name,
remoteBranchName,
PushAllTags,
ForcePush,
_isSetTrackOptionVisible && Tracking,
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 readonly 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;
private bool _isSetTrackOptionVisible = false;
}
}