yoongrammer

git 디버깅 하기 (blame, bisect) 본문

VCS (Version Control System)/git

git 디버깅 하기 (blame, bisect)

yoongrammer 2020. 11. 21. 15:53
728x90

목차

    git 디버깅 하기 (blame, bisect)


    Git에는 버전 관리 기능 말고도 디버깅용 명령어도 있습니다. 누가 버그를 만들었는지 언제 어디서 생겼는지 찾아내는 데 도움이 됩니다.

    git brame


    git blame은 파일의 각 라인을 누가 마지막으로 수정했는지 보여줍니다.

    $ git blame <file>

    -L 옵션을 사용하여 전체 파일이 아닌 원하는 라인 범위를 정할 수 있습니다.

    $ git blame -L 3,10 main.go
    ^608a065 (yoongrammer 2020-11-21 12:02:45 +0900  3) import "fmt"
    ^608a065 (yoongrammer 2020-11-21 12:02:45 +0900  4)
    af64134b (Tom         2020-11-21 12:06:08 +0900  5) func displayHello(str string) {
    af64134b (Tom         2020-11-21 12:06:08 +0900  6)     fmt.Println("Hello ", str)
    af64134b (Tom         2020-11-21 12:06:08 +0900  7) }
    af64134b (Tom         2020-11-21 12:06:08 +0900  8)
    ^608a065 (yoongrammer 2020-11-21 12:02:45 +0900  9) func main() {
    af64134b (Tom         2020-11-21 12:06:08 +0900 10)     displayHello("yoongrammer")

    main.go 파일을 3라인에서 9라인까지 blame 명령으로 출력한 결과입니다.

     

    첫 번째 항목은 그 라인을 마지막으로 수정한 커밋 SHA-1 값이고 두 번째 항목은 누가, 언제 그 라인을 커밋했는지 보여줍니다. 그 뒤에는 파일 라인 번호와 내용을 보여줍니다.

     

    ^608a065 값에 ^표시는 해당 라인에서 처음 커밋이 후 변경된 적이 없다는 의미입니다.

    git bisect


    git bisect은 이진 탐색 알고리즘을 사용해서 버그나 문제가 생긴 커밋을 찾아줍니다.

     

    사용 예를 보면서 사용방법을 익혀보도록 하겠습니다.

    출력이 원하는 결과가 아니라서 문제 커밋이 어느 것인지 git bisect을 사용하여 찾아보도록 하겠습니다.

     

    커밋 로그를 확인하면 아래와 같습니다.

    $ git log --pretty=oneline
    0c768c06620532bfd9f1ba97a10b4b111d1d3e6d (HEAD -> master) add START msg
    d743d6b5b047306b275311eefa15b3aa8380fb31 add END msg
    53811253a9e5fb06db281b4f7fb5f0c8af439008 change fmt.Println -> fmt.Print
    af64134b1459da2810d56414c4b981146d212a99 add displayHello func
    608a0655a6c8f0a5cccb2aa678414d8ff8673357 (tag: v1.0) add main.go

    tag v1.0 커밋은 문제가 없다고 가정하겠습니다.

     

    1. git bisect start 명령으로 이진 탐색을 시작합니다.

    $ git bisect start

     

    2. git bisect bad 명령으로 현재 커밋 부분에 문제가 있다고 표시를 합니다.

    $ git bisect bad

    현재 커밋 위치에 bad 브랜치가 생긴 것을 확인할 수 있습니다.

    $ git log --pretty=oneline
    0c768c06620532bfd9f1ba97a10b4b111d1d3e6d (HEAD -> master, refs/bisect/bad) add START msg
    d743d6b5b047306b275311eefa15b3aa8380fb31 add END msg
    53811253a9e5fb06db281b4f7fb5f0c8af439008 change fmt.Println -> fmt.Print
    af64134b1459da2810d56414c4b981146d212a99 add displayHello func
    608a0655a6c8f0a5cccb2aa678414d8ff8673357 (tag: v1.0) add main.go

    3. v1.0 tag에는 문제가 없기 때문에 git bisect good <커밋 해시값> 명령으로 문제가 없다고 표시합니다. 

    (커밋 해시값으로 tag 값(v1.0)을 사용했지만 해시값(608a0)을 사용해도 됩니다.)

    $ git bisect good v1.0
    Bisecting: 1 revision left to test after this (roughly 1 step)
    [53811253a9e5fb06db281b4f7fb5f0c8af439008] change fmt.Println -> fmt.Print

    bad(0c768)good(608a0) 사이에 커밋은 전부 3개(d743d, 53811, af641)이고 git은 이진 검색으로 인해 그 중간 커밋(53811)으로 checkout 해줍니다.

    $ git log --pretty=oneline
    53811253a9e5fb06db281b4f7fb5f0c8af439008 (HEAD) change fmt.Println -> fmt.Print
    af64134b1459da2810d56414c4b981146d212a99 add displayHello func
    608a0655a6c8f0a5cccb2aa678414d8ff8673357 (tag: v1.0, refs/bisect/good-608a0655a6c8f0a5cccb2aa678414d8ff8673357) add main.go

    HEAD에 위치가 53811 커밋으로 checkout 된 것을 확인할 수 있습니다.

     

    현재 커밋에서 테스트를 해보고 문제가 없다면 git bisect good 문제가 있다면 git bisect bad를 반복하여 HEAD위치를 이동시켜 점점 범위를 줄여가며 문제 커밋을 찾으면 됩니다. 

     

    4. 현재 커밋에서 문제가 있었기 때문에 bad로 표시해줍니다.

    $ git bisect bad
    Bisecting: 0 revisions left to test after this (roughly 0 steps)
    [af64134b1459da2810d56414c4b981146d212a99] add displayHello func

    bad(53811) 위치와 good(608a0) 위치 사이는 af641이기 때문에 HEAD 위치가 af641 커밋으로 checkout 된 것을 확인할 수 있습니다.

    $ git log --pretty=oneline
    af64134b1459da2810d56414c4b981146d212a99 (HEAD) add displayHello func
    608a0655a6c8f0a5cccb2aa678414d8ff8673357 (tag: v1.0, refs/bisect/good-608a0655a6c8f0a5cccb2aa678414d8ff8673357) add main.go

     

    5. 테스트 결과 현재 커밋에서는 문제가 없기 때문에 good으로 표시해 줍니다.

    $ git bisect good
    53811253a9e5fb06db281b4f7fb5f0c8af439008 is the first bad commit
    commit 53811253a9e5fb06db281b4f7fb5f0c8af439008
    Author: Tom <Tom@example.com>
    Date:   Sat Nov 21 12:20:29 2020 +0900
    
        change fmt.Println -> fmt.Print
    
    :100644 100644 db5bd75d635df2df4365c30bf672845a0f607e04 90c7cc25506487629f246c711b1c6dc4151e00b9 M	main.go

    문제 커밋(53811)을 찾으면 위와 같이 출력이 됩니다.

     

    6. 문제 커밋을 찾았으니까 git bisect reset 명령을 실행시켜서 이진 탐색을 시작하기 전으로 HEAD를 돌려놓습니다.

    $ git bisect reset
    Previous HEAD position was af64134 add displayHello func
    Switched to branch 'master'
    $ git log --pretty=oneline
    0c768c06620532bfd9f1ba97a10b4b111d1d3e6d (HEAD -> master) add START msg
    d743d6b5b047306b275311eefa15b3aa8380fb31 add END msg
    53811253a9e5fb06db281b4f7fb5f0c8af439008 change fmt.Println -> fmt.Print
    af64134b1459da2810d56414c4b981146d212a99 add displayHello func
    608a0655a6c8f0a5cccb2aa678414d8ff8673357 (tag: v1.0) add main.go

    git bisect 명령을 사용하면 쉽게 문제가 발생한 커밋을 찾을 수 있습니다.

     

    요약하면 아래와 같습니다.

    1. git bisect start 로 이진탐색을 시작합니다.

    2. git bisect goodgit bisect bad 를 반복하여 문제 커밋을 찾을 때까지 반복합니다.

    3. 문제 커밋을 찾았다면 git bisect reset을 합니다.

    728x90

    'VCS (Version Control System) > git' 카테고리의 다른 글

    git Meld, p4merge 사용하기  (0) 2020.11.30
    git diff 사용하기  (0) 2020.11.29
    git rebase 와 cherry-pick 알아보기  (0) 2020.11.20
    git remote 저장소  (0) 2020.11.19
    git 브랜치(branch) 란?  (0) 2020.11.18
    Comments