본문 바로가기

Git

Git - 기본적인 내용 정리2

브랜치 

커밋을 하게되면 Git 은 현 Staging area에 있는 데이터의 스냅샷에 대한 포인터,
저자나 커밋 메시지 같은 메타 데이터,
이전 커밋에 대한 포인터 등을 포함하는 커밋 객체(commit Object) 저장

최초 커밋을 제외한 나머지 커밋은 이전 커밋 포인터가 적어도 하나씩 있고
브랜치를 합친 Merge 커밋 같은 경우에는 이전 커밋 포인터가 여러 개 있다.

파일을 Stage 하면 Git 저장소에 파일을 저장하고(Blob) 
Staging Area에 해당 파일의 체크섬을 저장한다.

HEAD : 지금 작업하는 로컬 브랜치를 가리킨다.

git log --oneline --decorate
- 브랜치가 어떤 커밋을 가리키는지 확인

git log --oneline --decorate --graph --all
- 커밋 히스토리 확인

git checkout -b feature-xxx
- 브랜치를 만들면서 checkout

 


fast-forward
c2      <-    c4 
(master)     (hotfix)

hitfix 브랜치가 가리키는 c4 커밋이 c2 커밋에 기반한 브랜치이기 때문에
브랜치 포인터는 merge 과정 없이 그저 최신 커밋으로 이동한다. => fast-forward

A 브랜치에서 다른 B 브랜치를 merge 할 때 B 브랜치가 A 브랜치 이후의 커밋을 
가리키고 있으면 그저 A 브랜치가 B 브랜치와 동일한 커밋을 가리키도록 이동할 뿐이다.



3-way Merge
각 브랜치가 가리키는 커밋 두 개와 공통 조상 하나를 사용하여 merge

3-way Merge 실패

merge 하는 두 브랜치에서 같은 파일의 한 부분을 동시에 수정하고 
merge 하면 git은 해당 부분을 merge 하지 못한다.
=> conflict


트래킹 브랜치
- 리모트 트래킹 브랜치를 로컬 브랜치로 checkout 하면 자동으로 "트래킹(Tracking) 브랜치"가 만들어진다.
(트래킹 하는 대상 브랜치를 "Upstream 브랜치"라고 부른다.)
트래킹 브랜치는 리모트 브랜치와 직접적인 연결고리가 있는 로컬 브랜치이다.
트래킹 브랜치에서 git pull 명령을 내리면 리모트 저장소로부터 데이터를 내려받아 연결된 리모트 브랜치와 자동으로 merge 한다.

git checkout --track origin/serverfix
--trank 옵션을 사용하여 로컬 브랜치 이름을 자동으로 생성할 수 있다.

git checkout -b sf origin/serverfix
리모트 브랜치와 다른 이름으로 로컬 브랜치 이름을 생성하는 방법

git branch -vv
로컬 브랜치 목록과 로컬 브랜치가 추적하고 있는 리모트 브랜치도 함께 보여준다.
로컬 브랜치가 앞서가는지 뒤쳐지는지에 대한 내용도 보여준다.


rebase

두 브랜치가 나뉘기 전인 공통 커밋으로 이동하고 나서 그 커밋부터 지금 checkout 한 브랜치가 가리키는 커밋까지 diff를 차례로 만들어
어딘가에 임시로 저장해둔다.

Rabase 할 브랜치(experiment)가 합칠 브랜치(master)가 가리키는 커밋을 가리키게 하고 아까 저장해 놓았던 변경사항을 차례대로 적용한다.

 

* rebase로 합쳐진 기존 브랜치는 저장소 내에는 존재하지만, tag나 branch에서 가리킬 수 없는 dangling 상태가 되며,

dangling 된 커밋은 가비지 콜렉션의 대상이 된다.

rebase나 merge 둘 다 두 브랜치의 내용을 합치는 것이다.
하지만 rebase는 보통 리모트 브랜치에 커밋을 깔끔하게 적용하고 싶을 때 사용한다.
보통 rebase하는 리모트 브랜치는 직접 관리하는 브랜치(ex master or RB)가 아니라 참여하는 브랜치(ex feature)일 것이다.
메인 프로젝트에 patch를 보낼 준비가 되면 하는 것이 rebase니까 브랜치에서 하던 일을 완전히 마치고 orgin/master로 rebase 한다.
이렇게 rebase 하고 나면 프로젝트 관리자는 어떠한 통합작업도 필요 없다.
그냥 master 브랜치를 fast-forward 시키면 된다.

 

Merge의 경우 히스토리란 작업한 내용의 사실을 기록한 것이다.

Merge로 브랜치를 병합하게 되면 커밋 내역에 Merge commit이 추가로 남게 된다.

따라서 Merge를 사용하면 브랜치가 생기고 병합되는 모든 작업 내용을 그대로 기록하게 된다.

다음으로 Rebase의 경우는 브랜치를 병합할 때 이런 Merge commit을 남기지 않으므로,

마치 다른 브랜치는 없었던 것처럼 프로젝트의 작업 내용이 하나의 흐름으로 유지된다.

git rebase master server
토픽(server)브랜치를 checkout하고 베이스(master)브랜치에 rebase 한다.


그리고 나서 master 브랜치를 fast-forward 시킨다.

git checkout master
git merge server


Rebase의 위험성

[이미 공개 저장소에 Push 한 커밋을 Rebase 하지 마라]

Rebase는 기존의 커밋을 그대로 사용하는 것이 아니라 내용은 같지만 다른 커밋을 새로 만든다.
새 커밋을 서버에 push하고 동료 중 누군가가 그 커밋을 pull 해서 작업을 한다고 하자.
그런데 그 커밋을 git rebaseㄹ로 바꿔서 push 해버리면 동료가 다시 push 했을 때 동료는 다시 merge 해야 한다.
그리고 동료가 다시 merge한 내용을 내가 다시 pull 하면 .... 헬이다.

'Git' 카테고리의 다른 글

Git - 기본적인 내용 정리  (0) 2020.11.20