
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) }
}
아래와 같이 브랜치 이동 및 작업 디렉토리 초기화가 잘 이루어지는 모습을 볼 수 있다.
