public async Task ExecuteAsync(object?parameter = null, 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())); mainThread.Invoke(() => view.Refresh()); } }