From a40c0a1655f334ce338d97a6ee4abffdc505e643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Sat, 9 Sep 2023 00:14:17 +0200 Subject: [PATCH] Show file contents from commit or stash --- src/commands/diffingCommands.ts | 9 +++++---- src/commands/visitAtPointCommands.ts | 29 ++++++++++++++++++++++++---- src/models/magitChange.ts | 4 ++++ 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/commands/diffingCommands.ts b/src/commands/diffingCommands.ts index 1ff43ec..5cd7757 100644 --- a/src/commands/diffingCommands.ts +++ b/src/commands/diffingCommands.ts @@ -12,7 +12,7 @@ import * as VisitAtPoint from './visitAtPointCommands'; import * as Constants from '../common/constants'; import { Section } from '../views/general/sectionHeader'; import { Status } from '../typings/git'; -import { MagitChange } from '../models/magitChange'; +import { ContextualMagitChange, MagitChange } from '../models/magitChange'; import { Stash } from '../models/stash'; import ViewUtils from '../utils/viewUtils'; import { constants } from 'buffer'; @@ -104,7 +104,7 @@ async function showStash({ repository }: MenuState) { } } -function stashToMagitChanges(nameStatusText: string, diff: string): MagitChange[] { +export function stashToMagitChanges(repository: MagitRepository, contextId: string, nameStatusText: string, diff: string): ContextualMagitChange[] { const DIFF_PREFIX = 'diff --git'; const filesWithStatus = nameStatusText.split(Constants.LineSplitterRegex).filter(t => t !== '').map(s => s.split('\t')); const diffs = diff.split(DIFF_PREFIX).filter(r => r !== ''); @@ -115,11 +115,12 @@ function stashToMagitChanges(nameStatusText: string, diff: string): MagitChange[ return diffs.map((diff, idx) => { const [status, ...paths] = filesWithStatus[idx]; - const uri = Uri.file(paths[paths.length - 1]); + const uri = Uri.parse(repository.gitRepository.rootUri + '/' + paths[paths.length - 1]); const fileStatus = getStatusFromString(status); return { diff, uri, + contextId, originalUri: uri, status: fileStatus, renameUri: undefined, @@ -171,7 +172,7 @@ export async function showStashDetail(repository: MagitRepository, stash: Stash) const nameStatusText = (await nameStatusTask).stdout; const stashDiff = (await stashShowTask).stdout; - return ViewUtils.showView(uri, new StashDetailView(uri, stash, stashToMagitChanges(nameStatusText, stashDiff), stashUntrackedFiles)); + return ViewUtils.showView(uri, new StashDetailView(uri, stash, stashToMagitChanges(repository, `stash@{${stash.index}}`, nameStatusText, stashDiff), stashUntrackedFiles)); } async function showCommit({ repository }: MenuState) { diff --git a/src/commands/visitAtPointCommands.ts b/src/commands/visitAtPointCommands.ts index fb8b06d..33b09ef 100644 --- a/src/commands/visitAtPointCommands.ts +++ b/src/commands/visitAtPointCommands.ts @@ -1,4 +1,4 @@ -import { window, workspace, TextEditorRevealType, Range, Position, Selection, commands } from 'vscode'; +import { window, workspace, TextEditorRevealType, Range, Position, Selection, commands, WorkspaceEdit, Uri } from 'vscode'; import { MagitRepository } from '../models/magitRepository'; import { CommitItemView } from '../views/commits/commitSectionView'; import { DocumentView } from '../views/general/documentView'; @@ -21,6 +21,8 @@ import { PullRequestView } from '../views/forge/pullRequestView'; import { sep } from 'path'; import { ErrorMessageView } from '../views/errorMessageView'; import { processView } from './processCommands'; +import { stashToMagitChanges } from './diffingCommands'; +import { ContextualMagitChange } from '../models/magitChange'; export async function magitVisitAtPoint(repository: MagitRepository, currentView: DocumentView) { @@ -36,8 +38,27 @@ export async function magitVisitAtPoint(repository: MagitRepository, currentView const change = (selectedView as ChangeView).change; - if (change.hunks?.length) { - return visitHunk(selectedView.subViews.find(v => v instanceof HunkView) as HunkView); + /* Check if is ContextualMagitChange */ + if ((change as ContextualMagitChange).contextId !== undefined) { + const contextual = change as ContextualMagitChange; + const content = await gitRun(repository.gitRepository, ['show', `${contextual.contextId}:${change.relativePath}`]); + + let path = change.uri.path; + let filename = path.split('/').pop() ?? ''; + let extension = filename.split('.', 2).pop() ?? ''; + if (extension.length > 0) { + path = path.slice(0, -extension.length - 1); + } + + workspace.openTextDocument(Uri.parse(`untitled:${path}.~${contextual.contextId}~.${extension}`)) + .then(doc => window.showTextDocument(doc)) + .then(editor => { + editor.edit((edit) => { + edit.insert(new Position(0, 0), content.stdout); + }); + }); + } else if (change.hunks?.length) { + return visitHunk(selectedView.subViews.find(v => v instanceof HunkView) as HunkView); } else { // Check if change path is a directory. Reveal directories in file explorer @@ -145,5 +166,5 @@ export async function visitCommit(repository: MagitRepository, commitHash: strin const commit: MagitCommit = { hash: commitHash, message: '', parents: [] }; const uri = CommitDetailView.encodeLocation(repository, commit.hash); - return ViewUtils.showView(uri, new CommitDetailView(uri, commit, result.stdout)); + return ViewUtils.showView(uri, new CommitDetailView(uri, commit, header.stdout, stashToMagitChanges(repository, commitHash, nameStatus.stdout, diffs.stdout))); } \ No newline at end of file diff --git a/src/models/magitChange.ts b/src/models/magitChange.ts index a8201ac..3977569 100644 --- a/src/models/magitChange.ts +++ b/src/models/magitChange.ts @@ -6,3 +6,7 @@ export interface MagitChange extends Change { diff?: string; relativePath?: string; } + +export interface ContextualMagitChange extends MagitChange { + contextId: string +} \ No newline at end of file