Search
Duplicate
💪

커밋 손실 없이 2개의 레파지토리를 합쳐보자!

간단소개
커밋손실은 근손실만큼 무섭다
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
git
Github
Scrap
태그
9 more properties
커밋 손실은 안돼…
살다가 한 번 쯤은 깃헙에서 두개의 레파지토리(이하 레포)를 하나로 합치고 싶을 때가 있다.
그런데 문제는 커밋 손실..!!!
커밋 손실은 용납할 수 없다.
어떻게 커밋 손실 없이 합칠지 방법을 알아보도록 하자.

1. 우리의 전략

전략은 아주 간단하다. 3가지 방법만 진행하면 된다.
1.
기준 레포에서 병합할 상대 레포와 연결
2.
특정 브랜치에서 상대 레포의 데이터 세팅
3.
두 레포를 병합!
그림으로 보면 아래와 같다.
그럼 전략을 어떻게 진행할지 구체적으로 알아보자!

2. 구체적인 진행 방법

2-1. 기준 레포에서 병합할 상대 레포와 연결

기준이 될 레포를 git clone으로 로컬에 받아서 해당 폴더에 들어간 상태라고 가정하자.
그 상태에서 기준 레포에서 합치고자 하는 상대 레포의 원격 저장소를 remote로 연결시켜주자.
git remote add <remote-name> <url-of-repository-to-merge>
Bash
복사
<remote-name>에는 상대 레포에 대한 remote 이름이다. 특정 원격 저장소의 별칭과 같은 개념이므로 자유롭게 지정해주면 된다.
<url-of-repository-to-merge> 에는 상대 레포의 원격 저장소 주소를 넣자.
 참고 git remote는 원격 저장소와 관련된 작업을 수행하고 관리할 수 있는 명령어이다.
remote 연결이 성공했으면 fetch를 통해 상태를 업데이트해주자.
git fetch <remote-name>
Bash
복사
 참고 git fetch는 원격 저장소의 데이터를 로컬에 가져오기만 하는 것이다.

2-2. 특정 브랜치에서 상대 레포의 데이터 세팅

상대 레포에 접근할 브랜치를 설정해주고 해당 브랜치로 이동한다.
git branch <branch-name-another-remote> <remote-name>/main git checkout <branch-name-another-remote>
Bash
복사
같은 이름의 파일이나 폴더가 있다면 병합시에 데이터가 손실될 수 있다.
이건 커밋 손실보다 더 치명적이다.
그러므로 기준 레포에 없는 이름으로 폴더를 만들어 그 안에 내용들을 넣어주자.
mkdir <dir-name-for-another> mv <datas-to-move> <dir-name-for-another>
Bash
복사
데이터 충돌 방지를 위해 폴더에 넣었으니 addcommit으로 상태를 저장하자.
git add . git commit -m<commit-message>
Bash
복사

2-3. 특정 브랜치에서 두 레포를 병합!

자 이제 두 레포를 병합하고자 하는 특정 브랜치를 만들어 거기서 병합하면 된다.
물론 main 브랜치에서 바로 해도 된다. 결과물이 예상과 다를 경우 원격 저장소로 push만 하지 않으면 괜찮다. 로컬 데이터를 삭제하고 다시 처음부터 진행하면 된다.
원하는 브랜치로 이동한 후, 상대 레포의 데이터가 담긴 브랜치를 병합시키자.
git checkout <branch-name-to-merge> git merge <branch-name-another-remote>
Bash
복사
 병합시에 서로 다른 레포들 이라는 이유로 에러가 나타날 수 있다. 그럴 경우 --allow-unrelated-histories 옵션을 붙여주자.
git merge <branch-name-to-merge> --allow-unrelated-histories
Bash
복사
결과물이 예상과 같은가?
마음에 든다면 main 브랜치에 반영하고 기존 레포의 원격 저장소로 push하면 된다.
git checkout main git merge <branch-name-to-merge> git push origin main
Bash
복사
이후 간단한 예시도 추가해 설명했으니 참고해보자!

3. 예시: RepoA와 RepoB를 하나로 병합해보자

RepoA, RepoB 라는 2개의 레포가 있는 상태에서 1개의 레포로 합쳐보자.
기준 레포를 RepoA로 선택하여 상대 레포인 RepoB와 병합할 계획이다.
두 레포 모두 mine.txt 라는 파일이 있고 각각 from Afrom B 라는 내용이 적혀있다.
RepoA:
RepoB:

3-1. 로컬에 있는 RepoA에서 RepoB로 remote 연결

먼저 RepoA를 로컬에 받고 해당 폴더로 이동한 상태로 만들자.
git clone https://github.com/refigo/RepoA cd RepoA
Bash
복사
RepoA에서 RepoB로 remote 연결 후 fetch로 상태를 업데이트 해주자.
git remote add RepoB https://github.com/refigo/RepoB git fetch RepoB
Bash
복사

3-2. RepoB에 대한 브랜치를 만들고 데이터 세팅

RepoB에 대한 브랜치를 만들고 이동하자. 브랜치 이름은 fromRepoB로 지정했다.
git branch fromRepoB RepoB/main git checkout fromRepoB
Bash
복사
데이터 손실을 방지하기 위해 폴더를 만들어 RepoB의 데이터를 그 폴더에 저장하자.
from_repo_b라는 폴더를 이용했다.
mkdir from_repo_b mv * from_repo_b
Bash
복사
여기서는 테스트 삼아 *(Asterisk)를 이용해서 데이터를 옮겼는데 권장하지는 않는다.
RepoB에 대한 데이터 세팅이 끝났다면 addcommit로 상태를 저장하자!
git add . git commit -m “Set data from RepoB”
Bash
복사

3-3. RepoA로 RepoB 데이터를 merge 시키고 push!

RepoA에서 합칠 작업을 할 브랜치를 따로 만들어 병합 작업을 진행하면 되지만 아주 간단한 데이터를 가진 예제이므로 main 브랜치에서 작업하겠다.
(물론 병합 후에 문제가 생긴다면 원격저장소로 push만 하지 않으면 된다.)
main 브랜치로 이동한 다음에 fromRepoB를 병합시키자!
git checkout main git merge fromRepoB --allow-unrelated-histories # 병합!
Bash
복사
옵션 없이 merge를 할 경우 에러가 나는 것을 볼 수 있다.
결과물이 예상과 같고 마음에 든다면 기존 레포의 원격 저장소로 push하도록 하자.
git push origin main
Bash
복사
깃헙에서 RepoA의 커밋 내역을 보면 반영된 RepoB의 커밋 기록을 볼 수 있다.
기존의 RepoA:
RepoB:
하나로 병합된 결과:
커밋이 복제되어 중복되므로 기존의 RepoB는 삭제해주도록 하자.
그럼 커밋 손실 없이 RepoA와 RepoB를 하나의 레파지토리로 합쳐서 관리할 수 있게되었다.

마무리

이 방법을 반복하면 2개 뿐만 아니라 3개, 4개 등 원하는 수 만큼의 레포를 병합할 수 있다. 물론 그만큼 반복 작업을 해야겠지만 말이다.
또한 역으로 하면 커밋 기록을 유지하면서 하나의 레파지토리를 2개 이상으로 나눌 수도 있다. remote로 연결해서 데이터를 반영한 다음에 필요한 내용만 빼고 나머지를 다 지우면 된다. (물론 커밋 내용이 중복되는데 중복을 없애는 방법은 나중에 이런 상황이 생기면 따로 포스팅 해보겠다.)
커밋 손실 없이 레포를 병합하는 방법을 배웠으니 앞으로 더 열심히 레포를 만들면서 개발하도록 하자!