Skip to content
This page has been auto-translated and may contain errors.View in English

git log, show, diff를 사용하여 Git 히스토리 보기

docs.scrimba.com

월요일 아침에 weather-app을 열었는데 금요일에 배포한 것이 정확히 무엇인지 기억나지 않는다고 해봅시다. 또는 팀원이 지난주 온도 변환이 왜 변경되었는지 묻고, 추측 대신 실제 답변을 원합니다. 커밋 루프는 커밋이 어떻게 저장되는지 설명합니다. 이 장에서는 그 히스토리를 다시 읽는 방법을 설명합니다: 무엇이 일어났는지, 누가 했는지, 언제 했는지. 그 명령은 git log이며, 작은 프로젝트가 출력하는 모든 것이 여기 있습니다:

bash
$ git log
commit 4f2a1c9d8e7b6a5c4d3e2f1a0b9c8d7e6f5a4b3c
Author: 박민지 <[email protected]m>
Date:   Tue Jul 14 09:12:03 2026 +0100

    섭씨-화씨 온도 변환 공식 수정

commit 5f3d8b21a90e7c6d5b4a3f2e1d0c9b8a7f6e5d4c
Author: 이준호 <[email protected]m>
Date:   Mon Jul 13 16:45:22 2026 +0100

    대시보드에 5일 예보 추가

commit 1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b
Author: 이준호 <[email protected]m>
Date:   Mon Jul 13 11:03:47 2026 +0100

    프로젝트 구조 설정

한 명령으로 프로젝트의 전체 이야기가 바로 여기 있습니다: 세 개의 커밋, 가장 최신것부터, 각각 누가 작성했는지, 언제, 왜 했는지가 기록되어 있습니다.

git log로 로그 읽기

git log는 현재 위치에서 도달할 수 있는 모든 커밋을 거슬러 올라가며, 가장 최신것부터 표시합니다. 각 항목은 네 가지를 보여줍니다: 해시(그 정확한 커밋을 식별하는 문자와 숫자의 긴 문자열), 저자, 날짜, 저자가 작성한 메시지입니다.

**커밋**은 이 네 가지 모든 것을 함께 묶은 것입니다: 그 순간의 모든 추적 파일의 스냅샷, 변경사항을 설명하는 메시지, 누가 만들었는지, 바로 전에 나온 커밋인 부모 커밋으로의 링크. 이 부모 링크가 분리된 스냅샷들의 더미를 실제 타임라인으로 바꿔줍니다. 위에서 아래로 git log를 읽으면 그 타임라인을 역순으로, 지금에서 시작으로 읽는 것입니다.

해시는 처음에는 위협적으로 보이지만, 전체가 필요한 경우는 거의 없습니다. 4f2a1c9d8e7b6a5c4d3e2f1a0b9c8d7e6f5a4b3c4f2a1c9는 같은 커밋을 가리킵니다. Git은 리포지토리의 다른 모든 커밋과 구별하기 위해 충분한 해시만 필요하며, 처음 7개 정도의 문자는 거의 항상 충분합니다. 이 장의 나머지 명령을 포함하여 어디에서나 짧은 형식을 보게 될 것입니다.

기본 git log 출력은 철저하지만 길쭉합니다: 세 개의 커밋도 이미 터미널 전체를 차지했습니다. 몇 가지 형식이 일상적으로 더 유용하게 만듭니다.

bash
$ git log --oneline
4f2a1c9 섭씨-화씨 온도 변환 공식 수정
5f3d8b2 대시보드에 5일 예보 추가
1a2b3c4 프로젝트 구조 설정

--oneline은 각 커밋을 짧은 해시와 메시지로 축약하고, 커밋당 한 줄씩 표시합니다. 이것이 대부분 사용할 형식입니다. --graph는 히스토리 옆에 선과 점의 집합으로 히스토리의 모양을 그립니다. 아직 브랜치가 없는 프로젝트에서는 평면 직선을 그리지만, 일찍부터 손에 익혀두세요: 브랜치가 나타나는 순간(다음 장)이 바로 이 그림이 가치를 발휘하기 시작하는 때입니다.

로그를 스크롤하는 대신 필터링할 수도 있습니다. git log --author="준호"는 준호가 작성한 커밋만 표시하며, 공유 프로젝트에서 한 사람의 작업을 보고 싶을 때 유용합니다. git log -- src/index.js는 그 특정 파일에 닿은 커밋만 표시하여 그것에 결코 닿지 않은 것은 무시합니다:

bash
$ git log --oneline -- src/index.js
4f2a1c9 섭씨-화씨 온도 변환 공식 수정
1a2b3c4 프로젝트 구조 설정

두 번째 커밋인 예보 커밋은 src/index.js를 건드리지 않았으므로 표시되지 않습니다. 두 필터 모두 --oneline과 깔끔하게 결합됩니다.

위의 필터는 "이 파일을 건드린 커밋이 어떤 것인가"라는 질문에 답변합니다. 나쁜 날에 실제로 히스토리로 보내는 질문은 더 날카롭습니다: 이 정확한 코드가 언제 나타났거나 사라졌는가? 그것이 **곡괭이**라고 알려진 git log -S가 하는 일입니다. 문자열을 주면, 그 문자열의 발생 개수가 변경된 커밋만 유지합니다. 즉, 그것을 추가하거나 제거한 커밋:

bash
$ git log --oneline -S "showLoadingSpinner"
7d1e8c3 예보 데이터 로드 로딩 스피너 추가

전체 히스토리 중 한 커밋: 그 호출이 코드베이스에 들어온 순간. 이것이 "이 버그 줄은 언제 도입되었는가"라는 질문에 아무것도 체크 아웃하지 않고 답변하는 가장 빠른 방법입니다. 개수 세기 규칙에는 한 가지 알 가치가 있는 결과가 있습니다: 파일 내에서만 줄을 이동하는 커밋은 발생 개수를 변경하지 않으므로 -S는 그것을 건너뜁니다. 텍스트를 건드리는 모든 커밋을 원할 때는 이동을 포함하여 정규식과 함께 git log -G를 사용하세요. 먼저 -S를 사용하세요; 일반적으로 가지고 있는 질문에 더 날카로운 도구입니다.

Juno로그 읽기git log는 모든 커밋을 나열하며, 가장 최신것부터 해시, 저자, 날짜, 메시지와 함께 표시합니다. 커밋은 그 스냅샷과 메시지 그리고 그 전에 온 커밋으로의 링크입니다. 전체 해시가 필요한 경우는 거의 없으며, 처음 여러 문자만으로도 Git이 정확히 어느 커밋을 의미하는지 알 수 있습니다.
Juno로그 읽기git log --oneline은 일상적으로 사용할 형식이며, 커밋당 한 줄입니다. --author나 뒤에 오는 -- path를 추가하여 한 사람의 작업이나 한 파일의 히스토리로 필터링하고, 브랜치가 들어오면 --graph를 사용하세요.
Juno로그 읽기 모든 커밋의 해시는 자신의 내용과 부모의 해시의 지문이므로 두 커밋이 우연히 충돌하지 않으며 짧은 접두어를 입력하는 것이 안전합니다. 그리고 질문이 "이 줄은 언제 나타났거나 사라졌는가"일 때, git log -S "text"는 전체 히스토리를 당신을 위해 걸으며 그것을 추가하거나 제거한 커밋만 유지합니다. 그것과 부모 링크 사이에, 이 장은 내 디버깅 도구 상자의 대부분입니다.

git show로 한 커밋 검사하기

git log는 커밋이 일어났다는 것을 알려줍니다. git show <hash>는 정확히 그것이 무엇을 했는지 알려줍니다:

bash
$ git show 4f2a1c9
commit 4f2a1c9d8e7b6a5c4d3e2f1a0b9c8d7e6f5a4b3c
Author: 박민지 <[email protected]m>
Date:   Tue Jul 14 09:12:03 2026 +0100

    섭씨-화씨 온도 변환 공식 수정

diff --git a/src/index.js b/src/index.js
index 3f2c1a9..7b8e2d4 100644
--- a/src/index.js
+++ b/src/index.js
@@ -12,7 +12,7 @@ function celsiusToFahrenheit(celsius) {
-  return celsius * (9 / 5 + 32)
+  return (celsius * 9) / 5 + 32

위쪽 절반은 git log가 보여주는 것과 동일한 메타데이터입니다. 아래는 실제 변경사항입니다: -로 시작하는 줄은 커밋이 제거한 줄이고, +로 시작하는 줄은 추가한 줄이며, 표시되지 않은 줄은 동일하게 유지된 컨텍스트입니다. 여기서 명확하게 읽혀집니다: 이전 줄은 32를 괄호 안에 그룹화했으므로 곱셈이 발생하기 전에 추가되었습니다. 수정은 celsius * 9 주위에 괄호를 다시 그룹화하여 32가 마지막에 추가되도록 합니다. 이것이 민지의 메시지가 설명하는 연산자 우선순위 버그입니다.

더 큰 커밋의 일부만 보려면 경로를 추가하세요: git show 4f2a1c9 -- src/index.js는 그 파일의 변경 부분만 표시하며, 한 커밋이 여러 파일에 닿았을 때 그 중 하나만 신경 쓸 때 중요합니다.

Juno한 커밋 검사하기git show <hash>는 한 커밋을 전체로 표시합니다: 누가 만들었는지, 언제, 그리고 실제로 변경한 줄입니다. 제거된 줄은 빼기 기호로 시작하고, 추가된 줄은 더하기 기호로 시작합니다. "이 커밋이 실제로 무엇을 했는가"라는 질문에 답하는 가장 빠른 방법입니다.
Juno한 커밋 검사하기git show <hash>는 한 커밋의 메타데이터와 전체 diff를 제공합니다. 커밋이 여러 파일에 닿았을 때 특정 경로도 지정하세요, git show <hash> -- path/to/file, 한 파일의 부분만 필요할 때.
Juno한 커밋 검사하기git show는 커밋의 저장된 스냅샷을 부모 스냅샷과 비교하고 있으며, 다른 줄만 출력합니다. 이렇게 diff를 읽기 시작하면, 커밋은 더 이상 미스터리 상자가 아니라 그 사이에 차이가 있는 두 스냅샷이 됩니다.

git diff가 보여주는 것, 그리고 거의 모두가 맞는 함정

git loggit show는 커밋된 히스토리를 읽습니다. git diff는 아직 커밋되지 않은 것을 읽습니다: 지금 작업 디렉토리에 있는 변경사항을 마지막 커밋과 비교합니다.

bash
$ git diff
diff --git a/README.md b/README.md
index 1c2d3e4..9f8a7b6 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
 # weather-app
+순수 자바스크립트로 만든 5일 날씨 대시보드.

이것은 README.md에 대한 편집입니다. 아무것도 스테이징하거나 커밋하기 전에 표시됩니다. 첫 주에 거의 모두를 잡는 부분이 여기 있습니다: git add .를 실행하여 같은 변경사항을 스테이징한 다음, git diff를 다시 실행하면 전혀 아무것도 표시되지 않습니다.

bash
$ git add .
$ git diff

아무것도 출력되지 않습니다. 편집이 사라지지 않았고, 아무것도 잘못되지 않았습니다. 평문 git diff는 작업 디렉토리를 스테이징 영역과 비교하며, 모든 것을 스테이징했으면 이 둘은 이제 일치하므로 거기서 더 이상 보여줄 차이가 없습니다. 스테이징 영역에서 대기 중인 변경사항을 보려면 대신 git diff --staged를 사용하세요.

bash
$ git diff --staged
diff --git a/README.md b/README.md
index 1c2d3e4..9f8a7b6 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
 # weather-app
+순수 자바스크립트로 만든 5일 날씨 대시보드.

같은 변경사항, 이제 보입니다. --staged가 스테이징 영역을 마지막 커밋과 비교하기 때문입니다.

평문 git diffgit diff --staged는 두 가지 다른 질문에 답변하고 있으며, 정확하게 이름을 지우면 도움이 됩니다. 평문 git diff는 작업 디렉토리를 스테이징 영역과 비교합니다: 아직 스테이징하지 않은 편집을 표시합니다. git diff --staged는 스테이징 영역을 마지막 커밋과 비교합니다: 지금 git commit을 실행하면 다음 커밋으로 들어갈 정확히 무엇을 표시합니다. 둘 다 한 번에 둘 다 표시하지 않으며, 이것이 정확히 완전히 스테이징된 변경사항이 평문 git diff를 조용하게 하는 이유입니다. 나이가 많은 튜토리얼과 문서에서 --cached를 보게 될 것입니다; 그것은 --staged와 같은 의미입니다.

커밋 전에 둘 다 실행하는 것은 좋은 습관입니다: 평문 git diff는 중요한 것이 스테이징되지 않았는지 확인하고, git diff --staged는 정확히 무엇을 저장하려고 하는지 확인합니다.

Juno변경사항 보기git diff는 아직 스테이징되지 않은 작업 디렉토리의 편집을 표시합니다. git add로 모든 것을 스테이징하면, 평문 git diff는 조용해집니다. 이것은 예상된 것이며, 변경사항은 여전히 있습니다. git diff --staged를 사용하여 커밋을 기다리고 있는 것을 보세요.
Juno변경사항 보기 평문 git diff는 작업 디렉토리 대 스테이징 영역, git diff --staged는 스테이징 영역 대 마지막 커밋, 두 가지 다른 비교입니다. 커밋 전에 둘 다 실행하면 무엇이 스테이징되지 않았는지 그리고 무엇을 저장하려고 하는지 알려줍니다. 나이가 많은 자료는 때때로 --cached를 말하며, 같은 플래그, 다른 이름입니다.
Juno변경사항 보기 둘 다의 diff는 스냅샷의 다른 쌍에 적용된 같은 작업입니다: 작업 트리 대 스테이징 영역, 또는 스테이징 영역 대 마지막 커밋. 당신이 비교하는 어느 두 가지를 이름 지우는 것이 빈 git diff로 인해 혼동되지 않는 전체 트릭입니다.

Git 히스토리가 그래프를 형성하는 이유

지금까지 본 모든 커밋은 정확히 한 부모를 가리키며, 위에서 아래로 git log를 읽는 것이 직선을 읽는 것처럼 느껴졌습니다. 이것은 작업의 한 줄에서 작동하는 솔로 프로젝트에 적용됩니다. 브랜치와 병합이 그림에 들어오는 순간 그것은 멈춥니다. 다음 브랜치에서 다루어집니다. 프로젝트의 실제 히스토리는 별도의 줄로 분할되고 다시 함께 올 수 있기 때문입니다.

이것이 앞서 --graph 플래그가 실제로 하는 일입니다. weather-app에서 지금 그것은 한 칼럼을 그립니다. 브랜치가 갈라지고 나중에 병합될 때까지 그것만 그립니다. --graph가 분기와 재결합을 별도의 칼럼으로 그리기 시작하면 만나며, 이는 평면 해시 목록에서 그림을 그려보려고 하는 것보다 훨씬 읽기 쉽습니다.

병합 커밋에서 git show를 실행하면 기본적으로 메타데이터만 출력합니다: 전혀 diff가 없습니다. -m을 추가하면 각 부모에 대해 차례로 별도의 diff를 출력합니다. 두 동작 모두 같은 모양으로 거슬러 올라갑니다: Git의 히스토리는 **DAG**이며, 방향성 비순환 그래프입니다. "방향성"은 모든 링크가 한 방향을 가리킨다는 뜻이며, 커밋을 부모로 돌아가고, 절대 앞으로 가지 않습니다. "비순환"은 이 링크들이 절대 루프되지 않는다는 뜻이므로 그들을 따라가면 항상 프로젝트의 시작을 향해 움직이며, 이미 지난 커밋으로 돌아가지 않습니다. 일반 커밋은 정확히 하나의 부모를 가지며, 이것이 솔로 프로젝트의 로그가 직선처럼 읽히는 이유입니다. 병합 커밋은 예외입니다: 하나 대신 두 개의 부모 해시를 가지고 있으며, 두 부모가 있으면, 평문 git show-m이 각 부모에 대해 별도로 비교하도록 하기 전까지는 인쇄할 단일 "diff"가 없습니다. 브랜치와 병합, 다음 두 장, 이 같은 그래프에 직접 기반을 두고 있습니다.

Juno그래프로서의 히스토리 지금 본 모든 커밋은 한 부모를 가리키므로 로그는 직선처럼 읽힙니다. 브랜치가 갈라지고 다시 병합될 때 그것이 변경됩니다. 다음 장에서 만날 것입니다. 그 아래의 모양, 커밋을 그것 앞의 커밋으로 연결하는 것, 그것이 가능하게 하는 것입니다.
Juno그래프로서의 히스토리 커밋의 솔로 라인은 각각 하나의 부모를 가지기 때문에 직선처럼 보입니다. --graph 플래그는 분기가 시작될 때 모양을 보이게 하며, 평면 목록 대신 분기와 병합을 그립니다. 필요하기 전에도 도구 상자에 보관하세요.
Juno그래프로서의 히스토리 Git의 히스토리는 방향성 비순환 그래프입니다: 부모 포인터는 항상 역방향을 가리키고, 절대 루프되지 않습니다. 병합 커밋은 커밋이 하나 대신 두 부모를 얻는 한 곳이며, 이것이 평문 git show-m을 추가할 때까지 diff를 출력하지 않는 이유입니다. 분기와 병합은 다른 각도에서 이 같은 그래프의 나머지를 가르칩니다.