mirror of
https://github.com/Microsoft/vscode
synced 2024-10-02 09:18:59 +00:00
Git - fix viewing stahes with added/deleted/renamed files (#203341)
This commit is contained in:
parent
25af41dbb5
commit
97b8727343
|
@ -3708,19 +3708,26 @@ export class CommandCenter {
|
|||
return;
|
||||
}
|
||||
|
||||
const stashFiles = await repository.showStash(stash.index);
|
||||
const stashChanges = await repository.showStash(stash.index);
|
||||
|
||||
if (!stashFiles || stashFiles.length === 0) {
|
||||
if (!stashChanges || stashChanges.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const title = `Git Stash #${stash.index}: ${stash.description}`;
|
||||
const multiDiffSourceUri = toGitUri(Uri.file(repository.root), `stash@{${stash.index}}`, { scheme: 'git-stash' });
|
||||
|
||||
const resources: { originalUri: Uri; modifiedUri: Uri }[] = [];
|
||||
for (const file of stashFiles) {
|
||||
const fileUri = Uri.file(path.join(repository.root, file));
|
||||
resources.push({ originalUri: fileUri, modifiedUri: toGitUri(fileUri, `stash@{${stash.index}}`) });
|
||||
const resources: { originalUri: Uri | undefined; modifiedUri: Uri | undefined }[] = [];
|
||||
for (const change of stashChanges) {
|
||||
if (change.status === Status.INDEX_ADDED) {
|
||||
resources.push({ originalUri: undefined, modifiedUri: toGitUri(change.uri, `stash@{${stash.index}}`) });
|
||||
} else if (change.status === Status.DELETED) {
|
||||
resources.push({ originalUri: change.uri, modifiedUri: undefined });
|
||||
} else if (change.status === Status.INDEX_RENAMED) {
|
||||
resources.push({ originalUri: change.originalUri, modifiedUri: toGitUri(change.uri, `stash@{${stash.index}}`) });
|
||||
} else {
|
||||
resources.push({ originalUri: change.uri, modifiedUri: toGitUri(change.uri, `stash@{${stash.index}}`) });
|
||||
}
|
||||
}
|
||||
|
||||
commands.executeCommand('_workbench.openMultiDiffEditor', { multiDiffSourceUri, title, resources });
|
||||
|
|
|
@ -997,6 +997,70 @@ function parseGitStashes(raw: string): Stash[] {
|
|||
return result;
|
||||
}
|
||||
|
||||
// TODO@lszomoru - adopt in diffFiles()
|
||||
function parseGitChanges(repositoryRoot: string, raw: string): Change[] {
|
||||
let index = 0;
|
||||
const result: Change[] = [];
|
||||
const segments = raw.trim()
|
||||
.split('\x00')
|
||||
.filter(s => s);
|
||||
|
||||
segmentsLoop:
|
||||
while (index < segments.length - 1) {
|
||||
const change = segments[index++];
|
||||
const resourcePath = segments[index++];
|
||||
|
||||
if (!change || !resourcePath) {
|
||||
break;
|
||||
}
|
||||
|
||||
const originalUri = Uri.file(path.isAbsolute(resourcePath) ? resourcePath : path.join(repositoryRoot, resourcePath));
|
||||
|
||||
let uri = originalUri;
|
||||
let renameUri = originalUri;
|
||||
let status = Status.UNTRACKED;
|
||||
|
||||
// Copy or Rename status comes with a number (ex: 'R100').
|
||||
// We don't need the number, we use only first character of the status.
|
||||
switch (change[0]) {
|
||||
case 'A':
|
||||
status = Status.INDEX_ADDED;
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
status = Status.MODIFIED;
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
status = Status.DELETED;
|
||||
break;
|
||||
|
||||
// Rename contains two paths, the second one is what the file is renamed/copied to.
|
||||
case 'R': {
|
||||
if (index >= segments.length) {
|
||||
break;
|
||||
}
|
||||
|
||||
const newPath = segments[index++];
|
||||
if (!newPath) {
|
||||
break;
|
||||
}
|
||||
|
||||
status = Status.INDEX_RENAMED;
|
||||
uri = renameUri = Uri.file(path.isAbsolute(newPath) ? newPath : path.join(repositoryRoot, newPath));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// Unknown status
|
||||
break segmentsLoop;
|
||||
}
|
||||
|
||||
result.push({ status, uri, originalUri, renameUri });
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export interface PullOptions {
|
||||
unshallow?: boolean;
|
||||
tags?: boolean;
|
||||
|
@ -2147,15 +2211,16 @@ export class Repository {
|
|||
}
|
||||
}
|
||||
|
||||
async showStash(index: number): Promise<string[] | undefined> {
|
||||
const args = ['stash', 'show', `stash@{${index}}`, '--name-only'];
|
||||
async showStash(index: number): Promise<Change[] | undefined> {
|
||||
const args = ['stash', 'show', `stash@{${index}}`, '--name-status', '-z'];
|
||||
|
||||
try {
|
||||
const result = await this.exec(args);
|
||||
if (result.exitCode) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return result.stdout.trim()
|
||||
.split('\n')
|
||||
.filter(line => !!line);
|
||||
return parseGitChanges(this.repositoryRoot, result.stdout.trim());
|
||||
} catch (err) {
|
||||
if (/No stash found/.test(err.stderr || '')) {
|
||||
return undefined;
|
||||
|
|
|
@ -1995,7 +1995,7 @@ export class Repository implements Disposable {
|
|||
return await this.run(Operation.Stash, () => this.repository.applyStash(index));
|
||||
}
|
||||
|
||||
async showStash(index: number): Promise<string[] | undefined> {
|
||||
async showStash(index: number): Promise<Change[] | undefined> {
|
||||
return await this.run(Operation.Stash, () => this.repository.showStash(index));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue