public Task ExecuteAsync(CancellationToken cancellation = default) { var localBranch = repository.Head; var targetBranch = repository.Head.TrackedBranch ?? repository.Head; var dialog = new PushDialog( targetBranch.RemoteName ?? repository.GetDefaultRemoteName(), targetBranch.GetName(), trackRemoteBranch: repository.Head.TrackedBranch != null, remotes: repository.GetRemoteNames(), branches: repository.GetBranchNames()); var result = mainThread.Invoke(() => dialog.ShowDialog()); if (result == true && !string.IsNullOrEmpty(dialog.Remote)) { var remote = repository .Network .Remotes .FirstOrDefault(x => x.Name == dialog.Remote); if (remote != null) { var pushRefSpec = $"refs/heads/{localBranch.GetName()}:refs/heads/{dialog.Branch}"; if (dialog.Force) { pushRefSpec = "+" + pushRefSpec; } var pushOptions = new PushOptions() { CredentialsProvider = credentialsProvider, OnPushTransferProgress = (current, total, bytes) => { eventStream.Push <Status>((float)current / (float)total); return(true); } }; eventStream.Push(Status.Start("git push {0} {1}", dialog.Remote, pushRefSpec)); repository.Network.Push(remote, pushRefSpec, pushOptions); if (dialog.TrackRemoteBranch) { var trackedBranch = repository.Branches.FirstOrDefault(x => x.RemoteName == dialog.Remote && x.GetName() == dialog.Branch); if (trackedBranch != null) { localBranch.Track(repository, trackedBranch); } } eventStream.Push(Status.Succeeded()); mainThread.Invoke(() => view.Refresh()); } } return(Task.CompletedTask); }
public async Task ExecuteAsync(CancellationToken cancellation = default) { var repositoryStatus = repository.RetrieveStatus(); var localBranch = repository.Head; var targetBranch = repository.Head.TrackedBranch ?? repository.Head; var dialog = new PullDialog( targetBranch.RemoteName ?? repository.GetDefaultRemoteName(), targetBranch.GetName(), showStashWarning: repositoryStatus.IsDirty, trackRemoteBranch: false, remotes: repository.GetRemoteNames(), branches: repository.GetBranchNames()); if (mainThread.Invoke(() => dialog.ShowDialog()) == true && !string.IsNullOrEmpty(dialog.Branch)) { var targetBranchFriendlyName = string.IsNullOrEmpty(dialog.Remote) ? dialog.Branch : $"{dialog.Remote}/{dialog.Branch}"; targetBranch = repository.Branches.FirstOrDefault(x => x.FriendlyName == targetBranchFriendlyName); if (targetBranch == null) { throw new InvalidOperationException(string.Format("Branch {0} not found", targetBranchFriendlyName)); } eventStream.Push(Status.Start("Pull {0} {1}", targetBranchFriendlyName, dialog.IsFastForward ? "With Fast Fordward" : string.Empty)); var stash = default(Stash); var mergeResult = default(MergeResult); var stashResult = default(StashApplyStatus); // 1. Fetch if (targetBranch.IsRemote) { TryFetch(targetBranch); } // 2. Stash (optional, if the repo is dirty) and Merge try { if (repositoryStatus.IsDirty) { stash = repository.Stashes.Add(Signatures.GetStashSignature(), StashModifiers.IncludeUntracked); } mergeResult = Merge(targetBranch, dialog.IsFastForward); } finally { if (stash != null && repository.Stashes.Contains(stash) && !repository.RetrieveStatus().IsDirty) { stashResult = repository.Stashes.Pop(repository.Stashes.ToList().IndexOf(stash)); } } // 3. Resolve conflicts if (mergeResult?.Status == MergeStatus.Conflicts) { await commandService.RunAsync("ResolveConflicts"); } // 4. Track if (dialog.TrackRemoteBranch) { localBranch.Track(repository, targetBranch); } // 5. Update submodules if (dialog.UpdateSubmodules) { eventStream.Push(Status.Create(0.8f, "Updating submodules...")); repository.UpdateSubmodules(eventStream: eventStream); } eventStream.Push(Status.Finish(mergeResult?.Status.ToString() ?? "Done")); mainThread.Invoke(() => view.Refresh()); } }