[Git 만들어보기 - Geet] geet switch 명령어로 브랜치 이동하기

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

Git 만들어보기 - Geet

목록 보기
12/21
post-thumbnail

2024-02-19 구현

switch 명령어는 브랜치를 이동하는 역할을 한다.

-c 옵션과 함께 사용하면 브랜치를 생성하면서 이동할 수 있다.

// geet/commands/porcelain/geetSwitch.kt
package geet.commands.porcelain

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

data class GeetSwitchOptions(
    val branchName: String,
    val create: Boolean,
)

fun geetSwitch(commandLines: Array<String>) {
    var geetSwitchOptions: GeetSwitchOptions
    if (commandLines.size == 2) {  // switch <브랜치 이름> 만 입력한 경우
        geetSwitchOptions = GeetSwitchOptions(commandLines[1], false)
    } else if (commandLines.size == 3 && commandLines[1] == "-c") {  // switch -c <브랜치 이름> 를 입력한 경우
        geetSwitchOptions = GeetSwitchOptions(commandLines[2], true)
    } else throw BadRequest("switch 명령어에 대한 옵션이 잘못되었습니다.: ${commandLines.joinToString(" ")}")  // 그 외 에러

    switch(geetSwitchOptions)
}
// geet/utils/commandutil/porcelainutil/switchUtil.kt
package geet.utils.commandutil.porcelainutil

import geet.commands.porcelain.GeetSwitchOptions
import geet.exceptions.NotFound
import geet.objects.GeetBlob
import geet.utils.GEET_HEAD_FILE_PATH
import geet.utils.getObjectsFromCommit
import geet.utils.indexManager
import java.io.File

fun switch(geetSwitchOptions: GeetSwitchOptions) {
    if (geetSwitchOptions.create) {  // 생성 옵션이 들어가 있다면
        createBranch(geetSwitchOptions.branchName)
    }
    changeBranch(geetSwitchOptions.branchName)  // 브랜치 변경
}

fun changeBranch(branchName: String) {
    val headFile = File(GEET_HEAD_FILE_PATH)
    if (!headFile.exists()) {  // 헤드 파일이 존재하지 않으면 에러
        throw NotFound("HEAD 파일을 찾을 수 없습니다.\ninit 명령어를 통해 저장소를 초기화하세요.")
    }

    val branchFile = File(".geet/refs/heads/$branchName")
    if (!branchFile.exists()) {  // 해당 브랜치 파일이 없다면 에러
        throw NotFound("브랜치를 찾을 수 없습니다. : ${branchName}")
    }

    headFile.writeText("ref: refs/heads/$branchName")  // 헤드 파일 수정
    val branchCommitHash = getCurrentRefCommitHash()  // 옮긴 브랜치의 커밋 해시값 가져오기
    indexManager.getIndexFileData().lastCommitHash = branchCommitHash  // 인덱스의 마지막 커밋 해시 정보 수정
    indexManager.writeIndexFile()

    val branchObjects = getObjectsFromCommit(branchCommitHash)  // 브랜치 커밋 해시에 대한 파일들 복원
    clearWorkingDirectory()
    branchObjects.forEach { restoreObject(it as GeetBlob) }
}

아래와 같이 브랜치 이동 및 작업 디렉토리 초기화가 잘 이루어지는 모습을 볼 수 있다.

0개의 댓글