Skip to content

Commit e191c94

Browse files
committed
Merge branch 'main' into joh/swc
2 parents b46342e + 6a4e5cc commit e191c94

File tree

295 files changed

+4767
-5651
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

295 files changed

+4767
-5651
lines changed

build/azure-pipelines/product-build.yml

Lines changed: 164 additions & 156 deletions
Large diffs are not rendered by default.

build/azure-pipelines/product-publish.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ $stages = @(
4646
if ($env:VSCODE_BUILD_STAGE_WINDOWS -eq 'True') { 'Windows' }
4747
if ($env:VSCODE_BUILD_STAGE_LINUX -eq 'True') { 'Linux' }
4848
if ($env:VSCODE_BUILD_STAGE_MACOS -eq 'True') { 'macOS' }
49+
if ($env:VSCODE_BUILD_STAGE_WEB -eq 'True') { 'Web' }
4950
)
5051

5152
do {

build/azure-pipelines/product-publish.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ steps:
109109
if ($env:VSCODE_BUILD_STAGE_WINDOWS -eq 'True') { 'Windows' }
110110
if ($env:VSCODE_BUILD_STAGE_LINUX -eq 'True') { 'Linux' }
111111
if ($env:VSCODE_BUILD_STAGE_MACOS -eq 'True') { 'macOS' }
112+
if ($env:VSCODE_BUILD_STAGE_WEB -eq 'True') { 'Web' }
112113
)
113114
Write-Host "Stages to check: $stages"
114115

build/azure-pipelines/upload-nlsmetadata.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ function main() {
2020
.pipe(merge({
2121
fileName: 'combined.nls.metadata.json',
2222
jsonSpace: '',
23+
concatArrays: true,
2324
edit: (parsedJson, file) => {
2425
if (file.base === 'out-vscode-web-min') {
2526
return { vscode: parsedJson };

build/azure-pipelines/upload-nlsmetadata.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ function main(): Promise<void> {
3333
.pipe(merge({
3434
fileName: 'combined.nls.metadata.json',
3535
jsonSpace: '',
36+
concatArrays: true,
3637
edit: (parsedJson, file) => {
3738
if (file.base === 'out-vscode-web-min') {
3839
return { vscode: parsedJson };

build/lib/i18n.resources.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,10 @@
294294
"name": "vs/workbench/contrib/audioCues",
295295
"project": "vscode-workbench"
296296
},
297+
{
298+
"name": "vs/workbench/contrib/deprecatedExtensionMigrator",
299+
"project": "vscode-workbench"
300+
},
297301
{
298302
"name": "vs/workbench/contrib/offline",
299303
"project": "vscode-workbench"

extensions/git/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"scmActionButton",
1717
"scmSelectedProvider",
1818
"scmValidation",
19+
"tabInputTextMerge",
1920
"timeline"
2021
],
2122
"categories": [

extensions/git/package.nls.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,10 +221,10 @@
221221
"config.timeline.date.committed": "Use the committed date",
222222
"config.timeline.date.authored": "Use the authored date",
223223
"config.useCommitInputAsStashMessage": "Controls whether to use the message from the commit input box as the default stash message.",
224-
"config.showActionButton": "Controls whether an action button can be shown in the Source Control view.",
225-
"config.showActionButton.commit": "Show an action button to commit changes.",
226-
"config.showActionButton.publish": "Show an action button to publish a local branch.",
227-
"config.showActionButton.sync": "Show an action button to sync changes.",
224+
"config.showActionButton": "Controls whether an action button is shown in the Source Control view.",
225+
"config.showActionButton.commit": "Show an action button to commit changes when the local branch has modified files ready to be committed.",
226+
"config.showActionButton.publish": "Show an action button to publish the local branch when it does not have a tracking remote branch.",
227+
"config.showActionButton.sync": "Show an action button to synchronize changes when the local branch is either ahead or behind the remote branch.",
228228
"config.statusLimit": "Controls how to limit the number of changes that can be parsed from Git status command. Can be set to 0 for no limit.",
229229
"config.experimental.installGuide": "Experimental improvements for the git setup flow.",
230230
"config.repositoryScanIgnoredFolders": "List of folders that are ignored while scanning for Git repositories when `#git.autoRepositoryDetection#` is set to `true` or `subFolders`.",

extensions/git/src/actionButton.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ export class ActionButtonCommand {
5050
repository.onDidRunGitStatus(this.onDidRunGitStatus, this, this.disposables);
5151
repository.onDidChangeOperations(this.onDidChangeOperations, this, this.disposables);
5252

53+
this.disposables.push(postCommitCommandsProviderRegistry.onDidChangePostCommitCommandsProviders(() => this._onDidChange.fire()));
54+
5355
const root = Uri.file(repository.root);
5456
this.disposables.push(workspace.onDidChangeConfiguration(e => {
5557
if (e.affectsConfiguration('git.enableSmartCommit', root) ||
@@ -202,19 +204,18 @@ export class ActionButtonCommand {
202204
private getSyncChangesActionButton(): SourceControlActionButton | undefined {
203205
const config = workspace.getConfiguration('git', Uri.file(this.repository.root));
204206
const showActionButton = config.get<{ sync: boolean }>('showActionButton', { sync: true });
207+
const branchIsAheadOrBehind = (this.state.HEAD?.behind ?? 0) > 0 || (this.state.HEAD?.ahead ?? 0) > 0;
205208

206-
// Branch does not have an upstream, commit/merge is in progress, or the button is disabled
207-
if (!this.state.HEAD?.upstream || this.state.isCommitInProgress || this.state.isMergeInProgress || !showActionButton.sync) { return undefined; }
209+
// Branch does not have an upstream, branch is not ahead/behind the remote branch, commit/merge is in progress, or the button is disabled
210+
if (!this.state.HEAD?.upstream || !branchIsAheadOrBehind || this.state.isCommitInProgress || this.state.isMergeInProgress || !showActionButton.sync) { return undefined; }
208211

209212
const ahead = this.state.HEAD.ahead ? ` ${this.state.HEAD.ahead}$(arrow-up)` : '';
210213
const behind = this.state.HEAD.behind ? ` ${this.state.HEAD.behind}$(arrow-down)` : '';
211214
const icon = this.state.isSyncInProgress ? '$(sync~spin)' : '$(sync)';
212215

213-
const rebaseWhenSync = config.get<string>('rebaseWhenSync');
214-
215216
return {
216217
command: {
217-
command: rebaseWhenSync ? 'git.syncRebase' : 'git.sync',
218+
command: 'git.sync',
218219
title: `${icon}${behind}${ahead}`,
219220
tooltip: this.state.isSyncInProgress ?
220221
localize('syncing changes', "Synchronizing Changes...")

extensions/git/src/commands.ts

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import * as os from 'os';
77
import * as path from 'path';
8-
import { Command, commands, Disposable, LineChange, MessageOptions, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env, Selection, TextDocumentContentProvider, InputBoxValidationSeverity, TabInputText } from 'vscode';
8+
import { Command, commands, Disposable, LineChange, MessageOptions, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env, Selection, TextDocumentContentProvider, InputBoxValidationSeverity, TabInputText, TabInputTextMerge } from 'vscode';
99
import TelemetryReporter from '@vscode/extension-telemetry';
1010
import * as nls from 'vscode-nls';
1111
import { uniqueNamesGenerator, adjectives, animals, colors, NumberDictionary } from '@joaomoreno/unique-names-generator';
@@ -53,7 +53,7 @@ class CheckoutTagItem extends CheckoutItem {
5353

5454
class CheckoutRemoteHeadItem extends CheckoutItem {
5555

56-
override get label(): string { return `$(git-branch) ${this.ref.name || this.shortCommit}`; }
56+
override get label(): string { return `$(cloud) ${this.ref.name || this.shortCommit}`; }
5757
override get description(): string {
5858
return localize('remote branch at', "Remote branch at {0}", this.shortCommit);
5959
}
@@ -418,21 +418,25 @@ export class CommandCenter {
418418
return;
419419
}
420420

421+
const isRebasing = Boolean(repo.rebaseCommit);
421422

422423
type InputData = { uri: Uri; title?: string; detail?: string; description?: string };
423424
const mergeUris = toMergeUris(uri);
424425
const ours: InputData = { uri: mergeUris.ours, title: localize('Yours', 'Yours') };
425426
const theirs: InputData = { uri: mergeUris.theirs, title: localize('Theirs', 'Theirs') };
426427

427428
try {
428-
const [head, mergeHead] = await Promise.all([repo.getCommit('HEAD'), repo.getCommit('MERGE_HEAD')]);
429+
const [head, rebaseOrMergeHead] = await Promise.all([
430+
repo.getCommit('HEAD'),
431+
isRebasing ? repo.getCommit('REBASE_HEAD') : repo.getCommit('MERGE_HEAD')
432+
]);
429433
// ours (current branch and commit)
430434
ours.detail = head.refNames.map(s => s.replace(/^HEAD ->/, '')).join(', ');
431435
ours.description = head.hash.substring(0, 7);
432436

433437
// theirs
434-
theirs.detail = mergeHead.refNames.join(', ');
435-
theirs.description = mergeHead.hash.substring(0, 7);
438+
theirs.detail = rebaseOrMergeHead.refNames.join(', ');
439+
theirs.description = rebaseOrMergeHead.hash.substring(0, 7);
436440

437441
} catch (error) {
438442
// not so bad, can continue with just uris
@@ -442,8 +446,8 @@ export class CommandCenter {
442446

443447
const options = {
444448
base: mergeUris.base,
445-
input1: theirs,
446-
input2: ours,
449+
input1: isRebasing ? ours : theirs,
450+
input2: isRebasing ? theirs : ours,
447451
output: uri
448452
};
449453

@@ -1099,21 +1103,26 @@ export class CommandCenter {
10991103
return;
11001104
}
11011105

1106+
const { activeTab } = window.tabGroups.activeTabGroup;
1107+
if (!activeTab) {
1108+
return;
1109+
}
1110+
1111+
// make sure to save the merged document
11021112
const doc = workspace.textDocuments.find(doc => doc.uri.toString() === uri.toString());
11031113
if (!doc) {
11041114
console.log(`FAILED to accept merge because uri ${uri.toString()} doesn't match a document`);
11051115
return;
11061116
}
1117+
if (doc.isDirty) {
1118+
await doc.save();
1119+
}
11071120

1108-
await doc.save();
1109-
1110-
// TODO@jrieken there isn't a `TabInputTextMerge` instance yet, till now the merge editor
1111-
// uses the `TabInputText` for the out-resource and we use that to identify and CLOSE the tab
1112-
// see https://github.com/microsoft/vscode/issues/153213
1113-
const { activeTab } = window.tabGroups.activeTabGroup;
1121+
// find the merge editor tabs for the resource in question and close them all
11141122
let didCloseTab = false;
1115-
if (activeTab && activeTab?.input instanceof TabInputText && activeTab.input.uri.toString() === uri.toString()) {
1116-
didCloseTab = await window.tabGroups.close(activeTab, true);
1123+
const mergeEditorTabs = window.tabGroups.all.map(group => group.tabs.filter(tab => tab.input instanceof TabInputTextMerge && tab.input.result.toString() === uri.toString())).flat();
1124+
if (mergeEditorTabs.includes(activeTab)) {
1125+
didCloseTab = await window.tabGroups.close(mergeEditorTabs, true);
11171126
}
11181127

11191128
// Only stage if the merge editor has been successfully closed. That means all conflicts have been
@@ -1443,7 +1452,7 @@ export class CommandCenter {
14431452
private async smartCommit(
14441453
repository: Repository,
14451454
getCommitMessage: () => Promise<string | undefined>,
1446-
opts?: CommitOptions
1455+
opts: CommitOptions
14471456
): Promise<boolean> {
14481457
const config = workspace.getConfiguration('git', Uri.file(repository.root));
14491458
let promptToSaveFilesBeforeCommit = config.get<'always' | 'staged' | 'never'>('promptToSaveFilesBeforeCommit');
@@ -1489,14 +1498,8 @@ export class CommandCenter {
14891498
}
14901499
}
14911500

1492-
if (!opts) {
1493-
opts = { all: noStagedChanges };
1494-
} else if (!opts.all && noStagedChanges && !opts.empty) {
1495-
opts = { ...opts, all: true };
1496-
}
1497-
14981501
// no changes, and the user has not configured to commit all in this case
1499-
if (!noUnstagedChanges && noStagedChanges && !enableSmartCommit && !opts.empty) {
1502+
if (!noUnstagedChanges && noStagedChanges && !enableSmartCommit && !opts.empty && !opts.all) {
15001503
const suggestSmartCommit = config.get<boolean>('suggestSmartCommit') === true;
15011504

15021505
if (!suggestSmartCommit) {
@@ -1520,6 +1523,12 @@ export class CommandCenter {
15201523
}
15211524
}
15221525

1526+
if (opts.all === undefined) {
1527+
opts = { all: noStagedChanges };
1528+
} else if (!opts.all && noStagedChanges && !opts.empty) {
1529+
opts = { ...opts, all: true };
1530+
}
1531+
15231532
// enable signing of commits if configured
15241533
opts.signCommit = enableCommitSigning;
15251534

@@ -1633,7 +1642,7 @@ export class CommandCenter {
16331642
return true;
16341643
}
16351644

1636-
private async commitWithAnyInput(repository: Repository, opts?: CommitOptions): Promise<void> {
1645+
private async commitWithAnyInput(repository: Repository, opts: CommitOptions): Promise<void> {
16371646
const message = repository.inputBox.value;
16381647
const root = Uri.file(repository.root);
16391648
const config = workspace.getConfiguration('git', root);
@@ -2566,17 +2575,16 @@ export class CommandCenter {
25662575
}
25672576
}
25682577

2569-
if (rebase) {
2570-
await repository.syncRebase(HEAD);
2571-
} else {
2572-
await repository.sync(HEAD);
2573-
}
2578+
await repository.sync(HEAD, rebase);
25742579
}
25752580

25762581
@command('git.sync', { repository: true })
25772582
async sync(repository: Repository): Promise<void> {
2583+
const config = workspace.getConfiguration('git', Uri.file(repository.root));
2584+
const rebase = config.get<boolean>('rebaseWhenSync', false) === true;
2585+
25782586
try {
2579-
await this._sync(repository, false);
2587+
await this._sync(repository, rebase);
25802588
} catch (err) {
25812589
if (/Cancelled/i.test(err && (err.message || err.stderr || ''))) {
25822590
return;
@@ -2589,13 +2597,16 @@ export class CommandCenter {
25892597
@command('git._syncAll')
25902598
async syncAll(): Promise<void> {
25912599
await Promise.all(this.model.repositories.map(async repository => {
2600+
const config = workspace.getConfiguration('git', Uri.file(repository.root));
2601+
const rebase = config.get<boolean>('rebaseWhenSync', false) === true;
2602+
25922603
const HEAD = repository.HEAD;
25932604

25942605
if (!HEAD || !HEAD.upstream) {
25952606
return;
25962607
}
25972608

2598-
await repository.sync(HEAD);
2609+
await repository.sync(HEAD, rebase);
25992610
}));
26002611
}
26012612

0 commit comments

Comments
 (0)