본문 바로가기

OSSCA-2025-3rd-Class-yocto

[1주차] 프로젝트 개요 및 git 이해(fetch와 pull의 차이, merge와 rebase의 차이)

 

좋은 기회를 얻어 오픈소스 컨트리뷰션 Yocto팀 멘티로 프로그램에 참여할 수 있게 되었다! 1주차 내용은 git에 대한 내용이였다. 이전에 프로젝트 할때 git을 자주 사용하긴 했지만 매일 쓰던 것만 써서 사실 잘 모르는 부분도 있었다. 이번 포스팅에서는 새로 알게된 것들에 대해 써보려 한다.

 

1. git fetch와 git pull의 차이

리모트 트래킹 브랜치

리모트 서버(origin)에 fetch, pull, push 등으로 연결할 때마다 리모트 브랜치 업데이트 내용에 따라 자동 갱신되는 브랜치(일종의 북마크). 리모트 저장소에 마지막으로 연결했던 순간 브랜치가 무슨 커밋을 가리키고 있었는지 나타냄. => 로컬에 있지만 임의로 움직일 수 없다. 

  • clone과 fetch로 생성
    • 서버로부터 저장소를 clone하면 git은 자동으로 리모트 트래킹 브랜치(origin/master(or origin main))를 로컬에 만들고 master(or main) 브랜치라는 로컬 브랜치를 생성하여 이 둘을 연결하여 추적하도록(Upstream)한다. 
    • fetch시 리모트 브랜치 정보를 업데이트하고 리모트 트래킹 브랜치를 자동으로 생성/업데이트 한다.
  • 브랜치 추적
    fetch 명령으로 리모트 트래킹을 내려받는다고 해서 로컬 저장소에 수정할 수 있는 브랜치가 새로 생기는 것이 아니다!(포인터가 생기는 것이기 때문) 리모트 트래킹 브랜치를 로컬 브랜치로 checkout 하면 자동으로 트래킹 브랜치가 만들어진다.(트래킹 대상 브랜치 = Upstream 브랜치, 트래킹 브랜치 리모트 트래킹 브랜치) 트래킹 브랜치에서 pull 명령어를 사용하면 리모트 저장소로부터 데이터를 내려받아 연결된 리모트 브랜치와 자동으로 병합한다. 

이렇게만 리모트 트래킹과 트래킹 브랜치가 정말 정말 헷갈린다!! 예시와 함께 살펴보자

여기에서 내 로컬에 있는 teamone/master, origin/master가 리모트 트래킹 브랜치라할 수 있고 master 브랜치를 트래킹 브랜치라할 수 있다. 

 

그럼 이제 다른 사람의 작업물을 들고 오기 위해 fetch 또는 pull 명령어를 사용하는데 이때 트래킹 브랜치의 변화를 통해 차이점을 알 수 있다. fetch는 리모트 트래킹 브랜치(origin/master)와 연결된 내 트래킹 브랜치(master)에서 병합하는 작업을 수행해야 변경사항이 적용된다. 

 

git fetch

로컬에는 없지만 리모트 저장소에 있는 데이터(Clone 한 이후에(혹은 마지막으로 가져온 이후에) 수정된 것)을 모두 가져온다. 이때 워킹 디렉토리의 파일 내용은 변경되지 않아 사용자가 Merge 하도록 한다. 

 

git pull

Clone 한 서버에서 데이터를 가져오고 그 데이터를 자동으로 현재 작업하는 코드와 Merge 시킨다. 따라서 fetch 후 merge 명령을 실행하는 것과 같다.(현재 로컬 브랜치와 리모트 트래킹 브랜치 병합)

 

2.  merge와 rebase의 차이

아까 말했듯이 fetch를 사용하여 데이터를 가져왔다면 사용자가 수동으로 병합 작업을 수행해야한다. 병합하는 방법은 merge와 rebase 두가지로 볼 수 있다. 

 

1. merge

각 브랜치가 가리키는 커밋 두 개(C3, C4)와 공통 조상(C2)을 사용하여 3-way Merge를 하고 결과를 별도의 커밋으로 만들고 나서 해당 브랜치가 그 커밋을 가리키도록 이동시킨다.

 

2. rebase

 

두 브랜치가 나뉘기 전인 공통 커밋(C2)로 이동하고 나서 현재 브랜치의 커밋까지 diff를 차례로 만들어 임시로 저장한다. 이후 rebase할 브랜치가(experiment) 합칠 브랜치(master)가 가리키는 커밋을 가리키게 하고 저장해둔 변경사항을 차례대로 적용한다. 즉, C4에서 변경된 사항을 Patch로 만들고 이를 다시 C3에 적용한다. 

 

결국 C4'의 내용과 C5의 내용은 같을 것이다. 하지만, Rebase가 좀 더 깨끗한 히스토리(선형)으로 만든다. 일을 병렬로 동시에 진행해도 Rebase 하고 나면 모든 작업이 차례대로 수행된 것처럼 보인다. Rebase를 하든지, Merge를 하든지 최종 결과물은 같고 커밋 히스토리만 다르다는 것이 중요하다. Rebase 의 경우는 브랜치의 변경사항을 순서대로 다른 브랜치에 적용하면서 합치고 Merge 의 경우는 두 브랜치의 최종결과만을 가지고 합친다.

 

 

 

 

참고

https://git-scm.com/book/ko/v2/Git-브랜치-리모트-브랜치.html#_pull_하기

https://git-scm.com/book/ko/v2/Git-브랜치-Rebase-하기.html#_rebase_의_기초