mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 04:49:35 +00:00
Add support for --force-if-includes
to force push more safely (#187932)
* Add support for `--force-if-includes` to force push * Change force push failed error message * Separate force push (no with lease) failed error message * Switch to `"markdownDescription"` * Add Git version requirement for config description * Improve error message when safer force push is rejected * Eliminate the option's effect if Git is too old * Minor improvements to community contribution --------- Co-authored-by: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com>
This commit is contained in:
parent
f4f0a1dd95
commit
2683aa01ac
|
@ -2569,6 +2569,11 @@
|
|||
"default": true,
|
||||
"description": "%config.useForcePushWithLease%"
|
||||
},
|
||||
"git.useForcePushIfIncludes": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"markdownDescription": "%config.useForcePushIfIncludes%"
|
||||
},
|
||||
"git.confirmForcePush": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
|
|
|
@ -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. Note: This setting requires the `#git.useForcePushWithLease#` setting to be enabled, and Git version `2.30.0` or later.",
|
||||
"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.",
|
||||
|
|
5
extensions/git/src/api/git.d.ts
vendored
5
extensions/git/src/api/git.d.ts
vendored
|
@ -16,7 +16,8 @@ export interface InputBox {
|
|||
|
||||
export const enum ForcePushMode {
|
||||
Force,
|
||||
ForceWithLease
|
||||
ForceWithLease,
|
||||
ForceWithLeaseIfIncludes,
|
||||
}
|
||||
|
||||
export const enum RefType {
|
||||
|
@ -366,6 +367,8 @@ export const enum GitErrorCodes {
|
|||
StashConflict = 'StashConflict',
|
||||
UnmergedChanges = 'UnmergedChanges',
|
||||
PushRejected = 'PushRejected',
|
||||
ForcePushWithLeaseRejected = 'ForcePushWithLeaseRejected',
|
||||
ForcePushWithLeaseIfIncludesRejected = 'ForcePushWithLeaseIfIncludesRejected',
|
||||
RemoteConnectionError = 'RemoteConnectionError',
|
||||
DirtyWorkTree = 'DirtyWorkTree',
|
||||
CantOpenResource = 'CantOpenResource',
|
||||
|
|
|
@ -2793,7 +2793,9 @@ export class CommandCenter {
|
|||
return;
|
||||
}
|
||||
|
||||
forcePushMode = config.get<boolean>('useForcePushWithLease') === true ? ForcePushMode.ForceWithLease : ForcePushMode.Force;
|
||||
const useForcePushWithLease = config.get<boolean>('useForcePushWithLease') === true;
|
||||
const useForcePushIfIncludes = config.get<boolean>('useForcePushIfIncludes') === true;
|
||||
forcePushMode = useForcePushWithLease ? useForcePushIfIncludes ? ForcePushMode.ForceWithLeaseIfIncludes : ForcePushMode.ForceWithLease : ForcePushMode.Force;
|
||||
|
||||
if (config.get<boolean>('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?');
|
||||
|
@ -3682,6 +3684,10 @@ export class CommandCenter {
|
|||
case GitErrorCodes.PushRejected:
|
||||
message = l10n.t('Can\'t push refs to remote. Try running "Pull" first to integrate your changes.');
|
||||
break;
|
||||
case GitErrorCodes.ForcePushWithLeaseRejected:
|
||||
case GitErrorCodes.ForcePushWithLeaseIfIncludesRejected:
|
||||
message = l10n.t('Can\'t force push refs to remote. The tip of the remote-tracking branch has been updated since the last checkout. Try running "Pull" first to pull the latest changes from the remote branch first.');
|
||||
break;
|
||||
case GitErrorCodes.Conflict:
|
||||
message = l10n.t('There are merge conflicts. Resolve them before committing.');
|
||||
type = 'warning';
|
||||
|
|
|
@ -1910,8 +1910,11 @@ export class Repository {
|
|||
async push(remote?: string, name?: string, setUpstream: boolean = false, followTags = false, forcePushMode?: ForcePushMode, tags = false): Promise<void> {
|
||||
const args = ['push'];
|
||||
|
||||
if (forcePushMode === ForcePushMode.ForceWithLease) {
|
||||
if (forcePushMode === ForcePushMode.ForceWithLease || forcePushMode === ForcePushMode.ForceWithLeaseIfIncludes) {
|
||||
args.push('--force-with-lease');
|
||||
if (forcePushMode === ForcePushMode.ForceWithLeaseIfIncludes && this._git.compareGitVersionTo('2.30') !== -1) {
|
||||
args.push('--force-if-includes');
|
||||
}
|
||||
} else if (forcePushMode === ForcePushMode.Force) {
|
||||
args.push('--force');
|
||||
}
|
||||
|
@ -1940,7 +1943,13 @@ export class Repository {
|
|||
await this.exec(args, { env: { 'GIT_HTTP_USER_AGENT': this.git.userAgent } });
|
||||
} catch (err) {
|
||||
if (/^error: failed to push some refs to\b/m.test(err.stderr || '')) {
|
||||
err.gitErrorCode = GitErrorCodes.PushRejected;
|
||||
if (forcePushMode === ForcePushMode.ForceWithLease && /! \[rejected\].*\(stale info\)/m.test(err.stderr || '')) {
|
||||
err.gitErrorCode = GitErrorCodes.ForcePushWithLeaseRejected;
|
||||
} else if (forcePushMode === ForcePushMode.ForceWithLeaseIfIncludes && /! \[rejected\].*\(remote ref updated since checkout\)/m.test(err.stderr || '')) {
|
||||
err.gitErrorCode = GitErrorCodes.ForcePushWithLeaseIfIncludesRejected;
|
||||
} else {
|
||||
err.gitErrorCode = GitErrorCodes.PushRejected;
|
||||
}
|
||||
} else if (/Permission.*denied/.test(err.stderr || '')) {
|
||||
err.gitErrorCode = GitErrorCodes.PermissionDenied;
|
||||
} else if (/Could not read from remote repository/.test(err.stderr || '')) {
|
||||
|
|
Loading…
Reference in a new issue