사용자 도구

사이트 도구


git:bisect

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

다음 판
이전 판
git:bisect [2023/12/07 12:08] – 만듦 taekgugit:bisect [2025/04/15 10:05] (현재) – 바깥 편집 127.0.0.1
줄 1: 줄 1:
 +====== git bisect ======
  
 +===== 개요 =====
 +
 +bisect 는 'divide into two parts', 즉 '양분하다' 라는 의미를 가지고 있습니다. 그래서 Python 의 배열 이진 분할 알고리즘 이름도 bisect 이죠.
 +
 +그러면 git bisect 는 어떤 명령어일까요?
 +
 +
 +https://git-scm.com/docs/git-bisect
 +
 +버그가 발생한 commit 을 찾는데 사용하면 된다고 합니다! 위의 문제 상황에 딱 좋은 방법이겠죠?
 +
 +사실 원리는 매우 간단합니다.
 +이름에서도 유추할 수 있듯, 단지 git 에서 commit 이진 탐색을 도와주는 것이죠.
 +1024 개의 commit 이 있어도 10번이면 버그가 발생한 commit 을 찾을 수 있습니다.
 +
 +하지만 이 명령어가 없이 직접 이진 탐색을 하는 것은 꽤 고달픈 일이기 때문에, 단순한 기능이지만 역할을 톡톡히 해냅니다.
 +
 +===== 사용 방법 =====
 +
 +일단 사용해봅시다.
 +
 +
 +
 +위와 같이 중간 어딘가의 commit 에 버그가 있는 상황입니다.
 +
 +git bisect 를 시작하면서, 어느 commit 부터 어느 commit 까지를 탐색할지 설정하면 자동으로 commit 을 옮겨다니면서 이진 탐색을 시작합니다.
 +
 +<code bash>
 +# git bisect 시작
 +$ git bisect start
 +
 +# 현재 commit 에 버그가 존재하므로 'bad' 로 지정
 +$ git bisect bad
 +
 +# 버그가 없는 commit 을 찾아봅시다
 +# 3.1.0 tag 가 붙어있는 commit 에는 버그가 있을까요?
 +$ git checkout 3.1.0
 +...
 +
 +# ... 아 저 commit 에는 아직 버그가 있네요.
 +# d1cd42ae6 commit 에도 버그가 있을까요?
 +$ git checkout d1cd42ae6
 +...
 +
 +# 버그가 없는 것을 확인했습니다!
 +# 그러면 이 commit 을 'good' 으로 지정합니다.
 +$ git bisect good
 +Bisecting: 5 revisions left to test after this (roughly 2 steps)
 +</code>
 +
 +<다음에 탐색할 commit 에 대한 내용..>
 +
 +
 +
 +이제 계속해서 해당 commit 에 버그가 있는지 없는지 찾아서 `good`/ `bad` 를 지정해나가면 어느 commit 이 문제인지 빠르게 확인할 수 있습니다.최종적으로 버그가 발생한 commit 을 찾게 되면 ` is the first bad commit` ( 는 해당 commit 의 sha) 라는 메시지를 출력해줍니다.
 +
 +<code bash>
 +$ git bisect bad
 +Bisecting: 2 revisions left to test after this (roughly 1 steps)
 +...
 +
 +$ git bisect good
 +Bisecting: 1 revisions left to test after this (roughly 0 steps)
 +...
 +
 +# 마지막 탐색 대상 commit
 +$ git bisect bad
 +11d51be3567c64120a44bc2ba6704af6e14e69cf is the first bad commit
 +...
 +
 +# git bisect 종료
 +$ git bisect reset
 +</code>
 +
 +결국 아래와 같은 과정을 거쳐 최초로 버그가 발생한 commit 을 찾게 되었습니다.
 +
 +commit 이 7개인 경우를 예로 들어서 그다지 드라마틱한 효과가 없어보이지만, 위에서도 언급했듯 1024 개의 commit 이 있어도 10번만에 최초로 버그가 발생한 commit 을 찾을 수 있습니다.
 +
 +===== 부가 기능 =====
 +
 +위의 기능만 있다면 좀 아쉽겠죠? git bisect 에서는 위와 같이 이진 탐색에 필수적인 기능 말고도 여러가지 부가 기능을 제공하고 있습니다.
 +
 +==== 내가 어디까지 했더라? ====
 +
 +
 +git bisect log 를 통해 git bisect 과정을 확인할 수 있습니다.
 +
 +<code bash>
 +$ git bisect log
 +git bisect start
 +# bad: [<commit sha>] <commit message>
 +git bisect bad <commit sha>
 +...
 +</code>
 +
 +==== 이 commit 은 확인할 수가 없는데.. ====
 +
 +
 +탐색을 하다가 버그가 있는지 없는지 확인할 수 없는 commit (ex. 그러면 안되지만 build 가 안되는 commit 이라든지) 이 걸린 경우에는 git bisect skip 으로 해당 commit 말고 다른 commit 으로 탐색을 계속 진행할 수 있습니다.
 +
 +<code bash>
 +$ git bisect skip
 +Bisecting: 2 revisions left to test after this (roughly 1 steps)
 +...
 +</code>
 +
 +==== bad/good 말고 다른건 안되나요? ====
 +
 +
 +버그를 찾을 때는 bad/good 이 맞지만, 만약 새로운 기능이 적용된 commit 을 찾고 싶다면 bad/good 이라는 표현 때문에 오히려 헷갈릴 수 있겠죠? 그래서 그대신 new/old 를 사용해도 되고,
 + 원한다면 시작할 때 --term-old <term-old> --term-new <term-new> 옵션을 통해 자신이 직업 용어를 정해서도 작업할 수 있습니다.
 +
 +<code bash>
 + $ git bisect start --term-old wow --term-new woo
 +</code>
 +
 +==== 앗, 잘못 선택했다 ====
 +
 +
 +현재 git bisect 에는 undo 기능이 없습니다😓 그 대신 git bisect log 와 git bisect replay 기능을 이용해서 다시 해당 단계까지 갈 수 있습니다.
 +
 +<code bash>
 +# bisect.log 에 log 저장
 +$ git bisect log > bisect.log
 +
 +# bisect.log 을 열어서 잘못된 부분 수정
 +...
 +
 +# 수정된 bisect.log 로 replay
 +$ git bisect replay bisect.log
 +</code>
 +
 +==== 자동으로 어떻게 안되나요? ====
 +
 +
 +git bisect run <command> 를 이용해서 자동화가 가능합니다. 예를 들어 뒤늦게 mvn test 가 실패하고 있는 것을 찾았을 때, 처음으로 mvn test 가 깨진 commit 을 찾고 싶다면?
 +
 +<code bash>
 +# bisect_test.sh
 +
 +#!/bin/sh
 +mvn test
 +
 +$ git bisect bisect_test.sh
 +</code>
 +
 +이렇게 하면 mvn test 의 결과에 따라 git bisect 의 진행이 자동으로 진행되어 매우 편리합니다.
 +
 +===== 마무리 =====
 +
 +이 기능을 알고만 있다가 실제로 예전에 발생한 버그를 뒤늦게 발견해서 '이 방법을 사용해볼까?' 하고 써봤더니 매우 빠르고 편하게 버그가 발생한 commit 을 찾을 수 있었습니다. (다 뒤져볼 생각하면 끔찍...)
 +
 +하지만 가장 좋은 것은 이런 기능을 사용할 일이 없는 것이 아닐까 싶기도 하네요