Esempio n. 1
0
        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());
            }
        }