advanced git

102
Advanced GIT Merge, Rebase, etc.. 정정정 (@enghqii) GDG SSU

Upload: chanwoo-jeong

Post on 13-Jan-2017

1.453 views

Category:

Software


1 download

TRANSCRIPT

Page 1: Advanced git

Advanced GITMerge, Rebase, etc..

정찬우 (@enghqii)GDG SSU

Page 2: Advanced git

DISCLAIMER

여기서 설명하는 규칙 , 방법은제가 소프트웨어 마에스트로 1 차 프로젝트에서 썼던 것들 입니다 .

무조건적으로 받아 들이실 필요는 없고 , 각자 하실 프로젝트의 규칙 , 방법을 정할때 참고해주시면 좋겠네요 .

Page 3: Advanced git

Speaker

• 정찬우 (@enghqii)• 숭실대학교 컴퓨터 학부 12 학번• GDG SSU• 소프트웨어 마에스트로 6 기 멘티

게임도 만들고 , 학교 공부도 하고 , 안드로이드도 좀 만지다가 , 스크립트 언어 좀 만들어 보다가… 다시 게임 만듭니다 .

Page 4: Advanced git

Topic

커밋 병합하기커밋 뜯어 고치기

Page 5: Advanced git

I suppose that you know …

커밋을 어떻게 하는지 , staging 은 어떻게 하는지 , 브랜치를 어떻게 만드는지 , 나눠진 브랜치를 어떻게 병합하는지 , 원격 브랜치와 로컬 브랜치가 어떻게 진행 되는지 , 코드가 어떻게 / 언제 충돌 나는지 , 충돌난 코드를 어떻게 해결하는지 , 남들이랑 작업하면서 프로젝트가 어떻게 망가지는지 , Pull-Request 가 뭔지 , Pull-Request 를 어떻게 하는지 , 등등…

다른 사람이랑 git 으로 프로젝트를 해봤다고 가정합니다 .

Page 6: Advanced git

1. Commits

Page 7: Advanced git

What are commits?

얘는 Kermit

Page 8: Advanced git

Commit

• ‘git commit’ 하면 생기는 동그라미• 변경점을 가지고 있다• 스냅샷• 기본적인 단위

• Parent 를 가리키는 레퍼런스를 가진다• SHA 해쉬 ID 를 가진다• 절대 지워지지 않는다

47fd8aa

Page 9: Advanced git

Branch

• 커밋을 가리키는 레퍼런스 mas-ter

Page 10: Advanced git

HEAD

현재 브랜치 ( 또는 커밋 ) 를 가리킨다HEAD 가 바뀌면 작업공간도 바뀜

HEAD mas-ter

Page 11: Advanced git

Structure of commits

A B C D

E F

master

chan-woo/

feature

HGsome-body/

feature

Page 12: Advanced git

^ & ~

• 부모 커밋을 가리키는 연산자• ^ (caret) : 한 세대 앞을 가리키는 연산• HEAD^, HEAD^^, HEAD^^^ …

• ~n (tilde) : n 세대 앞을 가리키는 연산• HEAD~1, HEAD~2, HEAD~3 …

Page 13: Advanced git

^ & ~

B DCA HEAD

HEAD~1,HEAD^

HEAD~2, HEAD^^

HEAD~3,HEAD^^^

Page 14: Advanced git

^ & ~

B D

E

CA HEAD

HEAD~1,HEAD^

HEAD~2, HEAD~1^1HEAD~3

HEAD~2, HEAD~1^2

Page 15: Advanced git

A commit must be …

• 적절한 크기의 하나의 작업만 해야 합니다 잠수함 패치 하면 안됨

• 컴파일 가능해야 합니다 , 빌드 가능해야 합니다 커밋 하나가 완벽해야 합니다

• 커밋 메시지가 잘 쓰여져 있어야 합니다 . 생판 모르는 사람이 ( 미래의 내가 ) 봐도 이해 가능해야

Page 16: Advanced git

Completeness – Unit Test

• 테스트 결과로 판단가능• 컴파일 , 빌드 되는지• 기존 기능이 여전히 잘 동작하는지

Page 17: Advanced git

Completeness - CI

• push, pull-request 할때 마다 자동 빌드• ‘ 어 ? 내 머신에선 됐는데 ?’

• 빌드 머신에서 되는지 판단 가능

Page 18: Advanced git

Commit Message

Tag1: Tag2: Topic sentence

Body …… 50chars

Page 19: Advanced git

Commit Message

Page 20: Advanced git

Commit Message

Page 21: Advanced git

2. Merge

Page 22: Advanced git

git merge <branch>

병합을 하는 가장 기본적인 명령어( 이름도 merge)

Page 23: Advanced git

git merge chanwoo/feature

A B C D

E F

master

chan-woo/

featuremaster 에서 chanwoo/feature 를 병합 할껍니다 . (HEAD 는 master)

$ git merge chanwoo/feature

Page 24: Advanced git

git merge chanwoo/feature

A B C

E

G

F

D

Merge Commit 이 생깁니다 .

Page 25: Advanced git

git merge chanwoo/feature

A B C

E master

chan-woo/

feature

G

F

D

Merge Commit 이 생깁니다 .

Page 26: Advanced git

Fast Forward merge

‘ 앞으로 진행한’ 커밋들을 따라잡는 merge.

Merge commit 을 만들어내지 않음 .

Page 27: Advanced git

git merge chanwoo/feature - FFWD

A B C Dchan-woo/

feature

master

master 에서 chanwoo/feature 를 병합(HEAD 는 master)

Page 28: Advanced git

git merge chanwoo/feature - FFWD

A B C Dchan-woo/

feature

master

별거 없음 , 끝 .

Page 29: Advanced git

많이 만들지 않는 것이 좋습니다 .왜 ?

Merge commit

Page 30: Advanced git

Too many merge commits….

m

m

m

M

m

m

m

m

Page 31: Advanced git

Too many merge commits….

이런 식으로 많아질 수 있습니다 .

보기에 좋지 않음 .

Page 32: Advanced git

I don’t want to make merge commits

변경점이 존재하는 한

‘git merge’ 할 때 merge commit 이 생기지 않을 수 없다 .

Merge commit 만들기 싫은데 ?

그래서 준비했습니다 .

Page 33: Advanced git

3. Rebase

Page 34: Advanced git

git rebase <branch>

커밋들을 병합하는 또 다른 방법Base 를 다시 정합니다

Page 35: Advanced git

Rebase

A B C D

E F

master

chan-woo/

feature

Page 36: Advanced git

Rebase

A B C D

E F

master

chan-woo/

feature

Page 37: Advanced git

In fact,

이런식으로 base 를 다시 정합니다근데 사실 저렇게 진행되진 않음

Page 38: Advanced git

git rebase master

A B C D

E F

master

chan-woo/

featurechanwoo/feature 에서 master 를 병합할껍니다 . (HEAD 는 chanwoo/feature)

$ git rebase master

Page 39: Advanced git

git rebase master

A B C D

E F

master

chan-woo/

feature

Page 40: Advanced git

git rebase master

A B C D

E F

master

chan-woo/

feature

E’ F’

Page 41: Advanced git

git rebase master

A B C D

E F

master

chan-woo/

feature

E’ F’

Page 42: Advanced git

Has upstream?

만약 chanwoo/feature 의 upstream 이 존재한다면 ?

그냥 push 했을경우 reject 당함 ( 충돌나니까 )

현재 이력을 강제로 올려야 합니다 .

$ git push --force

# Be very careful with this command!

Page 43: Advanced git

Before Rebasing

A B C D

E F

master

chan-woo/

featureorigin/chan-woo

/feature

Page 44: Advanced git

After Rebasing

A B C D

E F

master

chan-woo/

featureE’ F’

origin/chan-woo

/feature

Page 45: Advanced git

git push --force

A B C D

E F

master

chan-woo/

featureE’ F’

origin/chan-woo

/feature

Page 46: Advanced git

Merge vs. Rebase

• Merge• 장점

• 이전 커밋들을 들쑤지진 않음 , ( 이전 커밋들이 ) 잘못될 가능성이 없음 .

• 단점• 다른 브랜치들이 매우 활발하다면 그 때문에 머지 커밋이 많이 발생할 수 있고 , 때문에 커밋 로그들이 지저분해 보일 수 있음 .

Page 47: Advanced git

Merge vs. Rebase

• Rebase• 장점

• 프로젝트 히스토리가 훨씬 깔끔해질 수 있음 .• 선형적인 커밋 구조를 만들 수 있음 .

• 단점• 이전 커밋들을 들쑤시고 다니기 때문에 , 충돌이 발생하면 merge commit 을 만드는 방법보다 해결이 귀찮음 .• 원격의 , 남이 건드릴 수 있는 브랜치 (public branch) 는 절대 리베이스 하면 안됨 .

Page 48: Advanced git

Rebasing public remote branch

A B C D

E F

master

chan-woo/

feature

Page 49: Advanced git

Rebasing public remote branch

A

B C D

E F

master

chan-woo/

feature

B’ C’ D’

Page 50: Advanced git

Rebasing public remote branch

A

B C D

E F

master

chan-woo/

feature

B’ C’ D’

Page 51: Advanced git

B != B’B 와 B’ 는 다른 커밋

chanwoo/feature 에서 master 로 rebase 하면 B 도 쌓아 올린다 .

만약 B 같은 커밋이 여러개라면 ?다른 개발자들도 B 에서 브랜치를 쳤다면 ?

C, D 에서도 다른 개발자들이 브랜치를 쳤다면 ?

이런 상황을 전문용어로 개판이라고 한다 .

원격의 , 남이 건드릴 수 있는 브랜치는 절대 리베이스 하면 안됨 !

Page 52: Advanced git

Discuss with your colleagues

Merge 를 해도 되고 Rebase 를 해도 됩니다 .어떤 방법으로 커밋들을 병합할지는

팀원들과 상의하세요( 아니면 PM 이 까라는대로 까야지 )

Page 53: Advanced git

Conflict!

• $ git rebase --continue• $ git rebase --skip• $ git rebase --abort

아직 rebase 가 끝난게 아닙니다 .

Page 54: Advanced git

git rebase --continue

A B C D

E F

master

chan-woo/

feature

E’ F’

F’ 를 쌓아 올릴때Conflict

Page 55: Advanced git

git rebase --continue

A B C D

E F

master

chan-woo/

feature

E’ F’--continue

Resolve 하고 난 후 ,--continue

Page 56: Advanced git

git rebase --skip

• 충돌난 상황에서 , 현재 커밋을 쌓아올리길 포기하고 건너뜁니다 .• 잘 안씀 , 커밋 하나하나가 중요하다면 .

• 종종 resolve 다 하고 보니 git add 할게 없을때 사용함 .• sourcetree 의 ‘ resolve with theirs/mine’ 만 사용할때 발생할 수 있음 .

Page 57: Advanced git

git rebase --abort

• 현재 rebase 세션을 포기하고 아예 없던일로 합니다 .

쌓아올리는 커밋을 하나하나 resolve 하며 --continue 한 두번 하다가 나중에 화나서 --abort 할때 주로 사용함 .

Page 58: Advanced git

git reset ORIG_HEAD

rebase 를 성공적으로 마치고 난 직후 , ‘ 아 이 리베이스 하면 안됐는데’ 라는 생각이 들때 사용함

HEAD 를 rebase 직전의 커밋을 가리키게 해 준다 .

뭐 이것저것 만졌으면 reflog 찾아봐야지 ..

Page 59: Advanced git
Page 60: Advanced git

4. Fix commits

Page 61: Advanced git

Too many commits

A I

B

C

D

E

F

G

H

Page 62: Advanced git

Reduce

AB+C+D+

E+F+G+H+

I

똑같은 목적을 가진 커밋들을 한곳에 몰아넣자

Page 63: Advanced git

git commit --amend

• 마지막 커밋을 고치는 기능• 커밋 로그 , 변경 사항 전부 수정 가능 .

• 커밋하고 나서 , ‘ 아 이거 하나 커밋 안 했는데’ 할때 사용• 같은 역할을 하는 작은 커밋들을 여러개 만들지 않기 위해

Page 64: Advanced git

쓰이지 않는 헤더파일을 지우는 커밋을 새로 만들었습니다

Page 65: Advanced git

커밋하고 보니 , 수정할게 하나 더 있었습니다

Page 66: Advanced git
Page 67: Advanced git

변경 내역이 하나의 커밋으로 합쳐져 있습니다

Page 68: Advanced git

git rebase -i

• Interactive• 리베이스 세션을 열고 , 어떻게 할지 다시 물어봅니다• 뭘 어떻게 ?• 원래 순서대로 할건지 , 이 커밋을 사용할건지 , 말건지 , 직전 커밋과 합칠지 , 커밋메세지를 새로 작성할지… . 등등

Page 69: Advanced git

git rebase –i HEAD~5

A B C D

E Fchan-woo/

featureG H

Page 70: Advanced git

git rebase –i HEAD~5

pick 781915a I’m hungry (D)pick 23158ce I want to sleep (E)pick c94880e I want to be fixed up (F)pick d173cc0 Hello! (G)pick daf497f I’ll change this commit log later (H)

Page 71: Advanced git

pick, reword, squash and fixup# Commands:# p, pick = use commit# r, reword = use commit, but edit the commit message# e, edit = use commit, but stop for amending# s, squash = use commit, but meld into previous commit# f, fixup = like "squash", but discard this commit's log message# x, exec = run command (the rest of the line) using shell## These lines can be re-ordered; they are executed from top to bottom.## If you remove a line here THAT COMMIT WILL BE LOST.# However, if you remove everything, the rebase will be aborted.

Page 72: Advanced git

git rebase –i HEAD~5

pick 781915a I’m hungry (D)squash 23158ce I want to sleep (E)fixup c94880e I want to be fixed up (F)reword daf497f I’ll change this commit log later (H)pick d173cc0 Hello! (G)

Page 73: Advanced git

Pick D

A B C D

I’m hungry

Page 74: Advanced git

Squash E

# This is a combination of 2 commits. # The first commit's message is: I’m hungry# This is the 2nd commit message: I want to sleep# Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # Explicit paths specified without -i nor -o; assuming --only paths... # Not currently on any branch. # Changes to be committed:

A B C D+E

I’m hungry and I wanna sleep

Page 75: Advanced git

Fixup F

A B C D+E+F

I’m hungry and I wanna sleep

Page 76: Advanced git

Reword H

A B C D+E+F

H

Commit Log Changed!

Page 77: Advanced git

Pick G

A B C D+E+F

H G

Hello!

Page 78: Advanced git

Rebase finished

A B C D+E+F

H Gchan-woo/

feature

Page 79: Advanced git

5. Branch strategy

Page 80: Advanced git

master is SACRED

master 브랜치는 성역입니다 . 기도하고 checkout 합시다 .

Page 81: Advanced git

Never Ever commit to master

branch 따와서 작업하고 , pull-request 날립시다

Page 82: Advanced git

Branch Naming

name/fea-ture

Page 83: Advanced git
Page 84: Advanced git

Pull-Request

A B

E F

master

chan-woo/

feature

DCsome-body/

feature

Page 85: Advanced git

Pull-Request merged

A B

E F

master

chan-woo/

feature

DCsome-body/

feature

G

Page 86: Advanced git

Somebody: ?!

somebody 가 작업한 C,D 가 auto mergeable 이면 괜찮은데 , E,F 때문에 conflict 가 떠서 자동 머지가 불가능 하다면 ?

somebody 입장에서는 갑자기 다른놈이 훼방하지만 먼저 PR 날리고 merge 된 놈이 승자 .

이 때 somebody 가 할 수 있는 행동은 ?

Page 87: Advanced git

git rebase master

A B

E F

master

chan-woo/

feature

D’C’some-body/

feature

G

Page 88: Advanced git
Page 89: Advanced git

Rules

unit test 는 사전에 미리 통과가 됐었어야 push 를 할 수 있다push 된 커밋들은 Travis 빌드 테스트를 통과해야 pull-request 를 보낼 수 있다

pull-request 가 별 다른 문제점이 없다면 merge 되지만커밋로그가 불충분 하거나 , 풀리퀘 로그가 불충분 하거나 ,

하나의 커밋에 너무 많은 일이 들어가 있거나 , 너무 적은 일이 들어가 있거나 , 쓸모 없는 기능으로 판단된다면 ?

REJECT

Page 90: Advanced git

Rejected PR

A B

E F

master

chan-woo/

feature

Page 91: Advanced git

git branch chanwoo/feature-v2

A B

E F

master

chan-woo/

featurechan-woo/

feature-v2

Page 92: Advanced git

Fix problems, Send PR again.

A B

E F

master

chan-woo/

featurechan-woo/

feature-v2

F’

Page 93: Advanced git
Page 94: Advanced git
Page 95: Advanced git

Summarize

• 하나의 커밋은• 적당한 크기 , 연관성 있는 변경점 , 상세한 커밋 메세지

• 여러개의 커밋은• 삽질은 커밋 로그에 , 하나의 기능은 하나의 커밋으로 줄인다• --amend, rebase -i

• 브랜치는• master 는 건들지 말고 , 기능별로 따 와서 , Pull-Request

Page 96: Advanced git

6. Tip commands

Page 97: Advanced git

git reset [--hard | --soft | …]

커밋을 취소하고 브랜치를 이전으로 돌리는 기능 --hard$ git reset --hard HEAD~1

--soft$ git reset --soft HEAD~1

Page 98: Advanced git

git revert <commit>

• 해당 커밋의 변경점을 상쇄하는 커밋을 새로 생성

A+B

-A-B A B

Page 99: Advanced git

git clean

• git 에 의해 추적되지 않는 파일들을 지우는 기능 추적되는 파일만 남기는 기능• 빌드시 자동 생성되는 파일들을 지울때 편함 .

$ git clean -xf

Page 100: Advanced git

git blame

• 어떤 파일의 몇번째 라인부터 몇번째 라인 까지 • 누가 작성했는지 고발

$ git blame -L 12,12 ./src/asdf.cppd5dde9d4 (ChanWoo Jeong 2015-08-27 00:38:31 +0900 12)cout << “Hello world!” << endl;

Page 101: Advanced git

git cherry-pick <commit>

• 특정 커밋 하나만 따와서 붙이는 기능 .

$ git cherry-pick 7cbce9a

Page 102: Advanced git

END

References누구나 쉽게 이해할 수 있는 git 입문 – 브랜치 전환 : https://backlogtool.com/git-guide/kr/stepup/stepup1_3.html

Atlassian Tutorial – merging vs. rebasing : https://www.atlassian.com/git/tutorials/merging-vs-rebasing/

Git 브랜치 rebase 하기 : https://git-scm.com/book/ko/v1/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98-Rebase%ED%95%98%EA%B8%B0

Git 도구 히스토리 단장하기 : https://git-scm.com/book/ko/v1/Git-%EB%8F%84%EA%B5%AC-%ED%9E%88%EC%8A%A4%ED%86%A0%EB%A6%AC-%EB%8B%A8%EC%9E%A5%ED%95%98%EA%B8%B0

소마 1 차 프로젝트 : https://github.com/swmaestro06-apus/apus