in src/services/cherryPickService.ts [20:109]
export async function CherryPickCommitsAsync(
pullRequestContext: GitPullRequest,
targetTopicBranchName: string,
targetBranchName: string
): Promise<IRestClientResult<GitCherryPick>> {
try {
if (!targetTopicBranchName.startsWith("refs/heads")) {
targetTopicBranchName = `refs/heads/${targetTopicBranchName}`;
}
if (!targetBranchName.startsWith("refs/heads")) {
targetBranchName = `refs/heads/${targetBranchName}`;
}
const cherryPickSource: any = {
pullRequestId: pullRequestContext.pullRequestId
};
const cherryPickRequestParams: GitAsyncRefOperationParameters = {
generatedRefName: targetTopicBranchName,
ontoRefName: targetBranchName,
repository: pullRequestContext.repository,
source: cherryPickSource
};
let cherryPick: GitCherryPick = await client.createCherryPick(
cherryPickRequestParams,
pullRequestContext.repository.project.id,
pullRequestContext.repository.id
);
// Check for new status every second
const intervalMs = 1000;
const timeoutMs = Constants.RequestTimeoutSeconds * 1000;
let retries = 0;
let inProgress =
cherryPick.status === GitAsyncOperationStatus.Queued ||
cherryPick.status === GitAsyncOperationStatus.InProgress;
while (inProgress && intervalMs * retries < timeoutMs) {
await new Promise(resolve => setTimeout(resolve, intervalMs));
cherryPick = await client.getCherryPick(
pullRequestContext.repository.project.id,
cherryPick.cherryPickId,
pullRequestContext.repository.id
);
inProgress =
cherryPick.status === GitAsyncOperationStatus.Queued ||
cherryPick.status === GitAsyncOperationStatus.InProgress;
retries++;
}
// If not complete, complain
if (inProgress) {
return { error: `Unable to cherry-pick to ${targetTopicBranchName}` };
}
if (cherryPick.status !== GitAsyncOperationStatus.Completed) {
if (
cherryPick.detailedStatus.conflict &&
cherryPick.detailedStatus.currentCommitId
) {
return {
error: `There were conflicts when cherry-picking commit ${
cherryPick.detailedStatus.currentCommitId
}. This operation needs to be done locally.`
};
} else if (
cherryPick.detailedStatus.failureMessage.toLowerCase() ===
"invalidrefname"
) {
return {
error: `Invalid branch name: ${trimStart(
targetTopicBranchName,
"refs/heads/"
)}`
};
}
return { error: cherryPick.detailedStatus.failureMessage };
}
return { result: cherryPick };
} catch (ex) {
return { error: ex };
}
}