코드를 읽다가 밖으로 빼기로 했던 설정값이 하드코딩된 채 남아 있는 것을 발견했다. 보고하려다 한 번 더 확인했는데, 그 체크아웃은 작업 브랜치였고 외부화 작업이 머지되기 전 시점이었다. 운영에는 이미 반영돼 있었다.
Table of contents
Open Table of contents
상황 — 읽은 것이 도는 것이 아닐 때
같은 성격의 상황을 몇 가지 만났다. 로컬에 체크아웃된 브랜치가 몇 주 전 것이라 그 뒤에 들어간 변경이 안 보이는 경우가 가장 흔했고, 작업하는 저장소와 배포 서버가 git pull 로 당겨 가는 저장소가 갈라져 있어서 아무리 머지하고 배포해도 반영되지 않는 경우도 있었다.
머신마다 같은 원격 별칭 origin 이 다른 서버를 가리키고 있던 적도 있다. 인자 없이 git push 하면 어디로 나가는지 알 수 없는 상태였다. 로컬 사본이 낡아서 원격에는 수십 커밋이 있는데 로컬에는 몇 개뿐인 경우에는 이력을 조사하고 그 작업이 없다고 결론지을 뻔했다.
읽은 함수가 분기 매핑에서 주석 처리돼 실제로는 절대 호출되지 않던 경우도 있었다. 전부 읽은 것과 도는 것이 다른 경우인데, 읽는 동안에는 그 차이가 드러나지 않는다는 점이 공통이다.
판단 기준 — 확인 항목
코드에서 무언가를 발견하면 단정하기 전에 몇 가지를 본다. git branch --show-current 로 현재 브랜치가 무엇인지 확인하고, 알려진 머지 커밋이 지금 HEAD 의 조상인지 확인한다.
git merge-base --is-ancestor <머지커밋> HEAD && echo "포함됨"
git 공식 문서의 git-merge-base 페이지대로 --is-ancestor 는 출력 없이 종료 코드로만 답하므로(조상이면 0, 아니면 1) 위처럼 && 로 받아야 한다.
배포가 어디서 당겨 가는지도 본다. git remote -v 로 원격 목록을 확인하고 url.<base>.insteadOf 재작성 규칙이 걸려 있는지까지 보는데, 주소를 바꿨는데도 다른 경로로 나가고 있던 적이 있었기 때문이다. 원격 이력을 보는 데는 두 가지 방법이 있었는데 git fetch 로 당겨 온 뒤 git log origin/main 을 보는 것과 git ls-remote 로 원격의 참조만 읽는 것이다. 앞쪽을 골랐다. 이유는 당겨 온 뒤에는 merge-base 로 포함 여부까지 같은 사본에서 판정할 수 있어서다. 대신 작업 사본의 원격 추적 참조가 움직이는 것을 감수했다. 근거는 ls-remote 가 참조 이름과 SHA 만 주고 조상 관계는 말해 주지 않는다는 점이다. 마지막으로 그 코드가 실제로 호출되는지 호출 지점을 역추적한다.
조치 — 배포 후의 확인 순서
배포한 뒤에도 같은 문제가 있었다. 수정을 배포했는데 같은 오류가 계속 나서 배포가 안 됐거나 캐시 때문이라고 생각했는데, 확인해 보니 서버 파일에는 수정이 정확히 반영돼 있었다. 진짜 원인은 그 함수에 도달하기 전에 앞선 호출에서 같은 오류가 나는 것이었다.
그래서 배포 후 증상이 그대로면 순서를 정해 뒀다. 서버에서 git log -1 과 파일 diff 로 수정이 반영됐는지를 먼저 직접 확인하고, 반영돼 있으면 그 지점보다 앞서 호출되는 것들을 훑는다. 같은 오류 메시지가 여러 곳에서 날 수 있다는 것을 전제로 두는 것이 요점이다. 메시지가 같다고 해서 발생 위치가 같지는 않다.
선언과 실제의 괴리
파일에 적힌 것과 실제 동작이 다른 경우도 몇 번 있었다. composer.json 의 php 제약에 적힌 런타임 버전으로 실행 환경을 판단했는데 실제로는 php -v 가 다른 버전을 냈고, 오류 메시지 형식이 그 버전에만 있는 것이라 뒤늦게 드러났다.
.env.example 을 보고 운영 값을 단정한 적도 있다. 운영 .env 는 저장소 밖에 있고 빌드할 때 당겨 오는 구조였는데 예시 파일의 값을 근거로 계획까지 세웠다. README 에 지원한다고 적힌 기능이 실제로는 동작하지 않아 한참 디버깅한 경우도 있었다.
선언과 예시와 문서는 전부 누군가가 그렇게 되기를 의도해 적어 둔 것이지 지금 그렇다는 관측이 아니다. 관측으로 쓰려면 실체를 한 번 더 확인해야 한다.
정리
- 코드에서 발견한 것을 운영 상태로 단정하기 전에 브랜치와 이력 포함 여부를 본다
- 작업하는 저장소와 배포가 당기는 저장소가 다를 수 있다
- 로컬 이력만 보면 원격 작업이 안 보이므로 원격을 직접 조회한다
- 읽은 코드가 실제로 호출되는지 호출 지점을 역추적한다
- 배포 후 증상이 그대로면 서버 파일을 직접 확인한다
- 반영돼 있으면 그 지점보다 앞선 호출을 훑는다
- 메시지가 같다고 발생 위치가 같지는 않다
- 선언과 예시와 문서는 의도이지 관측이 아니다