왜 이런 변화가 생겼나요?
예전에는 git pull을 실행하면 다음과 같은 두 가지 상황 중 하나가 자동으로 발생했습니다:
- Fast-forward 병합
로컬 커밋이 없고 원격 브랜치가 최신 상태인 경우 자동으로 병합. - Merge commit
로컬 브랜치와 원격 브랜치에 다른 커밋이 있으면 자동으로 merge commit을 생성.
이런 자동 병합 동작은 가끔 원치 않는 병합 커밋을 만들어 혼란스러운 Git 히스토리를 만드는 원인이 되었습니다.
변경된 이유
최근 Git은 사용자가 명확하게 의도를 지정하도록 개선되었습니다.
git pull을 실행할 때 병합할 것인지, 리베이스할 것인지, 혹은 fast-forward만 허용할 것인지 설정하라고 요구합니다.
해결 방법
이제 명시적으로 병합 방식(merge/rebase/fast-forward)을 정해줘야 합니다.
- 한 번만 설정
git pull 명령에 플래그를 붙여서 일시적으로 해결:
git pull --rebase origin main # 리베이스
git pull --no-rebase origin main # 병합
git pull --ff-only origin main # Fast-forward만 허용
2. 역 설정으로 기본값 지정
자주 사용하는 방식을 기본값으로 설정하려면:
- Merge를 기본값으로 설정:
git config --global pull.rebase false
- Rebase를 기본값으로 설정:
git config --global pull.rebase true
- Fast-forward만 허용:
git config --global pull.ff only
일반적으로 충돌이 발생했을 때 상황에 따라 어떤 명령어를 써야 하는지 쉽게 정리해 드릴게요. 상황별로 어떤 명령어를 사용하면 좋은지 이해하면 충돌을 빠르게 해결할 수 있습니다.
1. 충돌이 났을 때 상황별 해결법
상황 1: 충돌을 병합(Merge)으로 해결할 때
- 로컬 브랜치와 원격 브랜치의 커밋이 서로 다를 때 병합 커밋을 만들어 충돌을 해결합니다.
명령어:
git pull --no-rebase origin main
- git pull이 merge 방식을 사용합니다.
- 충돌이 발생하면 Git이 충돌 파일을 알려주고 수동으로 해결하면 됩니다.
단계:
- 충돌 파일 수정
- 수정된 파일 스테이징:
git add 파일명
- 병합 완료 커밋:
git commit
상황 2: 충돌을 리베이스(Rebase)로 해결할 때
- 내 로컬 브랜치의 커밋을 원격 브랜치 커밋 위에 재정렬하는 방식입니다.
- 히스토리를 깔끔하게 유지할 수 있지만, 충돌이 발생하면 수동으로 해결해야 합니다.
명령어:
git pull --rebase origin main
단계:
- 충돌이 발생하면 Git이 중단됩니다. 충돌 파일 수정.
- 수정된 파일 스테이징:
git add 파일명
- 리베이스 재개:
git rebase --continue
- 모든 충돌을 해결하면 리베이스가 완료됩니다.
중단된 리베이스를 취소하려면:
git rebase --abort
상황 3: Fast-forward 병합만 원할 때
- 로컬 브랜치가 원격 브랜치보다 뒤쳐져 있을 때만 병합하고, 충돌이 나거나 브랜치가 분기되면 에러를 발생시킵니다.
명령어:
git pull --ff-only origin main
용도:
- 충돌을 원하지 않고, 내가 단순히 원격의 최신 상태만 가져오고 싶을 때 사용합니다.
2. 내가 추천하는 일반적인 충돌 해결 순서
- 리베이스를 먼저 시도 (히스토리를 깔끔하게 유지하기 위해):
- 충돌이 나면 수동으로 파일을 수정하고:
git add 파일명 git rebase --continue
- 충돌이 나면 수동으로 파일을 수정하고:
- git pull --rebase origin main
- 리베이스가 어려우면 병합으로 전환:
- 충돌 파일을 수정한 후:
git add 파일명 git commit
- 충돌 파일을 수정한 후:
- git pull --no-rebase origin main
- 충돌을 무시하고 원격 브랜치를 덮어쓰고 싶을 때 (주의 필요!):
- 내 변경 사항을 버리고 원격 브랜치를 가져오려면:
git reset --hard origin/main
- 내 변경 사항을 버리고 원격 브랜치를 가져오려면:
정리 요약
상황 명령어 설명
병합 커밋으로 충돌 해결 | git pull --no-rebase origin main | 충돌이 나면 수정 후 git add와 git commit으로 해결 |
리베이스로 충돌 해결 | git pull --rebase origin main | 깔끔한 히스토리 유지. 충돌 시 git rebase --continue를 사용 |
Fast-forward만 병합 | git pull --ff-only origin main | 분기된 브랜치가 없을 때만 병합. 충돌 발생 시 에러를 띄움 |
원격 브랜치로 덮어쓰기 (주의!) | git reset --hard origin/main | 로컬 변경 사항을 버리고 원격 브랜치를 그대로 가져옴 (데이터 유실 가능) |
이렇게 상황별로 선택하면 충돌을 쉽게 해결할 수 있습니다. 일반적으로는 리베이스를 먼저 시도하고, 충돌이 너무 복잡하면 병합을 사용하세요! 😊