Git 실전 · 이등분과 고고학 · 실습
40개 커밋에서 범인 찾기
목표
"예전엔 됐는데요" 에서 커밋 하나를 특정합니다. 그리고 **자동화가 끝나는
자리**를 직접 만납니다.
환경
/root/repo 에 빈 저장소가 하나 있습니다. 이력은 직접 만듭니다 — 아래를
그대로 붙여 넣으세요. 이 부분은 과제가 아니라 준비입니다.
cd /root/repo && mkdir -p appi=1while [ "$i" -le 40 ]; do if [ "$i" -eq 22 ]; then printf '#!/bin/shecho $(( 100 +' > app/calc.sh elif [ "$i" -lt 23 ]; then printf '#!/bin/shecho 100' > app/calc.sh else printf '#!/bin/shecho 250' > app/calc.sh; fi echo "note $i" > app/notes.txt git add -A && git commit -qm "change $i" i=$((i + 1))doneprintf 'timeout=3retries=2' > app/settings.inigit add -A && git commit -qm "설정값 도입"printf ' timeout=3 retries=2' > app/settings.inigit add -A && git commit -qm "포매터 실행"git tag -f v1 "$(git rev-list --reverse HEAD | sed -n '2p')"mkdir -p /root/archapp/calc.sh 는 원래 100 을 내야 합니다. 지금은 250 을 냅니다. 그리고
중간 어딘가에 문법이 깨져 실행조차 안 되는 커밋이 하나 있습니다.
만들 것
/root/check.sh 판정 스크립트 — 종료코드로 good/bad/skip 을 말한다/root/wrong-check.sh 125 를 일부러 뺀 것 (4단계에서 비교용)/root/arch/bisect.txt bisect run 의 결과/root/arch/wrong.txt 125 를 뺐을 때의 결과/root/arch/culprit.txt 범인과 배제 근거/root/arch/pickaxe.txt log -S 로 찾은 결과/root/arch/blame.txt blame 과 blame -w 의 차이/root/arch/report.md 정리판정 스크립트를 저장소 밖에 두는 이유가 있습니다. 저장소 안에 두면
bisect 가 커밋을 옮겨 다닐 때 그 스크립트까지 함께 바뀝니다.
단계
1. 이력과 기준 태그를 만듭니다.
2. /root/check.sh 를 씁니다. 종료코드 세 가지를 정확히 구분해야 합니다.
3. git bisect start HEAD v1 뒤에 git bisect run sh /root/check.sh.
결과를 그대로 bisect.txt 에 옮깁니다. 하나로 안 좁혀집니다.
4. 125 를 뺀 wrong-check.sh 로 같은 이등분을 다시 돌립니다. 이번에는
확신 있게 답을 냅니다 — 그리고 그 답은 틀렸습니다. 둘을 나란히 적으세요.
5. 두 후보 중 어느 쪽이 범인인지 git show 로 확인하고, 다른 쪽을 **왜
배제했는지**까지 적습니다.
6. git log -S 로 같은 답을 한 번에 냅니다.
7. app/settings.ini 에 git blame 과 git blame -w 를 각각 돌려 봅니다.
8. 네 도구를 언제 쓰는지 정리합니다.
참고
3단계에서 화면에 The first bad commit could be any of: 가 뜨면 제대로 온
것입니다. 실패가 아니라 정직한 답입니다 — 판정할 수 없었던 커밋이 남아
있으면 bisect 는 거기까지만 말할 수 있습니다. 4단계와 비교해 보면, 틀린
답을 확신 있게 내는 쪽보다 이쪽이 낫다는 것이 분명해집니다.
단계 8개
- 이력과 기준점 만들기
- 종료코드로 말하는 판정 스크립트
- 이등분을 돌리면 어디까지 좁혀지나
- 125 를 빼면 무슨 일이 생기나
- 마지막 한 걸음은 사람이 정한다
- 무엇을 찾는지 알 때의 지름길
- 포매터 커밋을 지나 값을 정한 커밋으로
- 언제 무엇을 먼저 쓰는가