코드를 읽기 전에 실행하는 Git 명령들
(piechowski.io)- 새로운 코드베이스를 접할 때 Git 이력 분석으로 프로젝트의 구조와 위험 구역을 파악해 효율적인 탐색 방향을 설정
- 최근 1년간 가장 자주 변경된 파일을 찾아 변경 빈도와 버그 집중도를 교차 분석해 고위험 코드를 식별
- 기여자 분포와 활동 추세를 통해 버스 팩터, 유지보수 공백, 지식 단절 가능성을 점검
- 월별 커밋 수로 팀의 개발 속도와 동력 변화를 추적하고, Revert·Hotfix 빈도로 배포 안정성을 평가
- 이 다섯 가지 명령은 코드 한 줄을 열기 전 프로젝트 건강 상태를 빠르게 진단하는 실질적 도구로 활용 가능
코드 읽기 전 실행하는 다섯 가지 Git 명령
- 새로운 코드베이스를 분석할 때, 파일을 열기 전에 Git 이력으로 프로젝트의 건강 상태를 진단하는 접근
- 커밋 히스토리를 통해 누가 만들었는지, 문제가 어디에 집중되는지, 팀이 얼마나 안정적으로 배포하는지를 파악
-
무엇이 가장 자주 변경되는가
- 명령:
git log --format=format: --name-only --since="1 year ago" | sort | uniq -c | sort -nr | head -20 - 최근 1년간 가장 많이 수정된 상위 20개 파일을 표시
- 상위 파일은 종종 팀이 “건드리기 두려워하는” 파일로, 높은 변경 빈도(churn) 와 소유 회피가 결합될 경우 코드베이스의 가장 큰 부담 요인
- Microsoft Research(2005) 연구에 따르면 변경 빈도 기반 지표가 복잡도 지표보다 결함 예측력이 높음
- 상위 5개 파일을 버그 집중도 명령과 교차 분석해 변경 많고 버그도 많은 파일을 최대 위험 요소로 식별
- 명령:
-
누가 이 코드를 만들었는가
- 명령:
git shortlog -sn --no-merges - 커밋 수 기준으로 기여자를 순위화
- 한 사람이 60% 이상을 차지하면 버스 팩터(bus factor) 위험 존재
- 상위 기여자가 최근 6개월 내 활동하지 않았다면 유지보수 공백 가능성
- 30명의 기여자 중 최근 1년간 3명만 활동 중이라면 개발자 교체로 인한 지식 단절 발생
- 단, squash-merge 전략을 사용하는 팀은 작성자 정보가 병합자 중심으로 왜곡될 수 있어 병합 전략 확인 필요
- 명령:
-
버그는 어디에 집중되는가
- 명령:
git log -i -E --grep="fix|bug|broken" --name-only --format='' | sort | uniq -c | sort -nr | head -20 - 버그 관련 키워드가 포함된 커밋을 기반으로 버그 발생 파일 상위 20개를 추출
- 이 목록을 변경 빈도 목록과 비교해 자주 수정되고 자주 고장나는 파일을 고위험 코드로 식별
- 커밋 메시지 품질에 따라 결과 정확도가 달라지지만 대략적인 버그 밀도 지도로도 충분히 유용
- 명령:
-
프로젝트가 가속 중인가, 정체 중인가
- 명령:
git log --format='%ad' --date=format:'%Y-%m' | sort | uniq -c - 월별 커밋 수를 통해 활동 추세를 시각적으로 파악
- 일정한 리듬은 건강한 프로젝트를 의미
- 한 달 만에 커밋 수가 절반으로 줄면 핵심 인력 이탈 가능성
- 6~12개월간 지속적인 감소는 팀 동력 저하, 주기적 급증 후 정체는 배치형 릴리스 패턴을 시사
- 실제 사례로, 커밋 속도 차트를 통해 CTO가 “그 시점이 시니어 엔지니어가 떠난 때”임을 인식한 경우 존재
- 이 데이터는 코드 데이터가 아닌 팀 데이터로서 의미
- 명령:
-
팀이 얼마나 자주 긴급 대응 중인가
- 명령:
git log --oneline --since="1 year ago" | grep -iE 'revert|hotfix|emergency|rollback' - Revert·Hotfix 빈도를 측정
- 1년에 몇 건은 정상이나, 2주마다 발생한다면 배포 프로세스 불신 신호
- 이는 테스트 불안정, 스테이징 부재, 복잡한 롤백 절차 등 더 깊은 문제의 징후
- 결과가 0이라면 팀이 안정적이거나 커밋 메시지가 부정확한 경우
- 위기 패턴은 명확히 드러나며, 존재 여부만으로도 신뢰도 판단 가능
- 명령:
결론
- 이 다섯 가지 명령은 몇 분 만에 실행 가능하며, 코드 한 줄을 열기 전 어디서부터 읽어야 할지 방향을 제시
- 이를 통해 첫날을 무작정 탐색하는 대신 문제 영역 중심의 체계적 코드 분석이 가능
- 이러한 절차는 코드베이스 감사(codebase audit) 의 첫 한 시간에 해당하며, 이후 일주일간의 분석 과정으로 이어짐
Hacker News 의견들
-
Jujutsu에서 git 분석 명령어를 대체할 수 있는 예시들을 공유함
최근 1년간 가장 많이 바뀐 파일, 주요 기여자, 버그가 집중된 위치, 프로젝트의 생명력, 긴급 수정 빈도 등을 jj log 명령으로 확인할 수 있음
쉘 스크립트보다는 프로그래밍에 가까운 문법이지만, 기억해야 할 플래그 수는 적음- 나에게는 jujutsu가 버전 관리 시스템의 Nix처럼 보임
Nix가 멋지지만 복잡성을 더하듯, jujutsu도 그런 느낌이었음
몇 달 써보다가 git으로 돌아왔음. git은 손에 익었고 어디서나 쓰이기 때문임 - 이런 커스텀 스크립트 언어들을 어떻게 다 외우는지 이해가 안 됨
jq에서 배열 반복문만 기억해도 기쁨인데, 이런 문법은 도저히 감이 안 옴 - jj나 git 명령어 모두 너무 길고 복잡해서 외울 생각은 없음
자주 쓸 거라면 alias로 단축해서 쓰겠음 - 커밋이 없다고 프로젝트가 죽은 건 아님, 오히려 안정적이라는 뜻일 수 있음
예를 들어 10년째 업데이트 없는 QR 코드 생성 라이브러리가 있는데 완벽히 동작함
괜히 봇으로 쓸모없는 커밋을 추가해야 하나 고민될 때가 있음 - git을 프로그래밍하고 싶지 않음, 그냥 일을 끝내고 싶음
그래서 jujutsu 같은 도구보다는 전통적인 UNIX 파이프 명령어를 선호함
Gradle 대신 Maven을 쓰는 이유도 같은 맥락임
- 나에게는 jujutsu가 버전 관리 시스템의 Nix처럼 보임
-
글쓴이가 개발자들이 커밋 메시지를 잘 쓴다고 가정한 게 재밌었음
현실은 대부분 “changed stuff” 수준임
나처럼 커밋 로그를 중요하게 여기는 사람은 소수임
AI가 생성하는 커밋 메시지가 이런 문제를 많이 도와줄 수 있음- 이건 리더십의 문제임. 좋은 팀 리더나 CTO는 커밋 메시지 품질에 대한 기대치를 명확히 함
- PR을 squash해서 머지하는 팀에서는 PR 본문이 커밋 메시지가 되므로 품질이 더 좋음
- squash & merge 워크플로우에서는 결국 PR 제목이 핵심 메시지가 됨
개발자는 자유롭게 커밋 메시지를 써도 됨, 어차피 나중엔 안 읽음 - 우리 팀은 Core 레포와 Non-Core 레포를 구분함
Core는 PR 리뷰와 상세 설명이 필수이고, Non-Core는 자유롭게 실험 가능함
Core에서는 커밋 메시지가 코드보다 20배 길 때도 있음, Non-Core는 “hope this works” 수준임 - 개발자가 커밋 메시지를 안 쓰는 건 문화의 문제임
우리 회사는 서로에게 그걸 요구함
-
여러 코드베이스에 명령어를 돌려봤는데, 결과가 실제 상황과 달랐음
예를 들어git shortlog -sn --no-merges결과에서 가장 커밋이 많은 사람이 이미 퇴사한 경우도 있었음
커밋 수가 많다고 기여도가 높은 건 아님- 그래서 나는 squash-and-merge를 선호함
필요 이상으로 많은 커밋은 feature 브랜치에서만 유지하고, 메인에는 깔끔하게 머지함 - 이런 명령어는 문제 있는 프로젝트를 진단할 때 유용함
평범한 코드베이스에서는 별 의미 없는 결과만 나옴 - 솔직히 글쓴이가 실제로 명령어를 돌려봤는지 의심됨, LLM이 쓴 글 같음
- 자동화된 워크플로우가 한 사람의 자격증명을 쓰면 통계가 왜곡될 수 있음
- 나도 한 회사의 중앙 코드베이스에서 커밋 수가 압도적으로 많음
프로젝트를 처음부터 만들었기 때문이고, 지금은 다른 사람들이 더 자주 커밋함
- 그래서 나는 squash-and-merge를 선호함
-
“가장 많이 바뀐 파일이 사람들이 손대기 두려워하는 파일”이라는 말이 흥미로웠음
- 마치 “너무 붐벼서 아무도 안 가는 식당” 같은 역설 같음
- 테스트해보니 가장 자주 수정된 파일은 자동 생성 파일이나 진입점 같은 지루한 파일이었음
- 이런 명령어는 경고가 필요함
단순히 실행 결과로 결론을 내리면 오히려 어리석어 보일 수 있음
실제로는 최근 1년간 어떤 기능을 작업했는지 정도만 보여줌 -
Churn(변경 빈도) 과 Complexity(복잡도) 를 함께 보면 훨씬 유용함
둘 다 높은 곳이 진짜 문제 구역임
이런 구역이 쌓이면 “앱을 처음부터 다시 써야 한다”는 말이 나옴 - 사람들이 두려워하는 파일은 필수적이면서도 복잡한 파일임
모두가 수정해야 하지만 너무 커서 다루기 힘듦
-
나는 git에 summary alias를 만들어서 브랜치 요약, 커밋 수, 작성자 수, 파일 수 등을 한 번에 출력함
GitAlias/gitalias에서 아이디어를 얻었음- 왜
.gitconfig함수로 썼는지 궁금함, 그냥 git-summary 스크립트로 만드는 게 더 간단해 보임 - 이런 명령어를 매번 직접 친다는 건 AI가 쓴 글 같음, 실제 숙련자는 alias로 재사용함
- 멋진 스크립트지만 내 환경엔
log-of-count-and-email같은 명령이 없음 - 로컬에 man 페이지를 만들어두면 좋을 듯함
- 왜
-
정규식에 단어 경계(\b) 를 추가해야 함
예를 들어 “debugger” 안의 “bug” 때문에 잘못된 결과가 나올 수 있음
수정된 예시는 다음과 같음
git log -i -E --grep="\b(fix|fixed|fixes|bug|broken)\b" ...- macOS에서는
\b를 지원하지 않으므로-E대신 Perl 정규식 옵션 -P를 써야 함
git log -i -P --grep="\b(...)\b"형태로 수정 가능함 - 우리도 “rollback”이라는 단어를 다른 의미로 쓰기 때문에 필터링이 필요함
- 좋은 지적임, 훨씬 정확해짐
- macOS에서는
-
squash-merge를 하지 않으면 커밋 수가 많은 사람이 오히려 가장 엉망인 개발자일 수도 있음
예전에 그런 사람이 있었는데, 같은 파일만 계속 수정하다가 결국 해고됨
squash는 이런 문제를 가려주는 좋은 방법임 -
단순한 커밋 수 통계는 신뢰하기 어려움
어떤 사람은 완벽히 테스트된 코드만 커밋하고, 어떤 사람은 한 줄씩 자주 커밋함
커밋 하나의 가치가 사람마다 100배 차이남- 하지만 글쓴이는 변화 추세를 보는 것이 목적이었음
절대값보다 변화율이 더 의미 있음
- 하지만 글쓴이는 변화 추세를 보는 것이 목적이었음
-
이런 분석 접근법이 Adam Tornhill의 “Your Code as a Crime Scene” 을 떠올리게 함
원문 링크
또 Developer’s Legacy Index 개념과도 닮아 있음- Tornhill의 초기 C 관련 글들을 좋아했음, 반가움
-
글쓴이가 각 명령의 결과를 직접 보여줬다면 더 좋았을 것 같음
설명보다는 출력 예시가 더 설득력 있었을 것임- 나도 글이 약간 AI가 쓴 느낌이었지만, 그래도 다섯 가지 명령을 배웠으니 나쁘지 않음