Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix broken SCM tree #8048

Merged
merged 1 commit into from
Jun 23, 2020
Merged
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
22 changes: 13 additions & 9 deletions packages/scm/src/browser/scm-tree-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,19 +158,23 @@ export class ScmTreeModel extends TreeModelImpl {
expanded: true,
};

const sortedResources = group.resources.sort((r1, r2) =>
r1.sourceUri.toString().localeCompare(r2.sourceUri.toString())
);

switch (this._viewMode) {
case 'list':
groupNode.children = group.resources.map(fileChange => this.toFileChangeNode(fileChange, groupNode));
groupNode.children = sortedResources.map(resource => this.toFileChangeNode(resource, groupNode));
break;
case 'tree':
const rootUri = group.provider.rootUri;
if (rootUri) {
const resourcePaths = group.resources.map(resource => {
const resourcePaths = sortedResources.map(resource => {
const relativePath = new URI(rootUri).relative(resource.sourceUri);
const pathParts = relativePath ? relativePath.toString().split('/') : [];
return { resource, pathParts };
});
groupNode.children = this.buildFileChangeTree(resourcePaths, 0, group.resources.length, 0, groupNode);
groupNode.children = this.buildFileChangeTree(resourcePaths, 0, sortedResources.length, 0, groupNode);
}
break;
}
Expand All @@ -179,7 +183,7 @@ export class ScmTreeModel extends TreeModelImpl {
}

protected buildFileChangeTree(
resources: { resource: ScmResource, pathParts: string[] }[],
sortedResources: { resource: ScmResource, pathParts: string[] }[],
start: number,
end: number,
level: number,
Expand All @@ -189,14 +193,14 @@ export class ScmTreeModel extends TreeModelImpl {

let folderStart = start;
while (folderStart < end) {
const firstFileChange = resources[folderStart];
const firstFileChange = sortedResources[folderStart];
if (level === firstFileChange.pathParts.length - 1) {
result.push(this.toFileChangeNode(firstFileChange.resource, parent));
folderStart++;
} else {
let index = folderStart + 1;
while (index < end) {
if (resources[index].pathParts[level] !== firstFileChange.pathParts[level]) {
if (sortedResources[index].pathParts[level] !== firstFileChange.pathParts[level]) {
break;
}
index++;
Expand All @@ -207,19 +211,19 @@ export class ScmTreeModel extends TreeModelImpl {
if (folderEnd - folderStart < nestingThreshold) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me, the name "nestingThreshold" seems to indicate the depth of the tree. I don't see how the difference between two different indices in the list of resources is related to that. Shouldn't this expression involve the level somehow?

// Inline these (i.e. do not create another level in the tree)
for (let i = folderStart; i < folderEnd; i++) {
result.push(this.toFileChangeNode(resources[i].resource, parent));
result.push(this.toFileChangeNode(sortedResources[i].resource, parent));
}
} else {
const firstFileParts = firstFileChange.pathParts;
const lastFileParts = resources[folderEnd - 1].pathParts;
const lastFileParts = sortedResources[folderEnd - 1].pathParts;
// Multiple files with first folder.
// See if more folder levels match and include those if so.
let thisLevel = level + 1;
while (thisLevel < firstFileParts.length - 1 && thisLevel < lastFileParts.length - 1 && firstFileParts[thisLevel] === lastFileParts[thisLevel]) {
thisLevel++;
}
const nodeRelativePath = firstFileParts.slice(level, thisLevel).join('/');
result.push(this.toFileChangeFolderNode(resources, folderStart, folderEnd, thisLevel, nodeRelativePath, parent));
result.push(this.toFileChangeFolderNode(sortedResources, folderStart, folderEnd, thisLevel, nodeRelativePath, parent));
}
folderStart = folderEnd;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can get rid of result.sort(...) if we keep separate result arrays for file nodes and folder nodes and concatenate them at the end. With your change, the list of resources is already sorted and as far as I can see, the sorting will be correct under the algorithm.

Expand Down