Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions contributions.json
Original file line number Diff line number Diff line change
Expand Up @@ -3672,6 +3672,26 @@
]
}
},
"gitlens.regenerateMarkdownDocument": {
"label": "Regenerate",
"icon": "$(refresh)",
"menus": {
"editor/title": [
{
"when": "resourceScheme == gitlens-markdown && activeCustomEditorId == vscode.markdown.preview.editor",
"group": "navigation",
"order": 0
}
],
"editor/title/context": [
{
"when": "resourceScheme == gitlens-markdown && activeCustomEditorId == vscode.markdown.preview.editor",
"group": "1_gitlens",
"order": 0
}
]
}
},
"gitlens.reset": {
"label": "Reset Stored Data...",
"commandPalette": true
Expand Down
2 changes: 1 addition & 1 deletion docs/telemetry-events.md

Large diffs are not rendered by default.

26 changes: 26 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7554,6 +7554,11 @@
"title": "Quick Open File History",
"category": "GitLens"
},
{
"command": "gitlens.regenerateMarkdownDocument",
"title": "Regenerate",
"icon": "$(refresh)"
},
{
"command": "gitlens.reset",
"title": "Reset Stored Data...",
Expand Down Expand Up @@ -11771,6 +11776,10 @@
"command": "gitlens.quickOpenFileHistory",
"when": "resource in gitlens:tabs:tracked"
},
{
"command": "gitlens.regenerateMarkdownDocument",
"when": "false"
},
{
"command": "gitlens.revealCommitInView",
"when": "resource in gitlens:tabs:blameable"
Expand Down Expand Up @@ -14110,6 +14119,11 @@
"when": "resourceScheme =~ /^(gitlens|pr)$/ && gitlens:enabled && isInDiffEditor",
"group": "navigation@-97"
},
{
"command": "gitlens.regenerateMarkdownDocument",
"when": "resourceScheme == gitlens-markdown && activeCustomEditorId == vscode.markdown.preview.editor",
"group": "navigation@0"
},
{
"command": "gitlens.openPatch",
"when": "false && editorLangId == diff"
Expand All @@ -14131,6 +14145,11 @@
"when": "resourceScheme == gitlens && resourceScheme in gitlens:schemes:trackable",
"group": "2_a_gitlens@0"
},
{
"command": "gitlens.regenerateMarkdownDocument",
"when": "resourceScheme == gitlens-markdown && activeCustomEditorId == vscode.markdown.preview.editor",
"group": "1_gitlens@0"
},
{
"command": "gitlens.copyRemoteFileUrlWithoutRange",
"when": "resourceScheme in gitlens:schemes:trackable && gitlens:enabled && gitlens:repos:withRemotes && config.gitlens.menus.editorTab.clipboard",
Expand Down Expand Up @@ -23562,6 +23581,13 @@
"tildify": true,
"workspaceSuffix": "GitLens"
}
},
{
"scheme": "gitlens-markdown",
"authority": "*",
"formatting": {
"label": "${query.label}"
}
}
],
"viewsContainers": {
Expand Down
1 change: 1 addition & 0 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import './commands/patches';
import './commands/quickWizard';
import './commands/rebaseEditor';
import './commands/refreshHover';
import './commands/regenerateMarkdownDocument';
import './commands/remoteProviders';
import './commands/repositories';
import './commands/resets';
Expand Down
64 changes: 64 additions & 0 deletions src/commands/explainBase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import type { TextEditor, Uri } from 'vscode';
import type { GlCommands } from '../constants.commands';
import type { Container } from '../container';
import type { MarkdownContentMetadata } from '../documents/markdown';
import { getMarkdownHeaderContent } from '../documents/markdown';
import type { GitRepositoryService } from '../git/gitRepositoryService';
import { GitUri } from '../git/gitUri';
import type { AIExplainSource, AISummarizeResult } from '../plus/ai/aiProviderService';
import { getBestRepositoryOrShowPicker } from '../quickpicks/repositoryPicker';
import { showMarkdownPreview } from '../system/-webview/markdown';
import { GlCommandBase } from './commandBase';
import { getCommandUri } from './commandBase.utils';

export interface ExplainBaseArgs {
worktreePath?: string | Uri;
repoPath?: string | Uri;
source?: AIExplainSource;
}

export abstract class ExplainCommandBase extends GlCommandBase {
abstract pickerTitle: string;
abstract repoPickerPlaceholder: string;

constructor(
protected readonly container: Container,
command: GlCommands | GlCommands[],
) {
super(command);
}

protected async getRepositoryService(
editor?: TextEditor,
uri?: Uri,
args?: ExplainBaseArgs,
): Promise<GitRepositoryService | undefined> {
let svc;
if (args?.worktreePath) {
svc = this.container.git.getRepositoryService(args.worktreePath);
} else if (args?.repoPath) {
svc = this.container.git.getRepositoryService(args.repoPath);
} else {
uri = getCommandUri(uri, editor);
const gitUri = uri != null ? await GitUri.fromUri(uri) : undefined;
const repository = await getBestRepositoryOrShowPicker(
gitUri,
editor,
this.pickerTitle,
this.repoPickerPlaceholder,
);

svc = repository?.git;
}

return svc;
}

protected openDocument(result: AISummarizeResult, path: string, metadata: MarkdownContentMetadata): void {
const content = `${getMarkdownHeaderContent(metadata)}\n\n${result.parsed.summary}\n\n${result.parsed.body}`;

const documentUri = this.container.markdown.openDocument(content, path, metadata.header.title, metadata);

showMarkdownPreview(documentUri);
}
}
73 changes: 32 additions & 41 deletions src/commands/explainBranch.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,30 @@
import type { TextEditor, Uri } from 'vscode';
import { ProgressLocation } from 'vscode';
import type { Container } from '../container';
import { GitUri } from '../git/gitUri';
import type { GitBranchReference } from '../git/models/reference';
import { getBranchMergeTargetName } from '../git/utils/-webview/branch.utils';
import { showGenericErrorMessage } from '../messages';
import type { AIExplainSource } from '../plus/ai/aiProviderService';
import { prepareCompareDataForAIRequest } from '../plus/ai/aiProviderService';
import { ReferencesQuickPickIncludes, showReferencePicker } from '../quickpicks/referencePicker';
import { getBestRepositoryOrShowPicker } from '../quickpicks/repositoryPicker';
import { command } from '../system/-webview/command';
import { showMarkdownPreview } from '../system/-webview/markdown';
import { Logger } from '../system/logger';
import { getNodeRepoPath } from '../views/nodes/abstract/viewNode';
import { GlCommandBase } from './commandBase';
import { getCommandUri } from './commandBase.utils';
import type { CommandContext } from './commandContext';
import { isCommandContextViewNodeHasBranch } from './commandContext.utils';
import type { ExplainBaseArgs } from './explainBase';
import { ExplainCommandBase } from './explainBase';

export interface ExplainBranchCommandArgs {
repoPath?: string | Uri;
export interface ExplainBranchCommandArgs extends ExplainBaseArgs {
ref?: string;
source?: AIExplainSource;
}

@command()
export class ExplainBranchCommand extends GlCommandBase {
constructor(private readonly container: Container) {
super(['gitlens.ai.explainBranch', 'gitlens.ai.explainBranch:views']);
export class ExplainBranchCommand extends ExplainCommandBase {
pickerTitle = 'Explain Branch Changes';
repoPickerPlaceholder = 'Choose which repository to explain a branch from';

constructor(container: Container) {
super(container, ['gitlens.ai.explainBranch', 'gitlens.ai.explainBranch:views']);
}

protected override preExecute(context: CommandContext, args?: ExplainBranchCommandArgs): Promise<void> {
Expand All @@ -44,41 +41,26 @@ export class ExplainBranchCommand extends GlCommandBase {
async execute(editor?: TextEditor, uri?: Uri, args?: ExplainBranchCommandArgs): Promise<void> {
args = { ...args };

let repository;
if (args?.repoPath != null) {
repository = this.container.git.getRepository(args.repoPath);
} else {
uri = getCommandUri(uri, editor);
const gitUri = uri != null ? await GitUri.fromUri(uri) : undefined;
repository = await getBestRepositoryOrShowPicker(
gitUri,
editor,
'Explain Branch Changes',
'Choose which repository to explain a branch from',
);
const svc = await this.getRepositoryService(editor, uri, args);
if (svc == null) {
void showGenericErrorMessage('Unable to find a repository');
return;
}

if (repository == null) return;

try {
// Clarifying the head branch
if (args.ref == null) {
// If no ref is provided, show a picker to select a branch
const pick = (await showReferencePicker(
repository.path,
'Explain Branch Changes',
'Choose a branch to explain',
{
include: ReferencesQuickPickIncludes.Branches,
sort: { branches: { current: true } },
},
)) as GitBranchReference | undefined;
const pick = (await showReferencePicker(svc.path, this.pickerTitle, 'Choose a branch to explain', {
include: ReferencesQuickPickIncludes.Branches,
sort: { branches: { current: true } },
})) as GitBranchReference | undefined;
if (pick?.ref == null) return;
args.ref = pick.ref;
}

// Get the branch
const branch = await repository.git.branches.getBranch(args.ref);
const branch = await svc.branches.getBranch(args.ref);
if (branch == null) {
void showGenericErrorMessage('Unable to find the specified branch');
return;
Expand All @@ -88,7 +70,7 @@ export class ExplainBranchCommand extends GlCommandBase {
const baseBranchNameResult = await getBranchMergeTargetName(this.container, branch);
let baseBranch;
if (!baseBranchNameResult.paused) {
baseBranch = await repository.git.branches.getBranch(baseBranchNameResult.value);
baseBranch = await svc.branches.getBranch(baseBranchNameResult.value);
}

if (!baseBranch) {
Expand All @@ -97,7 +79,7 @@ export class ExplainBranchCommand extends GlCommandBase {
}

// Get the diff between the branch and its upstream or base
const compareData = await prepareCompareDataForAIRequest(repository, branch.ref, baseBranch.ref, {
const compareData = await prepareCompareDataForAIRequest(svc, branch.ref, baseBranch.ref, {
reportNoDiffService: () => void showGenericErrorMessage('Unable to get diff service'),
reportNoCommitsService: () => void showGenericErrorMessage('Unable to get commits service'),
reportNoChanges: () => void showGenericErrorMessage('No changes found to explain'),
Expand Down Expand Up @@ -137,9 +119,18 @@ export class ExplainBranchCommand extends GlCommandBase {
return;
}

const content = `# Branch Summary\n\n> Generated by ${result.model.name}\n\n## ${branch.name}\n\n${result.parsed.summary}\n\n${result.parsed.body}`;

void showMarkdownPreview(content);
this.openDocument(result, `/explain/branch/${branch.ref}/${result.model.id}`, {
header: {
title: 'Branch Summary',
subtitle: branch.name,
aiModel: result.model.name,
},
command: {
label: 'Explain Branch Changes',
name: 'gitlens.ai.explainBranch',
args: { repoPath: svc.path, ref: branch.ref, source: args.source },
},
});
} catch (ex) {
Logger.error(ex, 'ExplainBranchCommand', 'execute');
void showGenericErrorMessage('Unable to explain branch');
Expand Down
Loading