예제 #1
0
        /// <inheritdoc/>
        public async Task <IDifferenceViewer> OpenDiff(IPullRequestSession session, string relativePath, string headSha, bool scrollToFirstDiff)
        {
            Guard.ArgumentNotNull(session, nameof(session));
            Guard.ArgumentNotEmptyString(relativePath, nameof(relativePath));

            try
            {
                var workingDirectory = headSha == null;
                var file             = await session.GetFile(relativePath, headSha ?? "HEAD");

                var mergeBase = await pullRequestService.GetMergeBase(session.LocalRepository, session.PullRequest);

                var encoding  = pullRequestService.GetEncoding(session.LocalRepository, file.RelativePath);
                var rightFile = workingDirectory ?
                                Path.Combine(session.LocalRepository.LocalPath, relativePath) :
                                await pullRequestService.ExtractToTempFile(
                    session.LocalRepository,
                    session.PullRequest,
                    relativePath,
                    file.CommitSha,
                    encoding);

                var diffViewer = FocusExistingDiffViewer(session, mergeBase, rightFile);
                if (diffViewer != null)
                {
                    return(diffViewer);
                }

                var leftFile = await pullRequestService.ExtractToTempFile(
                    session.LocalRepository,
                    session.PullRequest,
                    relativePath,
                    mergeBase,
                    encoding);

                var leftPath = await GetBaseFileName(session, file);

                var rightPath  = file.RelativePath;
                var leftLabel  = $"{leftPath};{session.GetBaseBranchDisplay()}";
                var rightLabel = workingDirectory ? rightPath : $"{rightPath};PR {session.PullRequest.Number}";
                var caption    = $"Diff - {Path.GetFileName(file.RelativePath)}";
                var options    = __VSDIFFSERVICEOPTIONS.VSDIFFOPT_DetectBinaryFiles |
                                 __VSDIFFSERVICEOPTIONS.VSDIFFOPT_LeftFileIsTemporary;

                if (!workingDirectory)
                {
                    options |= __VSDIFFSERVICEOPTIONS.VSDIFFOPT_RightFileIsTemporary;
                }

                IVsWindowFrame frame;
                using (OpenWithOption(DifferenceViewerOptions.ScrollToFirstDiffName, scrollToFirstDiff))
                    using (OpenInProvisionalTab())
                    {
                        var tooltip = $"{leftLabel}\nvs.\n{rightLabel}";

                        // Diff window will open in provisional (right hand) tab until document is touched.
                        frame = VisualStudio.Services.DifferenceService.OpenComparisonWindow2(
                            leftFile,
                            rightFile,
                            caption,
                            tooltip,
                            leftLabel,
                            rightLabel,
                            string.Empty,
                            string.Empty,
                            (uint)options);
                    }

                diffViewer = GetDiffViewer(frame);

                var leftText  = diffViewer.LeftView.TextBuffer.CurrentSnapshot.GetText();
                var rightText = diffViewer.RightView.TextBuffer.CurrentSnapshot.GetText();
                if (leftText == string.Empty)
                {
                    // Don't show LeftView when empty.
                    diffViewer.ViewMode = DifferenceViewMode.RightViewOnly;
                }
                else if (rightText == string.Empty)
                {
                    // Don't show RightView when empty.
                    diffViewer.ViewMode = DifferenceViewMode.LeftViewOnly;
                }
                else if (leftText == rightText)
                {
                    // Don't show LeftView when no changes.
                    diffViewer.ViewMode = DifferenceViewMode.RightViewOnly;
                }

                AddBufferTag(diffViewer.LeftView.TextBuffer, session, leftPath, mergeBase, DiffSide.Left);

                if (!workingDirectory)
                {
                    AddBufferTag(diffViewer.RightView.TextBuffer, session, rightPath, file.CommitSha, DiffSide.Right);
                    EnableNavigateToEditor(diffViewer.LeftView, session);
                    EnableNavigateToEditor(diffViewer.RightView, session);
                    EnableNavigateToEditor(diffViewer.InlineView, session);
                }

                if (workingDirectory)
                {
                    await usageTracker.IncrementCounter(x => x.NumberOfPRDetailsCompareWithSolution);
                }
                else
                {
                    await usageTracker.IncrementCounter(x => x.NumberOfPRDetailsViewChanges);
                }

                return(diffViewer);
            }
            catch (Exception e)
            {
                ShowErrorInStatusBar("Error opening file", e);
                return(null);
            }
        }
        /// <inheritdoc/>
        public async Task <IDifferenceViewer> OpenDiff(IPullRequestSession session, string relativePath, string headSha, bool scrollToFirstDraftOrDiff)
        {
            Guard.ArgumentNotNull(session, nameof(session));
            Guard.ArgumentNotEmptyString(relativePath, nameof(relativePath));

            try
            {
                var workingDirectory = headSha == null;
                var file             = await session.GetFile(relativePath, headSha ?? "HEAD");

                var mergeBase = await pullRequestService.GetMergeBase(session.LocalRepository, session.PullRequest);

                var encoding  = pullRequestService.GetEncoding(session.LocalRepository, file.RelativePath);
                var rightFile = workingDirectory ?
                                Path.Combine(session.LocalRepository.LocalPath, relativePath) :
                                await pullRequestService.ExtractToTempFile(
                    session.LocalRepository,
                    session.PullRequest,
                    relativePath,
                    file.CommitSha,
                    encoding);

                var diffViewer = FocusExistingDiffViewer(session, mergeBase, rightFile);
                if (diffViewer != null)
                {
                    return(diffViewer);
                }

                var leftFile = await pullRequestService.ExtractToTempFile(
                    session.LocalRepository,
                    session.PullRequest,
                    relativePath,
                    mergeBase,
                    encoding);

                var leftPath = await GetBaseFileName(session, file);

                var rightPath  = file.RelativePath;
                var leftLabel  = $"{leftPath};{session.GetBaseBranchDisplay()}";
                var rightLabel = workingDirectory ? rightPath : $"{rightPath};PR {session.PullRequest.Number}";
                var caption    = $"Diff - {Path.GetFileName(file.RelativePath)}";
                var options    = __VSDIFFSERVICEOPTIONS.VSDIFFOPT_DetectBinaryFiles |
                                 __VSDIFFSERVICEOPTIONS.VSDIFFOPT_LeftFileIsTemporary;
                var openThread        = (line : -1, side : DiffSide.Left);
                var scrollToFirstDiff = false;

                if (!workingDirectory)
                {
                    options |= __VSDIFFSERVICEOPTIONS.VSDIFFOPT_RightFileIsTemporary;
                }

                if (scrollToFirstDraftOrDiff)
                {
                    var(key, _) = PullRequestReviewCommentThreadViewModel.GetDraftKeys(
                        session.LocalRepository.CloneUrl.WithOwner(session.RepositoryOwner),
                        session.PullRequest.Number,
                        relativePath,
                        0);
                    var drafts = (await draftStore.GetDrafts <PullRequestReviewCommentDraft>(key)
                                  .ConfigureAwait(true))
                                 .OrderByDescending(x => x.data.UpdatedAt)
                                 .ToList();

                    if (drafts.Count > 0 && int.TryParse(drafts[0].secondaryKey, out var line))
                    {
                        openThread        = (line, drafts[0].data.Side);