# 코드를 읽기 전에 실행하는 Git 명령들

> Clean Markdown view of GeekNews topic #28324. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=28324](https://news.hada.io/topic?id=28324)
- GeekNews Markdown: [https://news.hada.io/topic/28324.md](https://news.hada.io/topic/28324.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2026-04-09T09:37:42+09:00
- Updated: 2026-04-09T09:37:42+09:00
- Original source: [piechowski.io](https://piechowski.io/post/git-commands-before-reading-code/)
- Points: 89
- Comments: 1

## Summary

새로운 코드베이스를 접할 때 파일을 열기 전에 **Git 이력만으로 프로젝트 건강 상태를 진단**하는 다섯 가지 명령을 소개합니다. 가장 자주 변경된 파일, 기여자 분포, 버그 집중 지점, 월별 커밋 추세, Revert·Hotfix 빈도까지 — 코드 한 줄 안 읽고도 **어디가 위험하고 누가 핵심인지** 파악할 수 있습니다. 에이전트 시대에도 유효한, 오히려 에이전트에게 코드베이스 컨텍스트를 줄 때 **먼저 돌려보면 좋은 명령들**입니다.

## Topic Body

- 새로운 코드베이스를 접할 때 **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)** 의 첫 한 시간에 해당하며, 이후 일주일간의 분석 과정으로 이어짐

## Comments



### Comment 54954

- Author: neo
- Created: 2026-04-09T09:37:42+09:00
- Points: 1

###### [Hacker News 의견들](https://news.ycombinator.com/item?id=47687273) 
- Jujutsu에서 git 분석 명령어를 대체할 수 있는 예시들을 공유함  
  최근 1년간 가장 많이 바뀐 파일, 주요 기여자, **버그가 집중된 위치**, 프로젝트의 생명력, 긴급 수정 빈도 등을 jj log 명령으로 확인할 수 있음  
  쉘 스크립트보다는 **프로그래밍에 가까운 문법**이지만, 기억해야 할 플래그 수는 적음
  - 나에게는 jujutsu가 **버전 관리 시스템의 Nix**처럼 보임  
    Nix가 멋지지만 복잡성을 더하듯, jujutsu도 그런 느낌이었음  
    몇 달 써보다가 git으로 돌아왔음. git은 손에 익었고 어디서나 쓰이기 때문임
  - 이런 **커스텀 스크립트 언어**들을 어떻게 다 외우는지 이해가 안 됨  
    jq에서 배열 반복문만 기억해도 기쁨인데, 이런 문법은 도저히 감이 안 옴
  - jj나 git 명령어 모두 너무 길고 복잡해서 외울 생각은 없음  
    자주 쓸 거라면 **alias로 단축**해서 쓰겠음
  - 커밋이 없다고 프로젝트가 죽은 건 아님, 오히려 **안정적**이라는 뜻일 수 있음  
    예를 들어 10년째 업데이트 없는 QR 코드 생성 라이브러리가 있는데 완벽히 동작함  
    괜히 봇으로 쓸모없는 커밋을 추가해야 하나 고민될 때가 있음
  - git을 프로그래밍하고 싶지 않음, 그냥 **일을 끝내고 싶음**  
    그래서 jujutsu 같은 도구보다는 전통적인 **UNIX 파이프 명령어**를 선호함  
    Gradle 대신 Maven을 쓰는 이유도 같은 맥락임

- 글쓴이가 개발자들이 커밋 메시지를 잘 쓴다고 가정한 게 재밌었음  
  현실은 대부분 “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이 쓴 글** 같음
  - 자동화된 워크플로우가 한 사람의 자격증명을 쓰면 통계가 왜곡될 수 있음
  - 나도 한 회사의 중앙 코드베이스에서 커밋 수가 압도적으로 많음  
    프로젝트를 처음부터 만들었기 때문이고, 지금은 다른 사람들이 더 자주 커밋함

- “가장 많이 바뀐 파일이 사람들이 손대기 두려워하는 파일”이라는 말이 흥미로웠음
  - 마치 “너무 붐벼서 아무도 안 가는 식당” 같은 역설 같음
  - 테스트해보니 가장 자주 수정된 파일은 **자동 생성 파일**이나 진입점 같은 지루한 파일이었음
  - 이런 명령어는 **경고가 필요함**  
    단순히 실행 결과로 결론을 내리면 오히려 어리석어 보일 수 있음  
    실제로는 최근 1년간 어떤 기능을 작업했는지 정도만 보여줌
  - **Churn(변경 빈도)** 과 **Complexity(복잡도)** 를 함께 보면 훨씬 유용함  
    둘 다 높은 곳이 진짜 문제 구역임  
    이런 구역이 쌓이면 “앱을 처음부터 다시 써야 한다”는 말이 나옴
  - 사람들이 두려워하는 파일은 **필수적이면서도 복잡한 파일**임  
    모두가 수정해야 하지만 너무 커서 다루기 힘듦

- 나는 git에 **summary alias**를 만들어서 브랜치 요약, 커밋 수, 작성자 수, 파일 수 등을 한 번에 출력함  
  [GitAlias/gitalias](https://github.com/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”이라는 단어를 다른 의미로 쓰기 때문에 필터링이 필요함
  - 좋은 지적임, 훨씬 정확해짐

- **squash-merge**를 하지 않으면 커밋 수가 많은 사람이 오히려 **가장 엉망인 개발자**일 수도 있음  
  예전에 그런 사람이 있었는데, 같은 파일만 계속 수정하다가 결국 해고됨  
  squash는 이런 문제를 가려주는 좋은 방법임

- 단순한 **커밋 수 통계는 신뢰하기 어려움**  
  어떤 사람은 완벽히 테스트된 코드만 커밋하고, 어떤 사람은 한 줄씩 자주 커밋함  
  커밋 하나의 가치가 사람마다 100배 차이남
  - 하지만 글쓴이는 **변화 추세**를 보는 것이 목적이었음  
    절대값보다 변화율이 더 의미 있음

- 이런 분석 접근법이 **Adam Tornhill의 “Your Code as a Crime Scene”** 을 떠올리게 함  
  [원문 링크](https://www.adamtornhill.com/articles/crimescene/codeascrime...)  
  또 [Developer’s Legacy Index](https://www.javaadvent.com/2021/12/using-jgit-to-analyse-the...) 개념과도 닮아 있음
  - Tornhill의 초기 C 관련 글들을 좋아했음, 반가움

- 글쓴이가 각 명령의 결과를 직접 보여줬다면 더 좋았을 것 같음  
  설명보다는 **출력 예시**가 더 설득력 있었을 것임
  - 나도 글이 약간 **AI가 쓴 느낌**이었지만, 그래도 다섯 가지 명령을 배웠으니 나쁘지 않음
