깃허브 머지 충돌(Conflict) 해결하고 이전 버전으로 되돌리는 깃 명령어 정리 금요일 칼퇴 비법 공개
- 공유 링크 만들기
- X
- 이메일
- 기타 앱
깃허브 머지 충돌(Conflict) 해결하고 이전 버전으로 되돌리는 깃 명령어 정리 금요일 칼퇴 비법 공개
Git 충돌, 피할 수 없다면 즐기는 방법 (feat. 금요일 오후 5시의 악몽)
개발자로 일하면서 가장 심장이 쫄깃해지는 순간이 언제인가요? 서버가 다운되었을 때? 아니면 DB 데이터를 날렸을 때? 물론 그것들도 무섭지만, 저는 개인적으로 퇴근 직전, 특히 금요일 오후 5시에 "이제 배포하고 가야지~" 하며 머지(Merge) 버튼을 눌렀는데 뻘건 글씨로 Conflict(충돌)가 떴을 때가 가장 식은땀이 나더라고요. 😅 아마 이 글을 읽고 계신 여러분도 한 번쯤은 터미널 창에 뜬 무수한 <<<< HEAD, ====, >>>> 기호들을 보며 한숨 쉬어본 경험이 있으실 겁니다.
저도 주니어 시절에는 이 충돌 메시지가 마치 "넌 개발자 자격이 없어!"라고 혼내는 것 같아서 무서웠어요. 그래서 몰래 코드를 백업해두고 프로젝트를 통째로 다시 클론 받기도 했었죠. (솔직히 다들 한 번씩 해보셨죠?) 하지만 10년 차가 된 지금, 저는 Git 충돌을 조금 다른 시각으로 바라보게 되었습니다. 충돌은 우리가 일을 잘못한 게 아니라, 팀원들이 그만큼 치열하게 같은 코드를 고민하고 있다는 증거니까요. 오늘은 동료에게 커피 한 잔 사주면서 수다 떨듯이, 깃허브 충돌을 우아하게 해결하는 방법과 실수로 코드를 날렸을 때 시간을 되돌리는 마법 같은 명령어들에 대해 이야기해볼까 합니다.
충돌(Conflict)은 도대체 왜 나는 걸까요?
우선 적을 알고 나를 알면 백전백승이라고 하죠. 충돌이 왜 발생하는지 그 원리부터 짚고 넘어갑시다. Git은 정말 똑똑한 녀석입니다. 웬만한 수정 사항은 알아서 척척 합쳐줍니다. 예를 들어, 철수가 A파일의 10번째 줄을 고치고, 영희가 같은 파일의 100번째 줄을 고쳤다면 Git은 "오케이, 둘 다 반영!"하고 스무스하게 넘어갑니다.
하지만 문제는 "같은 파일의 같은 라인"을 서로 다르게 수정했을 때 발생합니다. Git 입장에서는 당황스러운 거죠. "철수는 이 변수를 a라고 불렀고, 영희는 b라고 불렀는데... 난 도대체 누구 편을 들어줘야 해?"라고 묻는 겁니다. 이게 바로 충돌입니다. 기계가 판단할 수 없으니 사람인 우리에게 결정을 위임하는 것이죠.
💡 경험담: 예전에 로그인 기능을 개발할 때였어요. 저는 보안 로직을 강화하느라 UserAuth 클래스를 수정 중이었고, 다른 동료는 소셜 로그인 기능을 붙이느라 같은 클래스를 수정 중이었죠. 서로 소통 없이 3일 동안 각자 작업하다가 합치려고 보니 파일 전체가 빨간색으로 뒤덮였던 적이 있습니다. 그때 깨달았죠. Git 충돌 해결의 가장 좋은 도구는 명령어가 아니라 '입'이라는 것을요. 미리 "나 여기 건드린다"고 말만 했어도 막을 수 있었던 참사였습니다.
실전! 충돌 해결 시나리오와 대처법
이제 진짜 상황으로 들어가 봅시다. git merge 명령어를 쳤는데 "CONFLICT (content): Merge conflict in..." 메시지가 떴습니다. 당황하지 마세요. 심호흡 한번 하고 다음 단계들을 따라가면 됩니다.
1단계: 충돌 난 파일 열어보기 (공포의 <<<< HEAD)
충돌이 난 파일을 에디터(VS Code, IntelliJ 등)로 열어보면 Git이 친절하게(?) 표시해 둔 마커들을 볼 수 있습니다. 처음 보면 외계어 같지만 구조는 단순합니다.
- <<<<<<< HEAD : 현재 내 브랜치(내가 작업한 내용)의 시작점입니다.
- ======= : 내 코드와 상대방 코드를 구분하는 경계선입니다.
- >>>>>>> branch-name : 들어오는 브랜치(상대방이 작업한 내용)의 끝점입니다.
우리는 이 세 가지 기호 사이의 내용을 보고 결정해야 합니다. 내 코드를 남길지(Accept Current Change), 상대방 코드를 받을지(Accept Incoming Change), 아니면 둘 다 섞어서 새로운 코드를 만들지(Accept Both Changes) 말이죠. 요즘 IDE들은 버튼 하나로 이걸 선택할 수 있게 해주지만, 무지성으로 버튼을 누르는 건 금물입니다.
2단계: 문맥 파악하기 (Context is King)
단순히 코드만 보고 "내 게 더 최신이니까 내 걸로 덮어써야지"라고 생각하면 큰일 납니다. 상대방이 왜 코드를 그렇게 짰는지 의도를 파악해야 해요. 예를 들어, 제가 변수명을 `userList`에서 `users`로 바꿨는데, 상대방은 `userList`를 그대로 쓰면서 새로운 필터링 로직을 추가했을 수 있습니다. 이때 제 코드로 덮어쓰면 상대방의 필터링 로직이 날아가고, 상대방 코드로 덮어쓰면 제가 바꾼 변수명이 원복되겠죠.
이럴 때는 두 코드를 적절히 섞는 '수동 병합'이 필요합니다. 변수명은 `users`로 바꾸되, 상대방이 추가한 필터링 로직도 가져오는 식이죠. 이 과정이 귀찮다고 대충 넘기면 나중에 배포 후에 "어? 그 기능 왜 안 돼요?"라는 소름 돋는 피드백을 받게 됩니다.
3단계: 해결 후 마무리 (Add & Commit)
코드를 정리하고 <<<<, ====, >>>> 같은 마커들을 모두 지웠다면 이제 Git에게 "나 해결했어!"라고 알려줘야 합니다. 터미널에서 `git add [파일명]`을 입력하고, `git commit`을 하면 비로소 충돌 해결이 완료되면서 머지 커밋이 생성됩니다.
시간을 달리는 개발자: Reset과 Revert 완벽 정리
사람은 누구나 실수를 합니다. 잘못된 코드를 커밋하거나, 머지를 잘못해서 프로젝트가 엉망이 되기도 하죠. 이럴 때 우리에게 필요한 건 타임머신입니다. Git에는 두 가지 종류의 타임머신이 있습니다. 바로 Reset과 Revert입니다. 이 둘의 차이를 명확히 아는 것이 시니어 개발자로 가는 지름길입니다.
🔎 관련 상품 추천
아래 링크를 통해 구매 시 운영자에게 일정 수수료가 발생할 수 있습니다.
1. **깃허브 머지 충돌(Conflict) 해결하고 이전 버전으로 되돌리는 깃 명령어 정리**
'1. **깃허브 머지 충돌(Conflict) 해결하고 이전 버전으로 되돌리는 깃 명령어 정리**' 관련 상품을 쿠팡에서 확인해 보세요.
상품 보러가기 →
아래 링크를 통해 구매 시 운영자에게 일정 수수료가 발생할 수 있습니다.
'1. **깃허브 머지 충돌(Conflict) 해결하고 이전 버전으로 되돌리는 깃 명령어 정리**' 관련 상품을 쿠팡에서 확인해 보세요.
상품 보러가기 →- 공유 링크 만들기
- X
- 이메일
- 기타 앱
댓글
댓글 쓰기