mirror of
https://github.com/sourcegit-scm/sourcegit
synced 2025-06-05 11:05:00 +00:00
228 lines
7.5 KiB
C#
228 lines
7.5 KiB
C#
using System.Collections.Generic;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace SourceGit.ViewModels
|
|
{
|
|
public class Pull : Popup
|
|
{
|
|
public List<Models.Remote> Remotes => _repo.Remotes;
|
|
public Models.Branch Current => _current;
|
|
|
|
public bool HasSpecifiedRemoteBranch
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
public Models.Remote SelectedRemote
|
|
{
|
|
get => _selectedRemote;
|
|
set
|
|
{
|
|
if (SetProperty(ref _selectedRemote, value))
|
|
PostRemoteSelected();
|
|
}
|
|
}
|
|
|
|
public List<Models.Branch> RemoteBranches
|
|
{
|
|
get => _remoteBranches;
|
|
private set => SetProperty(ref _remoteBranches, value);
|
|
}
|
|
|
|
[Required(ErrorMessage = "Remote branch to pull is required!!!")]
|
|
public Models.Branch SelectedBranch
|
|
{
|
|
get => _selectedBranch;
|
|
set => SetProperty(ref _selectedBranch, value, true);
|
|
}
|
|
|
|
public bool DiscardLocalChanges
|
|
{
|
|
get;
|
|
set;
|
|
} = false;
|
|
|
|
public bool UseRebase
|
|
{
|
|
get => _repo.Settings.PreferRebaseInsteadOfMerge;
|
|
set => _repo.Settings.PreferRebaseInsteadOfMerge = value;
|
|
}
|
|
|
|
public bool IsRecurseSubmoduleVisible
|
|
{
|
|
get => _repo.Submodules.Count > 0;
|
|
}
|
|
|
|
public bool RecurseSubmodules
|
|
{
|
|
get => _repo.Settings.UpdateSubmodulesOnCheckoutBranch;
|
|
set => _repo.Settings.UpdateSubmodulesOnCheckoutBranch = value;
|
|
}
|
|
|
|
public Pull(Repository repo, Models.Branch specifiedRemoteBranch)
|
|
{
|
|
_repo = repo;
|
|
_current = repo.CurrentBranch;
|
|
|
|
if (specifiedRemoteBranch != null)
|
|
{
|
|
_selectedRemote = repo.Remotes.Find(x => x.Name == specifiedRemoteBranch.Remote);
|
|
_selectedBranch = specifiedRemoteBranch;
|
|
|
|
var branches = new List<Models.Branch>();
|
|
foreach (var branch in _repo.Branches)
|
|
{
|
|
if (branch.Remote == specifiedRemoteBranch.Remote)
|
|
branches.Add(branch);
|
|
}
|
|
|
|
_remoteBranches = branches;
|
|
HasSpecifiedRemoteBranch = true;
|
|
}
|
|
else
|
|
{
|
|
var autoSelectedRemote = null as Models.Remote;
|
|
if (!string.IsNullOrEmpty(_current.Upstream))
|
|
{
|
|
var remoteNameEndIdx = _current.Upstream.IndexOf('/', 13);
|
|
if (remoteNameEndIdx > 0)
|
|
{
|
|
var remoteName = _current.Upstream.Substring(13, remoteNameEndIdx - 13);
|
|
autoSelectedRemote = _repo.Remotes.Find(x => x.Name == remoteName);
|
|
}
|
|
}
|
|
|
|
if (autoSelectedRemote == null)
|
|
{
|
|
var remote = null as Models.Remote;
|
|
if (!string.IsNullOrEmpty(_repo.Settings.DefaultRemote))
|
|
remote = _repo.Remotes.Find(x => x.Name == _repo.Settings.DefaultRemote);
|
|
_selectedRemote = remote ?? _repo.Remotes[0];
|
|
}
|
|
else
|
|
{
|
|
_selectedRemote = autoSelectedRemote;
|
|
}
|
|
|
|
PostRemoteSelected();
|
|
HasSpecifiedRemoteBranch = false;
|
|
}
|
|
}
|
|
|
|
public override Task<bool> Sure()
|
|
{
|
|
_repo.SetWatcherEnabled(false);
|
|
|
|
var log = _repo.CreateLog("Pull");
|
|
Use(log);
|
|
|
|
var updateSubmodules = IsRecurseSubmoduleVisible && RecurseSubmodules;
|
|
return Task.Run(() =>
|
|
{
|
|
var changes = new Commands.CountLocalChangesWithoutUntracked(_repo.FullPath).Result();
|
|
var needPopStash = false;
|
|
if (changes > 0)
|
|
{
|
|
if (DiscardLocalChanges)
|
|
{
|
|
Commands.Discard.All(_repo.FullPath, false, log);
|
|
}
|
|
else
|
|
{
|
|
var succ = new Commands.Stash(_repo.FullPath).Use(log).Push("PULL_AUTO_STASH");
|
|
if (!succ)
|
|
{
|
|
log.Complete();
|
|
CallUIThread(() => _repo.SetWatcherEnabled(true));
|
|
return false;
|
|
}
|
|
|
|
needPopStash = true;
|
|
}
|
|
}
|
|
|
|
bool rs = new Commands.Pull(
|
|
_repo.FullPath,
|
|
_selectedRemote.Name,
|
|
!string.IsNullOrEmpty(_current.Upstream) && _current.Upstream.Equals(_selectedBranch.FullName) ? string.Empty : _selectedBranch.Name,
|
|
UseRebase).Use(log).Exec();
|
|
|
|
if (rs)
|
|
{
|
|
if (updateSubmodules)
|
|
{
|
|
var submodules = new Commands.QueryUpdatableSubmodules(_repo.FullPath).Result();
|
|
if (submodules.Count > 0)
|
|
new Commands.Submodule(_repo.FullPath).Use(log).Update(submodules, true, true);
|
|
}
|
|
|
|
if (needPopStash)
|
|
new Commands.Stash(_repo.FullPath).Use(log).Pop("stash@{0}");
|
|
}
|
|
|
|
log.Complete();
|
|
|
|
var head = new Commands.QueryRevisionByRefName(_repo.FullPath, "HEAD").Result();
|
|
CallUIThread(() =>
|
|
{
|
|
_repo.NavigateToCommitDelayed(head);
|
|
_repo.SetWatcherEnabled(true);
|
|
});
|
|
|
|
return rs;
|
|
});
|
|
}
|
|
|
|
private void PostRemoteSelected()
|
|
{
|
|
var remoteName = _selectedRemote.Name;
|
|
var branches = new List<Models.Branch>();
|
|
foreach (var branch in _repo.Branches)
|
|
{
|
|
if (branch.Remote == remoteName)
|
|
branches.Add(branch);
|
|
}
|
|
|
|
RemoteBranches = branches;
|
|
|
|
var autoSelectedBranch = false;
|
|
if (!string.IsNullOrEmpty(_current.Upstream) &&
|
|
_current.Upstream.StartsWith($"refs/remotes/{remoteName}/", System.StringComparison.Ordinal))
|
|
{
|
|
foreach (var branch in branches)
|
|
{
|
|
if (_current.Upstream == branch.FullName)
|
|
{
|
|
SelectedBranch = branch;
|
|
autoSelectedBranch = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!autoSelectedBranch)
|
|
{
|
|
foreach (var branch in branches)
|
|
{
|
|
if (_current.Name == branch.Name)
|
|
{
|
|
SelectedBranch = branch;
|
|
autoSelectedBranch = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!autoSelectedBranch)
|
|
SelectedBranch = null;
|
|
}
|
|
|
|
private readonly Repository _repo = null;
|
|
private readonly Models.Branch _current = null;
|
|
private Models.Remote _selectedRemote = null;
|
|
private List<Models.Branch> _remoteBranches = null;
|
|
private Models.Branch _selectedBranch = null;
|
|
}
|
|
}
|