안녕하세요! [생각하는 개발자]입니다.
지난 시간 우리는 Git의 기본 저장 메커니즘과 동료들에게 신뢰를 주는 커밋 메시지 규약을 마스터했습니다. 이제 혼자 쓰는 저장소를 넘어, 여러 명이 동시에 하나의 프로젝트를 개발하는 실전 협업의 문을 열어보겠습니다.
여러 개발자가 같은 파일을 동시에 수정하고 서버에 올릴 때, 필연적으로 마주치는 깃의 수호신이 있습니다. 바로 충돌(Conflict)입니다. 특히 iOS 개발자들이 가장 무서워한다는 .xcodeproj 파일의 충돌 원인과 이를 깔끔하게 해결하는 법까지 오늘 완벽하게 조각내 드리겠습니다.

4.3.1 캔버스 위에 재료 얹기 (브랜치와 충돌의 원리)
우리가 작업하는 메인 줄기를 main 브랜치라고 부릅니다. 이 줄기에서 나만의 독립된 개발 공간을 만드는 명령어가 바로 Branch입니다.
# 1. 'feature/login' 이라는 이름의 새로운 브랜치(방) 만들기
git branch feature/login
# 2. 새로 만든 브랜치로 이동하기
git checkout feature/login
# (최신 Git에서는 이 두 과정을 'git checkout -b feature/login'으로 한 번에 처리합니다)
# 3. 내 방에서 작업 완료 후 메인 줄기로 돌아와 합치기 (Merge)
git checkout main
git merge feature/login
만약 내가 main 브랜치에서 분기해 나와 코드를 고치는 동안, 동료가 먼저 main 브랜치에 있는 같은 파일의 같은 줄을 고치고 Push해 버렸다면?
내가 합치려고 할 때 Git은 "두 소스코드 중 어떤 것을 살려야 할지 모르겠어!"라며 폭탄(Conflict)을 던집니다.
4.3.2 [단계별 실습] 공포의 Conflict 안전하게 제압하기
충돌이 나면 당황하지 않고 아래의 순서대로 해결하면 됩니다.
1단계: 충돌 발생 상황 직시하기
터미널이나 Xcode에서 merge를 실행했을 때 CONFLICT (content): Merge conflict in ViewController.swift라는 빨간 경고가 떴다면, 해당 파일을 열어봅니다. 소스코드에 요상한 외계어가 적혀 있을 것입니다.
<<<<<<< HEAD
// 메인 줄기(혹은 내가 현재 머물고 있는 곳)의 코드
welcomeLabel.text = "안녕하세요, 생각하는 개발자님!"
=======
// 합치려고 들어오는 브랜치(feature/login)의 코드
welcomeLabel.text = "반갑습니다, 생각하는 개발자님!"
>>>>>>> feature/login
- <<<<<<< HEAD부터 =======까지: 현재 내가 작업하던 기준의 코드입니다.
- =======부터 >>>>>>> 브랜치명까지: 새로 들어와서 부딪힌 상대방의 코드입니다.
2단계: 코드 교통정리 후 커밋하기
- 동료와 상의하거나 코드의 맥락을 분석하여 어떤 코드를 남길지 결정합니다. (예: 반갑습니다로 통일하기로 합의)
- <<<<<<<, =======, >>>>>>> 기호와 쓸모없어진 코드를 직접 텍스트 에디터에서 깨끗하게 지워줍니다.
- 수정 완료 후, 충돌을 해결했다는 신호를 깃에 보냅니다.
git add ViewController.swift
git commit -m "fix: ViewController.swift 충돌 해결"
🛠️ iOS 개발자만의 치트키: .xcodeproj 충돌 해결법
소스코드 충돌은 눈으로 보고 고치면 되지만, iOS 프로젝트 파일인 project.pbxproj (xcodeproj 내부 파일)이 충돌 나면 머리가 하얘집니다. Xcode에서 프로젝트 파일이 빨간색으로 변하며 열리지도 않기 때문이죠.
이유는 간단합니다. 나도 파일을 하나 추가했고, 동료도 파일을 하나 추가했다면, Xcode는 프로젝트 내부 파일 관리 대장인 project.pbxproj 파일의 같은 위치에 파일 식별 코드를 적기 때문에 무조건 충돌이 납니다.
💡 실무 해결 꿀팁 3단계
- 절대 Xcode 프로젝트를 끄고 멘붕에 빠지지 마세요.
- 충돌이 난 .xcodeproj 우클릭 ➔ 패키지 내용 보기 ➔ project.pbxproj 파일을 텍스트 편집기(VS Code 등)로 엽니다.
- 똑같이 <<<<<<< HEAD를 검색해 찾아간 뒤, 나와 동료가 추가한 파일 고유 ID 라인을 둘 다 살려두고 기호만 삭제해 줍니다. 저장 후 Xcode를 다시 켜면 마술처럼 프로젝트가 정상적으로 로드됩니다!
👨💻 안드로이드 개발자와의 비교 조각
안드로이드 스튜디오의 빌드 도구인 Gradle 환경에서도 멀티 모듈 세팅이나 build.gradle 라이브러리 추가 시 충돌이 자주 발생합니다. 하지만 안드로이드는 텍스트 기반의 복사·붙여넣기가 비교적 명확한 편이죠.
반면 iOS의 xcodeproj 파일은 UUID 같은 난수 기반의 기계식 코드로 내부 파일 구조를 링크하기 때문에 사람이 직관적으로 읽기 매우 어렵습니다.
그래서 최근 현대 iOS 프로젝트에서는 이러한 깃 충돌을 근본적으로 피하기 위해, 프로젝트 파일을 수동으로 관리하지 않고 코드로 프로젝트 구조를 자동 생성해 주는 XcodeGen이나 Tuist 같은 오픈소스 도구를 도입해 .xcodeproj 자체를 아예 .gitignore에 넣어 버전 관리 대상에서 배제해 버리는 아키텍처 전략을 선호하기도 합니다.
🎯 오늘의 요약
- Branch는 메인 줄기에 영향을 주지 않고 안전하게 새 기능을 개발하는 독립된 방이다.
- Conflict는 같은 파일의 같은 줄을 동시에 수정했을 때 발생하며, 개발자가 직접 코드를 조율해 기호를 지우고 다시 커밋해야 한다.
- iOS 협업의 복병인 .xcodeproj 충돌은 내부의 project.pbxproj 텍스트 코드를 수동으로 병합하여 해결한다.
충돌을 두려워하지 않는 개발자가 진짜 협업의 중심에 설 수 있습니다.
다음 장 [iOS 4-4]에서는 브랜치 관리를 체계적으로 정립해 주는 현업 표준 전략인 Git-Flow와, 코드의 품질을 높이는 Pull Request(PR)를 통한 상호 리뷰 생태계를 들여다보겠습니다. 생각의 힘을 모아 더 큰 협업으로 나아가봅시다!