터미널 창에 붉은색 글씨로 CONFLICT (content): Merge conflict in... 이라는 경고가 뜨는 순간, 가슴이 철렁 내려앉았던 경험 다들 한 번쯤 있으실 거예요. “혹시 내가 작성한 코드가 다 날아가는 건 아닐까?”, “동료의 소중한 코드를 실수로 지워버리면 어쩌지?” 하는 두려움이 앞서기 마련이죠. 저 역시 주니어 시절 팀 프로젝트에서 첫 머지 충돌을 겪었을 때, 식은땀을 뻘뻘 흘리며 프로젝트 전체를 다시 내려받아야 하나 심각하게 고민했던 기억이 생생하답니다 😊
하지만 전혀 당황하실 필요 없어요! Git 충돌은 시스템 오류나 치명적인 버그가 아닙니다. 오히려 같은 파일의 같은 줄을 수정한 두 작업 내역을 Git이 임의로 덮어쓰지 않고, 개발자에게 직접 안전하게 선택해 달라고 요청하는 고마운 안전장치거든요. 오늘 이 글 하나만 차근차근 따라오시면, 앞으로 어떤 복잡한 충돌 상황을 마주하더라도 차분하고 프로페셔널하게 해결하실 수 있을 거예요!
충돌(Conflict)이 발생하는 원리와 마커 해부 🤔
충돌을 명쾌하게 해결하려면 먼저 Git이 언제 충돌을 일으키는지 그 원리를 알아야 해요. Git은 기본적으로 두 브랜치의 공통 조상 커밋(Base)을 기준으로 양쪽의 변경 사항을 자동으로 합치는 3-Way Merge 알고리즘을 사용합니다. 서로 다른 파일이 수정되었거나, 같은 파일이라도 수정된 줄 위치가 다르면 Git이 알아서 깔끔하게 병합해 주죠.
문제는 동일한 파일의 동일한 코드 라인을 두 사람이 서로 다르게 수정했을 때 발생해요. Git 입장에서는 A 개발자의 코드가 맞는지, B 개발자의 코드가 맞는지 독단적으로 판단할 수 없기 때문에 머지 작업을 일시 정지하고 파일 내부에 특수한 충돌 마커(Conflict Marker)를 남겨 놓습니다.
📝 충돌 마커 구조 3요소
<<<<<<< HEAD : 현재 내가 체크아웃하여 작업 중인 로컬 브랜치의 코드 시작점
======= : 양쪽 브랜치 변경 사항을 구분하는 기준선
>>>>>>> [브랜치명] : 머지하려는 상대방 브랜치에서 가져온 코드의 끝점
충돌 마커(
<<<<<<<, =======, >>>>>>>) 자체도 일반 텍스트 문자열입니다. 코드를 조율한 뒤 이 특수 기호들을 말끔히 지우지 않고 커밋하면, 실제 애플리케이션 실행 시 런타임 문법 에러(Syntax Error)가 발생하므로 반드시 마커 라인을 모두 삭제해야 합니다.
실전! Git Merge 충돌 해결 4단계 워크플로우 📊
충돌 메시지를 만났을 때 당황하지 않고 순서대로 따라 할 수 있는 4단계 정석 워크플로우를 정리해 드릴게요. 실무에서 충돌의 95% 이상은 이 4단계 안에서 안전하게 마무리됩니다.
- 1단계 – 충돌 파일 목록 확인:
git status를 입력하여 빨간색으로 표시되는 Unmerged paths 항목의 파일들을 확인합니다. - 2단계 – 충돌 코드 조율 및 마커 제거: 해당 파일을 에디터(VS Code 등)로 열어 내 코드와 상대 코드를 비교한 뒤, 최종 남길 코드만 남기고 마커 기호를 지웁니다.
- 3단계 – 해결 완료 스테이징: 파일 저장을 완료한 후
git add [파일명]명령어로 충돌이 해결되었음을 Git에 알립니다. - 4단계 – 머지 커밋 완료:
git commit을 실행하여 머지 프로세스를 마칩니다. (Git이 자동으로 생성한 기본 머지 커밋 메시지를 그대로 저장해도 좋습니다.)
충돌 해결 방식 및 도구별 장단점 비교
| 해결 방식 | 주요 특징 | 장점 | 권장 사용자 |
|---|---|---|---|
| VS Code 내장 에디터 | 클릭 한 번으로 Current / Incoming 선택 지원 | 직관적이며 시각적 비교가 매우 편함 | 모든 초보 및 실무 개발자 |
| CLI 터미널 수동 편집 | Vim/Nano 등으로 마커 직접 타이핑 수정 | GUI가 없는 원격 서버 환경에서 필수적임 | 서버 관리자 및 백엔드 개발자 |
| 전용 머지툴 (Meld, KDiff3) | git mergetool을 활용한 3-Way 병렬 뷰 |
대규모 파일 충돌 시 세밀한 비교 가능 | 복잡한 대형 프로젝트 팀 |
| 전체 채택 명령어 (ours/theirs) | 특정 브랜치 코드로 파일 전체를 일괄 덮어쓰기 | 수백 줄의 변경을 한 번에 정리 가능 | 빌드 산출물/설정 충돌 해결 시 |
충돌 해결 중 당황하여
git push -f(강제 푸시)를 시도하거나, 파일을 덜컥 지워버리는 일이 없도록 주의해야 합니다. 작업이 꼬여서 도저히 갈피를 잡을 수 없을 때는 언제든지 git merge --abort를 실행하면 머지 시도 직전의 안전한 상태로 1초 만에 되돌아갈 수 있습니다.
상황별 Git 충돌 대처 명령어 찾기 🧮
충돌 상황마다 필요한 명령어가 머릿속에서 잘 떠오르지 않을 때가 많죠? 현재 마주한 상황을 아래 셀렉트 박스에서 선택하시면, 가장 안전하고 알맞은 Git 해결 명령어와 설명을 즉시 확인하실 수 있습니다.
🔢 상황별 Git 해결 명령어 추천기
실전 예시: 로그인 모듈 코드 충돌 해결 과정 📚
이론만 보는 것보다 실제 코드로 살펴보면 훨씬 이해하기 쉬워요. 동료 개발자 민수 님과 제가 동일한 authService.js 파일의 로그인 함수를 각자의 브랜치에서 수정한 뒤 병합하는 상황을 가정해 볼게요.
충돌 발생 당시의 코드 화면
<<<<<<< HEAD
// 내 브랜치 (feature/session-login)
function authenticateUser(user) {
return sessionManager.createSession(user.id);
}
=======
// 민수 님의 브랜치 (feature/jwt-auth)
function authenticateUser(user) {
return jwt.sign({ id: user.id }, process.env.JWT_SECRET);
}
>>>>>>> feature/jwt-auth
해결 및 조율 과정
1) 상황 파악: 팀 회의 결과 기존 세션 방식 대신 JWT 토큰 인증 방식을 최종 표준으로 도입하기로 합의했습니다.
2) 코드 편집: <<<<<<< HEAD, =======, 세션 로그인 코드, >>>>>>> feature/jwt-auth를 깨끗하게 지우고 민수 님의 JWT 생성 로직만 남깁니다.
최종 완료 처리 (터미널)
– 파일 저장 후 스테이징: git add authService.js
– 병합 커밋 완료: git commit -m "Merge branch 'feature/jwt-auth' - JWT 인증 모듈 채택"
보시다시피 충돌 해결이란 상대방의 코드를 무조건 지우는 것이 아니라, 두 변경 사항 중 비즈니스 요구사항에 맞는 올바른 코드를 협의하여 선택하는 과정이랍니다.
협업에서 충돌을 80% 줄여주는 실무 습관 👩💻👨💻
충돌을 잘 해결하는 능력도 훌륭하지만, 애초에 충돌 자체가 적게 일어나도록 예방하는 개발 습관을 들이는 것이 훨씬 생산적이에요. 현업 시니어 개발자들이 입을 모아 강조하는 세 가지 핵심 습관을 전해드립니다.
- 원격 main 브랜치를 수시로 pull 받기: 출근 직후나 새로운 작업을 시작하기 전, 습관적으로
git pull origin main을 실행해 로컬 베이스를 최신 상태로 유지하세요. - 작고 잦은 커밋과 짧은 PR 수명: 하나의 브랜치에 수천 줄의 코드를 몇 주 동안 쌓아두지 마세요. 작업 단위는 1~2일 내에 머지될 수 있을 만큼 잘게 쪼개는 것이 좋습니다.
- 단일 책임 원칙에 따른 파일 분리: 하나의 거대한 파일에 여러 기능이 몰려 있으면 충돌 확률이 급증합니다. 파일과 모듈을 기능별로 분리해 두면 동시 수정 확률이 크게 낮아집니다.
팀원과 같은 파일의 핵심 로직을 동시에 건드려야 할 때는 작업 착수 전 메신저로 가볍게 대화를 나누는 것만으로도 대규모 충돌의 90%를 사전에 방지할 수 있습니다. 깃은 어디까지나 도구일 뿐, 최고의 버전 관리는 팀원 간의 투명한 소통에서 시작됩니다.
마무리: 핵심 내용 요약 📝
Git 충돌 해결의 전 과정을 핵심만 쏙 뽑아 카드로 정리해 두었습니다. 머지 도중 충돌이 발생해 막막할 때마다 아래 요약 카드를 꺼내 보며 순서대로 점검해 보세요!
Git 충돌 해결 핵심 치트시트
자주 묻는 질문 ❓
git diff로 마커가 남아있는지 꼭 확인하세요.git checkout --ours [파일명]을, 상대 브랜치 버전을 쓰려면 git checkout --theirs [파일명]을 입력한 뒤 git add를 진행하시면 됩니다.git commit 대신 git rebase --continue 명령어를 입력해야 다음 단계로 넘어갑니다.깃 충돌은 실력 있는 개발자로 성장하는 과정에서 누구나 수없이 겪게 되는 자연스러운 관문이에요. 오늘 정리해 드린 원리와 워크플로우를 마음속에 담아두신다면 다음번 충돌 경고가 떴을 때도 미소 지으며 여유롭게 해결하실 수 있을 겁니다. 포스트 내용 중 이해하기 어렵거나 더 알고 싶은 깃 명령어가 있다면 언제든 댓글로 편하게 물어봐 주세요~ 😊