Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 14 additions & 15 deletions src/github/folderRepositoryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2554,6 +2554,20 @@ export class FolderRepositoryManager extends Disposable {

const isBrowser = (vscode.env.appHost === 'vscode.dev' || vscode.env.appHost === 'github.dev');

if (pullRequest.item.mergeable !== PullRequestMergeability.Conflict && !pullRequest.githubRepository.remote.isEnterprise) {
const result = await vscode.window.withProgress(
{ location: vscode.ProgressLocation.Notification, title: vscode.l10n.t('Updating branch...') },
async () => {
const success = await pullRequest.updateBranchWithGraphQL();
if (success && pullRequest.isActive) {
await this.repository.pull();
}
return success;
}
);
return result;
}

if (!pullRequest.isActive || isBrowser) {
const conflictModel = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: vscode.l10n.t('Finding conflicts...') }, () => createConflictResolutionModel(pullRequest));
if (conflictModel === undefined) {
Expand All @@ -2576,21 +2590,6 @@ export class FolderRepositoryManager extends Disposable {
}
}

if (pullRequest.item.mergeable !== PullRequestMergeability.Conflict && !pullRequest.githubRepository.remote.isEnterprise) {
const result = await vscode.window.withProgress(
{ location: vscode.ProgressLocation.Notification, title: vscode.l10n.t('Updating branch...') },
async () => {
const success = await pullRequest.updateBranchWithGraphQL();
if (success && pullRequest.isActive) {
await this.repository.pull();
}
return success;
}
);
return result;
}


if (this.repository.state.workingTreeChanges.length > 0 || this.repository.state.indexChanges.length > 0) {
await vscode.window.showErrorMessage(vscode.l10n.t('The pull request branch cannot be updated when the there changed files in the working tree or index. Stash or commit all change and then try again.'), { modal: true });
return false;
Expand Down
4 changes: 1 addition & 3 deletions src/github/pullRequestReviewCommon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,6 @@ export namespace PullRequestReviewCommon {
return ctx.replyMessage(message, {});
}
const mergeSucceeded = await ctx.folderRepositoryManager.tryMergeBaseIntoHead(ctx.item, true);
if (!mergeSucceeded) {
ctx.replyMessage(message, {});
}
// The mergability of the PR doesn't update immediately. Poll.
let mergability = PullRequestMergeability.Unknown;
let attemptsRemaining = 5;
Expand All @@ -194,6 +191,7 @@ export namespace PullRequestReviewCommon {
const result: Partial<PullRequest> = {
events: await ctx.getTimeline(),
mergeable: mergability,
canUpdateBranch: !mergeSucceeded,
};
await refreshAfterUpdate();

Expand Down
51 changes: 51 additions & 0 deletions src/test/github/folderRepositoryManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ import { GitHubServerType } from '../../common/authentication';
import { CreatePullRequestHelper } from '../../view/createPullRequestHelper';
import { RepositoriesManager } from '../../github/repositoriesManager';
import { MockThemeWatcher } from '../mocks/mockThemeWatcher';
import { PullRequestReviewCommon, ReviewContext } from '../../github/pullRequestReviewCommon';
import { IRequestMessage } from '../../common/webview';
import { PullRequestMergeability } from '../../github/interface';
import { PullRequest } from '../../github/views';

describe('PullRequestManager', function () {
let sinon: SinonSandbox;
Expand Down Expand Up @@ -68,6 +72,53 @@ describe('PullRequestManager', function () {
assert.deepStrictEqual(manager.activePullRequest, pr);
});
});

describe('tryMergeBaseIntoHead', function () {
it('updates a conflict-free pull request that is not checked out using GraphQL', async function () {
const url = 'https://github.com/aaa/bbb.git';
const remote = new GitHubRemote('origin', url, new Protocol(url), GitHubServerType.GitHubDotCom);
const repository = new GitHubRepository(1, remote, Uri.file('C:\\users\\test\\repo'), manager.credentialStore, telemetry);
const prItem = convertRESTPullRequestToRawPullRequest(new PullRequestBuilder().build(), repository);
const pr = new PullRequestModel(manager.credentialStore, telemetry, repository, remote, prItem);
sinon.stub(manager, 'isHeadUpToDateWithBase').resolves(false);
const updateBranchWithGraphQL = sinon.stub(pr, 'updateBranchWithGraphQL').resolves(true);
const updateBranch = sinon.stub(pr, 'updateBranch').resolves(true);

const result = await manager.tryMergeBaseIntoHead(pr, true);

assert.strictEqual(result, true);
assert.strictEqual(updateBranchWithGraphQL.calledOnce, true);
assert.strictEqual(updateBranch.notCalled, true);
});
});

describe('updateBranch', function () {
it('reports that the branch is up to date after a successful update', async function () {
const url = 'https://github.com/aaa/bbb.git';
const remote = new GitHubRemote('origin', url, new Protocol(url), GitHubServerType.GitHubDotCom);
const repository = new GitHubRepository(1, remote, Uri.file('C:\\users\\test\\repo'), manager.credentialStore, telemetry);
const prItem = convertRESTPullRequestToRawPullRequest(new PullRequestBuilder().build(), repository);
const pr = new PullRequestModel(manager.credentialStore, telemetry, repository, remote, prItem);
sinon.stub(manager, 'tryMergeBaseIntoHead').resolves(true);
sinon.stub(pr, 'getMergeability').resolves({ mergeability: PullRequestMergeability.Mergeable });
let reply: Partial<PullRequest> | undefined;
const context: ReviewContext = {
item: pr,
folderRepositoryManager: manager,
existingReviewers: [],
postMessage: sinon.stub().resolves(),
replyMessage: (_message, response) => reply = response,
throwError: sinon.stub(),
getTimeline: sinon.stub().resolves([]),
};
const message: IRequestMessage<string> = { req: '1', command: 'pr.update-branch', args: '' };

await PullRequestReviewCommon.updateBranch(context, message, sinon.stub().resolves());

assert.strictEqual(reply?.canUpdateBranch, false);
assert.strictEqual(reply?.mergeable, PullRequestMergeability.Mergeable);
});
});
});

describe('titleAndBodyFrom', function () {
Expand Down
1 change: 1 addition & 0 deletions webviews/common/context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ export class PRContext {
const result: Partial<PullRequest> = await this.postMessage({ command: 'pr.update-branch' });
state.events = result.events ?? state.events;
state.mergeable = result.mergeable ?? state.mergeable;
state.canUpdateBranch = result.canUpdateBranch ?? state.canUpdateBranch;
this.updatePR(state);
};

Expand Down