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 LocalBranches { get; private set; } public List Remotes { get => _repo.Remotes; } [Required(ErrorMessage = "Remote is required!!!")] public Models.Remote SelectedRemote { get => _selectedRemote; set { if (SetProperty(ref _selectedRemote, value)) AutoSelectBranchByRemote(); } } public List 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(); 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 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, string.IsNullOrEmpty(_selectedLocalBranch.Upstream), SetProgressDescription).Exec(); CallUIThread(() => _repo.SetWatcherEnabled(true)); return succ; }); } private void AutoSelectBranchByRemote() { // Gather branches. var branches = new List(); 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 _remoteBranches = new List(); private Models.Branch _selectedRemoteBranch = null; } }