Git에서 merge와 rebase의 차이점

pull 명령어에서 rebase나 merge는 각각 스스로 “작업 내용을 지우지 않습니다” — 둘 다 당신의 커밋들이 저장소에 남아 있습니다 (분기의 역사 내에서, 또는 reflog가 살아 있을 동안은 오래된 SHAs로 남아 있음).

  • pull.rebase false (merge): git pull메리지 커밋을 생성하며, 당신의 커밋과 다른 사람의 커밋은 재작성되지 않습니다. 단지 분기의 끝이 서로 합쳐지는 형태로 역사가 연결됩니다. 시각적으로 더 안전합니다: 명확하게 만나는 라인을 볼 수 있습니다.
  • pull.rebase true (rebase): 당신의 로컬 커밋들이 원격 커밋 위에 복사됩니다 (새로운 해시를 가집니다). 커밋의 내용은 일반적으로 동일하지만, 성공한 rebase 후에는 **git reflog**에 “오래된” 커밋들이 남아 있을 수 있습니다 — 이는 정상이며, 필요할 때 **git reset --hard**를 통해 reflog에서 원하는 ref로 복원할 수 있습니다 (예: 실수로 잘못된 작업이 발생했을 경우).

“작업 내용을 잃지 않기”가 가장 중요하다면:

  1. 위험한 작업 전에 — 커밋 (또는 git stash) 하고, 필요에 따라 별도의 분기 (git branch backup-tgisn-46)를 만들어 포인터의 백업을 만듭니다. (가볍고 저렴한 백업입니다.)
  2. git reset --hard, force push (필요 없을 경우), git clean -fd 같은 명령어로 인한 실제 손실과 혼동하지 마세요.
  3. rebase/merge 이후에는 git gc를 과도하게 실행하지 마세요 — reflog는 복구를 위한 보존 공간입니다.

“작업 내용을 잃지 않으면서도 역사 구조를 크게 복잡하게 만들지 않으려면”: **git config pull.rebase false**를 설정하세요 — 충돌이 발생하면 항상 메리지가 생성되어 로컬 커밋이 재작성되지 않습니다. 만약 이미 rebase를 선호하는 경우 (예: 이전 pull --rebase처럼) — **pull.rebase true**를 유지하되, 공통 분기로 push --force를 하지 마세요 (협의 없이).

결론: pull 전략의 선택으로 인해 작업 내용이 사라지는 일은 없습니다; 위험은 다른 명령어force push에 있습니다. 안전을 위해 — 커밋 + 백업 분기모호한 작업 전에 항상 만들어두세요.

아래는 당신의 상황과 동일한 예시입니다: 공통 커밋 C 하나가 있고, origin에는 r1~r5 5개 커밋, 로컬에는 L 하나 (당신의 작업)이 있습니다.

1. pull 전 (분리된 상태)

gitGraph
  commit id: "C (공통)"
  branch local
  checkout local
  commit id: "L (내 커밋)"
  checkout main
  commit id: "r1"
  commit id: "r2"
  commit id: "r3"
  commit id: "r4"
  commit id: "r5"

의미: local의 끝은 L, main의 끝은 r5, 공통 조상은 C. 이 상태는 두 방식 모두에서 작업 내용이 잃어버리지 않습니다어떻게 역사가 연결되는지만 달라집니다.


2. git pullrebase 없이 (pull.rebase falsemerge)

gitGraph
  commit id: "C"
  branch local
  checkout local
  commit id: "L"
  checkout main
  commit id: "r1"
  commit id: "r2"
  commit id: "r3"
  commit id: "r4"
  commit id: "r5"
  checkout local
  merge main
  commit id: "M (메리지 커밋)"

메리지 커밋 M이 생성되며, 두 부모 (Lr5)를 가집니다. 커밋 Lr1~r5객체로서 계속 남아 있습니다; 역사 구조는 분기형이며, 재작성은 없습니다.


3. git pullrebase로 (pull.rebase truerebase)

gitGraph
  commit id: "C"
  commit id: "r1"
  commit id: "r2"
  commit id: "r3"
  commit id: "r4"
  commit id: "r5"
  commit id: "L′ (동일 패치, 새 해시)"

선형 구조가 됩니다: 당신의 작업은 원격 커밋 위에 놓입니다. L의 역사에는 새로운 커밋 L′ (r5 대비 동일한 패치, 다른 해시)가 생깁니다. 원래 L은 **git reflog**에 잠시 남아 있으며, reflog expire를 삭제하기 전까지는 보존됩니다.


요약: merge는 분기 + 메리지 노드; rebase는 **한 줄의 역사, 당신의 커밋이 “재생성”**됩니다. 파일의 변경 내용은 두 가지 정상적인 시나리오에서 모두 사라지지 않습니다; 차이점은 역사 구조rebase 시 로컬 커밋의 해시입니다.