extensions/github/src/pushErrorHandler.ts/handlePushError
async function handlePushError(repository: Repository, remote: Remote, refspec: string, owner: string, repo: string): Promise<void> {
	const yes = l10n.t('Create Fork');
	const no = l10n.t('No');
	const askFork = l10n.t('You don\'t have permissions to push to "{0}/{1}" on GitHub. Would you like to create a fork and push to it instead?', owner, repo);

	const answer = await window.showWarningMessage(askFork, { modal: true }, yes, no);
	if (answer !== yes) {
		return;
	}

	const match = /^([^:]*):([^:]*)$/.exec(refspec);
	const localName = match ? match[1] : refspec;
	let remoteName = match ? match[2] : refspec;

	const [octokit, ghRepository] = await window.withProgress({ location: ProgressLocation.Notification, cancellable: false, title: l10n.t('Create GitHub fork') }, async progress => {
		progress.report({ message: l10n.t('Forking "{0}/{1}"...', owner, repo), increment: 33 });

		const octokit = await getOctokit();

		type CreateForkResponseData = Awaited<ReturnType<typeof octokit.repos.createFork>>['data'];

		// Issue: what if the repo already exists?
		let ghRepository: CreateForkResponseData;
		try {
			if (isInCodespaces()) {
				// Call into the codespaces extension to fork the repository
				const resp = await commands.executeCommand<{ repository: CreateForkResponseData; ref: string }>('github.codespaces.forkRepository');
				if (!resp) {
					throw new Error('Unable to fork respository');
				}

				ghRepository = resp.repository;

				if (resp.ref) {
					let ref = resp.ref;
					if (ref.startsWith('refs/heads/')) {
						ref = ref.substr(11);
					}

					remoteName = ref;
				}
			} else {
				const resp = await octokit.repos.createFork({ owner, repo });
				ghRepository = resp.data;
			}
		} catch (ex) {
			console.error(ex);
			throw ex;
		}

		progress.report({ message: l10n.t('Pushing changes...'), increment: 33 });

		// Issue: what if there's already an `upstream` repo?
		await repository.renameRemote(remote.name, 'upstream');

		// Issue: what if there's already another `origin` repo?
		const protocol = workspace.getConfiguration('github').get<'https' | 'ssh'>('gitProtocol');
		const remoteUrl = protocol === 'https' ? ghRepository.clone_url : ghRepository.ssh_url;
		await repository.addRemote('origin', remoteUrl);

		try {
			await repository.fetch('origin', remoteName);
			await repository.setBranchUpstream(localName, `origin/${remoteName}`);
		} catch {
			// noop
		}

		await repository.push('origin', localName, true);

		return [octokit, ghRepository] as const;
	});

	// yield
	(async () => {
		const openOnGitHub = l10n.t('Open on GitHub');
		const createPR = l10n.t('Create PR');
		const action = await window.showInformationMessage(l10n.t('The fork "{0}" was successfully created on GitHub.', ghRepository.full_name), openOnGitHub, createPR);

		if (action === openOnGitHub) {
			await commands.executeCommand('vscode.open', Uri.parse(ghRepository.html_url));
		} else if (action === createPR) {
			const pr = await window.withProgress({ location: ProgressLocation.Notification, cancellable: false, title: l10n.t('Creating GitHub Pull Request...') }, async _ => {
				let title = `Update ${remoteName}`;
				const head = repository.state.HEAD?.name;

				let body: string | undefined;

				if (head) {
					const commit = await repository.getCommit(head);
					title = commit.message.split('\n')[0];
					body = commit.message.slice(title.length + 1).trim();
				}

				const templates = await findPullRequestTemplates(repository.rootUri);
				if (templates.length > 0) {
					templates.sort((a, b) => a.path.localeCompare(b.path));

					const template = await pickPullRequestTemplate(repository.rootUri, templates);

					if (template) {
						body = new TextDecoder('utf-8').decode(await workspace.fs.readFile(template));
					}
				}

				const { data: pr } = await octokit.pulls.create({
					owner,
					repo,
					title,
					body,
					head: `${ghRepository.owner.login}:${remoteName}`,
					base: ghRepository.default_branch
				});

				await repository.setConfig(`branch.${localName}.remote`, 'upstream');
				await repository.setConfig(`branch.${localName}.merge`, `refs/heads/${remoteName}`);
				await repository.setConfig(`branch.${localName}.github-pr-owner-number`, `${owner}#${repo}#${pr.number}`);

				return pr;
			});

			const openPR = l10n.t('Open PR');
			const action = await window.showInformationMessage(l10n.t('The PR "{0}/{1}#{2}" was successfully created on GitHub.', owner, repo, pr.number), openPR);

			if (action === openPR) {
				await commands.executeCommand('vscode.open', Uri.parse(pr.html_url));
			}
		}
	})();
}