나는 그것이 git bisect
굉장 하다는 기사를 읽었습니다 . 그러나 나는 원어민이 아니며 왜 멋진 지 이해할 수 없습니다.
누군가 코드 샘플로 시연 할 수 있습니까?
- 사용 방법?
- 그냥 같은
svn blame
가요?
나는 그것이 git bisect
굉장 하다는 기사를 읽었습니다 . 그러나 나는 원어민이 아니며 왜 멋진 지 이해할 수 없습니다.
누군가 코드 샘플로 시연 할 수 있습니까?
svn blame
가요?답변:
아이디어 git bisect
는 히스토리에서 이진 검색을 수행하여 특정 회귀를 찾는 것입니다. 다음과 같은 개발 기록이 있다고 상상해보십시오.
... --- 0 --- 1 --- 2 --- 3 --- 4* --- 5 --- current
프로그램이 current
개정판 에서 제대로 작동하지 않고 개정판 에서 작동하고 있음을 알고 있습니다 0
. 회귀가 가능성이 커밋 중 하나에 도입 그래서 1
, 2
, 3
, 4
, 5
, current
.
각 커밋을 확인하고 빌드하고 회귀가 있는지 확인하십시오. 커밋이 많은 경우 시간이 오래 걸릴 수 있습니다. 이것은 선형 검색입니다. 이진 검색을 수행하면 더 잘할 수 있습니다. 이것이 git bisect
명령이하는 일입니다. 각 단계에서 잠재적으로 불량한 개정 수를 절반으로 줄입니다.
다음과 같은 명령을 사용합니다.
$ git stash save
$ git bisect start
$ git bisect bad
$ git bisect good 0
Bisecting: 2 revisions left to test after this (roughly 2 steps)
[< ... sha ... >] 3
이 명령 후에 git
커밋을 체크 아웃합니다. 우리의 경우에는 commit 3
입니다. 프로그램을 작성하고 회귀가 있는지 확인해야합니다. 또한 회귀가 존재하거나 존재 하지 않는 git
경우이 개정의 상태 를 알려야 합니다 .git bisect bad
git bisect good
회귀가 commit에 도입되었다고 가정 해 봅시다 4
. 그런 다음이 개정판에는 회귀 분석이 없으며이를 회귀합니다 git
.
$ make
$ make test
... ... ...
$ git bisect good
Bisecting: 0 revisions left to test after this (roughly 1 step)
[< ... sha ... >] 5
그런 다음 다른 커밋을 체크 아웃합니다. 하나 4
또는 5
(두 커밋 있기 때문에). 그것이 고른다 고 가정 해 봅시다 5
. 빌드 후 우리는 프로그램을 테스트하고 회귀가 존재하는지 확인합니다. 그런 다음에 알려주세요 git
.
$ make
$ make test
... ... ...
$ git bisect bad
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[< ... sha ... >] 4
마지막 개정판을 테스트합니다 4
. 회귀를 도입 한 것이기 때문에 다음과 같이 말합니다 git
.
$ make
$ make test
... ... ...
$ git bisect bad
< ... sha ... > is the first bad commit
< ... commit message ... >
이 간단한 상황에서, 우리는 시험에 3 버전을했다 ( 3
, 4
, 5
) 대신 4 ( 1
, 2
, 3
, 4
). 이것은 작은 승리이지만 우리의 역사가 너무 작기 때문입니다. 검색 범위가 N 커밋 인 git bisect
경우 선형 검색 을 사용하여 대략 N / 2 커밋 대신 1 + log2 N 커밋을 테스트해야합니다 .
회귀를 도입 한 커밋을 발견하면 문제를 찾기 위해이를 연구 할 수 있습니다. 이 작업이 완료되면 명령 git bisect reset
을 사용하기 전에 모든 것을 원래 상태로 되돌릴 수 있습니다 git bisect
.
git bisect bad <rev> [<rev>...]
특정 개정을 불량 (또는 양호 git bisect good <rev> [<rev>...]
) 으로 표시 하는 데 사용할 수 있습니다 . rev
모든 수정 지점 이름 같은 식별자, 태그, 커밋 해시 (또는 고유 접두어 커밋 해시), ... 일 수있다
git bisect reset
은 최근 커밋에 모든 것을 다시 넣어 입력 합니다
git bisect run
자동 이등분./test
종료 상태가 0 인 자동화 된 스크립트 가있는 경우 테스트가 정상이면 다음을 통해 버그를 자동으로 찾을 수 있습니다 bisect run
.
git checkout KNOWN_BAD_COMMIT
git bisect start
# Confirm that our test script is correct, and fails on the bad commit.
./test
# Should output != 0.
echo $?
# Tell Git that the current commit is bad.
git bisect bad
# Same for a known good commit in the past.
git checkout KNOWN_GOOD_COMMIT
./test
# Should output 0.
echo $?
# After this, git automatically checks out to the commit
# in the middle of KNOWN_BAD_COMMIT and KNOWN_GOOD_COMMIT.
git bisect good
# Bisect automatically all the way to the first bad or last good rev.
git bisect run ./test
# End the bisect operation and checkout to master again.
git bisect reset
이것은 물론 테스트 스크립트 ./test
가 git track되면, bisection 동안 이전 커밋에서 사라지지 않는다고 가정합니다.
인 트리 스크립트를 트리에서 복사하고 PATH
비슷한 변수로 재생하고 대신 거기에서 실행하면 매우 자주 벗어날 수 있습니다 .
물론, 테스트 인프라가 test
이전 커밋에 영향을 미치는 경우 솔루션이 없으므로 커밋을 하나씩 테스트하는 방법을 결정하여 수동으로 작업을 수행해야합니다.
그러나이 자동화를 사용하면 종종 작동하며 작업 백 로그에 누워있는 느린 테스트의 경우 시간을 절약 할 수 있다는 것을 알았습니다. 시도.
bisect 후 다음으로 돌아 가지 않고 첫 번째 실패 커밋을 유지하십시오 master
.
git bisect reset HEAD
start
+ 이니셜 bad
과 good
한 번에 :
git bisect start KNOWN_BAD_COMMIT KNOWN_GOOD_COMMIT~
와 같다:
git checkout KNOWN_BAD_COMMIT
git bisect start
git bisect bad
git bisect good KNOWN_GOOD_COMMIT
지금까지 테스트 한 내용을 참조하십시오 (수동 good
및 bad
또는 run
).
git bisect log
샘플 출력 :
git bisect log
git bisect start
# bad: [00b9fcdbe7e7d2579f212b51342f4d605e53253d] 9
git bisect bad 00b9fcdbe7e7d2579f212b51342f4d605e53253d
# good: [db7ec3d602db2d994fe981c0da55b7b85ca62566] 0
git bisect good db7ec3d602db2d994fe981c0da55b7b85ca62566
# good: [2461cd8ce8d3d1367ddb036c8f715c7b896397a5] 4
git bisect good 2461cd8ce8d3d1367ddb036c8f715c7b896397a5
# good: [8fbab5a3b44fd469a2da3830dac5c4c1358a87a0] 6
git bisect good 8fbab5a3b44fd469a2da3830dac5c4c1358a87a0
# bad: [dd2c05e71c246f9bcbd2fbe81deabf826c54be23] 8
git bisect bad dd2c05e71c246f9bcbd2fbe81deabf826c54be23
# bad: [c536b1b7242d5fcf92cd87e9a534bedb1c0c9c05] 7
git bisect bad c536b1b7242d5fcf92cd87e9a534bedb1c0c9c05
# first bad commit: [c536b1b7242d5fcf92cd87e9a534bedb1c0c9c0
더 나은 시간 개념을 얻으려면 git log에 좋고 나쁜 참조를 표시하십시오.
git log --decorate --pretty=fuller --simplify-by-decoration master
이것은 해당 참조를 가진 커밋 만 보여 주어 노이즈 그리스를 줄이지 만 자동 생성 된 참조 유형은 포함합니다 :
refs/bisect/good*
refs/bisect/bad*
어느 커밋이 좋거나 나쁘다고 표시되었는지 알려줍니다.
명령을 가지고 놀고 싶다면 이 테스트 저장소를 고려하십시오 .
때때로:
이러한 경우, 예를 들어 실패가 항상 5 초 안에 발생한다고 가정하고 실제로 테스트를 더 구체적으로 작성하기가 게으른 경우 다음과 같이 사용할 수 있습니다 timeout
.
#!/usr/bin/env bash
timeout 5 test-command
if [ $? -eq 1 ]; then
exit 1
fi
이 때문에 작동 timeout
종료 124
의 실패하면서 test-command
종료 1
.
git bisect run
종료 상태에 대해 약간 까다 롭습니다.
127 이상이면 이분법이 다음과 같이 실패합니다.
git bisect run failed:
exit code 134 from '../test -aa' is < 0 or >= 128
특히, C assert(0)
는 a로 이어지고 SIGABRT
상태 134로 빠져 나와 매우 성가시다.
125는 마법이며으로 달리기를 생략합니다 git bisect skip
.
이 목적은 관련없는 이유로 인해 손상된 빌드를 건너 뛰는 데 도움이됩니다.
자세한 내용 man git-bisect
은 참조 하십시오.
따라서 다음과 같은 것을 사용하고 싶을 수도 있습니다.
#!/usr/bin/env bash
set -eu
./build
status=0
./actual-test-command || status=$?
if [ "$status" -eq 125 ] || [ "$status" -gt 127 ]; then
status=1
fi
exit "$status"
자식 2.16.1에서 테스트되었습니다.
test_script
+ 모듈 식 테스트 스위트가 포함 된 필요한 테스트 상용구를 포함 시키고 이등분하는 동안 별도의 파일에서 실행하십시오. 수정하면 테스트를 기본 테스트 스위트로 병합하십시오.
bisect run
테스트를 완료하는 데 시간이 오래 걸립니다 때 특히 유용합니다, 나는 확신 테스트 시스템이 중단되지 않습니다입니다. 이렇게하면 백그라운드에서 실행하거나 뇌 컨텍스트 전환 시간을 잃지 않고 너무 많은 리소스를 사용하는 경우 밤새도록 할 수 있습니다.
$ git bisect start
$ git bisect bad
$ git bisect good <goodcommit>
Bisecting: X revisions left to test after this (roughly Y steps)
여전히 문제가 있습니까?
$ git bisect bad
$ git bisect good
<abcdef> is the first bad commit
git bisect reset
git bisect good
다음 커밋으로 이동하도록 수정하십시오 .
추가 포인트를 추가하려면 다음을 수행하십시오.
git bisect start
버그가 특정 파일에서 왔다는 것을 알 수 있도록 파일 이름이나 경로를 지정할 수 있습니다. 예를 들어, 회귀의 원인이 된 변경 사항이 com / workingDir 디렉토리에 있다는 것을 알고 있다고 가정 git bisect start com/workingDir
하면이 디렉토리의 내용을 변경 한 커밋 만 검사하여 훨씬 빠르게 처리 할 수 있습니다.
또한 특정 커밋이 좋은지 나쁜지를 판단하기 어려운 경우을 실행 git bisect skip
하면 무시할 수 있습니다. 다른 커밋이 충분하면 git bisect는 다른 커밋을 사용하여 검색 범위를 좁 힙니다.
$ git bisect ..
기본적으로 디버깅을위한 Git 도구입니다 . 'Git Bisect' 는 마지막으로 알려진 커밋 이후 의 이전 커밋을 통해 디버그합니다 . 바이너리 검색을 사용하여 모든 커밋을 거쳐 회귀 / 버그를 도입 한 커밋을 얻습니다.
$ git bisect start
# 이등분 시작
$ git bisect bad
# 현재 커밋 (v1.5)에 회귀 / 설정 '나쁜'지점이 있음을 나타냅니다.
$ git bisect good v1.0
# 마지막으로 성공한 커밋을 언급 (회귀없이)
'나쁜'점과 '좋은'점을 언급하면 git bisect (바이너리 검색)가 중간 요소 (커밋 v1.3)를 선택하는 데 도움이됩니다 . 커밋 v1.3에 회귀가있는 경우 새로운 '나쁜'포인트로 설정합니다 (예 : Good-> v1.0 및 Bad-> v1.3 )
$ git bisect bad
또는 커밋 v1.3에 버그가없는 경우이를 새로운 'Good point'(예 : * Good-> v1.3 및 Bad-> v1.6)로 설정합니다.
$ git bisect good
참고 : 용어 good
및 용어 bad
는 특정 속성의 유무에 관계없이 커밋을 표시하는 데 사용할 수 있는 용어 는 아닙니다.
Git 2.7 (2015 년 4 분기)에는 새로운 git bisect
옵션이 도입되었습니다 .
git bisect start [--term-{old,good}=<term> --term-{new,bad}=<term>]
[--no-checkout] [<bad> [<good>...]] [--] [<paths>...]
설명서 추가시 :
때때로 당신은 파손 을 일으킨 커밋을 찾지 않고 오히려 다른 "오래된"상태와 "새로운"상태 사이에서 변화를 일으키는 커밋을 찾고 있습니다 .
예를 들어, 특정 수정 사항을 도입 한 커미트를 찾고있을 수 있습니다.
또는 소스 코드 파일 이름이 회사의 명명 표준으로 모두 변환 된 첫 번째 커밋을 찾고있을 것입니다. 또는 무엇이든.이러한 경우 "좋은"및 "나쁜"이라는 용어를 사용하여 "변경 전 상태"와 "변경 후 상태"를 나타내는 것은 매우 혼란 스러울 수 있습니다.
그래서 그 대신, 당신은 용어 "를 사용할 수 있습니다
old
"과 "을new
"대신 각각 "good
"와 "bad
".
그러나 단일 세션에서 "good
"및 "bad
"를 "old
"및 "new
" 와 함께 사용할 수는 없습니다 .이보다 일반적인 사용법에서는
git bisect
"new
"커밋에 일부 속성이 있고 "old
"커밋에 해당 속성이 없습니다.
git bisect
커밋을 체크 아웃 할 때마다 해당 커밋에 속성이 있는지 테스트합니다.이 속성이
있으면 커밋을 "new
"; 그렇지 않으면 "old
" 로 표시하십시오 .이 분이 완료되면
git bisect
어떤 커밋이 속성을 도입했는지보고합니다.
참조 06e6a74 커밋 , 21b55e3 커밋 , fe67687 커밋 에 의해 (2015년 6월 29일) 마티유 Moy와을 ( moy
) . Antoine Delaite ( )의 commit 21e5cfd (2015 년 6 월 29 일)를
참조하십시오 . (가 합병 Junio C 하마노 - - 에 커밋 22dd6eb , 2015년 10월 5일)CanardChouChinois
gitster