Skip to content
Merged
18 changes: 18 additions & 0 deletions extensions/git/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,16 @@
"title": "%command.pushWithTagsForce%",
"category": "Git"
},
{
"command": "git.addRemote",
"title": "%command.addRemote%",
"category": "Git"
},
{
"command": "git.removeRemote",
"title": "%command.removeRemote%",
"category": "Git"
},
{
"command": "git.sync",
"title": "%command.sync%",
Expand Down Expand Up @@ -561,6 +571,14 @@
"command": "git.pushWithTagsForce",
"when": "config.git.enabled && config.git.allowForcePush && gitOpenRepositoryCount != 0"
},
{
"command": "git.addRemote",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
},
{
"command": "git.removeRemote",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
},
{
"command": "git.sync",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
Expand Down
2 changes: 2 additions & 0 deletions extensions/git/package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
"command.pushToForce": "Push to... (Force)",
"command.pushWithTags": "Push With Tags",
"command.pushWithTagsForce": "Push With Tags (Force)",
"command.addRemote": "Add Remote",
"command.removeRemote": "Remove Remote",
"command.sync": "Sync",
"command.syncRebase": "Sync (Rebase)",
"command.publish": "Publish Branch",
Expand Down
73 changes: 73 additions & 0 deletions extensions/git/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1711,6 +1711,79 @@ export class CommandCenter {
await this._push(repository, { pushType: PushType.PushTo, forcePush: true });
}

@command('git.addRemote', { repository: true })
async addRemote(repository: Repository): Promise<void> {
const remotes = repository.remotes;

const sanitize = (name: string) => {
name = name.trim();

if (!name) {
return name;
}

return name.replace(/^\.|\/\.|\.\.|~|\^|:|\/$|\.lock$|\.lock\/|\\|\*|\s|^\s*$|\.$|\[|\]$/g, '-');
};

const resultName = await window.showInputBox({
placeHolder: localize('remote name', "Remote name"),
prompt: localize('provide remote name', "Please provide a remote name"),
ignoreFocusOut: true,
validateInput: (name: string) => {
if (sanitize(name)) {
return null;
}
return localize('remote name format invalid', "Remote name format invalid");
}
});

const name = sanitize(resultName || '');

if (!name) {
return;
}

if (remotes.find(r => r.name === name)) {
window.showErrorMessage(localize('remote already exists', 'Remote by name \"{0}\" already exists.', name));
return;
}

const resultUrl = await window.showInputBox({
placeHolder: localize('remote url', "Remote URL"),
prompt: localize('provide remote URL', "Enter URL for remote \"{0}\"", name),
ignoreFocusOut: true
});

const url = sanitize(resultUrl || '');

if (!url) {
return;
}

await repository.addRemote(name, url);
}

@command('git.removeRemote', { repository: true })
async removeRemote(repository: Repository): Promise<void> {
const remotes = repository.remotes;

if (remotes.length === 0) {
window.showErrorMessage(localize('no remotes added', "Your repository has no remotes."));
return;
}

const picks = remotes.map(r => r.name);
const placeHolder = localize('remove remote', "Pick a remote to remove");

const remoteName = await window.showQuickPick(picks, { placeHolder });

if (!remoteName) {
return;
}

await repository.removeRemote(remoteName);
}

private async _sync(repository: Repository, rebase: boolean): Promise<void> {
const HEAD = repository.HEAD;

Expand Down