Browse Source

Fixes reveal commit in view

Optimizes fs watcher for repo file changes
 - Ignores gitignored files
 - Only updates the nodes required
main
Eric Amodio 5 years ago
parent
commit
3eebb4d24f
6 changed files with 80 additions and 10 deletions
  1. +9
    -0
      src/git/git.ts
  2. +17
    -0
      src/git/gitService.ts
  3. +11
    -2
      src/git/models/repository.ts
  4. +8
    -1
      src/system/array.ts
  5. +34
    -7
      src/views/nodes/repositoryNode.ts
  6. +1
    -0
      src/views/nodes/viewNode.ts

+ 9
- 0
src/git/git.ts View File

@ -483,6 +483,15 @@ export namespace Git {
}
}
export function check_ignore(repoPath: string, ...files: string[]) {
return git<string>(
{ cwd: repoPath, errors: GitErrorHandling.Ignore, stdin: files.join('\0') },
'check-ignore',
'-z',
'--stdin'
);
}
export function check_mailmap(repoPath: string, author: string) {
return git<string>({ cwd: repoPath, errors: GitErrorHandling.Ignore, local: true }, 'check-mailmap', author);
}

+ 17
- 0
src/git/gitService.ts View File

@ -605,6 +605,23 @@ export class GitService implements Disposable {
}
}
@log()
async excludeIgnoredUris(repoPath: string, uris: Uri[]): Promise<Uri[]> {
const paths = new Map<string, Uri>(uris.map(u => [Strings.normalizePath(u.fsPath), u]));
const data = await Git.check_ignore(repoPath, ...paths.keys());
if (data == null) return uris;
const ignored = data.split('\0').filter(Boolean);
if (ignored.length === 0) return uris;
for (const file of ignored) {
paths.delete(file);
}
return [...paths.values()];
}
@gate()
@log()
fetch(repoPath: string, options: { all?: boolean; prune?: boolean; remote?: string } = {}) {

+ 11
- 2
src/git/models/repository.ts View File

@ -24,6 +24,8 @@ import { Messages } from '../../messages';
import { Logger } from '../../logger';
import { runGitCommandInTerminal } from '../../terminal';
const ignoreGitRegex = /\.git(?:\/|\\|$)/;
export enum RepositoryChange {
Config = 'config',
Closed = 'closed',
@ -178,7 +180,7 @@ export class Repository implements Disposable {
private onFileSystemChanged(uri: Uri) {
// Ignore .git changes
if (/\.git(?:\/|\\|$)/.test(uri.fsPath)) return;
if (ignoreGitRegex.test(uri.fsPath)) return;
this.fireFileSystemChange(uri);
}
@ -670,9 +672,16 @@ export class Repository implements Disposable {
this._fireFileSystemChangeDebounced(e);
}
private fireFileSystemChangeCore(e: RepositoryFileSystemChangeEvent) {
private async fireFileSystemChangeCore(e: RepositoryFileSystemChangeEvent) {
this._pendingChanges.fs = undefined;
const uris = await Container.git.excludeIgnoredUris(this.path, e.uris);
if (uris.length === 0) return;
if (uris.length !== e.uris.length) {
e = { ...e, uris: uris };
}
this._onDidChangeFileSystem.fire(e);
}

+ 8
- 1
src/system/array.ts View File

@ -1,5 +1,10 @@
'use strict';
import { intersectionWith as _intersectionWith, isEqual as _isEqual, xor as _xor } from 'lodash-es';
import {
findLastIndex as _findLastIndex,
intersectionWith as _intersectionWith,
isEqual as _isEqual,
xor as _xor
} from 'lodash-es';
export namespace Arrays {
export function countUniques<T>(source: T[], accessor: (item: T) => string): { [key: string]: number } {
@ -37,6 +42,8 @@ export namespace Arrays {
}, [] as any);
}
export const findLastIndex = _findLastIndex;
export function groupBy<T>(source: T[], accessor: (item: T) => string): { [key: string]: T[] } {
return source.reduce((groupings, current) => {
const value = accessor(current);

+ 34
- 7
src/views/nodes/repositoryNode.ts View File

@ -12,7 +12,7 @@ import {
RepositoryChangeEvent,
RepositoryFileSystemChangeEvent
} from '../../git/gitService';
import { Dates, debug, gate, log, Strings } from '../../system';
import { Arrays, Dates, debug, gate, log, Strings } from '../../system';
import { RepositoriesView } from '../repositoriesView';
import { CompareBranchNode } from './compareBranchNode';
import { BranchesNode } from './branchesNode';
@ -219,10 +219,13 @@ export class RepositoryNode extends SubscribeableViewNode {
@gate()
@debug()
async refresh() {
this._status = this.repo.getStatus();
async refresh(reset: boolean = false) {
if (reset) {
this._status = this.repo.getStatus();
this._children = undefined;
}
this._children = undefined;
await this.ensureSubscription();
}
@ -270,8 +273,32 @@ export class RepositoryNode extends SubscribeableViewNode {
.join(', ')}${e.uris.length > 1 ? ', ...' : ''}] }`
}
})
private onFileSystemChanged(e: RepositoryFileSystemChangeEvent) {
void this.triggerChange();
private async onFileSystemChanged(e: RepositoryFileSystemChangeEvent) {
this._status = this.repo.getStatus();
if (this._children !== undefined) {
const status = await this._status;
let index = this._children.findIndex(c => c instanceof StatusFilesNode);
if (status !== undefined && (status.state.ahead || status.files.length !== 0)) {
let deleteCount = 1;
if (index === -1) {
index = Arrays.findLastIndex(
this._children,
c => c instanceof BranchTrackingStatusNode || c instanceof BranchNode
);
deleteCount = 0;
index++;
}
const range = status.upstream ? GitRevision.createRange(status.upstream, status.sha) : undefined;
this._children.splice(index, deleteCount, new StatusFilesNode(this.view, this, status, range));
} else if (index !== -1) {
this._children.splice(index, 1);
}
}
void this.triggerChange(false);
}
@debug({
@ -292,7 +319,7 @@ export class RepositoryNode extends SubscribeableViewNode {
e.changed(RepositoryChange.Repository) ||
e.changed(RepositoryChange.Config)
) {
void this.triggerChange();
void this.triggerChange(true);
return;
}

+ 1
- 0
src/views/nodes/viewNode.ts View File

@ -219,6 +219,7 @@ export abstract class SubscribeableViewNode extends V
}
}
@gate()
@debug()
async ensureSubscription() {
// We only need to subscribe if we are visible and if auto-refresh enabled (when supported)

Loading…
Cancel
Save