extensions/git/src/repository.ts/Repository/_sync
class Repository:	private async _sync(head: Branch, rebase: boolean): Promise<void> {
		let remoteName: string | undefined;
		let pullBranch: string | undefined;
		let pushBranch: string | undefined;

		if (head.name && head.upstream) {
			remoteName = head.upstream.remote;
			pullBranch = `${head.upstream.name}`;
			pushBranch = `${head.name}:${head.upstream.name}`;
		}

		await this.run(Operation.Sync, async () => {
			await this.maybeAutoStash(async () => {
				const config = workspace.getConfiguration('git', Uri.file(this.root));
				const fetchOnPull = config.get<boolean>('fetchOnPull');
				const tags = config.get<boolean>('pullTags');
				const followTags = config.get<boolean>('followTagsWhenSync');
				const supportCancellation = config.get<boolean>('supportCancellation');

				const fn = async (cancellationToken?: CancellationToken) => {
					// When fetchOnPull is enabled, fetch all branches when pulling
					if (fetchOnPull) {
						await this.repository.fetch({ all: true, cancellationToken });
					}

					if (await this.checkIfMaybeRebased(this.HEAD?.name)) {
						await this.repository.pull(rebase, remoteName, pullBranch, { tags, cancellationToken });
					}
				};

				if (supportCancellation) {
					const opts: ProgressOptions = {
						location: ProgressLocation.Notification,
						title: localize('sync is unpredictable', "Syncing. Cancelling may cause serious damages to the repository"),
						cancellable: true
					};

					await window.withProgress(opts, (_, token) => fn(token));
				} else {
					await fn();
				}

				const remote = this.remotes.find(r => r.name === remoteName);

				if (remote && remote.isReadOnly) {
					return;
				}

				const shouldPush = this.HEAD && (typeof this.HEAD.ahead === 'number' ? this.HEAD.ahead > 0 : true);

				if (shouldPush) {
					await this._push(remoteName, pushBranch, false, followTags);
				}
			});
		});
	}