Eunjeong Ko
👩💻Software Engineer 👤LinkedIn: http://bit.ly/2Hid4MT 🏠Blog: https://velog.io/@godori
2019.07.20
@godori
sat10am Git Study
브랜치를 합치는 방법
두 브랜치의 마지막 커밋 두 개(C3, C4)와 공통 조상(C2)을 사용하는 3-way Merge로 새로운 커밋을 만들어 낸다
전략:
C4 C3
C2
C5
1. 내 브랜치 커밋
2. 남의 브랜치 커밋
3. base가 되는 공통 조상 커밋
다음 세 개의 변화를 비교합니다.
My | Base | Other |
---|---|---|
a | ||
b | ||
c | ||
d |
My | Base | Other |
---|---|---|
a | a | a' |
b | b | b |
c' | c | c'' |
d' | d | d |
My | Base | Other |
---|---|---|
a | a | a' |
b | b | b |
c' | c | c'' |
d' | d | d |
Merge |
---|
a' |
b |
conflict |
d' |
Other |
---|
a' |
b |
c'' |
d' |
Merge |
---|
? |
b |
? |
? |
My |
---|
a |
b |
c' |
d |
그래서 git은 3-way-merge를 씁니다.
C3 에서 변경된 사항을 Patch로 만들고 이를 다시 C4 에 적용시킨다.
전략:
diff 내용이 담긴 파일
$ git checkout feature
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: f1
Applying: f2
$ git merge feature
feature
master
base
m1
m2
f1
f2
b
a
하려는 것: feature의 base를 b가 아니라 m2로 바꾸고 싶다
feature
master
base
m1
m2
f1
f2
b
a
feature
master
base
m1
m2
f1
f2
b
a
f1
f2
master
base
m2
f1
f2
b
a
m1
feature를 master에 rebase 한다
=
feature의 master에 대한 공통 조상인 base를 master로 변경한다
feature
head
master
base
m2
f1
f2
b
a
m1
▵1
▵2
feature
head
Step 1
base에서 현재 브랜치(feature)까지의 변경 사항을 구한다
diff patch: ▵1, ▵2
master
base
m2
f1
f2
b
a
m1
feature
head
Step 2
head를 master로 변경한다
diff patch: ▵1, ▵2
master
base
m2
f1
f2
b
a
m1
feature
head
Step 3
변경사항 ▵1을 적용하여 새로운 커밋 f1' 생성
diff patch: ▵1, ▵2
f1'
▵1
master
base
m2
f1
f2
b
a
m1
feature
head
Step 4
변경사항 ▵2를 적용하여 새로운 커밋 f1' 생성
diff patch: ▵1, ▵2
f1'
▵1
f2'
▵2
master
base
m2
f1
f2
b
a
m1
feature
head
Step 5
feature가 f2'를 가리키도록 한다
이때 f1과 f2는 저장소 내에는 존재하지만, 찾아갈 포인터가 없는 dangling 상태가 된다.
f1'
f2'
(dangling)
dangling 된 커밋은 가비지 컬릭션 대상이 된다.
git gc 참조
master
base
m2
b
a
m1
feature
Step 6
feature를 master로 fast-forward merge하여 완료
f1'
f2'
head
master
base
m1
m2
f1
f2
b
a
feature
feature로 체크아웃 한다
2. Master의 워킹 카피에 f2를 병합한다 (Applying f2)
master
base
f1'
m2
f1
f2
b
a
m1
f2'
1. Master의 워킹 카피에 f1을 병합한다(Applying f1)
master
base
f1'
m2
f1
f2
b
a
m1
feature
3. Master로 체크아웃하고 병합하여 마무리(fast-forward)
master
base
f1'
m2
b
a
m1
f2'
feature
Server는 테스트가 덜 된 상태
Client만 master에 합치고 싶다
이때 server와 상관없는 커밋은 c8, c9
git rebase --onto master server client
onto 옵션을 사용
client에서만 변경된 브랜치를 적용하고 싶을 때 유용하다
server와 client의 공통 조상을 찾음
client의 변경 부분만 master에 적용
$ git checkout master
$ git merge client
이제 다시 마스터로 돌아가서 fast-foward merge
리모트에 Push한 커밋을 Rebase 하면 안 됨
Rebase는 기존의 커밋을 그대로 사용하는 것이 아니라 내용은 같지만 다른 커밋을 새로 만들기 때문
내가 올린 커밋을 동료가 체크아웃 받아 작성하는데
그 커밋을 리베이스 해버리면
동료는 없는 커밋으로 작업한 꼴
히스토리를 보는 관점의 차이
💬
프로젝트가 어떻게 진행되었나에 대한 이야기
📜
작업한 내용의
사실 기록
역사가 어떻게 변경될 수 있어!
커밋 히스토리 변경은 거짓말을 하는 것
지저분한 Merge 기록을 남겨야 할까?
다른 사람에게 다듬어서 보여주자
로컬에서는 히스토리를 정리를 위해
Rebase 할 수도 있음
리모트에 Push한 커밋은
절대로 Rebase 하면 안됨!
프로젝트나 팀 상황에 따라 다르지만, 일반적인 원칙은
By Eunjeong Ko
👩💻Software Engineer 👤LinkedIn: http://bit.ly/2Hid4MT 🏠Blog: https://velog.io/@godori