Git 개념 정리 (2) - Git Branch , Merge
Git Branch
코드를 통쨰로 복사하고 나서 다른 개발자들과 독립적으로 개발을 진행할 수 있도록 branch를 나눌 수 있다.
Git branch는 commit 사이를 이동할 수 있는 포인터와 비슷한 개념으로, 기본적으로 Git은 master branch를 먼저 만든다. 이후 commit을 하게 되면 master branch 는 자동적으로 가장 마지막(최근) commit을 가르킨다.
branch 생성하기
git branch 는 git branch <branch명> 명령어로 만들 수 있다. branch를 새로 만들면 가장 마지막 commit을 가르키게 된다.
1 | C:\Users\katd6\OneDrive\바탕 화면\hello-git>git branch testbranch |
그럼 두 branch중에 현재 working directory에서 작업중인 branch를 어떻게 나눌까?
Git은 HEAD라고 하는 로컬 Branch를 가르키는 특수한 pointer가 존재한다.
1 | C:\Users\katd6\OneDrive\바탕 화면\hello-git>git branch -a |
branch 이동하기
git checkout <이동할 branch명>
git branch 는 checkout 명령어로 이동할 수 있다. 아까 정리했던것처럼 Git은 HEAD라고 하는 현재 작업중인 Local branch를 가르키는 pointer인 HEAD가 존재한다고 하였다. git checkout 명령어로 로컬 branch를 바꾼다는 것은 결국에 이 pointer가 가르키는 branch를 변경하겠다는 말이랑 동일하다.
1 | C:\Users\katd6\OneDrive\바탕 화면\hello-git>git branch -a |
변경된 branch에서 파일을 변경 (modified status) 및 add (Staged ) 및 commit 하게 되면 어떻게 될까?
1 | C:\Users\katd6\OneDrive\바탕 화면\hello-git>git status . |
다음과 같이 testbranch에서 file을 add, commit해보았다.
이전까지 master , testbranch는 가장 최근 commit 을 동일하게 가르켰지만, 이젠 testbranch는 방금전 수행한 commit을 가르키고 , master branch 는 master branch에서 가장 최근에 수행한 commit을 가르키고 있다.
master branch에서 또다른 commit을 수행하고 각각 두 branch에서 git log 를 찍어보았다.
test branch , master branch가 분기해서 각각의 최근 commit을 가르키는 것을 볼 수 있으며, 이는 HEAD pointer에 의해 가르켜진다.
branch 사용예제
Git pro (https://git-scm.com/book/ko/v2) 에 따르면 git branch 사용 예시는 다음과 같다.
1 | 실제 개발과정에서 겪을 만한 예제를 하나 살펴보자. 브랜치와 Merge는 보통 이런 식으로 진행한다. |
먼저 이슈가 발생했다고 가정하면 이슈처리용 branch를 생성 및 이동한다.
1 | C:\Users\katd6\OneDrive\바탕 화면\hello-git>git checkout -b iss53 |
참고로 git checkout -b 는 git branch 생성 후에 해당 branch로 HEAD pointer를 이동하라는 명령어다.
다음으로 issue에 대해 어떤 코드를 작성하고 commit을 하였다고 가정하자
이떄 도중에 다른 긴급한 이슈가 생겼다고 하면 먼저 master branch로 이동하고, 해당 issue에 대한 branch를 또하나파서 작업한다.
이렇게 작업하면 issue별로 branch를 따서 서로 독립적으로 개발이 가능하다.
고친 issue를 master branch 와 병합하고 싶으면 git merge <병합할branch명> 명령어를 통해서 두 branch를 합칠 수 있다. 이떄 두 branch가 공동 선상에 있다면 fast-forward 방식으로 HEAD pointer를 이동시켜줄 수 있다.
branch 가 합쳐진 이후에 고친 issue branch가 필요없다면 다음과 같이 제거하고, 원래 개발자가 수행하던 issue로 돌아가면 된다.
issue 가 모두 종료되어 master branch에 해당 issue도 merge 한다고 가정하자
이떄는 아까처럼 fast-forward 방식이 아니다. 그 이유는 두 branch가 동일 선상에 있는기 떄문에 두 branch간 공통조상 하나를 사용해서 3way merge를 한다.
3way merge 방법은 단순히 branch pointer (HEAD)를 최신 commit으로 이동시키는 방법이 아니다, 3way merge 병합 결과 자체를 새로운 commit으로 만들어서 두 branch 모두를 부모로 갖게 만든다.
- Merge commit : 3 way merge 방식에 의해 2 branch를 부모로 갖는 commit
branch 관리
branch 관리하는데 필요한 그 외 명령어는 다음과 같으며, 자세한 내용은 git branch –help를 통해 api 문서를 보면 된다.
- git branch -v : 현재 작업 branch 내역과 마지막 commit message들
- git branch –merged: 현재 branch 기준으로 merge된 branch
- git branch –no-merged: 현재 branch 기준으로 merge되지 않은 branch
- git branch -d <branch명> : 해당 branch 삭제
git branch workflow
branch를 만들고 merge하는 방식에 대해 convention처럼 workflow가 만들어진것이 있다.
- Long-Running branch
master branch는 안정된 코드 (배포할 코드) 만 두고, 개발 진행하는 과정에서 기능이 추가될 branch 는 develop branch에 둔다.
이후 test code를 작성해서 정상적으로 pass되면 master branch에 merge 한다.
remote branch
remote branch란 원격 저장소에 있는 branch,tag등을 의미한다. git ls-remote <원격저장소> 를 통해 해당 원격저장소에 있는 remote branch를 조회할 수 있다.
remote branch (정확히는 remote tracking branch인데, local에 있지만 서버에 연결될때마다 자동으로 갱신된다.) 는 <원격저장소명>/<branch명> 형식으로 되어 있다.
예를 들어 어떤 원격저장소에 있는 프로젝트를 clone해서 local로 가져오면 다음과 같은 일이 벌어진다.
git clone 명령어는 이전에 말햇던것처럼 자동으로 origin 이라는 이름으로 원격저장소를 등록해준다. 또한 원격의 master branch를 가르켜주는 (origin/master) pointer를 만들어주는데, 이 pointer는 개발자가 조종할수 없다.
git pull vs fetch
원격저장소로부터 저장소 정보를 동기화 하려면 git fetch <원격저장소명> 을 통해 새로운 정보가 있으면 모두 내려받고, origin/master pointer를 최신 commit으로 이동시켜준다.
반면 git pull 은 원격저장소로부터 저장소 정보를 동기함과 더불어 자동으로 로컬 branch와 병합까지 수행한다.
원격 저장소에 push 하기
local branch를 서버로 전송하려면 write 권한이 있는 원격 저장소에 push해야 한다.
git push <원격저장소명> <push할branch명>
remote branch 삭제
git push <원격저장소명> –delete <삭제할branch명>