mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-28 04:23:32 +01:00
more submodule support, diff colorization
This commit is contained in:
@@ -169,14 +169,33 @@ export class CommandCenter {
|
||||
}
|
||||
|
||||
private async _openResource(resource: Resource, preview?: boolean, preserveFocus?: boolean, preserveSelection?: boolean): Promise<void> {
|
||||
const stat = await new Promise<Stats>((c, e) => lstat(resource.resourceUri.fsPath, (err, stat) => err ? e(err) : c(stat)));
|
||||
let stat: Stats | undefined;
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
return;
|
||||
try {
|
||||
stat = await new Promise<Stats>((c, e) => lstat(resource.resourceUri.fsPath, (err, stat) => err ? e(err) : c(stat)));
|
||||
} catch (err) {
|
||||
// noop
|
||||
}
|
||||
|
||||
const left = await this.getLeftResource(resource);
|
||||
const right = await this.getRightResource(resource);
|
||||
let left: Uri | undefined;
|
||||
let right: Uri | undefined;
|
||||
|
||||
if (stat && stat.isDirectory()) {
|
||||
outer:
|
||||
for (const repository of this.model.repositories) {
|
||||
for (const submodule of repository.submodules) {
|
||||
const submodulePath = path.join(repository.root, submodule.path);
|
||||
|
||||
if (submodulePath === resource.resourceUri.fsPath) {
|
||||
right = toGitUri(Uri.file(submodulePath), resource.resourceGroupType === ResourceGroupType.Index ? 'index' : 'wt', { submoduleOf: repository.root });
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
left = await this.getLeftResource(resource);
|
||||
right = await this.getRightResource(resource);
|
||||
}
|
||||
|
||||
const title = this.getTitle(resource);
|
||||
|
||||
@@ -1697,7 +1716,7 @@ export class CommandCenter {
|
||||
const isSingleResource = arg instanceof Uri;
|
||||
|
||||
const groups = resources.reduce((result, resource) => {
|
||||
const repository = this.model.getRepository(resource);
|
||||
const repository = this.model.getRepository(resource, true);
|
||||
|
||||
if (!repository) {
|
||||
console.warn('Could not find git repository for ', resource);
|
||||
|
||||
@@ -52,7 +52,7 @@ export class GitContentProvider {
|
||||
return;
|
||||
}
|
||||
|
||||
this._onDidChange.fire(toGitUri(uri, '', true));
|
||||
this._onDidChange.fire(toGitUri(uri, '', { replaceFileExtension: true }));
|
||||
}
|
||||
|
||||
@debounce(1100)
|
||||
@@ -83,6 +83,18 @@ export class GitContentProvider {
|
||||
}
|
||||
|
||||
async provideTextDocumentContent(uri: Uri): Promise<string> {
|
||||
let { path, ref, submoduleOf } = fromGitUri(uri);
|
||||
|
||||
if (submoduleOf) {
|
||||
const repository = this.model.getRepository(submoduleOf);
|
||||
|
||||
if (!repository) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return await repository.diff(path, { cached: ref === 'index' });
|
||||
}
|
||||
|
||||
const repository = this.model.getRepository(uri);
|
||||
|
||||
if (!repository) {
|
||||
@@ -95,8 +107,6 @@ export class GitContentProvider {
|
||||
|
||||
this.cache[cacheKey] = cacheValue;
|
||||
|
||||
let { path, ref } = fromGitUri(uri);
|
||||
|
||||
if (ref === '~') {
|
||||
const fileUri = Uri.file(path);
|
||||
const uriString = fileUri.toString();
|
||||
|
||||
@@ -597,6 +597,10 @@ export function parseGitmodules(raw: string): Submodule[] {
|
||||
return result;
|
||||
}
|
||||
|
||||
export interface DiffOptions {
|
||||
cached?: boolean;
|
||||
}
|
||||
|
||||
export class Repository {
|
||||
|
||||
constructor(
|
||||
@@ -735,6 +739,19 @@ export class Repository {
|
||||
}
|
||||
}
|
||||
|
||||
async diff(path: string, options: DiffOptions = {}): Promise<string> {
|
||||
const args = ['diff'];
|
||||
|
||||
if (options.cached) {
|
||||
args.push('--cached');
|
||||
}
|
||||
|
||||
args.push('--', path);
|
||||
|
||||
const result = await this.run(args);
|
||||
return result.stdout;
|
||||
}
|
||||
|
||||
async add(paths: string[]): Promise<void> {
|
||||
const args = ['add', '-A', '--'];
|
||||
|
||||
|
||||
@@ -265,19 +265,19 @@ export class Model {
|
||||
|
||||
getRepository(sourceControl: SourceControl): Repository | undefined;
|
||||
getRepository(resourceGroup: SourceControlResourceGroup): Repository | undefined;
|
||||
getRepository(path: string): Repository | undefined;
|
||||
getRepository(resource: Uri): Repository | undefined;
|
||||
getRepository(hint: any): Repository | undefined {
|
||||
const liveRepository = this.getOpenRepository(hint);
|
||||
getRepository(path: string, possibleSubmoduleRoot?: boolean): Repository | undefined;
|
||||
getRepository(resource: Uri, possibleSubmoduleRoot?: boolean): Repository | undefined;
|
||||
getRepository(hint: any, possibleSubmoduleRoot?: boolean): Repository | undefined {
|
||||
const liveRepository = this.getOpenRepository(hint, possibleSubmoduleRoot);
|
||||
return liveRepository && liveRepository.repository;
|
||||
}
|
||||
|
||||
private getOpenRepository(repository: Repository): OpenRepository | undefined;
|
||||
private getOpenRepository(sourceControl: SourceControl): OpenRepository | undefined;
|
||||
private getOpenRepository(resourceGroup: SourceControlResourceGroup): OpenRepository | undefined;
|
||||
private getOpenRepository(path: string): OpenRepository | undefined;
|
||||
private getOpenRepository(resource: Uri): OpenRepository | undefined;
|
||||
private getOpenRepository(hint: any): OpenRepository | undefined {
|
||||
private getOpenRepository(path: string, possibleSubmoduleRoot?: boolean): OpenRepository | undefined;
|
||||
private getOpenRepository(resource: Uri, possibleSubmoduleRoot?: boolean): OpenRepository | undefined;
|
||||
private getOpenRepository(hint: any, possibleSubmoduleRoot?: boolean): OpenRepository | undefined {
|
||||
if (!hint) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -295,15 +295,21 @@ export class Model {
|
||||
|
||||
outer:
|
||||
for (const liveRepository of this.openRepositories.sort((a, b) => b.repository.root.length - a.repository.root.length)) {
|
||||
if (possibleSubmoduleRoot && liveRepository.repository.root === resourcePath) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isDescendant(liveRepository.repository.root, resourcePath)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const submodule of liveRepository.repository.submodules) {
|
||||
const submoduleRoot = path.join(liveRepository.repository.root, submodule.path);
|
||||
if (!possibleSubmoduleRoot) {
|
||||
for (const submodule of liveRepository.repository.submodules) {
|
||||
const submoduleRoot = path.join(liveRepository.repository.root, submodule.path);
|
||||
|
||||
if (isDescendant(submoduleRoot, resourcePath)) {
|
||||
continue outer;
|
||||
if (isDescendant(submoduleRoot, resourcePath)) {
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
'use strict';
|
||||
|
||||
import { Uri, Command, EventEmitter, Event, scm, SourceControl, SourceControlInputBox, SourceControlResourceGroup, SourceControlResourceState, SourceControlResourceDecorations, Disposable, ProgressLocation, window, workspace, WorkspaceEdit, ThemeColor, DecorationData, Memento } from 'vscode';
|
||||
import { Repository as BaseRepository, Ref, Branch, Remote, Commit, GitErrorCodes, Stash, RefType, GitError, Submodule } from './git';
|
||||
import { Repository as BaseRepository, Ref, Branch, Remote, Commit, GitErrorCodes, Stash, RefType, GitError, Submodule, DiffOptions } from './git';
|
||||
import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant, IDisposable, onceEvent, EmptyDisposable, debounceEvent } from './util';
|
||||
import { memoize, throttle, debounce } from './decorators';
|
||||
import { toGitUri } from './uri';
|
||||
@@ -280,6 +280,7 @@ export class Resource implements SourceControlResourceState {
|
||||
|
||||
export enum Operation {
|
||||
Status = 'Status',
|
||||
Diff = 'Diff',
|
||||
Add = 'Add',
|
||||
RevertFiles = 'RevertFiles',
|
||||
Commit = 'Commit',
|
||||
@@ -557,7 +558,7 @@ export class Repository implements Disposable {
|
||||
return;
|
||||
}
|
||||
|
||||
return toGitUri(uri, '', true);
|
||||
return toGitUri(uri, '', { replaceFileExtension: true });
|
||||
}
|
||||
|
||||
private async updateCommitTemplate(): Promise<void> {
|
||||
@@ -573,6 +574,10 @@ export class Repository implements Disposable {
|
||||
await this.run(Operation.Status);
|
||||
}
|
||||
|
||||
diff(path: string, options: DiffOptions = {}): Promise<string> {
|
||||
return this.run(Operation.Diff, () => this.repository.diff(path, options));
|
||||
}
|
||||
|
||||
async add(resources: Uri[]): Promise<void> {
|
||||
await this.run(Operation.Add, () => this.repository.add(resources.map(r => r.fsPath)));
|
||||
}
|
||||
|
||||
@@ -7,20 +7,45 @@
|
||||
|
||||
import { Uri } from 'vscode';
|
||||
|
||||
export function fromGitUri(uri: Uri): { path: string; ref: string; } {
|
||||
export interface GitUriParams {
|
||||
path: string;
|
||||
ref: string;
|
||||
submoduleOf?: string;
|
||||
}
|
||||
|
||||
export function fromGitUri(uri: Uri): GitUriParams {
|
||||
return JSON.parse(uri.query);
|
||||
}
|
||||
|
||||
export interface GitUriOptions {
|
||||
replaceFileExtension?: boolean;
|
||||
submoduleOf?: string;
|
||||
}
|
||||
|
||||
// As a mitigation for extensions like ESLint showing warnings and errors
|
||||
// for git URIs, let's change the file extension of these uris to .git,
|
||||
// when `replaceFileExtension` is true.
|
||||
export function toGitUri(uri: Uri, ref: string, replaceFileExtension = false): Uri {
|
||||
export function toGitUri(uri: Uri, ref: string, options: GitUriOptions = {}): Uri {
|
||||
const params: GitUriParams = {
|
||||
path: uri.fsPath,
|
||||
ref
|
||||
};
|
||||
|
||||
if (options.submoduleOf) {
|
||||
params.submoduleOf = options.submoduleOf;
|
||||
}
|
||||
|
||||
let path = uri.path;
|
||||
|
||||
if (options.replaceFileExtension) {
|
||||
path = path + `${path}.git`;
|
||||
} else if (options.submoduleOf) {
|
||||
path = path + `${path}.diff`;
|
||||
}
|
||||
|
||||
return uri.with({
|
||||
scheme: 'git',
|
||||
path: replaceFileExtension ? `${uri.path}.git` : uri.path,
|
||||
query: JSON.stringify({
|
||||
path: uri.fsPath,
|
||||
ref
|
||||
})
|
||||
path,
|
||||
query: JSON.stringify(params)
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user