[Git 만들어보기 - Geet] geet log 명령어로 커밋 기록 출력하기

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

Git 만들어보기 - Geet

목록 보기
10/21
post-thumbnail

2024-02-16 구현

log 명령어도 여러 옵션이 있지만 git 자체에 대해 학습을 하는 내용은 아니라서 그냥 기본 형식으로 출력하기로 함

git은 위와 같은 형식으로 기본적으로 출력함

이대로 구현을 해보려고 함

// geet/commands/procelain/geetLog.kt
package geet.commands.porcelain

import geet.exceptions.BadRequest
import geet.utils.commandutil.porcelainutil.getCommitObjectData
import geet.utils.commandutil.porcelainutil.getCurrentRefCommitHash

fun geetLog(commandLines: Array<String>): Unit {
    if (commandLines.size != 1) {
        throw BadRequest("log 명령어는 다른 옵션을 받지 않습니다.")
    }

    var commitHash = getCurrentRefCommitHash()
    while (true) {
        println("-------------------------------------")
        val commitObjectData = getCommitObjectData(commitHash)
        println("\u001B[32mcommit \u001B[0m${commitHash}")
        if (commitObjectData.parent != null) println("\u001B[34mMerge To: \u001B[0m${commitObjectData.parent}")
        println("\u001B[33mDate: \u001B[0m${commitObjectData.datetime}")
        println()
        println("\t${commitObjectData.message}")
        commitHash = commitObjectData.parent ?: break
    }
}

여기서 사용한 getCommitObjectData는 저장된 커밋 개체로부터 정보를 받아오는 기능을 한다.

받아오는 정보는 가리키는 트리 해시값, 부모 커밋 해시값, 생성 날짜, 커밋 메세지이다.

구현은 아래와 같다.

// geet/utils/commandutil/procelainutil/logUtil.kt
package geet.utils.commandutil.porcelainutil

import geet.utils.GEET_OBJECTS_DIR_PATH
import geet.utils.decompressFromZlib
import java.io.File
import java.time.LocalDateTime

data class CommitObjectData(  // 정보에 대한 데이터 클래스
    val tree: String,
    val parent: String?,
    val datetime: LocalDateTime,
    val message: String
)

fun getCommitObjectData(commitHash: String): CommitObjectData {
    val dirName = commitHash.substring(0, 2)
    val fileName = commitHash.substring(2)
    val file = File("${GEET_OBJECTS_DIR_PATH}/$dirName/$fileName")
    val content = decompressFromZlib(file.readText()).trim()

    val splitContent = content.split("\n")
    val tree = splitContent[0].split(" ")[1]
    var parent: String?
    var datetime: LocalDateTime
    var message: String

    if (splitContent[3] == "") {  // parent가 있다면 세 번째 줄이 공백줄
        parent = splitContent[1].split(" ")[1]
        datetime = LocalDateTime.parse(splitContent[2].split(" ")[1])
        message = splitContent.subList(4, splitContent.size).joinToString("\n")
    } else {  // parent가 없다면 두 번째 줄이 공백줄
        parent = null
        datetime = LocalDateTime.parse(splitContent[1].split(" ")[1])
        message = splitContent.subList(3, splitContent.size).joinToString("\n")
    }

    return CommitObjectData(tree, parent, datetime, message)
}

이렇게 구현하면 결과는 아래와 같이 나온다.

0개의 댓글