Skip to content
Draft
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
15 changes: 13 additions & 2 deletions src/github/pullRequestGitHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,17 @@ export class PullRequestGitHelper {
return `${owner}#${repository}#${baseBranch}`;
}

private static async setConfig(repository: Repository, key: string, value: string): Promise<void> {
const existingConfigs = (await repository.getConfigs()).filter(config => config.key === key);
if (existingConfigs.some(config => config.value === value)) {
return;
}
if (existingConfigs.length === 1 && repository.unsetConfig) {
await repository.unsetConfig(key);
}
await repository.setConfig(key, value);
}

static parsePullRequestMetadata(value: string): PullRequestMetadata | undefined {
if (value) {
const matches = /(.*)#(.*)#(.*)/g.exec(value);
Expand Down Expand Up @@ -434,7 +445,7 @@ export class PullRequestGitHelper {
}
const prConfigKey = `branch.${branchName}.${PullRequestMetadataKey}`;
if (pullRequest) {
await repository.setConfig(prConfigKey, PullRequestGitHelper.buildPullRequestMetadata(pullRequest));
await PullRequestGitHelper.setConfig(repository, prConfigKey, PullRequestGitHelper.buildPullRequestMetadata(pullRequest));
} else if (repository.unsetConfig) {
await repository.unsetConfig(prConfigKey);
}
Expand All @@ -458,7 +469,7 @@ export class PullRequestGitHelper {
const prConfigKey = `branch.${branch}.${BaseBranchMetadataKey}`;
if (base) {
Logger.appendLine(`associate ${branch} with base branch ${base.owner}/${base.repo}#${base.branch}`, PullRequestGitHelper.ID);
await repository.setConfig(prConfigKey, PullRequestGitHelper.buildBaseBranchMetadata(base.owner, base.repo, base.branch));
await PullRequestGitHelper.setConfig(repository, prConfigKey, PullRequestGitHelper.buildBaseBranchMetadata(base.owner, base.repo, base.branch));
} else if (repository.unsetConfig) {
await repository.unsetConfig(prConfigKey);
const vscodeBaseBranchConfigKey = `branch.${branch}.${VscodeBaseBranchMetadataKey}`;
Expand Down
46 changes: 46 additions & 0 deletions src/test/github/pullRequestGitHelper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,52 @@ describe('PullRequestGitHelper', function () {
});
});

describe('associateBranchWithPullRequest', function () {
const pullRequest = (number: number) => ({
number,
base: {
repositoryCloneUrl: {
owner: 'owner',
repositoryName: 'name',
},
},
}) as PullRequestModel;

it('replaces pull request metadata instead of appending values', async function () {
await PullRequestGitHelper.associateBranchWithPullRequest(repository, pullRequest(100), 'feature');
await PullRequestGitHelper.associateBranchWithPullRequest(repository, pullRequest(100), 'feature');
await PullRequestGitHelper.associateBranchWithPullRequest(repository, pullRequest(101), 'feature');

const key = 'branch.feature.github-pr-owner-number';
assert.deepStrictEqual((await repository.getConfigs()).filter(config => config.key === key), [
{ key, value: 'owner#name#101' },
]);
});

it('does not append to existing duplicate metadata', async function () {
const key = 'branch.feature.github-pr-owner-number';
await repository.setConfig(key, 'owner#name#100');
await repository.setConfig(key, 'owner#name#100');

await PullRequestGitHelper.associateBranchWithPullRequest(repository, pullRequest(100), 'feature');

assert.strictEqual((await repository.getConfigs()).filter(config => config.key === key).length, 2);
});
});

describe('associateBaseBranchWithBranch', function () {
it('replaces base branch metadata instead of appending values', async function () {
await PullRequestGitHelper.associateBaseBranchWithBranch(repository, 'feature', { owner: 'owner', repo: 'name', branch: 'main' });
await PullRequestGitHelper.associateBaseBranchWithBranch(repository, 'feature', { owner: 'owner', repo: 'name', branch: 'main' });
await PullRequestGitHelper.associateBaseBranchWithBranch(repository, 'feature', { owner: 'owner', repo: 'name', branch: 'next' });

const key = 'branch.feature.github-pr-base-branch';
assert.deepStrictEqual((await repository.getConfigs()).filter(config => config.key === key), [
{ key, value: 'owner#name#next' },
]);
});
});

describe('getMatchingPullRequestMetadataForBranch', function () {
it('returns the highest-numbered PR when duplicate config entries exist for the branch', async function () {
// Simulate the case where a branch name has been associated with multiple
Expand Down