瀏覽代碼

Adds stash searching to commit search

main
Eric Amodio 1 年之前
父節點
當前提交
d8048b24ba
共有 7 個檔案被更改,包括 113 行新增33 行删除
  1. +10
    -5
      src/env/node/git/git.ts
  2. +25
    -1
      src/env/node/git/localGitProvider.ts
  3. +48
    -19
      src/git/parsers/logParser.ts
  4. +4
    -0
      src/system/array.ts
  5. +6
    -3
      src/views/nodes/resultsCommitsNode.ts
  6. +8
    -2
      src/views/nodes/stashFileNode.ts
  7. +12
    -3
      src/views/nodes/stashNode.ts

+ 10
- 5
src/env/node/git/git.ts 查看文件

@ -16,6 +16,7 @@ import { GitBranchParser } from '../../../git/parsers/branchParser';
import { GitLogParser } from '../../../git/parsers/logParser';
import { GitReflogParser } from '../../../git/parsers/reflogParser';
import { GitTagParser } from '../../../git/parsers/tagParser';
import { splitAt } from '../../../system/array';
import { join } from '../../../system/iterable';
import { Logger } from '../../../system/logger';
import { LogLevel, slowCallWarningThreshold } from '../../../system/logger.constants';
@ -1258,6 +1259,7 @@ export class Git {
ordering?: 'date' | 'author-date' | 'topo' | null;
skip?: number;
shas?: Set<string>;
stdin?: string;
},
) {
if (options?.shas != null) {
@ -1272,18 +1274,21 @@ export class Git {
);
}
let files;
[search, files] = splitAt(search, search.indexOf('--'));
return this.git<string>(
{ cwd: repoPath, configs: ['-C', repoPath, ...gitLogDefaultConfigs] },
{ cwd: repoPath, configs: ['-C', repoPath, ...gitLogDefaultConfigs], stdin: options?.stdin },
'log',
...(options?.stdin ? ['--stdin'] : emptyArray),
'--name-status',
`--format=${GitLogParser.defaultFormat}`,
'--use-mailmap',
'--full-history',
'-m',
...search,
...(options?.ordering ? [`--${options.ordering}-order`] : emptyArray),
...(options?.limit ? [`-n${options.limit + 1}`] : emptyArray),
...(options?.skip ? [`--skip=${options.skip}`] : emptyArray),
...(options?.ordering ? [`--${options.ordering}-order`] : emptyArray),
...search,
...files,
);
}

+ 25
- 1
src/env/node/git/localGitProvider.ts 查看文件

@ -2796,6 +2796,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
limit,
false,
undefined,
undefined,
hasMoreOverride,
);
@ -4413,11 +4414,33 @@ export class LocalGitProvider implements GitProvider, Disposable {
args.push(...files);
}
let stashes: Map<string, GitStashCommit> | undefined;
let stdin: string | undefined;
if (shas == null) {
const stash = await this.getStash(repoPath);
// TODO@eamodio this is insanity -- there *HAS* to be a better way to get git log to return stashes
if (stash?.commits.size) {
stashes = new Map();
for (const commit of stash.commits.values()) {
stashes.set(commit.sha, commit);
for (const p of commit.parents) {
stashes.set(p, commit);
}
}
stdin = join(
map(stash.commits.values(), c => c.sha.substring(0, 9)),
'\n',
);
}
}
const data = await this.git.log__search(repoPath, shas?.size ? undefined : args, {
ordering: configuration.get('advanced.commitOrdering'),
...options,
limit: limit,
shas: shas,
stdin: stdin,
});
const log = GitLogParser.parse(
this.container,
@ -4430,6 +4453,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
limit,
false,
undefined,
stashes,
);
if (log != null) {
@ -4537,7 +4561,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
const stash = await this.getStash(repoPath);
let stdin: string | undefined;
// TODO@eamodio this is insanity -- there *HAS* to be a better way to get git log to return stashes
if (stash != null && stash.commits.size !== 0) {
if (stash?.commits.size) {
stdin = join(
map(stash.commits.values(), c => c.sha.substring(0, 9)),
'\n',

+ 48
- 19
src/git/parsers/logParser.ts 查看文件

@ -4,7 +4,7 @@ import { filterMap } from '../../system/array';
import { debug } from '../../system/decorators/log';
import { normalizePath, relative } from '../../system/path';
import { getLines } from '../../system/string';
import type { GitCommitLine } from '../models/commit';
import type { GitCommitLine, GitStashCommit } from '../models/commit';
import { GitCommit, GitCommitIdentity } from '../models/commit';
import { uncommitted } from '../models/constants';
import type { GitFile, GitFileChangeStats } from '../models/file';
@ -431,6 +431,7 @@ export class GitLogParser {
limit: number | undefined,
reverse: boolean,
range: Range | undefined,
stashes?: Map<string, GitStashCommit>,
hasMoreOverride?: boolean,
): GitLog | undefined {
if (!data) return undefined;
@ -718,6 +719,7 @@ export class GitLogParser {
relativeFileName,
commits,
currentUser,
stashes,
);
break;
@ -746,6 +748,7 @@ export class GitLogParser {
relativeFileName: string | undefined,
commits: Map<string, GitCommit>,
currentUser: GitUser | undefined,
stashes: Map<string, GitStashCommit> | undefined,
): void {
if (commit == null) {
if (entry.author != null) {
@ -776,24 +779,50 @@ export class GitLogParser {
);
}
commit = new GitCommit(
container,
repoPath!,
entry.sha!,
new GitCommitIdentity(entry.author!, entry.authorEmail, new Date((entry.authorDate! as any) * 1000)),
new GitCommitIdentity(
entry.committer!,
entry.committerEmail,
new Date((entry.committedDate! as any) * 1000),
),
entry.summary?.split('\n', 1)[0] ?? '',
entry.parentShas ?? [],
entry.summary ?? '',
files,
undefined,
entry.line != null ? [entry.line] : [],
entry.tips,
);
const stash = stashes?.get(entry.sha!);
if (stash != null) {
commit = new GitCommit(
container,
repoPath!,
stash.sha,
stash.author,
stash.committer,
stash.summary,
stash.parents,
stash.message,
files,
undefined,
entry.line != null ? [entry.line] : [],
entry.tips,
stash.stashName,
stash.stashOnRef,
);
} else {
commit = new GitCommit(
container,
repoPath!,
entry.sha!,
new GitCommitIdentity(
entry.author!,
entry.authorEmail,
new Date((entry.authorDate! as any) * 1000),
),
new GitCommitIdentity(
entry.committer!,
entry.committerEmail,
new Date((entry.committedDate! as any) * 1000),
),
entry.summary?.split('\n', 1)[0] ?? '',
entry.parentShas ?? [],
entry.summary ?? '',
files,
undefined,
entry.line != null ? [entry.line] : [],
entry.tips,
);
}
commits.set(entry.sha!, commit);
}

+ 4
- 0
src/system/array.ts 查看文件

@ -250,6 +250,10 @@ export function joinUnique(source: readonly T[], separator: string): string {
return join(new Set(source), separator);
}
export function splitAt<T>(source: T[], index: number): [T[], T[]] {
return index < 0 ? [source, []] : [source.slice(0, index), source.slice(index)];
}
export function uniqueBy<TKey, TValue>(
source: readonly TValue[],
uniqueKey: (item: TValue) => TKey,

+ 6
- 3
src/views/nodes/resultsCommitsNode.ts 查看文件

@ -1,5 +1,6 @@
import { TreeItem, TreeItemCollapsibleState } from 'vscode';
import { GitUri } from '../../git/gitUri';
import { isStash } from '../../git/models/commit';
import type { GitLog } from '../../git/models/log';
import { configuration } from '../../system/configuration';
import { gate } from '../../system/decorators/gate';
@ -13,6 +14,7 @@ import { LoadMoreNode } from './common';
import { insertDateMarkers } from './helpers';
import type { FilesQueryResults } from './resultsFilesNode';
import { ResultsFilesNode } from './resultsFilesNode';
import { StashNode } from './stashNode';
import type { PageableViewNode } from './viewNode';
import { ContextValues, ViewNode } from './viewNode';
@ -105,9 +107,10 @@ export class ResultsCommitsNode
children.push(
...insertDateMarkers(
map(
log.commits.values(),
c => new CommitNode(this.view, this, c, undefined, undefined, getBranchAndTagTips, options),
map(log.commits.values(), c =>
isStash(c)
? new StashNode(this.view, this, c, { icon: true })
: new CommitNode(this.view, this, c, undefined, undefined, getBranchAndTagTips, options),
),
this,
undefined,

+ 8
- 2
src/views/nodes/stashFileNode.ts 查看文件

@ -2,13 +2,19 @@ import type { GitStashCommit } from '../../git/models/commit';
import type { GitFile } from '../../git/models/file';
import type { RepositoriesView } from '../repositoriesView';
import type { StashesView } from '../stashesView';
import type { ViewsWithCommits } from '../viewBase';
import { CommitFileNode } from './commitFileNode';
import type { ViewNode } from './viewNode';
import { ContextValues } from './viewNode';
export class StashFileNode extends CommitFileNode<StashesView | RepositoriesView> {
export class StashFileNode extends CommitFileNode<ViewsWithCommits | StashesView | RepositoriesView> {
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
constructor(view: StashesView | RepositoriesView, parent: ViewNode, file: GitFile, commit: GitStashCommit) {
constructor(
view: ViewsWithCommits | StashesView | RepositoriesView,
parent: ViewNode,
file: GitFile,
commit: GitStashCommit,
) {
super(view, parent, file, commit);
}

+ 12
- 3
src/views/nodes/stashNode.ts 查看文件

@ -1,4 +1,4 @@
import { TreeItem, TreeItemCollapsibleState } from 'vscode';
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from 'vscode';
import { ViewFilesLayout } from '../../config';
import { CommitFormatter } from '../../git/formatters/commitFormatter';
import type { GitStashCommit } from '../../git/models/commit';
@ -9,6 +9,7 @@ import { joinPaths, normalizePath } from '../../system/path';
import { sortCompare } from '../../system/string';
import type { RepositoriesView } from '../repositoriesView';
import type { StashesView } from '../stashesView';
import type { ViewsWithCommits } from '../viewBase';
import type { FileNode } from './folderNode';
import { FolderNode } from './folderNode';
import { RepositoryNode } from './repositoryNode';
@ -16,13 +17,18 @@ import { StashFileNode } from './stashFileNode';
import type { ViewNode } from './viewNode';
import { ContextValues, ViewRefNode } from './viewNode';
export class StashNode extends ViewRefNode<StashesView | RepositoriesView, GitStashReference> {
export class StashNode extends ViewRefNode<ViewsWithCommits | StashesView | RepositoriesView, GitStashReference> {
static key = ':stash';
static getId(repoPath: string, ref: string): string {
return `${RepositoryNode.getId(repoPath)}${this.key}(${ref})`;
}
constructor(view: StashesView | RepositoriesView, parent: ViewNode, public readonly commit: GitStashCommit) {
constructor(
view: ViewsWithCommits | StashesView | RepositoriesView,
parent: ViewNode,
public readonly commit: GitStashCommit,
private readonly options?: { icon?: boolean },
) {
super(commit.getGitUri(), view, parent);
}
@ -73,6 +79,9 @@ export class StashNode extends ViewRefNode
dateFormat: configuration.get('defaultDateFormat'),
});
item.contextValue = ContextValues.Stash;
if (this.options?.icon) {
item.iconPath = new ThemeIcon('gitlens-stashes');
}
item.tooltip = CommitFormatter.fromTemplate(
`\${'On 'stashOnRef\n}\${ago} (\${date})\n\n\${message}`,
this.commit,

Loading…
取消
儲存