git diff 사용법

git diff 사용법

코드를 수정하다 보면 “내가 방금 뭘 바꿨더라?” 하는 순간이 자주 찾아옵니다. 여러 파일을 동시에 고치고 있으면 어디를 얼마나 바꿨는지 감을 잃기 쉽죠.

git diff는 변경 내용을 한눈에 확인할 수 있게 해주는 명령어인데요. 작업 디렉토리, 스테이징 영역, 커밋 사이의 차이를 비교해주기 때문에 커밋 전에 변경 내용을 점검하거나 브랜치 간 차이를 파악할 때 쓸 일이 많습니다.

이번 글에서는 git diff의 기본 사용법부터 실전에서 유용한 옵션까지 함께 알아보겠습니다.

기본 사용법

git diff를 인자 없이 실행하면 작업 디렉토리에서 수정했지만 아직 스테이징하지 않은 변경 내용을 보여줍니다.

$ git diff
diff --git a/src/app.js b/src/app.js
index 3b18e51..f9c5a82 100644
--- a/src/app.js
+++ b/src/app.js
@@ -1,5 +1,6 @@
 import express from "express";
+import cors from "cors";

 const app = express();
+app.use(cors());
 app.listen(3000);

출력 결과를 살펴보면 ---가 변경 전 파일, +++가 변경 후 파일을 나타냅니다. -로 시작하는 줄은 삭제된 내용이고 +로 시작하는 줄은 추가된 내용이죠. @@ 기호 뒤의 숫자는 변경이 일어난 줄 번호 범위를 알려주고요.

처음엔 좀 복잡해 보여도 몇 번 읽다 보면 금방 익숙해질 거예요.

diff 출력 형식 이해하기

git diff의 출력을 좀 더 자세히 뜯어보겠습니다.

diff --git a/src/app.js b/src/app.js

어떤 파일을 비교하고 있는지 알려주는 줄입니다. a/는 변경 전(이전 상태), b/는 변경 후(현재 상태)를 뜻해요.

index 3b18e51..f9c5a82 100644

파일의 blob 해시와 권한 정보인데 보통은 신경 안 써도 됩니다.

--- a/src/app.js
+++ b/src/app.js

---가 이전 버전, +++가 현재 버전이에요.

@@ -1,5 +1,6 @@

이 부분을 hunk 헤더라고 부릅니다. -1,5는 이전 파일에서 1번째 줄부터 5줄을, +1,6은 현재 파일에서 1번째 줄부터 6줄을 보여준다는 뜻이에요. 변경이 여러 군데 흩어져 있으면 hunk가 여러 개 나옵니다.

스테이징된 변경 내용 보기

git add로 스테이징 영역에 올린 변경 내용을 확인하려면 --staged 옵션을 붙이면 돼요.

$ git add src/app.js
$ git diff --staged
diff --git a/src/app.js b/src/app.js
--- a/src/app.js
+++ b/src/app.js
@@ -1,5 +1,6 @@
 import express from "express";
+import cors from "cors";

 const app = express();
+app.use(cors());
 app.listen(3000);

--cached도 같은 의미입니다. 예전에는 --cached만 있었는데 나중에 좀 더 직관적인 --staged가 추가되었거든요. 둘 중 편한 쪽을 쓰면 됩니다.

# 둘 다 같은 결과
$ git diff --staged
$ git diff --cached

참고로 인자 없이 git diff를 실행하면 스테이징 영역에 올라간 변경 내용은 나오지 않습니다. 그래서 git add를 한 뒤에 git diff가 아무것도 안 나온다고 당황하는 경우가 종종 있는데요. 스테이징한 변경 내용을 보려면 반드시 --staged를 붙여야 해요.

커밋과 비교하기

현재 작업 디렉토리의 상태를 특정 커밋과 비교할 수도 있어요.

# HEAD(마지막 커밋)와 작업 디렉토리 비교
$ git diff HEAD

# 2개 전 커밋과 작업 디렉토리 비교
$ git diff HEAD~2

git diff HEAD는 스테이징 여부와 상관없이 마지막 커밋 이후 변경된 모든 내용을 보여줍니다. git diff(스테이징 전 변경만)와 git diff --staged(스테이징 후 변경만)를 합친 거라고 생각하면 돼요.

두 커밋 사이의 차이를 볼 때는 커밋 해시를 두 개 넘기면 됩니다.

# 두 커밋 간의 차이
$ git diff a1b2c3d f4e5d6c

# HEAD 기준 상대 참조도 가능
$ git diff HEAD~3 HEAD

Git에서 HEAD가 무엇을 의미하는지는 HEAD 개념 정리에서 자세히 다루고 있으니 참고 바랍니다.

브랜치 간 비교

두 브랜치 사이에서 뭐가 다른지 확인하고 싶을 때도 git diff를 쓸 수 있어요.

# main 브랜치와 feature 브랜치의 차이
$ git diff main feature

# 현재 브랜치와 main 브랜치의 차이
$ git diff main

이렇게 하면 두 브랜치의 최신 커밋 시점을 기준으로 전체 차이를 보여줍니다.

한 가지 주의할 점이 있는데요. git diff main feature는 두 브랜치의 현재 상태를 단순 비교하기 때문에 feature 브랜치에서 작업하는 동안 main에도 새 커밋이 추가되었다면 그 변경 내용까지 diff에 섞여 나와요.

“feature 브랜치에서 실제로 뭘 바꿨는가”만 보고 싶다면 ...(점 세 개) 표기법을 쓰면 됩니다.

# feature 브랜치가 main에서 갈라진 이후의 변경만 표시
$ git diff main...feature

이 표기법은 두 브랜치의 공통 조상(merge base)을 기준으로 비교해서 feature 브랜치에서 작업한 내용만 깔끔하게 보여줘요. 풀 리퀘스트 올리기 전에 변경 내용을 검토할 때 특히 유용하죠.

특정 파일만 비교

변경된 파일이 많을 때 전체 diff를 읽기 부담스러우면 -- 뒤에 파일 경로를 지정해서 원하는 파일만 볼 수 있어요.

# 특정 파일의 변경 내용만 보기
$ git diff -- src/app.js

# 여러 파일 지정
$ git diff -- src/app.js src/index.js

# 특정 디렉토리 아래의 변경만 보기
$ git diff -- src/components/

커밋이나 브랜치 비교와 함께 쓸 수도 있고요.

# main 브랜치와 현재 브랜치에서 특정 파일만 비교
$ git diff main -- src/app.js

# 스테이징된 변경 중 특정 파일만 보기
$ git diff --staged -- src/app.js

변경 통계만 보기

코드 변경 내용 없이 어떤 파일이 얼마나 바뀌었는지 요약만 보고 싶을 때는 --stat 옵션이 편해요.

$ git diff --stat
 src/app.js             | 4 +++-
 src/components/Nav.jsx | 8 ++++----
 src/styles/global.css  | 2 ++
 3 files changed, 9 insertions(+), 5 deletions(-)

파일별 추가/삭제된 줄 수가 막대그래프로 나와서 변경 규모를 빠르게 파악할 수 있습니다. 하단에는 변경된 파일 목록과 전체 추가/삭제 줄 수도 요약되고요.

파일 이름만 보고 싶으면 --name-only 옵션을 쓰면 돼요.

$ git diff --name-only
src/app.js
src/components/Nav.jsx
src/styles/global.css

파일의 변경 상태(추가, 수정, 삭제)까지 함께 보려면 --name-status를 쓰면 됩니다.

$ git diff --name-status main
A       src/pages/profile.js
M       src/app.js
D       src/utils/old-helper.js

A는 새로 추가된 파일, M은 수정된 파일, D는 삭제된 파일이에요.

단어 단위로 비교

git diff는 기본적으로 줄 단위로 변경을 보여주는데요. 한 줄에서 단어 하나만 고쳤는데 줄 전체가 삭제/추가로 표시되면 정확히 뭐가 바뀌었는지 파악하기 어렵죠.

이럴 때 --word-diff 옵션을 쓰면 단어 단위로 변경을 보여줍니다.

$ git diff --word-diff
const message = [-"Hello"-]{+"Hello, World!"+};

[-삭제된 부분-]{+추가된 부분+}으로 표시되어서 어떤 단어가 바뀌었는지 바로 알 수 있어요.

색상만으로 구분하고 싶다면 --color-words 옵션도 있습니다. 기호 없이 삭제된 부분은 빨간색, 추가된 부분은 초록색으로 나타나요.

$ git diff --color-words

문서나 설정 파일처럼 긴 줄에서 작은 변경이 자주 생기는 경우에 유용합니다.

공백 무시

코드 포매팅을 바꾸면서 들여쓰기나 공백만 변경된 경우가 있죠. 실질적인 코드 수정이 아닌데 diff에 잡히면 진짜 바뀐 내용을 읽기 번거로워집니다.

-w 옵션을 쓰면 모든 공백 차이를 무시할 수 있어요.

# 모든 공백 차이 무시
$ git diff -w

좀 더 세밀하게 제어하고 싶으면 다른 옵션도 있습니다.

# 줄 끝의 공백만 무시
$ git diff --ignore-space-at-eol

# 연속된 공백의 개수 차이만 무시 (탭 2칸 → 4칸 같은 변경)
$ git diff -b

탭과 스페이스를 변환하거나 들여쓰기 규칙을 바꾼 뒤에 진짜 코드 변경만 확인하고 싶을 때 쓰면 좋아요.

diff 출력 제어

diff가 길어지면 원하는 부분을 찾기 어려울 때가 있는데요. 몇 가지 옵션으로 출력을 조절할 수 있습니다.

변경 주변에 표시되는 컨텍스트 줄 수를 조절하려면 -U 옵션을 씁니다. 기본값은 3줄이라 변경 앞뒤로 3줄씩 보여주는데 좀 더 넓은 맥락이 필요하면 늘리면 돼요.

# 변경 앞뒤 10줄씩 표시
$ git diff -U10

# 변경 부분만 표시 (컨텍스트 0줄)
$ git diff -U0

파일 이름 패턴으로 특정 파일만 보거나 제외할 수도 있어요.

# JavaScript 파일만 diff 표시
$ git diff -- '*.js'

# 테스트 파일 제외
$ git diff -- ':!*.test.js'

# 특정 디렉토리 제외
$ git diff -- ':!node_modules/'

:로 시작하는 pathspec 문법을 쓰면 유연하게 파일을 걸러낼 수 있습니다.

실전 활용

git diff를 실제로 어떤 상황에서 쓰는지 몇 가지 예를 들어볼게요.

가장 흔한 경우는 커밋 전에 변경 내용을 최종 점검할 때입니다.

# 스테이징 전 변경 내용 확인
$ git diff

# 스테이징한 내용 확인
$ git diff --staged

# 모든 변경 내용 확인 (스테이징 + 미스테이징)
$ git diff HEAD

풀 리퀘스트를 올리기 전에 내가 뭘 바꿨는지 전체적으로 훑어볼 때도 좋아요.

# main 브랜치 대비 변경된 파일 목록 확인
$ git diff main...HEAD --stat

# 실제 변경 내용 확인
$ git diff main...HEAD

특정 커밋이 도입한 변경 내용을 보고 싶으면 그 커밋과 부모를 비교하면 됩니다.

# 특정 커밋이 변경한 내용
$ git diff a1b2c3d~1 a1b2c3d

참고로 이 경우에는 git show 사용법에서 다루는 git show 명령어가 더 간편할 수 있어요. git show a1b2c3d를 실행하면 커밋 메시지와 함께 변경 내용을 바로 보여주거든요.

git log -p와의 비교

커밋의 변경 내용을 보는 방법이 여러 가지라 헷갈릴 수 있는데요. 간단히 정리하면 이렇습니다.

명령어용도
git diff아직 커밋하지 않은 작업 중인 변경 확인
git diff A B두 커밋(또는 브랜치) 간의 차이 확인
git show <커밋>특정 커밋 하나의 변경 내용 확인
git log -p여러 커밋의 변경 내용을 히스토리로 탐색

git log 사용법에서 다루듯이 -p 옵션을 붙이면 각 커밋의 diff를 함께 보여주기 때문에 히스토리를 탐색하면서 변경 내용을 확인할 때 좋습니다. 반면 git diff는 특정 두 지점 사이의 차이를 한 번에 보여주기 때문에 “지금 내가 뭘 바꿨는지” 확인할 때 더 적합하죠.

외부 diff 도구 연동

터미널에서 diff를 읽기 어렵다면 VS Code 같은 GUI diff 도구를 연동할 수 있어요.

# VS Code를 diff 도구로 설정
$ git config --global diff.tool vscode
$ git config --global difftool.vscode.cmd 'code --wait --diff $LOCAL $REMOTE'

설정 후 git difftool 명령어를 쓰면 GUI 도구에서 diff를 볼 수 있습니다.

$ git difftool
$ git difftool --staged
$ git difftool main feature

git diff와 같은 인자를 받으니 사용법은 동일해요. VS Code 외에도 IntelliJ나 Beyond Compare, Meld 같은 도구도 연동할 수 있습니다.

마치며

git diff는 코드 변경 내용을 확인하는 가장 기본적인 명령어입니다. 자주 쓰이는 옵션을 정리해 볼게요.

  • git diff — 스테이징 전 변경 내용 확인
  • git diff --staged — 스테이징 후 변경 내용 확인
  • git diff HEAD — 마지막 커밋 이후 모든 변경 확인
  • git diff A B — 두 커밋 또는 브랜치 간 차이 확인
  • git diff main...feature — 브랜치가 갈라진 이후의 변경만 확인
  • git diff --stat — 변경된 파일 목록과 통계 확인
  • git diff --word-diff — 단어 단위로 변경 확인
  • git diff -w — 공백 차이 무시

커밋 전에 git diff로 변경 내용을 꼼꼼히 확인하는 습관을 들이면 의도치 않은 변경이 커밋에 섞여 들어가는 실수를 줄일 수 있습니다.

git stash 사용법이나 git show 사용법도 함께 읽어보시면 Git 작업 흐름을 더 잘 이해할 수 있을 거예요.

더 자세한 내용은 Git 공식 문서를 참고하세요.

This work is licensed under CC BY 4.0 CC BY

Discord