blog
git push --mirror로 저장소 통째로 복제하기
Front-end / Git#Git#mirror#저장소 이전
회사 저장소를 개인 저장소로 옮기거나 GitLab → GitHub로 이전할 때처럼, 모든 브랜치와 태그를 그대로 복제해야 할 때 --mirror를 사용한다.
권장 방법: bare mirror 클론에서 push
# 1. 원본을 mirror 형태(bare)로 클론
git clone --mirror https://github.com/old-owner/repo.git
cd repo.git
# 2. 비어 있는 새 저장소로 mirror push
git push --mirror https://github.com/new-owner/repo.git
# 3. 작업이 끝나면 임시 디렉터리 삭제
cd .. && rm -rf repo.git
git clone --mirror는 원본의 모든 ref(브랜치, 태그, 기타 ref)를 원본과 같은 이름으로 가져온다. 여기서 push하면 새 저장소가 원본과 동일해진다.
기존 작업 디렉터리에서 remote를 추가해 push하는 경우
git remote add mirror https://github.com/new-owner/repo.git
git push --mirror mirror
git remote remove mirror
동작은 하지만 주의할 점이 있다.
--mirror는 로컬의 모든 ref를 그대로 보낸다. 일반 클론에서는refs/remotes/origin/*(원격 추적 브랜치)까지 대상 저장소에 올라가, 대상에origin/main같은 이상한 브랜치가 생길 수 있다.- 반대로 로컬에 체크아웃하지 않은 원격 브랜치는
refs/heads/로 올라가지 않는다. - 대상 저장소에만 있고 로컬에는 없는 ref는 삭제된다. 강제 push와 같으므로 이미 사용 중인 저장소를 대상으로 하면 안 된다.
그래서 "통째로 복제"가 목적이라면 위의 clone --mirror 방식을 쓴다.
일반 push와 비교
| 명령 | 보내는 ref | 대상에만 있는 ref |
|---|---|---|
git push origin main | 지정한 브랜치 | 유지 |
git push --all | 모든 로컬 브랜치 | 유지 |
git push --tags | 모든 태그 | 유지 |
git push --mirror | 모든 ref | 삭제 |
GitHub의 Pull Request ref(refs/pull/*)는 대상 저장소에서 거부되어 ! [remote rejected] 메시지가 출력될 수 있다. 브랜치와 태그가 정상적으로 올라갔다면 무시해도 된다.