master, develop 과 같은 역할을 하는 브랜치들을 말한다. feature 브랜치들을 생성하고 다시 통합하는 역할을 해서 이름이 통합브랜치라고 붙여진 것 같다.
토픽브랜치 (Topic branch)
feature 브랜치라고도 말한다. 실제 운영 버그를 수정하거나, 새로운 기능을 추가하거나 등의 작업을 하는 브랜치라고 생각하면 된다.
인덱스 (index)
git을 조금 사용할 수 있게 되면 보통 로컬 저장소와, 원격 저장소로 나뉜다는 것 쯤은 쉽게 인지하고 있다. 그러나 그 중간에 존재하는 index 저장공간은 종종 잊혀지는데, index 의 존재를 한번씩 상기하는 것이 git을 올바르게 이해하는데에 좀 더 도움이 될 수 있다.
예를 들어서 로컬 저장소에서 어떤 작업을 끝내고 그 작업에 대해 commit 을 하였다고 하자. 우리는 git을 통해서 각 commit 에 해당하는 형상들로 자유롭게 오고갈 수 잇다. 이를 위해서는 그 commit 들이 의미하는 형상을 저장하고 있어야 하는데, 이 저장공간을 index 라고 한다.
index 는 로컬 저장소에 존재하며, commit 이 일어났을 때 이 commit 과 관련된 작업 내용들을 저장한다. 생각해보면 당연히 필요한 저장 공간이지만 막상 인지하지 않으면 index 공간은 쉽게 부각되지 않는다. 이 index 라는 공간은 단순히 알고 있는 것 만으로도 충분하다.
스태쉬 (stash)
index 공간에서 commit 이전 단계에 수정 작업들을 임시적으로 저장하고 싶을 때에 사용할 수 있는 영역이다. commit 을 하지 않고 내가 작업한 내용들을 저장하고 싶을 때 사용할 수 있다. 이 작업물들은 나중에 현재 브랜치나 다른 브랜치에서 불러와 사용할 수 있다.
예를 들어서 A, B 두 브랜치가 있고, A 브랜치에서 꽤 많은 양의 코드를 수정했다고 하자. 이 상태에서 B 브랜치로 checkout 을 하려고 하면 git 은 기본적으로 이 수정된 많은 코드들을 B 브랜치로 들고 온다. 물론 만약 이 때 같은 파일을 수정하게 되어서 충돌이 발생한다면 이 또한 조치를 해주어야 한다.
이렇기 때문에 보통 commit 하지 않은 수정 내용들이 있는 상태에서 브랜치를 이동하는 것은 성가실 수 있는데, 이럴 때 stash 저장공간을 활용해서 이곳에 수정 내용을 넣어두고 다른 브랜치를 이동하게 되면 보다 수월하게 브랜치 이동이 가능하다.
리비전 (revision)
이전 commit 상태부터 현재 상태까지의 변경 이력들이 기록되며, 이를 확인할 수 있는 것을 의미한다. git history, git log 등과 유사한 개념으로 바라보면 될 것 같다.
fast-forward merge
master 브랜치에서 bugfix 브랜치를 땃고 이상태에서 master 브랜치가 더이상 커밋내역이 없다면. bugfix 브랜치를 빠르게 병합할 수 있다. 이를 fast-forward merge 라고 부른다. 이것은 커밋이 따로 생성되지 않으며 bugfix 브랜치의 방향을 master 브랜치가 그대로 따라간다.
병합 실행 시에 ‘fast-forward merge’ 가 가능한 경우라도, ‘non fast-forward’ 옵션을 지정하여 merge commit을 만들어낼 수 있다.
1 2 3 4 5 6
// Before merge A -> B ㄴ X -> Y
// After merge A -> B -> X -> Y
merge commit
만약 bugfix 브랜치를 만들고 난 이후에 master 브랜치에 추가적인 commit 내역이 존재한다면 fast-forward merge 가 아닌 merge commit 이 실행된다
1 2 3 4 5 6 7
// Before merge A -> B -> C -> D ㄴ X -> Y
// After merge A -> B -> C -> D -> M ㄴ X -> Y -> (M 으로 병합)
리버트 (revert)
rebase
1 2
A -> B -> C -> D ㄴ -> X -> Y
위와 동일하게 master, bugfix 브랜치 두개가 존재한다고 할 때, rebase 방법은 X, Y 커밋 내역을 master 브랜치의 마지막 커밋내역인 D 뒤로 일자로 붙여서 통합하는 방법이다.
1
A -> B -> C -> D -> X -> Y
C, D 의 작업과 X, Y 의 작업이 충돌이 발생할 수 있으며 이는 수동 수정해주어야 한다. 하나 주의할 점은 rebase 를 했다고 해서 master 브랜치의 커밋내역은 X, Y 가 들어와있지 않다. 이를 위해서 fast-forward 머지를 한번 더 호출해주어야 한다.
일반적인 사용방법
1 2 3 4
토픽(피처) 브랜치에 통합(마스터) 브랜치의 최신 코드를 적용할 경우에는 rebase 를 사용, 통합(마스터) 브랜치에 토픽(피처) 브랜치를 불러올 경우에는 우선 rebase 를 한 후 merge
리베이스할때는 보통 피쳐 브랜치에서 통합 브랜치를 리베이스!
git flow
master
‘배포 가능한 형상’ 만을 관리하는 브랜치. 커밋할 때에는 태그를 사용하여 배포번호를 기록.
develop
위에서 언급한 통합 브랜치의 역할. 이 브랜치를 기반으로 개발을 진행한다.
feature
위에서 언급한 토픽 브랜치의 역할. develop 브랜치로 부터 분기되어서 작업을 진행한다. 이 브랜치의 작업들은 보통 공유될 필요가 없기 때문에, 원격으로는 관리하지 않는다.
release
배포 이전에 배포 테스트를 위해서 사용하는 브랜치이다. 모든 기능이 정상적으로 동작하는지 확인하기 위해 사용. 릴리즈 브랜치에서 수정될 내용을 수정하고 커밋을 하고 난 뒤 확인이 모두 끝나게 되면 이 브랜치는 develop 브랜치와 master 두 브랜치에 머지가 되어야 한다.
hotfix
이미 master 를 통해 배포된 형상에 문제가 있을 때에, 빠르게 수정하기 위한 브랜치.
원격 저장소의 브랜치와, 로컬 저장소의 브랜치도 결국 두 브랜치 라고 생각하면 될듯. 그렇게 추상화가 되어있음. 단지 물리적으로 멀리 존재할 뿐. 테크닉은 동일함.
태그는 두 종류가 존재챼
일반 태그(Lightweight tag) 이름만 붙일 수 있어요
주석 태그(Annotated tag) 이름을 붙일 수 있어요 태그에 대한 설명도 포함할 수 있어요 서명도 넣을 수 있어요 이 태그를 만든 사람의 이름, 이메일과 태그를 만든 날짜 정보도 포함시킬 수 있어요
보통 ‘릴리스 브랜치(Release branch)’에서는 주석 태그를 사용하여 설명이나 서명을 넣은 보다 상세한 정보를 포함하는 태그를 사용하고, 로컬에서 일시적으로 사용하는 ‘토픽 브랜치(Topic branch)’에서는 이름만 만들어 붙이는 태그를 사용합니다.
태그를 활용해서 checkout, reset, pull, push 등이 가능하다.
1
git tag 활용해서 checkout, reset, pull, push, 생성, 삭제 해보기
#
‘—amend’ 옵션을 지정하여 커밋을 수행하면, 같은 브랜치 상에서 이전에 커밋했던 내용에 새로운 내용을 추가하거나 설명을 수정할 수 있습니다.
reset 브랜치를 통합브랜치에서 사용하기는 어려운게. 만약 내가 작업한게 가장 마지막 커밋 내역이 아니라면. reset 을 썼을 경우 나의 다음에 적용된 커밋 내역들도 삭제가 된다.
그래서 보통 나의 커밋 작업만을 지우기 위해서 revert 커밋을 한다. revert 커밋은 내가 작업한 내용의 반대 작업을 하는 커밋을 새롭게 날리는 것.
그래서 커밋 이력도 지운 커밋이라고 새롭게 추가된다. (즉 이력도 남게됨.)
reset 명령어를 이용하면 더 이상 필요 없어진 커밋들을 버릴 수 있습니다. 명령어 실행 시 어떤 모드로 실행할 지 지정하여 ‘HEAD’ 위치와 인덱스, 작업 트리 내용을 함께 되돌릴지 여부를 선택할 수 있습니다.
cherry-pick
cherry-pick 을 이용하면 다른 브랜치에서 지정한 커밋을 복사하여 현재 브랜치로 가져올 수 있습니다.
이럴 때 사용해 보세요 :
특정 브랜치에 잘못 추가한 커밋을 올바른 브랜치로 옮기려고 할 때 다른 브랜치의 커밋을 현재 브랜치에도 추가하고 싶을 때
1
cherry-pick 한번 활용해서 다른 브랜치 내용을 가져와보자.
squash
이번에는 병합(merge) 할 때 사용할 수 있는, 조금 특별한 옵션인 ‘—squash’를 소개합니다.
이 옵션을 지정하여 브랜치를 병합하면 해당 브랜치의 커밋 전체를 통합한 커밋이 추가됩니다.
// 'README.md is changed by Feature branch' commit is not appear in here // because you can see this commit only in Feature branch. // Let's try to merge feature into master.
// 'README.md is changed by Feature branch' commit is not appear in here // because you can see this commit only in Feature branch. // Let's try to merge feature into master.
> vi README.md It's written by Master branch twice :wq
> cat README.md It's written by Master branch twice It's written by Master branch
> git add .
> git commit -m "README.md is changed by Master branch"
// It's the log of master branch but you can see the history of feature's thing. // because They are merged as master branch and importantly, this branch have had the new commit for merging them. // It's called merge commit.