Programming

자식 bisect를 사용하는 방법?

procodes 2020. 2. 20. 23:40
반응형

자식 bisect를 사용하는 방법?


나는 그것이 git bisect굉장 하다는 기사를 읽었습니다 . 그러나 나는 원어민이 아니며 왜 멋진 지 이해할 수 없습니다.

누군가 코드 샘플로 시연 할 수 있습니까?

  1. 사용 방법?
  2. 그냥 같은 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 badgit 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 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+ 초기 badgood한 번에 :

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

지금까지 테스트 한 내용을 참조하십시오 (수동 goodbad또는 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에서 테스트되었습니다.


TL; DR

스타트:

$ 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 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

참고 URL : https://stackoverflow.com/questions/4713088/how-to-use-git-bisect


반응형