Git Diff 심층 탐구

GitBeginner
지금 연습하기

소개

Git 탐험가 여러분, 환영합니다! 오늘은 Git 에서 가장 강력하고 자주 사용되는 기능 중 하나인 git diff 명령어를 깊이 있게 살펴볼 것입니다. 파일에 어떤 변경을 가했는지 정확히 알고 싶거나, 코드의 서로 다른 버전을 비교해야 했던 적이 있다면 git diff가 바로 여러분이 찾던 도구입니다.

git diff 명령어는 코드 변경 사항을 들여다보는 현미경과 같습니다. 작업 디렉토리, 스테이징 영역, 커밋 사이, 심지어 서로 다른 브랜치 간의 차이점까지 저장소의 다양한 상태를 정밀하게 비교할 수 있게 해줍니다.

이 실습에서는 다음 내용을 학습합니다:

  1. 작업 디렉토리와 스테이징 영역 비교하기
  2. 스테이징 영역과 마지막 커밋 비교하기
  3. 서로 다른 브랜치 비교하기
  4. 특정 파일 비교하기
  5. 시각적인 비교를 위해 외부 diff 도구 사용하기

이 실습을 마칠 때쯤이면 여러분은 git diff 전문가가 되어, 변경 사항을 정밀하고 자신 있게 검토할 수 있게 될 것입니다. 이 기술은 자신의 작업을 검토하고, 커밋을 준비하며, 동료들과 효과적으로 협업하는 데 필수적입니다.

그럼 이제 git diff의 강력한 기능을 탐험해 봅시다!

이 과정은 학습과 실습을 돕기 위해 단계별 지침을 제공하는 가이드 랩입니다. 각 단계를 완료하고 실무 경험을 쌓으려면 지침을 주의 깊게 따르십시오. 과거 데이터에 따르면 이 과정은 초급 수준이며 98%의 완료율을 기록하고 있습니다. 또한 학습자들로부터 99%의 긍정적인 평가를 받았습니다.

작업 공간 설정하기

비교 작업을 시작하기 전에, 비교할 파일과 커밋이 있는 작업 공간을 설정해 보겠습니다. 새 디렉토리를 만들고, Git 저장소를 초기화한 다음, 여러 번의 커밋을 통해 파일을 추가하겠습니다.

터미널을 열고 다음 명령어들을 입력하세요:

cd ~/project
mkdir git-diff-lab
cd git-diff-lab
git init

이제 다음 명령어들을 복사하여 붙여넣어 파일들을 생성하고 일련의 커밋을 만듭니다:

echo "## Git Diff Lab" > README.md
git add README.md
git commit -m "Initial commit"

echo "function greet(name) {" > greet.js
echo "  return 'Hello, ' + name + '!';" >> greet.js
echo "}" >> greet.js
git add greet.js
git commit -m "Add greet function"

echo "const numbers = [1, 2, 3, 4, 5];" > numbers.js
echo "console.log(numbers);" >> numbers.js
git add numbers.js
git commit -m "Add numbers array"

방금 수행한 작업의 내용은 다음과 같습니다:

  1. README 파일을 생성하고 첫 번째 커밋을 만들었습니다.
  2. 인사말 함수가 포함된 JavaScript 파일을 생성하고 커밋했습니다.
  3. 숫자 배열이 포함된 또 다른 JavaScript 파일을 생성하고 커밋했습니다.

이제 탐색할 수 있는 히스토리가 있는 저장소가 준비되었습니다!

작업 디렉토리와 스테이징 영역 비교하기

git diff의 가장 기본적인 용도는 아직 스테이징되지 않은 작업 디렉토리의 변경 사항을 확인하는 것입니다. 이를 직접 확인해 봅시다.

먼저 greet.js 파일을 수정해 보겠습니다:

echo "function farewell(name) {" >> greet.js
echo "  return 'Goodbye, ' + name + '!';" >> greet.js
echo "}" >> greet.js

이제 git diff를 사용하여 변경 사항을 확인합니다:

git diff

다음과 유사한 출력이 나타날 것입니다:

diff --git a/greet.js b/greet.js
index 95f5574..a3641f6 100644
--- a/greet.js
+++ b/greet.js
@@ -1,3 +1,7 @@
 function greet(name) {
   return 'Hello, ' + name + '!';
 }
+function farewell(name) {
+  return 'Goodbye, ' + name + '!';
+}

출력 내용을 분석해 보겠습니다:

  • 첫 번째 줄은 어떤 파일들이 비교되고 있는지 보여줍니다.
  • +++--- 줄은 비교되는 파일 버전을 나타냅니다 (a/는 원본, b/는 수정된 버전).
  • @@ 줄은 파일의 어느 부분에서 변경이 일어났는지에 대한 문맥 정보를 제공합니다.
  • +로 시작하는 줄은 추가된 내용이며, -는 삭제된 내용을 나타냅니다.

이 diff 결과는 greet.js에 세 줄이 새로 추가되었음을 보여줍니다.

q를 눌러 diff 뷰에서 나갑니다.

이제 이 변경 사항을 스테이징해 보겠습니다:

git add greet.js

git diff를 다시 실행하면 아무런 출력도 나오지 않습니다. 이는 git diff가 기본적으로 스테이징되지 않은 변경 사항만 보여주기 때문입니다. 스테이징된 변경 사항을 보려면 git diff --staged를 사용해야 하며, 이는 다음 단계에서 다루겠습니다.

기억하세요. 아무런 인자 없이 git diff를 실행하면 작업 디렉토리와 스테이징 영역을 비교합니다. 이는 변경 사항을 스테이징하기 전에 검토하기에 아주 좋은 방법입니다.

스테이징 영역과 마지막 커밋 비교하기

변경 사항을 스테이징했으므로, 이제 스테이징 영역과 마지막 커밋을 비교하는 방법을 배워보겠습니다. 이 기능은 다음 커밋에 어떤 변경 사항이 포함될지 검토할 때 유용합니다.

스테이징 영역과 마지막 커밋 사이의 차이점을 보려면 다음 명령어를 사용합니다:

git diff --staged

이전 단계에서 보았던 것과 유사하게 farewell 함수가 추가된 것을 확인할 수 있습니다.

이 명령어는 시간을 두고 여러 변경 사항을 스테이징한 후, 다음 커밋에 포함될 모든 내용을 한꺼번에 검토하고 싶을 때 특히 유용합니다.

작동 방식을 더 자세히 보기 위해 또 다른 변경 사항을 만들고 스테이징해 봅시다:

echo "console.log(greet('World'));" >> greet.js
git add greet.js

이제 git diff --staged를 실행하면 farewell 함수와 새로 추가된 console.log 줄이 모두 표시됩니다.

git diff --staged(또는 동의어인 git diff --cached) 는 마지막 커밋과 비교하여 현재 스테이징 영역에 있는 변경 사항을 보여준다는 점을 기억하세요. 커밋 직전에 스테이징된 내용을 최종 점검하는 훌륭한 방법입니다.

브랜치 비교하기

Git diff 는 서로 다른 브랜치를 비교할 때도 유용합니다. 특히 기능 브랜치 (feature branch) 에서 작업 중일 때 메인 브랜치와 어떻게 다른지 확인하고 싶을 때 큰 도움이 됩니다.

새 브랜치를 만들고 변경 사항을 적용해 봅시다:

git checkout -b feature-branch
echo "const PI = 3.14159;" >> numbers.js
git add numbers.js
git commit -m "Add PI constant"

이제 이 브랜치를 메인 브랜치와 비교해 보겠습니다:

git diff master feature-branch

numbers.jsPI 상수가 추가된 것을 보여주는 출력이 나타날 것입니다.

이 명령어는 masterfeature-branch의 끝부분 (tip) 사이의 차이점을 보여줍니다. 즉, "master에는 없지만 feature-branch에는 있는 변경 사항이 무엇인가?"를 묻는 것과 같습니다.

첫 번째 브랜치 이름을 생략하여 현재 브랜치와 다른 브랜치를 비교할 수도 있습니다:

git diff master

이것은 현재 브랜치 (feature-branch) 를 master와 비교합니다.

브랜치를 비교할 때 다음 사항을 기억하세요:

  • 첫 번째 브랜치 (또는 생략된 경우 현재 브랜치) 에는 있지만 두 번째 브랜치에는 없는 변경 사항은 삭제 (-) 로 표시됩니다.
  • 두 번째 브랜치에는 있지만 첫 번째 브랜치에는 없는 변경 사항은 추가 (+) 로 표시됩니다.

이 기능은 브랜치를 병합 (merge) 하기 위해 준비하거나 기능 브랜치가 어떤 변화를 가져오는지 확인하고 싶을 때 매우 유용합니다.

특정 파일 비교하기

때로는 특정 파일이나 파일 집합의 변경 사항만 보고 싶을 때가 있습니다. Git diff 를 사용하면 이를 쉽게 수행할 수 있습니다.

여러 파일에 변경 사항을 만들어 봅시다:

echo "function multiply(a, b) { return a * b; }" >> greet.js
echo "const doubledNumbers = numbers.map(n => n * 2);" >> numbers.js

이제 greet.js의 변경 사항만 보고 싶다면 다음과 같이 입력합니다:

git diff greet.js

이렇게 하면 greet.js에 가해진 변경 사항만 표시됩니다.

브랜치 간의 특정 파일 비교도 가능합니다:

git diff master feature-branch -- numbers.js

이것은 masterfeature-branch 브랜치 사이의 numbers.js 파일 차이점만 보여줍니다.

위 명령어에서 --는 브랜치 이름과 파일 경로를 구분하기 위해 사용됩니다. 항상 필수적인 것은 아니지만, 파일 이름이 브랜치 이름으로 오해받을 수 있는 상황을 방지하기 위해 사용하는 습관을 들이는 것이 좋습니다.

우리가 배운 모든 diff 명령어에 파일 경로를 사용할 수 있다는 점을 기억하세요. 이는 수많은 파일이 변경된 대규모 프로젝트에서 특정 부분에만 집중하고 싶을 때 특히 유용합니다.

외부 diff 도구 사용하기

Git 의 내장 diff 기능도 강력하지만, 때로는 변경 사항을 더 시각적으로 보고 싶을 수 있습니다. 많은 개발자들이 이를 위해 외부 diff 도구를 사용합니다.

인기 있는 도구 중 하나는 vimdiff입니다. Git 이 vimdiff를 사용하도록 설정해 봅시다:

git config --global diff.tool vimdiff
git config --global difftool.prompt false

이제 git diff 대신 git difftool을 사용할 수 있습니다:

git difftool

이 명령어를 실행하면 수정된 각 파일이 vimdiff에서 열립니다. 다음 파일로 이동하려면 :n을, 이전 파일로 이동하려면 :prev를 입력하면 됩니다. vimdiff를 종료하려면 :qa!를 입력하세요.

Beyond Compare, KDiff3, P4Merge 등 다양한 diff 도구가 존재합니다. 도구의 선택은 보통 개인의 취향과 사용하는 운영 체제에 따라 달라집니다.

시각적인 diff 도구가 대규모 변경 사항을 파악하는 데 큰 도움이 되지만, 항상 필수적인 것은 아닙니다. 많은 개발자들은 표준 git diff 출력에 익숙해져 일상적인 작업에서는 그 속도와 단순함을 선호하기도 합니다.

요약

축하합니다, diff 탐정 여러분! git diff의 세계를 깊이 있게 탐험하셨습니다. 우리가 다룬 핵심 개념들을 정리해 봅시다:

  1. 작업 디렉토리와 스테이징 영역 비교: 작업 디렉토리에서 아직 스테이징되지 않은 변경 사항을 확인하는 방법을 배웠습니다.
  2. 스테이징 영역과 마지막 커밋 비교: 커밋하기 전에 스테이징된 내용을 검토하는 방법을 익혔습니다.
  3. 브랜치 비교: 서로 다른 브랜치가 어떻게 갈라졌는지 비교하는 방법을 확인했습니다.
  4. 특정 파일 비교: 관심 있는 특정 파일에만 집중하여 diff 를 확인하는 방법을 배웠습니다.
  5. 외부 diff 도구 사용: 변경 사항을 다른 관점에서 보기 위해 시각적 diff 도구를 사용하는 방법을 살펴보았습니다.

git diff 명령어는 여러분의 Git 도구 상자에서 매우 강력한 도구입니다. 커밋을 준비하거나, 동료의 코드를 리뷰하거나, 프로젝트의 히스토리를 이해하려 할 때 변경 사항을 정밀하게 검사할 수 있게 해줍니다.

git diff에 능숙해지려면 연습이 필요하다는 점을 기억하세요. 처음에는 출력이 다소 난해해 보일 수 있지만, 시간이 지나면 diff 를 빠르고 효율적으로 읽을 수 있게 될 것입니다.

Git 여정을 계속하면서 git diff의 다양한 옵션과 활용 사례를 계속 탐구해 보세요. 이 다재다능한 명령어는 다른 Git 기능들과 결합되어 프로젝트의 변화에 대한 깊은 통찰력을 제공할 것입니다.

즐거운 diff 탐색 되시길 바라며, 여러분의 코드 변경 사항이 항상 명확하고 의도한 대로 이루어지길 응원합니다!