머지 옵션
평범한 머지는 버튼 하나면 끝이고, 대부분의 경우 그게 이야기의 전부예요. 이 페이지는 나머지 경우를 위한 것이에요. 머지할 때마다 부딪히는 잠금 파일, 누군가 들여쓰기를 다시 한 파일, 경로가 서로 맞지 않는 벤더링된 프로젝트. git은 이 세 가지를 위한 스위치를 오래전부터 갖고 있었어요. 다만 충돌이 난 와중에는 아무도 열어 보지 않는 매뉴얼 페이지에 묻혀 있을 뿐이에요.
브랜치를 우클릭 → 옵션을 지정해 머지… — 사이드바의 브랜치 행과 원격 행에서,
그리고 하나의 메뉴 블록을 공유하는 그래프의 색깔 있는 ref 배지에서 — 또는 ⌘K
→ 옵션을 지정해 머지.

명령은 옵션을 조립하는 대로 화면에 찍혀요. 매뉴얼과 대조해 보라고, 그리고 다음 번에는 이 대화 상자 없이 터미널에서 실행하라고 거기 있는 것이에요.
헝크가 충돌할 때
| 선택 | 플래그 | 의미 |
|---|---|---|
| 멈추고 물어보기 | — | 기본값. 직접 해결해요 |
| 이 브랜치 쪽을 유지 | -X ours |
부딪히는 헝크는 이미 체크아웃되어 있는 쪽으로 해결돼요 |
| 들어오는 쪽을 채택 | -X theirs |
부딪히는 헝크는 들어오는 브랜치 쪽으로 해결돼요 |
-X ours는 -s ours가 아니에요. 여기의 스위치는 실제로 부딪히는 헝크만
결정해요. 다른 브랜치의 나머지 변경은 모두 정상적으로 머지돼요. ours라는
이름의 전략은 — Gitcito는 제공하지 않아요 — 여러분의 트리를 통째로 가져가고
반대쪽은 버려서, 담고 있지도 않은 작업을 담았다고 주장하는 머지 커밋을 만들어요.
그 구분이 git 머지에 대해 가장 많이 오해받는 단 하나의 지점이에요.
모든 것을 결정해 주지는 못해요. 수정/삭제 충돌 — 한쪽은 파일을 편집하고
다른 쪽은 삭제한 경우 — 은 내용 헝크가 아니라서 -X는 그것을 여러분 몫으로
남겨 둬요. 그게 맞아요. 삭제된 파일이 돌아와야 하는지에 대해 "우리 쪽을
선호한다"가 답이 되는 경우는 없으니까요.
공백
| 선택 | 플래그 |
|---|---|
| 기존 공백의 변경을 무시 | -X ignore-space-change |
| 공백을 전부 무시 | -X ignore-space-at-eol, -X ignore-all-space |
이것이 존재하는 이유가 되는 사례: 한 브랜치가 파일의 들여쓰기를 다시 했고(또는 포매터가 했고), 다른 쪽은 같은 줄을 편집했어요. git은 한 줄에 두 개의 편집이 있다고 보고 멈춰요. 공백을 무시하면 들여쓰기 재조정은 저울에 올릴 변경이 아니게 되고, 진짜 편집이 그대로 머지돼요.
결과는 반대쪽이 건드린 줄에 대해 그쪽의 공백을 유지하므로, 이어서 포매터를 한 번 돌리는 것도 나쁘지 않은 생각이에요.
무엇을 기록할 것인가
| 선택 | 플래그 | 남는 것 |
|---|---|---|
| 가능하면 fast-forward | — | 히스토리가 갈라졌을 때만 머지 커밋 |
| 항상 머지 커밋 만들기 | --no-ff |
fast-forward가 가능해도 머지 커밋을 만들어, 그래프에 브랜치가 영원히 보이게 |
| fast-forward만, 아니면 거부 | --ff-only |
진짜 머지가 필요했다면 아무것도 남지 않아요. 검사용으로 유용 |
| 스쿼시 | --squash |
변경은 스테이징되고, 머지는 기록되지 않으며, 커밋은 직접 써요 |
| 머지하되 커밋은 하지 않기 | --no-commit |
머지가 스테이징된 채 진행 중이라, 먼저 살펴보거나 고칠 수 있어요 |
스쿼시와 --no-commit은 같지 않아요. 스쿼시는 머지가 있었다는 사실 자체를
잊어요. git은 두 번째 부모를 기록하지 않고, 다음번에 그 브랜치는 머지되지 않은
것으로 보여요. --no-commit은 그저 여러분을 기다리고 있는 진행 중인 머지예요.
MERGE_HEAD가 설정되어 있고, 커밋하면 평소대로 마무리돼요.
--ff-only는 조용히 실패하지 않아요. 머지 커밋이 필요하다면 git은 거부하고
아무것도 움직이지 않아요. 스크립트로 돌리는 머지 전에 좋은 안전 점검이 되는
이유가 바로 그것이에요.
전략
| 전략 | 용도 |
|---|---|
기본 (ort) |
모든 경우. git의 현대적인 3-way 머지 |
subtree |
양쪽이 서로 다른 경로에 있을 때 — 이 프로젝트의 하위 디렉터리로 벤더링된 프로젝트 |
resolve |
옛 3-way 머지. 교차 히스토리에서 ort가 포기하는 경우 가끔 성공해요 |
기억해 둘 만한 것은 -s subtree예요. vendor/parser/에 들어 있는 프로젝트의
업데이트를 머지하면 그러지 않고서는 "모든 파일 삭제, 모든 파일 추가"로 읽히게
돼요. subtree 전략은 경로가 얼마나 밀렸는지를 먼저 계산해요. 전체 워크플로는
서브트리를 보세요.
왜 충돌하는가
충돌 해결기 안에는 왜 충돌하는가 버튼이 있어요. 눈앞의
파일에 대해 git log --merge를 실행해서, 브랜치가 갈라진 뒤로 그 파일을 건드린
커밋을 양쪽별로 나열해요.

충돌 마커는 무엇이 부딪히는지를 말해 줘요. 이것은 누가, 언제, 왜 바꿨는지를 말해 줘요. 보통은 그쪽이 해결 방식을 실제로 결정하는 질문이고, 한쪽을 고르기 전에 누군가에게 물어보러 가야 할 이유예요.
아무것도 나오지 않는다면 어느 쪽도 정확히 이 파일에 대한 변경을 커밋하지 않은 것이에요. 부딪힘은 더 윗단의 이름 변경이나 디렉터리 이동에서 와요.
알아 둘 만한 한계
- 옵션은 한 번의 머지에만 적용돼요. 기억되지 않으며, 평범한 현재 브랜치로 머지 항목이나 드래그 앤 드롭 메뉴를 바꾸지도 않아요.
- 되돌리기는 여전히 동작해요: 옵션을 지정해 실행한 머지도 같은 되돌리기
항목을 기록하며,
ORIG_HEAD로 리셋해요. - 옥토퍼스 머지(한 번에 두 개를 넘는 브랜치)는 여기서 제공하지 않아요.
- 커밋 메뉴의 ref별 "X를 Y로 머지" 항목은 평범한 머지로 남아요. 옵션을 원한다면 ref 배지 자체를 쓰세요.
-X는 조용히 결정해요. 어떤 헝크가 자동으로 해결되었는지 아무 표시도 남지 않으므로, 중요한 머지에서는 충돌이 없다는 사실을 믿기보다 나중에 차이를 읽어 보세요.