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

feat(engine): Implement STEM #91

Merged
merged 7 commits into from
Sep 8, 2022
Merged

feat(engine): Implement STEM #91

merged 7 commits into from
Sep 8, 2022

Conversation

ooooorobo
Copy link
Contributor

@ooooorobo ooooorobo commented Sep 6, 2022

#73 의 리뷰를 반영한 PR입니다.
closed #25

설명

(아래 내용은 토요일에 @anpaul0615 님께서 같이 고민해 주셨던 내용입니다. 감사합니다 👍 )

용어

  • leaf node: 그래프의 leaf node에 해당하는 커밋 노드. branches.length > 0 이다.
  • head / tail node: stem의 노드 리스트에서 가장 앞에 위치하는 노드(head)와 가장 뒤에 위치하는 노드(tail)
  • sub branches: main/master 브랜치가 아닌 브랜치

STEM 생성 알고리즘

단일 브랜치에 포함되어 있는 커밋을 모아 STEM을 만듭니다.

  1. 커밋 그래프에서, leaf 노드부터 순회를 시작합니다.
    1. main/master 브랜치 커밋 노드 enqueue
    2. (HEAD를 제외한) sub 브랜치 커밋 노드 enqueue
    3. HEAD 브랜치 커밋 노드 enqueue
  2. dequeue 된 커밋 노드부터 새로운 STEM을 만듭니다.
    1. 순회한 노드는 Stem의 node 리스트에 넣습니다.
    2. parent 노드 방향으로 순회를 진행합니다.
      1. parents.length > 1 이라면, index > 0인 parent 노드들을 큐에 넣습니다.
      2. parents.length === 0 이라면, 루트 노드에 도착한 것이므로 순회를 종료합니다.
      3. parents[0].stemId !== undefined라면, 이미 순회한 노드이므로 순회를 종료합니다.
  3. 큐가 빌 때까지 2번을 반복합니다.

큐 정렬 우선순위

큐에 들어간 커밋 노드의 우선순위입니다. 큐에 enqueue가 발생할 때마다 아래 우선순위를 따라 정렬됩니다. 우선순위가 높을수록 큐의 앞에 위치합니다.

  1. main/master 브랜치 커밋
  2. HEAD가 아닌 sub 브랜치 커밋들
  3. HEAD 커밋
  4. branches.length === 0인 커밋들
    1. 나중에 커밋된 것이 우선순위가 높음

Stem ID 결정

  • tail node가 브랜치를 가지고 있다면, 그 브랜치의 이름
  • tail node가 브랜치를 가지고 있지 않다면, implicit-{numbering}

그림 보충 설명

image

  • 8번 노드

buildStem 호출 시, 6번 노드부터 순회를 시작합니다. 그러면 큐에는 10번, 8번이 담기게 됩니다.
그런데 만약 10번이 아니라 8번부터 순회를 시작한다면, 8번 노드가 만드는 Stem은 [8]이 되고, 10번 노드가 만드는 Stem은 [9, 10]이 됩니다.
올바른 Stem은 [8, 9, 10]이 되어야 합니다. 따라서 10번이 8번보다 앞에 위치해야 하므로, 커밋된 시간이 더 늦은 노드가 우선순위가 높습니다.

  • 9’

9’ 노드는 9번 노드의 체리픽 노드입니다. 따라서 authorDate와 CommitterDate이 다릅니다.
authorDate는 9번 노드와 같은 값을, CommitterDate는 cherry-pick을 수행한 시간을 가집니다.
따라서 커밋 노드를 정렬할 때 CommitterDate를 기준으로 정렬해야 합니다.

  • 16

16번은 HEAD가 가리키는 브랜치입니다. 그리고 15번은

  1. 9’번을 커밋한 시점에서,
  2. 13번 커밋에 checkout한 다음,
  3. 10번 커밋을 merge한 상황입니다.

이런 상황에서, 다른 브랜치의 커밋 노드보다 HEAD 브랜치의 노드인 16번부터 순회를 시작한다면, [11, 12, 13, 15 ,16] Stem이 생성되고, Dev 브랜치의 Stem은 [14, 9’]로 만들어집니다.
따라서 main/master/sub 브랜치의 Stem이 모두 생성된 다음, HEAD Stem을 만들고, implicit 브랜치의 Stem을 만들어야 합니다.

@ooooorobo ooooorobo self-assigned this Sep 6, 2022
@ooooorobo ooooorobo requested a review from a team as a code owner September 6, 2022 15:13
Copy link
Contributor

@hy57in hy57in left a comment

Choose a reason for hiding this comment

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

선 어프룹 후 리뷰 드립니당


type CommitDict = Map<string, CommitNode>;

export function generateCommitNodeDict(commits: CommitRaw[]): CommitDict {
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

commits = dummy.map(createTestCommit);
commitDict = generateCommitNodeDict(commits);
});

it("temp test", () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

test desc를 변경해도 괜찮을 것 같습니다.

q: Queue<CommitNode>,
stemId: string
): CommitNode[] {
let now = commitDict.get(tailId);
Copy link
Contributor

Choose a reason for hiding this comment

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

제가 잘 모르는 것일수도 있겠습니다. type이 자동으로 고정이 되나요?

후행하는 라인에 now = 3;과 같은 부분이 가능하지 않을까 해서,
let now: CommitNode = commitDict.get(tailId);가 필요하지 않을까 합니다.
만약에 type 고정이 된다면 상단의 처리는 필요 없을 것 같습니다~

Copy link
Contributor Author

Choose a reason for hiding this comment

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

CommitNode | undefined로 고정되어서, now = 3; 같은 할당을 시도하면 타입 에러가 발생하네요!
commitDict.get의 return type으로 고정된 것 같아요

return nodes;
}

function compareCommitPriority(a: CommitNode, b: CommitNode): number {
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

Copy link
Contributor

@ansrlm ansrlm left a comment

Choose a reason for hiding this comment

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

LGTM~! 고생하셨습니다.

@ooooorobo ooooorobo merged commit e215305 into githru:main Sep 8, 2022
@ooooorobo ooooorobo deleted the stem branch September 8, 2022 10:50
@hanseul-lee hanseul-lee added this to the v0.1.0 milestone Sep 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[engine] STEM 구현
4 participants