Git & GitHub 강좌

Git 충돌 미리 알아보고 안전하게 작업하기: Git Hooks 활용 가이드

_Blue_Sky_ 2025. 2. 16. 20:38
728x90

만일 내가 a.txt 파일을 수정했는데 다른 직원이 이미 a.txt를 같은 위치에 수정을 해서  push를 했어, 나는 pull하면 당연히 충돌할건데 미리 알아 낼수는 없을까?

 

1. git fetch 후 git status 확인

로컬에서 작업하기 전에 원격 저장소의 변경 사항을 가져와서 비교하면 충돌 가능성을 미리 알 수 있습니다.

  git fetch origin git status 
  • git fetch는 원격 저장소의 최신 변경 사항을 가져오지만, 병합(merge)하지 않습니다.
  • git status에서 Your branch is behind 'origin/main' by X commits 같은 메시지가 나타나면, 원격 저장소에 변경 사항이 있으므로 충돌 가능성이 있습니다.

2. git diff origin/main으로 변경 사항 비교

원격 저장소(origin/main 브랜치)와 로컬 브랜치의 차이를 비교할 수 있습니다.

git diff origin/main 
  • 만약 a.txt에 대한 변경 내용이 표시되면, 다른 직원이 해당 파일을 수정했을 가능성이 큽니다.

3. git pull --rebase 시도하기 전에 확인

충돌을 방지하려면 git pull을 수행하기 전에 원격 브랜치와 비교하는 것이 좋습니다.

  git pull --rebase 
  • 만약 a.txt에서 충돌이 발생하면 Git이 자동으로 알려주고, 충돌을 해결한 후 다시 git rebase --continue를 실행하면 됩니다.

4. Push 전에 git pull --dry-run으로 미리 확인

아래 명령어를 사용하면 실제로 병합을 하지 않고, 충돌 가능성을 확인할 수 있습니다.

  git pull --dry-run
  • 아무런 출력이 없으면 충돌 없이 pull이 가능하다는 의미입니다.
  • 만약 충돌이 예상된다면 git pull을 먼저 수행하여 해결한 후 push하는 것이 좋습니다.
728x90

Git 충돌, 더 이상 걱정 마세요!

팀원들과 함께 Git을 사용하다 보면, 같은 파일을 동시에 수정하여 발생하는 충돌 문제에 부딪히기 쉽습니다. 이러한 충돌은 개발 프로세스를 방해하고, 불필요한 시간 낭비를 초래할 수 있습니다. 하지만, Git은 이러한 문제를 해결하기 위한 다양한 기능을 제공합니다.

이번 글에서는 Git 충돌을 미리 예방하고 안전하게 작업할 수 있도록 도와주는 Git Hooks에 대해 자세히 알아보고, 실제 예제를 통해 활용 방법을 살펴보겠습니다.

Git Hooks란 무엇일까요?

Git Hooks는 특정 Git 이벤트가 발생할 때 자동으로 실행되는 사용자 정의 스크립트입니다. 예를 들어, 커밋을 하기 전, push 하기 전 등과 같은 상황에서 미리 정의된 작업을 수행할 수 있습니다.

Git Hooks의 종류

  • 커밋 워크플로 훅: pre-commit, prepare-commit-msg, commit-msg, post-commit 등
  • 이메일 워크플로 훅: applypatch-msg, pre-applypatch, post-applypatch 등
  • 기타 훅: pre-rebase, post-rewrite, post-merge, pre-push, pre-receive, prepare-commit-msg, push-to-checkout, update 등

Git Hooks를 활용한 충돌 예방

1. pre-push 훅 설정하기

pre-push 훅은 push를 하기 전에 실행되는 훅으로, 원격 저장소와의 차이를 확인하고 충돌 가능성을 미리 알려줍니다.

# .git/hooks/pre-push 파일 생성
#!/bin/sh

git fetch
if ! git diff --quiet origin/main; then
  echo "⚠️  원격 저장소에 변경 사항이 있습니다. pull을 먼저 수행하세요."
  exit 1
fi

위 스크립트를 .git/hooks/pre-push 파일에 추가하고 실행 권한을 부여하면, push를 할 때마다 자동으로 원격 저장소와의 차이를 비교하게 됩니다. 만약 차이가 있다면, push가 중단되고 위의 메시지가 출력됩니다.

2. 충돌 시 자동 알림

Slack, Discord 등의 메시징 앱을 사용하여 충돌 발생 시 팀원들에게 알림을 보낼 수 있습니다.

# .git/hooks/pre-push 파일 수정
#!/bin/sh

git fetch
if ! git diff --quiet origin/main; then
  echo "⚠️  원격 저장소에 변경 사항이 있습니다. pull을 먼저 수행하세요."
  # Slack에 알림 보내기 (예시)
  curl -X POST -H 'Content-type: application/json' --data '{"text": "Git 충돌 발생! 즉시 확인해주세요."}' https://hooks.slack.com/services/YOUR_SLACK_WEBHOOK
  exit 1
fi

3. 자동으로 pull 수행하기

충돌이 발생했을 때, 자동으로 pull을 수행하여 충돌을 해결할 수도 있습니다. 하지만, 이 경우 충돌 해결 과정에서 데이터 손실이 발생할 수 있으므로 주의해야 합니다.

# .git/hooks/pre-push 파일 수정 (권장하지 않음)
#!/bin/sh

git fetch
if ! git diff --quiet origin/main; then
  echo "⚠️  원격 저장소에 변경 사항이 있습니다. 자동으로 pull을 수행합니다."
  git pull
fi

추가적인 활용

  • 코드 스타일 검사: 커밋하기 전에 코드 스타일 검사를 수행하여 코드 품질을 유지할 수 있습니다.
  • 테스트 실행: 커밋하기 전에 테스트를 실행하여 버그를 미리 찾아낼 수 있습니다.
  • 커밋 메시지 검사: 커밋 메시지의 형식을 검사하여 표준을 준수하도록 할 수 있습니다.
728x90

Git Hooks를 활용하면 개발 과정에서 발생할 수 있는 다양한 문제를 미리 예방하고, 팀원들과의 협업 효율을 높일 수 있습니다. 특히, pre-push 훅을 사용하여 충돌을 미리 확인하고, 자동화된 프로세스를 구축하면 더욱 안정적인 개발 환경을 구축할 수 있습니다.

 


git diff origin/main 명령어를 실행하면, 로컬 브랜치와 원격 브랜치(origin/main 기준)의 차이를 보여줍니다. 예제를 들어보겠습니다.


예제 시나리오

  • a.txt라는 파일이 존재함.
  • 원격(origin/main)에서는 다른 직원이 a.txt의 내용을 수정하고 push함.
  • 나는 로컬에서도 a.txt를 수정했지만 아직 push하지 않음.

이 상태에서 git diff origin/main 명령어를 실행하면 다음과 같이 출력될 수 있습니다.


출력 예시

 
diff --git a/a.txt b/a.txt
index e69de29..a837ac7 100644
--- a/a.txt
+++ b/a.txt
@@ -1,2 +1,2 @@
-Hello, world!
+Hello, Git!
 This is a test file.

출력 내용 설명

  1. diff --git a/a.txt b/a.txt
    • a.txt 파일에서 차이가 발생했음을 의미합니다.
  2. index e69de29..a837ac7 100644
    • 파일의 체크섬 정보 (무시해도 됨).
  3. --- a/a.txt
    • 원격(origin/main)의 파일 버전.
  4. +++ b/a.txt
    • 로컬에서 수정한 버전.
  5. @@ -1,2 +1,2 @@
    • 변경된 라인의 위치 정보 (-는 원격, +는 로컬).
  6. -Hello, world!
    • 원격에서의 기존 내용.
  7. +Hello, Git!
    • 로컬에서 수정한 내용.

이제 어떻게 해야 할까?

  • 만약 원격의 변경 사항을 반영해야 한다면, git pull --rebase 또는 git merge origin/main을 실행하여 충돌을 해결한 후 push하세요.
  • 변경 내용이 충돌하지 않는다면 그대로 git push할 수도 있습니다.

충돌한 팀원이 누구인지 확인하는 방법은 몇 가지 있습니다.


1. git blame으로 확인 (파일별 최근 변경자 추적)

git blame을 사용하면 특정 파일에서 누가 마지막으로 어떤 줄을 변경했는지 확인할 수 있습니다.

git blame a.txt

출력 예시:

a837ac7b (Alice  2025-02-10 12:30:45 +0900) Hello, world!
e69de29b (Bob    2025-02-09 15:12:12 +0900) This is a test file.
  • 각 줄 앞에 커밋 해시, 작성자, 날짜, 시간이 표시됩니다.
  • 최신 커밋의 작성자가 Alice이므로, 최근에 이 파일을 수정한 사람이 Alice입니다.

2. git log로 특정 파일의 변경 기록 확인

이전 변경 이력을 보려면 git log를 사용합니다.

git log --oneline -- a.txt

출력 예시:

a837ac7b (Alice) Update greeting message
e69de29b (Bob) Initial commit
  • 가장 위에 있는 a837ac7b 커밋이 최신 변경 사항이며, 작성자는 Alice입니다.
  • Alice가 a.txt를 최근에 수정하고 push한 것을 알 수 있습니다.

3. git log --author로 특정 사람이 한 변경 확인

만약 특정 사람이 충돌을 일으켰을 것으로 의심된다면, 그 사람의 최근 커밋을 조회할 수 있습니다.

git log --author="Alice" --oneline

이렇게 하면 Alice가 최근에 한 모든 커밋을 확인할 수 있습니다.


4. git fetch 후 git diff origin/main 으로 변경 사항 확인

파일 전체가 아니라 어떤 내용이 변경되었는지 확인하려면 다음을 실행합니다.

git fetch
git diff origin/main
  • 누가 변경했는지는 나오지 않지만, 어떤 부분이 수정되었는지는 확인할 수 있습니다.
  • 그런 다음 git blame 또는 git log -p를 사용하면 누가 변경했는지도 알 수 있습니다.

5. git shortlog -sne로 팀원들의 전체 기여도 확인

프로젝트에서 누가 얼마나 많이 커밋했는지 보고 싶다면 다음을 실행합니다.

git shortlog -sne

출력 예시:

  25  Alice <alice@example.com>
  18  Bob <bob@example.com>
  10  Charlie <charlie@example.com>
  • Alice가 가장 많은 커밋을 했고, 충돌 가능성이 높은 사람일 수도 있습니다.

 

728x90