본문 바로가기

Project Management/Git & Github

[Chapter 4] 복수의 repository로 협업(2) - rebase 2

github logo image

 

 

이전 아티클에서 세팅한 ME와 NEWBIE의 원본 / 원격 저장소의 상태를 다시 한번 되짚어 보도록 하겠습니다. 

 

이제 현재까지 ME의 원본 저장소와 NEWBIE의 원격 저장소 상태를 정리해 봅시다. 일단 두 저장소 모두 '즐겨찾기 기능 추가' 커밋까지는 동일합니다. 하지만, NEWBIE는 이다음 단계에 'favorite.md' 2번 라인에 "선물하기 기능 추가"가 추가되었습니다. 
 
ME는 원격 저장소에서 'favorite.md' 2번 라인에 "포인트 지급 기능 추가"가 추가되었습니다. 그리고 여기에 더해 'readme.txt'파일에 NEWBIE 텍스트도 하나 더 추가해 둔 상태입니다. 이제 이 저장소에서 풀 리퀘스트가 일어난다면, 충돌이 발생하겠죠? (favorite.md 2번 라인 때문에)

 

아래의 각 저장소 히스토리를 기준으로, '포인트 지급 기능'과 '선물하기 기능'이 충돌하는 상태가 되었습니다. 

 

ME의 원본 저장소 히스토리

 

 

NEWBIE의 원격 저장소 히스토리

 

 

 

 


 

 

자, 이제 이 상태에서 NEWBIE는 상대가 '즐겨찾기 기능 추가' 상태에서 멈춰있는 것으로 알고, [선물하기 기능 추가]를 보내기 위해서 풀 리퀘스트를 보내게 됩니다. 당연히 이를 시도하면 원본 저장소에서 ME가 [포인트 지급 기능]을 같은 파일의 같은 라인에 작업을 해두었기 때문에 충돌이 발생하겠죠? 이를 본격적으로 실습해 보겠습니다.

 

NEWBIE의 원격 저장소로 이동해, 현재 상태에서 [Pull request] 탭으로 들어가 [New pull request]를 클릭해보겠습니다. 기존과는 다른 메시지가 출력되는 것을 확인할 수 있습니다!

 

풀 리퀘스트에서 충돌이 발생한 것을 확인할 수 있습니다

 

 

· 일단 최상단 좌측을 보면, NEWBIE의 원격 저장소에서 풀 리퀘스트를 실행 했는데, 원본 저장소가 출력됩니다. 혼란스러울 수 있는데, 풀 리퀘스트는 기본적으로 작업이 성공하면 원본 저장소로 이동하는 성질을 갖고 있기 때문에 이렇게 출력됩니다. 

· Comparing changes 항목을 보면, base repository에는 원본 저장소와 그 브랜치 / head repository에는 (NEWBIE의) 원격 저장소와 그 브랜치가 지정되어 있습니다.

· 그 하단에는 "Can't automatically merge...."라는 문장이 경고성으로 출력되고 있습니다. 충돌이 있다는 의미입니다.

 

 


 

 

기본적으로 이러한 문제는 왜 생겼을까요? 다름아닌 NEWBIE가 ME의 원본 저장소의 히스토리는 알 수 없기 때문입니다. 우리는 v1.0.0 태그를 붙인 시점에 원본 저장소를 포크 해서 (그 시점까지의 이력을 모두 복사해) 별도의 원격 저장소를 만들었기 때문에, 해당 시점까지의 히스토리는 똑같이 확인할 수 있습니다. 

 

하지만 포크를 진행한 이후의 시점부터는 두 개의 저장소는 완벽히 독립적으로 움직이기 때문에(우리는 한 대의 PC로 작업하지만 실제로는 다른 회사에 있는 개별의 인물이죠?) 그 이후의 히스토리는 소스트리나 깃허브 페이지를 통해서는 확인할 수 없습니다. 

 

그림으로 표현해볼까요? 간략히 축약해서 개념만 살펴보겠습니다. 

 

 

ME와 NEWBIE의 저장소 충돌 상황

 

 

 

 

위의 그림처럼 각각의 저장소가 독립적으로 운영되고 있기 때문에 생기는 문제입니다. 이때 우리가 취해야 할 조치는 무엇일까요? 바로 [소스트리가 원본 저장소와 원격 저장소를 모두 함께 추적하도록] 만들어야 합니다. 어떠한 형태의 분류가 될지는 자세히 살펴보겠지만, 소스트리에서 모든 커밋을 아래의 그림처럼 한눈에 알아볼 수 있다면 우리는 이와 같은 실수를 줄일 수 있게 되겠죠.

 

 

한번에 모든 히스토리를 함께 볼 수 있다면...?

 

 

 

자, 지금은 브랜치와 저장소의 개념이 살짝 헷갈리는게 당연합니다. 하나씩 step by step으로 다음 절차를 따라가 보도록 하겠습니다. 

 

 


 

 

우선은, 해당 작업은 NEWBIE의 입장에서 - ME의 원본 저장소의 히스토리를 NEWBIE의 원격 저장소에 추가하여 보는 것입니다(git_study_NEWBIE). 그렇기 때문에 소스트리에서는 일단 NEWBIE의 계정으로 전환하는 것이 기본입니다. 주의하세요!

 

우선 현재 NEWBIE의 입장에서 NEWBIE의 원격 저장소는 자신의 원격 저장소만 origin이라는 이름으로 바라보고 있는 상태입니다. 이제, ME의 원본 저장소를 별도로 다른 이름으로 추가를 진행해 보겠습니다. 우선 아래 그림처럼 [원격 저장소 추가] 메뉴를 실행합니다.

 

NEWBIE 계정에서, NEWBIE의 저장소에서 [원격 저장소 추가]를 실행합니다

 

 

 

새롭게 추가할 원격 저장소의 정보를 기입합니다. 우선, "원격 이름" 항목이 있습니다. 여기에는 일단 'upstream'을 작성합니다. 이는 통상적으로 사용하는 원본 저장소의 명칭이니 기억해 두세요.

 

참고로 우리는 초기 챕터에서 [git remote add origin http://.....] 형태의 명령을 실행한 적이 있습니다. 여기서는 기본적으로 "원격 이름"을 origin으로 설정한다는 의미였습니다. 현재 우리는 NEWBIE의 입장에서, 원래 우리의 저장소를 origin / ME의 원본 저장소를 upstream으로 설정하는 것입니다. 주의하세요!

 

"URL / 경로" 항목에는 ME의 원본 저장소 주소를 입력합니다. 그리고 "사용자명"에는 ME의 이름을 작성하고 확인을 클릭합니다.

 

새로 추가할 저장소의 정보를 작성합니다

 

 

이 작업을 완료하고 나면, 아래와 같이 두 개의 origin, upstream 저장소가 등록된 것을 확인할 수 있습니다. URL도 각각 다른 것을 확인할 수 있지요?

 

origin, upstream 두 개의 원격 저장소가 보입니다

 

 

확인을 클릭하고 나면, NEWBIE의 저장소에 'upstream' 원격 저장소가 추가된 것을 볼 수 있습니다. 하지만, 실제로는 해당 저장소가 추가되었다는 것 외에는 별다른 변화가 없습니다. 사실, 쉽게 말해서 upstream 저장소에서의 히스토리를 '새로고침' 하지 않았기 때문이지요. 여기서는 'Pull'이 아닌, 이력만을 가져오는 것이기 때문에 'Fetch'를 진행해야 합니다.

 

패치(Fetch)를 실행하는 과정은 우리가 모르는 과정이 아닙니다. 만일 이런저런 커밋으로 인해, 우리의 [master]와 [origin/master]에 이격이 생겼다고 가정해 봅시다. 패치가 진행되었다면 우리의 로컬 [master] 브랜치는 커밋 5에 머물러 있는데 [origin/master]는 커밋 7에 가 있는 경우가 있습니다. 이 상태가 "패치가 진행된" 상태입니다. 히스토리를 불러왔고, 그 히스토리와 우리의 차이를 인지하는 것이죠. 여기서 풀을 진행하면 비로소 [master]도 [origin/master]와 같은 커밋을 가리키며 두 개의 차이가 없어지는 것입니다. 

 

이제 패치를 진행하기 위해 'upstream'을 우클릭하여 [upstream에서 가져오기]를 클릭합시다.

 

패치(fetch)를 진행합니다

 

그럼 이제 비로소 아래 그림처럼 히스토리가 보이기 시작합니다. 우리는 선물하기 기능을 추가했는데, 원본 저장소의 마스터 브랜치에서 포인트 지급 기능이 추가되고 개발자 NEWBIE 추가 커밋이 된 것을 확인할 수 있습니다. 우리는 여기서 다른 커밋을 추적해, 충돌을 확인할 수 있습니다.