[Git 만들어보기 - Geet] geet merge 명령어 구현 도중 느낀 점

송준섭 Junseop Song·2024년 3월 18일

Git 만들어보기 - Geet

목록 보기
14/21
post-thumbnail

2024-02-26 ~ 2024-02-28 구현

merge 명령어는 브랜치와 브랜치를 병합하는 역할을 한다.

내가 구현할 것은 다음과 같다.

  • 브랜치 병합 병합 요청이 오면 현재 브랜치와 병합하고자 하는 브랜치를 비교하여 충돌 검사 충돌이 없다면 내용을 합쳐 새로운 tree를 만들고 새로운 커밋을 남긴다.
  • 충돌 발생한 경우 충돌이 발생한 경우 .geet/MERGE_HEAD 파일에 현재 브랜치 커밋, 병합하고자 하는 브랜치의 커밋, 충돌 파일 정보 등을 남긴다. MERGE_HEAD 파일이 존재하면 충돌이 존재한다는 뜻이고, 충돌이 해결되지 않는 이상 커밋되지 않는다. 충돌을 해결했다면 add 후 merge —continue로 진행하면 된다.
  • 병합 중지 충돌이 발생한 경우 병합을 취소하고 싶다면 merge —abort 명령어로 merge 명령어를 실행하기 전으로 돌아갈 수 있다.

일단 merge 명령어에 대한 옵션을 다음과 같이 얻어온다.

// geet/commands/porcelain/geetMerge.kt
package geet.commands.porcelain

import geet.exceptions.BadRequest
import geet.utils.commandutil.porcelainutil.merge

data class GeetMergeOptions(
    val branchName: String? = null,  // 브랜치 이름
    val option: String? = null  // --abort 또는 --continue
)

fun geetMerge(commandLines: Array<String>): Unit {
    val geetMergeOptions = getGeetMergeOptions(commandLines)
    merge(geetMergeOptions)
}

fun getGeetMergeOptions(commandLines: Array<String>): GeetMergeOptions {
    if (commandLines.size == 1) {
        throw BadRequest("병합할 브랜치 이름을 함께 입력하세요.")
    }

    if (commandLines.size > 3) {
        throw BadRequest("옵션을 잘못 입력하셨습니다.")
    }

    when (val command = commandLines[1]) {
        "--abort" -> return GeetMergeOptions(option = "abort")
        "--continue" -> return GeetMergeOptions(option = "continue")
        else -> return GeetMergeOptions(branchName = command)
    }
}

그리고 옵션에 대해 merge 명령어를 구현하는 도중 많은 문제점을 느꼈다.

  • 직접 명령어를 실행하며 테스트를 하는데 add 명령어 실행이 오래걸린 다는 점 → Object들이 많아질수록 objects 폴더 안에 개체들이 많아지는데 그걸 다 순회해서 그런 것 같음.. 손을 봐야함
  • merge 명령어는 두 브랜치의 커밋을 할 때 공통 부모 커밋을 찾고, 그 이후로 차이점을 계산하여 충돌을 확인함 → 이 과정이 생각보다 복잡하며 전략도 다양함,, 지금까지 내가 한 내용으로 뭔가 힘들 것 같다는 느낌을 받음
  • 파일 구조 및 코드 복잡함 → 어떤 함수가 어디있는지 직관적이지 않아서 매번 찾기 힘듦, 이제와서 리팩토링하기 힘들 것 같아 다시 시작하기로 마음 먹음

위와 같은 이유로 프로젝트를 처음부터 다시 시작하기로 마음 먹었다.

힘든 결정이었지만 내 정신 건강을 위해서, 그리고 다시 좀 더 완벽하게 구현하고 싶은 마음이 있어서 그렇게 하기로 했다..

0개의 댓글