사내에서 Gitlab을 사용중인데, 잠시 서버가 내려가 다른 쪽에 코드를 옮길 때 당황했던 경험을 오늘 하여 내용을 정리해보고자 한다.
물론 실 사례 내용은 적기가 애매하여 대략적인 상황을 작성하고 개념에 대한 내용과 그래서 앞으로 어떻게 할 지에 대해서 정리해보겠습니다.
상황 정리
- 기존에 잘 쓰던 Git 서버(GitLab 등)가 내려갔다
- 새로 배포해야 할 최종 코드가 로컬에 있다
- Git으로 관리 중이었고, 아직 push 하지 못한 커밋들이 있다
- 목표는 새로운 Git 서버(GitHub)에 코드를 올리고 main에 merge하는 것
이 상태에서 초보자가 가장 많이 하는 실수는
“push부터 어떻게 할지”를 먼저 고민하는 것이다.
하지만 이 상황에서 제일 중요한 건 push가 아니다.
1. 이 상황에서 가장 먼저 확인해야 할 것
❗ 로컬 코드가 “Git에 저장돼 있는가?”
여기서 말하는 저장은:
- ❌ push
- ⭕ commit
즉, 지금 확인해야 할 질문은 이거다.
“내가 수정한 코드들이
전부 커밋으로 남아 있는 상태인가?”
git status
git log --oneline
- git status에 변경 사항이 남아 있다면
→ 아직 안전하지 않다 - 커밋으로 남아 있다면
→ 서버가 없어도 코드는 살아 있다
2. 아직 push 못 한 코드가 있다면, 가장 먼저 할 일
이 상황에서의 정답 행동은 하나뿐이다.
“어디로 push할지 고민하기 전에
일단 커밋으로 고정한다.”
git add .
git commit -m "WIP: local changes before server migration"
이 커밋은:
- 배포용이 아니어도 되고
- 메시지가 정리돼 있지 않아도 된다
목적은 단 하나다.
“이 상태를 Git이 기억하게 만든다.”
이걸 해두면:
- 서버 이전 작업 중 실수해도
- 브랜치를 바꿔도
- remote 설정을 잘못해도
코드는 복구 가능 상태다.
3. 그 다음에야 “새 서버로 어떻게 옮길지”를 결정한다
로컬 코드가 커밋으로 안전하게 고정된 상태라면
이제서야 다음 질문을 할 수 있다.
“이 커밋들을 그대로 새 GitHub에 옮길 것인가, 아니면 코드 상태만 옮길 것인가?”
이 선택에 따라 전략이 갈린다.
| 구분 | 커밋 이력 그대로 옮길 경우 | 코드 상태만 |
| 이전 대상 | 모든 커밋 히스토리 | 현재 로컬 코드 상태 |
| 과거 커밋 포함 | O (전부 포함) | X |
| 실패 가능성 | 높음 | 매우 낮음 |
| GitHub 정책 영향 | 큼 (용량·보안 등) | 거의 없음 |
| 대용량 파일 문제 | 자주 발생 | 거의 발생 안 함 |
| 초보자 난이도 | 높음 | 낮음 |
| 이전 속도 | 느림 | 빠름 |
| 심리적 안정감 | 낮음 | 높음 |
| 서버 장애 대응 | 부적합 | 적합 |
| main merge 용이성 | 상황에 따라 다름 | 매우 쉬움 |
4. 초보자 기준으로 가장 안전한 기본 전략
이런 상황에서는 보통 이 선택이 가장 안전하다.
“새 GitHub 서버에는 ‘현재 코드 상태’를 기준으로 새로운 히스토리를 만든다.”
즉,
- 기존 서버의 커밋 이력은 참고용으로 두고
- 새 서버에서는 새 출발
이 방식은:
- 서버 정책 차이(GitLab ↔ GitHub)
- 과거 커밋에 섞인 문제 요소
- 대용량 파일 이슈 (100MB 넘을 경우)
같은 변수들을 한 번에 제거해준다.
4-1. 안전한 기본 전략을 실제로 실행하는 순서
전제 상황은 이거다.
- 새 Private GitHub Repository가 이미 생성됨
- GitHub SSH 주소도 발급됨
예: git@github.com:my-org/my-project.git - 로컬에는 배포해야 할 최종 코드가 있고, 커밋까지 완료된 상태
- 기존 GitLab 서버는 더 이상 신뢰하기 어려움
목표는 단순하다.
“현재 코드 상태를 기준으로
GitHub에서 새로운 히스토리를 시작하고
main에 반영한다.”
1️⃣ 먼저 GitHub remote를 추가한다
기존 GitLab remote는 그대로 둬도 된다.
우리는 새 출발용 remote를 하나 더 추가한다.
git remote add github git@github.com:my-org/my-project.git
git remote -v
origin git@gitlab.company.com:old/project.git (fetch)
origin git@gitlab.company.com:old/project.git (push)
github git@github.com:my-org/my-project.git (fetch)
github git@github.com:my-org/my-project.git (push)
여기까지는 아직 아무 것도 GitHub에 안 올라갔다
(remote는 “연결 정보”일 뿐이다)
2️⃣ GitHub 기준으로 깨끗한 브랜치를 만든다
이 단계가 이 전략의 핵심이다.
GitHub의 main을 기준으로 완전히 새로운 브랜치를 만든다.
git fetch github
git checkout -b import-from-gitlab github/main
이 브랜치의 의미는 이거다.
“GitHub가 이해할 수 있는
깨끗한 히스토리에서 시작한다”
- 과거 GitLab 커밋 ❌
- 대용량 파일 히스토리 ❌
- 정책 충돌 요소 ❌
3️⃣ 기존 브랜치에서 “파일 상태만” 가져온다
이제 핵심 동작이다.
git checkout old-gitlab-branch -- .
이 명령이 의미하는 바는 정확히 이거다.
- 커밋 이력 ❌
- 브랜치 히스토리 ❌
- 현재 파일 내용만 ⭕
즉,
“old-gitlab-branch의 결과물만 지금 브랜치에 복사한다”
조합하면 이렇게 된다.
“old-gitlab-branch에 있는
모든 파일 상태를
현재 브랜치의 워킹 디렉토리에 덮어써라.”
4️⃣ 혹시 모를 대용량 파일을 한 번 더 점검한다
GitHub 이전에서 이 단계는 안전벨트다.
git status
불필요한 대용량 파일이 보이면:
git rm --cached path/to/large-file.zip
그리고 .gitignore에 추가:
*.zip
*.tar
*.model
5️⃣ 이 상태를 첫 커밋으로 만든다
이 커밋이 GitHub에서의 시작점이다.
git add .
git commit -m "import: initial snapshot from GitLab"
이 커밋의 의미는 명확하다.
“이 시점의 코드 상태가
GitHub에서의 최초 버전이다”
6️⃣ 이제 GitHub로 push 한다 (거의 실패하지 않는다)
git push -u github import-from-gitlab
이 시점에서:
- 과거 문제 커밋 ❌
- GitHub 정책 위반 ❌
- push 실패 가능성 ❌
7️⃣ GitHub에서 main에 merge 한다
이제 GitHub UI에서:
- import-from-gitlab → main
- Pull Request 생성
- 코드 확인 후 merge
혹은 로컬에서 바로 하고 싶다면:
git checkout main
git pull github main
git merge import-from-gitlab
git push github main
배울점
1️⃣ push는 저장이 아니라 “복사”다
- ❌ push를 해야 코드가 안전해진다
- ⭕ commit만 되어 있으면 코드는 이미 안전하다
push는 로컬 커밋을 원격 서버로 복사하는 행위일 뿐이다.
서버가 없어도, push를 못 해도 커밋은 로컬에 남아 있다.
2️⃣ Git은 “파일”이 아니라 “커밋 그래프”를 관리한다
- ❌ 지금 파일에 뭐가 있느냐
- ⭕ 과거 커밋에 무엇이 있었느냐
그래서:
- 대용량 파일을 지금 지워도
- 과거 커밋에 있으면
- GitHub push는 계속 막힌다
3️⃣ 브랜치를 새로 만든다고 히스토리가 사라지지 않는다
git checkout -b new-branch
이건:
- 히스토리를 새로 만드는 게 아니라
- 기존 커밋 그래프 위에 포인터 하나를 더 얹는 것
그래서:
- 문제 커밋도
- 대용량 파일 이력도
- 그대로 따라온다
4️⃣ “코드 상태만 옮긴다”는 건 Git에서 가능한 공식적인 방법이다
git checkout old-branch -- .
이 명령은:
- 브랜치 이동 ❌
- merge ❌
- rebase ❌
- 파일 내용만 복사 ⭕
즉:
히스토리를 버리고 결과물만 가져오는,
Git이 허용하는 정상적인 전략
5️⃣ commit 안 된 변경 사항은 어떤 전략으로도 보호되지 않는다
- commit ❌
- stash ❌
- 백업 ❌
이 상태에서:
- 브랜치 이동
- reset
- checkout
→ 코드 날아간다
그래서 서버 이전에서 제일 먼저 할 일은 항상:
git commit
6️⃣ remote는 “이름”이 아니라 “다른 세계”다
origin → GitLab
github → GitHub
- 같은 브랜치라도
- 다른 remote로 push하면
- 전혀 다른 레포에 다른 히스토리가 생긴다
remote를 바꾼다는 건:
“다른 서버에 다른 프로젝트를 만든다”에 가깝다
7️⃣ GitHub의 100MB 제한은 버그가 아니라 설계다
- GitHub는 Git을 코드 저장소로 쓰길 원한다
- 대용량 파일은:
- Git LFS
- 외부 스토리지
- 릴리즈 아티팩트
즉:
“Git에 넣지 말라는 신호”
8️⃣ 서버 이전은 Git 명령 문제가 아니라 “의사결정 문제”다
이전 상황에서 가장 중요한 질문은 이거였다.
- 커밋 이력을 살릴 것인가?
- 아니면 결과물만 살릴 것인가?
이걸 정하지 않으면:
- 명령어를 바꿔도
- 브랜치를 바꿔도
- 계속 같은 문제에 부딪힌다
한 문장 요약 (이건 진짜 중요)
Git을 쓰기 시작한 초보자는
파일을 관리한다고 생각하지만,
Git은 처음부터 끝까지 ‘히스토리’를 관리한다.
이 차이를 이해한 순간부터:
- push 에러가 덜 무섭고
- 서버 이전이 덜 위험하고
- Git이 도구처럼 느껴지기 시작한다
마지막 전체 실행 예시
git status
git branch
git remote -v
git remote add github git@github-company:example-org/project.git
git remote -v
git remote set-url github git@github-company:example-org/project.git
git fetch github
git config user.name "Your Name"
git config user.email "your.email@example.com"
git config --list
git checkout -b test-import-from-gitlab github/main
git branch
git checkout old-branch -- .
git rm --cached deps/*.zip
git status
git add . # 상황에 따라 다르게
git commit -m "import: initial snapshot from GitLab"
git push -u github test-import-from-gitlab'개발 > Git' 카테고리의 다른 글
| GitLab 협업 가이드: Issue → 브랜치 → MR → Merge 전체 프로세스 (0) | 2025.06.03 |
|---|