Browse Source

Renames commit search methods for clarity

main
Eric Amodio 2 years ago
parent
commit
ad2bcfd278
9 changed files with 1114 additions and 1113 deletions
  1. +1
    -1
      src/commands/git/search.ts
  2. +220
    -220
      src/env/node/git/localGitProvider.ts
  3. +14
    -14
      src/git/gitProvider.ts
  4. +20
    -20
      src/git/gitProviderService.ts
  5. +6
    -4
      src/git/models/repository.ts
  6. +850
    -851
      src/plus/github/githubGitProvider.ts
  7. +1
    -1
      src/plus/webviews/graph/graphWebview.ts
  8. +1
    -1
      src/views/nodes/searchResultsNode.ts
  9. +1
    -1
      src/webviews/rebase/rebaseEditor.ts

+ 1
- 1
src/commands/git/search.ts View File

@ -169,7 +169,7 @@ export class SearchGitCommand extends QuickCommand {
const searchKey = getSearchQueryComparisonKey(search);
if (context.resultsPromise == null || context.resultsKey !== searchKey) {
context.resultsPromise = state.repo.searchForCommits(search);
context.resultsPromise = state.repo.richSearchCommits(search);
context.resultsKey = searchKey;
}

+ 220
- 220
src/env/node/git/localGitProvider.ts View File

@ -2638,226 +2638,6 @@ export class LocalGitProvider implements GitProvider, Disposable {
}
@log()
async searchForCommitShas(
repoPath: string,
search: SearchQuery,
options?: { cancellation?: CancellationToken; limit?: number; ordering?: 'date' | 'author-date' | 'topo' },
): Promise<GitSearch> {
search = { matchAll: false, matchCase: false, matchRegex: true, ...search };
const comparisonKey = getSearchQueryComparisonKey(search);
try {
const refAndDateParser = getRefAndDateParser();
const { args: searchArgs, files, shas } = getGitArgsFromSearchQuery(search);
if (shas?.size) {
const data = await this.git.show2(
repoPath,
{ cancellation: options?.cancellation },
'-s',
...refAndDateParser.arguments,
...shas.values(),
...searchArgs,
'--',
);
const results = new Map<string, number>(
map(refAndDateParser.parse(data), c => [
c.sha,
Number(options?.ordering === 'author-date' ? c.authorDate : c.committerDate) * 1000,
]),
);
return {
repoPath: repoPath,
query: search,
comparisonKey: comparisonKey,
results: results,
};
}
const limit = options?.limit ?? configuration.get('advanced.maxSearchItems') ?? 0;
const similarityThreshold = configuration.get('advanced.similarityThreshold');
const args = [
...refAndDateParser.arguments,
`-M${similarityThreshold == null ? '' : `${similarityThreshold}%`}`,
'--use-mailmap',
];
if (options?.ordering) {
args.push(`--${options.ordering}-order`);
}
const results = new Map<string, number>();
let total = 0;
let iterations = 0;
async function searchForCommitsCore(
this: LocalGitProvider,
limit: number,
cursor?: { sha: string; skip: number },
): Promise<GitSearch> {
iterations++;
if (options?.cancellation?.isCancellationRequested) {
// TODO@eamodio: Should we throw an error here?
return { repoPath: repoPath, query: search, comparisonKey: comparisonKey, results: results };
}
const data = await this.git.log2(
repoPath,
{ cancellation: options?.cancellation },
...args,
...(cursor?.skip ? [`--skip=${cursor.skip}`] : []),
...(limit ? [`-n${limit + 1}`] : []),
...searchArgs,
'--',
...files,
);
if (options?.cancellation?.isCancellationRequested) {
// TODO@eamodio: Should we throw an error here?
return { repoPath: repoPath, query: search, comparisonKey: comparisonKey, results: results };
}
let count = 0;
for (const r of refAndDateParser.parse(data)) {
results.set(
r.sha,
Number(options?.ordering === 'author-date' ? r.authorDate : r.committerDate) * 1000,
);
count++;
}
total += count;
const lastSha = last(results)?.[0];
cursor =
lastSha != null
? {
sha: lastSha,
skip: total - iterations,
}
: undefined;
return {
repoPath: repoPath,
query: search,
comparisonKey: comparisonKey,
results: results,
paging:
limit !== 0 && count > limit
? {
limit: limit,
hasMore: true,
}
: undefined,
more: async (limit: number): Promise<GitSearch> => searchForCommitsCore.call(this, limit, cursor),
};
}
return searchForCommitsCore.call(this, limit);
} catch (ex) {
// TODO@eamodio: Should we throw an error here?
// TODO@eamodio handle error reporting -- just invalid queries? or more detailed?
return {
repoPath: repoPath,
query: search,
comparisonKey: comparisonKey,
results: new Map<string, number>(),
};
}
}
@log()
async getLogForSearch(
repoPath: string,
search: SearchQuery,
options?: { limit?: number; ordering?: 'date' | 'author-date' | 'topo' | null; skip?: number },
): Promise<GitLog | undefined> {
search = { matchAll: false, matchCase: false, matchRegex: true, ...search };
try {
const limit = options?.limit ?? configuration.get('advanced.maxSearchItems') ?? 0;
const similarityThreshold = configuration.get('advanced.similarityThreshold');
const { args, files, shas } = getGitArgsFromSearchQuery(search);
args.push(`-M${similarityThreshold == null ? '' : `${similarityThreshold}%`}`, '--');
if (files.length !== 0) {
args.push(...files);
}
const data = await this.git.log__search(repoPath, args, {
ordering: configuration.get('advanced.commitOrdering'),
...options,
limit: limit,
useShow: Boolean(shas?.size),
});
const log = GitLogParser.parse(
this.container,
data,
LogType.Log,
repoPath,
undefined,
undefined,
await this.getCurrentUser(repoPath),
limit,
false,
undefined,
);
if (log != null) {
log.query = (limit: number | undefined) =>
this.getLogForSearch(repoPath, search, { ...options, limit: limit });
if (log.hasMore) {
log.more = this.getLogForSearchMoreFn(log, search, options);
}
}
return log;
} catch (ex) {
return undefined;
}
}
private getLogForSearchMoreFn(
log: GitLog,
search: SearchQuery,
options?: { limit?: number; ordering?: 'date' | 'author-date' | 'topo' | null },
): (limit: number | undefined) => Promise<GitLog> {
return async (limit: number | undefined) => {
limit = limit ?? configuration.get('advanced.maxSearchItems') ?? 0;
const moreLog = await this.getLogForSearch(log.repoPath, search, {
...options,
limit: limit,
skip: log.count,
});
// If we can't find any more, assume we have everything
if (moreLog == null) return { ...log, hasMore: false, more: undefined };
const commits = new Map([...log.commits, ...moreLog.commits]);
const mergedLog: GitLog = {
repoPath: log.repoPath,
commits: commits,
sha: log.sha,
range: log.range,
count: commits.size,
limit: (log.limit ?? 0) + limit,
hasMore: moreLog.hasMore,
query: (limit: number | undefined) =>
this.getLogForSearch(log.repoPath, search, { ...options, limit: limit }),
};
if (mergedLog.hasMore) {
mergedLog.more = this.getLogForSearchMoreFn(mergedLog, search, options);
}
return mergedLog;
};
}
@log()
async getLogForFile(
repoPath: string | undefined,
pathOrUri: string | Uri,
@ -4243,6 +4023,226 @@ export class LocalGitProvider implements GitProvider, Disposable {
}
@log()
async richSearchCommits(
repoPath: string,
search: SearchQuery,
options?: { limit?: number; ordering?: 'date' | 'author-date' | 'topo' | null; skip?: number },
): Promise<GitLog | undefined> {
search = { matchAll: false, matchCase: false, matchRegex: true, ...search };
try {
const limit = options?.limit ?? configuration.get('advanced.maxSearchItems') ?? 0;
const similarityThreshold = configuration.get('advanced.similarityThreshold');
const { args, files, shas } = getGitArgsFromSearchQuery(search);
args.push(`-M${similarityThreshold == null ? '' : `${similarityThreshold}%`}`, '--');
if (files.length !== 0) {
args.push(...files);
}
const data = await this.git.log__search(repoPath, args, {
ordering: configuration.get('advanced.commitOrdering'),
...options,
limit: limit,
useShow: Boolean(shas?.size),
});
const log = GitLogParser.parse(
this.container,
data,
LogType.Log,
repoPath,
undefined,
undefined,
await this.getCurrentUser(repoPath),
limit,
false,
undefined,
);
if (log != null) {
function richSearchCommitsCore(
this: LocalGitProvider,
log: GitLog,
): (limit: number | undefined) => Promise<GitLog> {
return async (limit: number | undefined) => {
limit = limit ?? configuration.get('advanced.maxSearchItems') ?? 0;
const moreLog = await this.richSearchCommits(log.repoPath, search, {
...options,
limit: limit,
skip: log.count,
});
// If we can't find any more, assume we have everything
if (moreLog == null) return { ...log, hasMore: false, more: undefined };
const commits = new Map([...log.commits, ...moreLog.commits]);
const mergedLog: GitLog = {
repoPath: log.repoPath,
commits: commits,
sha: log.sha,
range: log.range,
count: commits.size,
limit: (log.limit ?? 0) + limit,
hasMore: moreLog.hasMore,
query: (limit: number | undefined) =>
this.richSearchCommits(log.repoPath, search, { ...options, limit: limit }),
};
if (mergedLog.hasMore) {
mergedLog.more = richSearchCommitsCore.call(this, mergedLog);
}
return mergedLog;
};
}
log.query = (limit: number | undefined) =>
this.richSearchCommits(repoPath, search, { ...options, limit: limit });
if (log.hasMore) {
log.more = richSearchCommitsCore.call(this, log);
}
}
return log;
} catch (ex) {
return undefined;
}
}
@log()
async searchCommits(
repoPath: string,
search: SearchQuery,
options?: { cancellation?: CancellationToken; limit?: number; ordering?: 'date' | 'author-date' | 'topo' },
): Promise<GitSearch> {
search = { matchAll: false, matchCase: false, matchRegex: true, ...search };
const comparisonKey = getSearchQueryComparisonKey(search);
try {
const refAndDateParser = getRefAndDateParser();
const { args: searchArgs, files, shas } = getGitArgsFromSearchQuery(search);
if (shas?.size) {
const data = await this.git.show2(
repoPath,
{ cancellation: options?.cancellation },
'-s',
...refAndDateParser.arguments,
...shas.values(),
...searchArgs,
'--',
);
const results = new Map<string, number>(
map(refAndDateParser.parse(data), c => [
c.sha,
Number(options?.ordering === 'author-date' ? c.authorDate : c.committerDate) * 1000,
]),
);
return {
repoPath: repoPath,
query: search,
comparisonKey: comparisonKey,
results: results,
};
}
const limit = options?.limit ?? configuration.get('advanced.maxSearchItems') ?? 0;
const similarityThreshold = configuration.get('advanced.similarityThreshold');
const args = [
...refAndDateParser.arguments,
`-M${similarityThreshold == null ? '' : `${similarityThreshold}%`}`,
'--use-mailmap',
];
if (options?.ordering) {
args.push(`--${options.ordering}-order`);
}
const results = new Map<string, number>();
let total = 0;
let iterations = 0;
async function searchForCommitsCore(
this: LocalGitProvider,
limit: number,
cursor?: { sha: string; skip: number },
): Promise<GitSearch> {
iterations++;
if (options?.cancellation?.isCancellationRequested) {
// TODO@eamodio: Should we throw an error here?
return { repoPath: repoPath, query: search, comparisonKey: comparisonKey, results: results };
}
const data = await this.git.log2(
repoPath,
{ cancellation: options?.cancellation },
...args,
...(cursor?.skip ? [`--skip=${cursor.skip}`] : []),
...(limit ? [`-n${limit + 1}`] : []),
...searchArgs,
'--',
...files,
);
if (options?.cancellation?.isCancellationRequested) {
// TODO@eamodio: Should we throw an error here?
return { repoPath: repoPath, query: search, comparisonKey: comparisonKey, results: results };
}
let count = 0;
for (const r of refAndDateParser.parse(data)) {
results.set(
r.sha,
Number(options?.ordering === 'author-date' ? r.authorDate : r.committerDate) * 1000,
);
count++;
}
total += count;
const lastSha = last(results)?.[0];
cursor =
lastSha != null
? {
sha: lastSha,
skip: total - iterations,
}
: undefined;
return {
repoPath: repoPath,
query: search,
comparisonKey: comparisonKey,
results: results,
paging:
limit !== 0 && count > limit
? {
limit: limit,
hasMore: true,
}
: undefined,
more: async (limit: number): Promise<GitSearch> => searchForCommitsCore.call(this, limit, cursor),
};
}
return searchForCommitsCore.call(this, limit);
} catch (ex) {
// TODO@eamodio: Should we throw an error here?
// TODO@eamodio handle error reporting -- just invalid queries? or more detailed?
return {
repoPath: repoPath,
query: search,
comparisonKey: comparisonKey,
results: new Map<string, number>(),
};
}
}
@log()
validateBranchOrTagName(repoPath: string, ref: string): Promise<boolean> {
return this.git.check_ref_format(ref, repoPath);
}

+ 14
- 14
src/git/gitProvider.ts View File

@ -296,20 +296,6 @@ export interface GitProvider extends Disposable {
since?: string | undefined;
},
): Promise<Set<string> | undefined>;
searchForCommitShas(
repoPath: string | Uri,
search: SearchQuery,
options?: { cancellation?: CancellationToken; limit?: number; ordering?: 'date' | 'author-date' | 'topo' },
): Promise<GitSearch>;
getLogForSearch(
repoPath: string,
search: SearchQuery,
options?: {
limit?: number | undefined;
ordering?: 'date' | 'author-date' | 'topo' | null | undefined;
skip?: number | undefined;
},
): Promise<GitLog | undefined>;
getLogForFile(
repoPath: string,
pathOrUri: string | Uri,
@ -417,6 +403,20 @@ export interface GitProvider extends Disposable {
pathOrUri?: string | Uri,
options?: { timeout?: number | undefined },
): Promise<string>;
richSearchCommits(
repoPath: string,
search: SearchQuery,
options?: {
limit?: number | undefined;
ordering?: 'date' | 'author-date' | 'topo' | null | undefined;
skip?: number | undefined;
},
): Promise<GitLog | undefined>;
searchCommits(
repoPath: string | Uri,
search: SearchQuery,
options?: { cancellation?: CancellationToken; limit?: number; ordering?: 'date' | 'author-date' | 'topo' },
): Promise<GitSearch>;
validateBranchOrTagName(repoPath: string, ref: string): Promise<boolean>;
validateReference(repoPath: string, ref: string): Promise<boolean>;

+ 20
- 20
src/git/gitProviderService.ts View File

@ -1466,26 +1466,6 @@ export class GitProviderService implements Disposable {
}
@log()
searchForCommitShas(
repoPath: string | Uri,
search: SearchQuery,
options?: { cancellation?: CancellationToken; limit?: number; ordering?: 'date' | 'author-date' | 'topo' },
): Promise<GitSearch> {
const { provider, path } = this.getProvider(repoPath);
return provider.searchForCommitShas(path, search, options);
}
@log()
async getLogForSearch(
repoPath: string | Uri,
search: SearchQuery,
options?: { limit?: number; ordering?: 'date' | 'author-date' | 'topo' | null; skip?: number },
): Promise<GitLog | undefined> {
const { provider, path } = this.getProvider(repoPath);
return provider.getLogForSearch(path, search, options);
}
@log()
async getLogForFile(
repoPath: string | Uri | undefined,
pathOrUri: string | Uri,
@ -2246,6 +2226,26 @@ export class GitProviderService implements Disposable {
}
@log()
async richSearchCommits(
repoPath: string | Uri,
search: SearchQuery,
options?: { limit?: number; ordering?: 'date' | 'author-date' | 'topo' | null; skip?: number },
): Promise<GitLog | undefined> {
const { provider, path } = this.getProvider(repoPath);
return provider.richSearchCommits(path, search, options);
}
@log()
searchCommits(
repoPath: string | Uri,
search: SearchQuery,
options?: { cancellation?: CancellationToken; limit?: number; ordering?: 'date' | 'author-date' | 'topo' },
): Promise<GitSearch> {
const { provider, path } = this.getProvider(repoPath);
return provider.searchCommits(path, search, options);
}
@log()
validateBranchOrTagName(repoPath: string | Uri, ref: string): Promise<boolean> {
const { provider, path } = this.getProvider(repoPath);
return provider.validateBranchOrTagName(path, ref);

+ 6
- 4
src/git/models/repository.ts View File

@ -852,18 +852,20 @@ export class Repository implements Disposable {
this.runTerminalCommand('revert', ...args);
}
searchForCommits(
@debug()
richSearchCommits(
search: SearchQuery,
options?: { limit?: number; ordering?: 'date' | 'author-date' | 'topo'; skip?: number },
): Promise<GitLog | undefined> {
return this.container.git.getLogForSearch(this.path, search, options);
return this.container.git.richSearchCommits(this.path, search, options);
}
searchForCommitShas(
@debug()
searchCommits(
search: SearchQuery,
options?: { cancellation?: CancellationToken; limit?: number; ordering?: 'date' | 'author-date' | 'topo' },
): Promise<GitSearch> {
return this.container.git.searchForCommitShas(this.path, search, options);
return this.container.git.searchCommits(this.path, search, options);
}
async setRemoteAsDefault(remote: GitRemote, value: boolean = true) {

+ 850
- 851
src/plus/github/githubGitProvider.ts
File diff suppressed because it is too large
View File


+ 1
- 1
src/plus/webviews/graph/graphWebview.ts View File

@ -478,7 +478,7 @@ export class GraphWebview extends WebviewBase {
const cancellation = new CancellationTokenSource();
this._searchCancellation = cancellation;
search = await this._repository.searchForCommitShas(e.search, {
search = await this._repository.searchCommits(e.search, {
limit: configuration.get('graph.searchItemLimit') ?? 100,
ordering: configuration.get('graph.commitOrdering'),
cancellation: cancellation.token,

+ 1
- 1
src/views/nodes/searchResultsNode.ts View File

@ -265,7 +265,7 @@ export class SearchResultsNode extends ViewNode implements
let useCacheOnce = true;
return async (limit: number | undefined) => {
log = await (log ?? this.view.container.git.getLogForSearch(this.repoPath, this.search));
log = await (log ?? this.view.container.git.richSearchCommits(this.repoPath, this.search));
if (!useCacheOnce && log != null && log.query != null) {
log = await log.query(limit);

+ 1
- 1
src/webviews/rebase/rebaseEditor.ts View File

@ -540,7 +540,7 @@ async function parseRebaseTodo(
const authors = new Map<string, Author>();
const commits: Commit[] = [];
const log = await container.git.getLogForSearch(repoPath, {
const log = await container.git.richSearchCommits(repoPath, {
query: `${onto ? `#:${onto} ` : ''}${join(
map(entries, e => `#:${e.ref}`),
' ',

Loading…
Cancel
Save