Skip to content

Commit b168216

Browse files
authored
[FEAT] CSMDict 최신 → 과거 순서 정렬
[FEAT] CSMDict 최신 → 과거 순서 정렬
2 parents b9a661f + 22e3999 commit b168216

3 files changed

Lines changed: 50 additions & 39 deletions

File tree

packages/analysis-engine/src/csm.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ describe("csm", () => {
8484
expect(nonMergeCSMNodes.length).toBeGreaterThan(0);
8585

8686
// 0,1,4,5 commits have no-squash-commits
87-
const expectedNonMergeCommitIds = ["0", "1", "4", "5"];
87+
const expectedNonMergeCommitIds = ["5", "4", "1", "0"];
8888
const nonMergeCommitIds = nonMergeCSMNodes.map((csmNode) => csmNode.base.commit.id);
8989
nonMergeCommitIds.forEach((commitId) => {
9090
expect(expectedNonMergeCommitIds.includes(commitId)).toBe(true);
@@ -97,7 +97,7 @@ describe("csm", () => {
9797
expect(mergeCSMNodes.length).toBeGreaterThan(0);
9898

9999
// 2,3 commits have sqaush-commits
100-
const expectedMergeCommitIds = ["2", "3"];
100+
const expectedMergeCommitIds = ["3", "2"];
101101
const mergeCommitIds = mergeCSMNodes.map((csmNode) => csmNode.base.commit.id);
102102
mergeCommitIds.forEach((commitId) => {
103103
expect(expectedMergeCommitIds.includes(commitId)).toBe(true);
@@ -132,11 +132,11 @@ describe("csm", () => {
132132
});
133133

134134
it("has squash-commits", () => {
135-
const expectedBaseCommitIds = ["0", "1", "6", "7", "8", "9", "10", "11"];
135+
const expectedBaseCommitIds = ["11", "10", "9", "8", "7", "6", "1", "0"];
136136
expect(csmDict.sub1.map((node) => node.base.commit.id)).toEqual(expectedBaseCommitIds);
137137

138138
const mergeCommitNodes = csmDict.sub1.filter((node) => node.source.length);
139-
const expectedMergeCommitIds = ["8", "11"];
139+
const expectedMergeCommitIds = ["11", "8"];
140140
expect(mergeCommitNodes.map((node) => node.base.commit.id)).toEqual(expectedMergeCommitIds);
141141

142142
const expectedSquashCommitIds: Record<string, string[]> = {

packages/analysis-engine/src/csm.ts

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import { convertPRCommitsToCommitNodes, convertPRDetailToCommitRaw } from "./pullRequest";
22
import type { CommitDict, CommitNode, CSMDictionary, CSMNode, PullRequest, PullRequestDict, StemDict } from "./types";
33

4-
const buildCSMNode = (baseCommitNode: CommitNode, commitDict: CommitDict, stemDict: StemDict): CSMNode => {
4+
/**
5+
*
6+
* @param baseCommitNode merge-commit node
7+
* @param commitDict commit-node dictionary
8+
* @returns
9+
*/
10+
const buildCSMNode = (baseCommitNode: CommitNode, commitDict: CommitDict): CSMNode => {
511
const mergeParentCommit = commitDict.get(baseCommitNode.commit.parents[1]);
612
if (!mergeParentCommit) {
713
return {
@@ -10,46 +16,51 @@ const buildCSMNode = (baseCommitNode: CommitNode, commitDict: CommitDict, stemDi
1016
};
1117
}
1218

13-
const squashCommitNodes: CommitNode[] = [];
14-
15-
const squashTaskQueue: CommitNode[] = [mergeParentCommit];
16-
while (squashTaskQueue.length > 0) {
17-
// get target
18-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
19-
const squashStartNode = squashTaskQueue.shift()!;
19+
// 1. stop point: first-parent of baseCommitNode
20+
const baseAncestors = new Set<string>();
21+
const baseParentsQueue: CommitNode[] = [];
22+
const firstParent = commitDict.get(baseCommitNode.commit.parents[0]);
23+
if (firstParent) {
24+
baseParentsQueue.push(firstParent);
25+
}
2026

21-
// get target's stem
22-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
23-
const squashStemId = squashStartNode.stemId!;
24-
const squashStem = stemDict.get(squashStemId);
25-
if (!squashStem) {
27+
while (baseParentsQueue.length > 0) {
28+
const node = baseParentsQueue.shift();
29+
if (!node || baseAncestors.has(node.commit.id)) {
2630
continue;
2731
}
32+
baseAncestors.add(node.commit.id);
33+
for (const pId of node.commit.parents) {
34+
const parentNode = commitDict.get(pId);
35+
if (parentNode) {
36+
baseParentsQueue.push(parentNode);
37+
}
38+
}
39+
}
2840

29-
// prepare squash
30-
const squashStemLastIndex = squashStem.nodes.length - 1;
31-
const squashStartNodeIndex = squashStem.nodes.findIndex(({ commit: { id } }) => id === squashStartNode.commit.id);
32-
const spliceCount = squashStemLastIndex - squashStartNodeIndex + 1;
41+
// 2. find squash-commits by DFS
42+
const squashCommitNodes: CommitNode[] = [];
43+
const squashTaskStack: CommitNode[] = [mergeParentCommit];
44+
const visited = new Set<string>();
3345

34-
// squash
35-
const spliceCommitNodes = squashStem.nodes.splice(squashStartNodeIndex, spliceCount);
36-
squashCommitNodes.push(...spliceCommitNodes);
46+
while (squashTaskStack.length > 0) {
47+
const currentNode = squashTaskStack.pop()!; // LIFO
3748

38-
// check nested-merge
39-
const nestedMergeParentCommitIds = spliceCommitNodes
40-
.filter((node) => node.commit.parents.length > 1)
41-
.map((node) => node.commit.parents)
42-
.reduce((pCommitIds, parents) => [...pCommitIds, ...parents], []);
43-
const nestedMergeParentCommits = nestedMergeParentCommitIds
44-
.map((commitId) => commitDict.get(commitId))
45-
.filter((node): node is CommitNode => node !== undefined)
46-
.filter((node) => node.stemId !== baseCommitNode.stemId && node.stemId !== squashStemId);
49+
if (!currentNode || visited.has(currentNode.commit.id) || baseAncestors.has(currentNode.commit.id)) {
50+
continue;
51+
}
4752

48-
squashTaskQueue.push(...nestedMergeParentCommits);
53+
visited.add(currentNode.commit.id);
54+
squashCommitNodes.push(currentNode);
55+
// add parents to stack
56+
for (const parentId of currentNode.commit.parents) {
57+
const parentNode = commitDict.get(parentId);
58+
if (parentNode) {
59+
squashTaskStack.push(parentNode);
60+
}
61+
}
4962
}
5063

51-
squashCommitNodes.sort((a, b) => a.commit.sequence - b.commit.sequence);
52-
5364
return {
5465
base: baseCommitNode,
5566
source: squashCommitNodes,
@@ -101,9 +112,9 @@ export const buildCSMDict = (
101112
);
102113

103114
const csmDict: CSMDictionary = {};
104-
const stemNodes = masterStem.nodes.reverse(); // start on root-node
115+
const stemNodes = masterStem.nodes; // start on latest-node
105116
csmDict[baseBranchName] = stemNodes.map((commitNode) => {
106-
const csmNode = buildCSMNode(commitNode, commitDict, stemDict);
117+
const csmNode = buildCSMNode(commitNode, commitDict);
107118
const pr = prDictByMergedCommitSha.get(csmNode.base.commit.id);
108119
return pr ? buildCSMNodeWithPullRequest(csmNode, pr) : csmNode;
109120
});

packages/view/src/hooks/useAnalayzedData.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export const useAnalayzedData = () => {
1111

1212
const handleChangeAnalyzedData = (analyzedData: ClusterNode[]) => {
1313
setData(analyzedData);
14-
setFilteredData([...analyzedData.reverse()]);
14+
setFilteredData([...analyzedData]);
1515
setSelectedData([]);
1616
setLoading(false);
1717
};

0 commit comments

Comments
 (0)