diff --git a/extensions/git/package.json b/extensions/git/package.json index f45447de7f1a2..9c84c737f0731 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -2567,6 +2567,11 @@ "default": true, "description": "%config.useForcePushWithLease%" }, + "git.useForcePushIfIncludes": { + "type": "boolean", + "default": true, + "description": "%config.useForcePushIfIncludes%" + }, "git.confirmForcePush": { "type": "boolean", "default": true, diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 24f03414ce609..a25d0ccedf8da 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -217,6 +217,7 @@ "config.autoStash": "Stash any changes before pulling and restore them after successful pull.", "config.allowForcePush": "Controls whether force push (with or without lease) is enabled.", "config.useForcePushWithLease": "Controls whether force pushing uses the safer force-with-lease variant.", + "config.useForcePushIfIncludes": "Controls whether force pushing uses the safer force-if-includes variant.", "config.confirmForcePush": "Controls whether to ask for confirmation before force-pushing.", "config.allowNoVerifyCommit": "Controls whether commits without running pre-commit and commit-msg hooks are allowed.", "config.confirmNoVerifyCommit": "Controls whether to ask for confirmation before committing without verification.", diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts index ae1d57d30985c..7415a865dfb8f 100644 --- a/extensions/git/src/api/git.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -16,7 +16,8 @@ export interface InputBox { export const enum ForcePushMode { Force, - ForceWithLease + ForceWithLease, + ForceWithLeaseIfIncludes, } export const enum RefType { diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 8eba9cbac03f2..87a7d30c778b0 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -2751,6 +2751,13 @@ export class CommandCenter { await repository.pullWithRebase(repository.HEAD); } + private _getForcePushMode(withLease: boolean | undefined, ifIncludes: boolean | undefined): ForcePushMode { + if (!withLease) { + return ForcePushMode.Force; + } + return ifIncludes ? ForcePushMode.ForceWithLeaseIfIncludes : ForcePushMode.ForceWithLease; + } + private async _push(repository: Repository, pushOptions: PushOptions) { const remotes = repository.remotes; @@ -2778,7 +2785,7 @@ export class CommandCenter { return; } - forcePushMode = config.get('useForcePushWithLease') === true ? ForcePushMode.ForceWithLease : ForcePushMode.Force; + forcePushMode = this._getForcePushMode(config.get('useForcePushWithLease'), config.get('useForcePushIfIncludes')); if (config.get('confirmForcePush')) { const message = l10n.t('You are about to force push your changes, this can be destructive and could inadvertently overwrite changes made by others.\n\nAre you sure to continue?'); diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index ab03a354d1161..19f2d59281fbe 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -1872,8 +1872,11 @@ export class Repository { async push(remote?: string, name?: string, setUpstream: boolean = false, followTags = false, forcePushMode?: ForcePushMode, tags = false): Promise { const args = ['push']; - if (forcePushMode === ForcePushMode.ForceWithLease) { + if (forcePushMode === ForcePushMode.ForceWithLease || forcePushMode === ForcePushMode.ForceWithLeaseIfIncludes) { args.push('--force-with-lease'); + if (forcePushMode === ForcePushMode.ForceWithLeaseIfIncludes) { + args.push('--force-if-includes'); + } } else if (forcePushMode === ForcePushMode.Force) { args.push('--force'); }