깃과 브랜치

1. 브랜치란?


버전 관리 시스템에서는 나무가 가지에서 새 줄기를 뻗듯이 여러 갈래로 퍼지는 데이터 흐름을 가리키는 말로 사용합니다.

브랜치 기능 살펴보기

  • 깃으로 버전 관리를 시작하면 기본적으로 master라는 브랜치가 만들어집니다. 사용자가 커밋할 때 마다 master 브랜치는 최신 커밋을 가리킵니다. 즉, 브랜치는 커밋을 가리키는 포인터와 비슷하다고 생각하면 됩니다.
  • 기존에 저장한 파일을 master 브랜치에 그대로 유지하면서 기존 파일 내용을 수정하고나 새로운 기능을 구현할 파일을 만들 수 있습니다. 이렇게 master 브랜치에서 뻗어 나오는 새 브랜치를 만드는 것을 ‘분기(branch)한다’라고 합니다.
  • 새 브랜치에서 원하는 작업을 다 끝냈다면 새 브랜치에 있던 파일을 원래 master 브랜치에 합칠 수 있습니다. 이를 ‘병합(merge)한다’라고 합니다.

2. 브랜치 만들기


새 브랜치 만들기

$ git branch

깃에서 브랜치를 확인하는 명령입니다. 저장소를 만들 때 기본적으로 master 브랜치가 만들어집니다. 따로 특별히 branch를 만들지 않았다면 항상 master 브랜치에서 작업하고 있던 것입니다.

$ git branch 브랜치명

브랜치명을 apple이라고 가정하겠습니다. 그렇다면 apple 브랜치가 생성되었고 $ git branch를 입력시 master 브랜치과 apple 브랜치가 생성된 것을 알 수 있습니다.

브랜치 사이 이동하기

$ git checkout 이름

이름에 해당하는 브랜치로 이동합니다.

$ git checkout -b 이름

브랜치를 만들고 체크아웃을 한 번에 할 수 있습니다.

3. 브랜치 정보 확인하기


브랜치 관계 확인하기

$ git log --online // 한 줄에 한 커밋씩 간략하게 확인 가능
$ git log --oneline --branches // 각 브랜치의 커밋을 확인 가능
$ git log --oneline --branches --graph // 수직선으로 관계확인 가능


브랜치 사이의 차이점 알아보기

$ git log master..apple // 두 브랜치 사이에 ..

마침표 왼쪽에 있는 브랜치를 기준으로 오른쪽 브랜치와 비교합니다. 위와 같이 예를 들면 master 브랜치에는 없고 apple 브랜치에만 있는 커밋을 보여줍니다.

4. 브랜치 병합하기


서로 다른 파일 병합하기

$ git merge 브랜치명
  1. 브랜치로 병합하려면 가장 먼저 master 브랜치로 체크아웃 해야합니다.
  2. merge 뒤에 가져올 브랜치명을 적습니다.
  3. 자동으로 빔이 실행되면서 ‘Merge branch 브랜치명’라는 커밋 메시지가 나타납니다.
  4. master 브랜치에 병합되면서 새로운 커밋이 생성됩니다.
$ git merge 브랜치명 --no-edit // 깃에서 지정하는 커밋 메시지를 그대로 사용
$ git merge 브랜치명 --egit // 커밋 메시지를 추가하거나 수정


cf) 빨리 감기 병합(fast-forward merge)
master 브랜치에서 브랜치를 분기한 후에 master 브랜치에 아무 변화가 없는 경우의 병합과정은 간단합니다. 분기한 브랜치에서 만든 최신 커밋을 master 브랜치가 가리키게만 하면 되기 때문입니다. 이 경우에는 화면에 커밋 해시가 업데이트되었다는 내용과 함께 fast-forward라는 메시키가 나타나고 커밋 메시지 창은 열리지 않습니다.

같은 문서의 다른 위치 수정했을 때 병합하기

master branchapple branch병합된 master
titletitletitle
happy happy
 birthbirth

브랜치가 분기하기 전에 title이라는 내용만 있었고 분기 이후에 표와 같이 형성되었다면 $ git merge apple 입력시 master branch의 3행에 birth가 입력되면서 충돌없이 실행됩니다.

같은 문서의 같은 위치를 수정했을 때 병합하기

master branchapple branch병합된 master
titletitletitle
happybirthday«««<HEAD
  happy
  birthday
  »»»> apple

브랜치가 분기하기 전에 title이라는 내용만 있었고 분기 이후에 표와 같이 형성되었다면 $ git merge apple 입력시 HEAD 아래줄에는 현재 브랜치, 즉 master 브랜치에서 수정한 내용을 나타내고 === 아래줄에는 apple 브랜치에서 수정한 내용을 나타냅니다. 이런 경우에는 직접 확인하고 수정해줘야 합니다.

cf) 병합 및 충돌 해결 프로그램
프로젝트 규모라 클수록 브랜치가 많아지므로 브랜치에서 병합해야 할 파일도 많아집니다. 그만큼 충돌이 많이 생길 가능성이 높아집니다. 그래서 깃의 브랜치 병합을 자동으로 처리해 주고 충돌을 해결해 주는 프로그램이 많이 존재합니다. 병합 알고리즘에는 2 way merge와 3way merge가 있는데 3 way merge가 효율적으로 3 way merge를 지원하는 프로그램을 선택하는 것이 좋습니다.

병합이 끝난 브랜치 삭제하기

$ git branch -d 브랜치명

저장소의 기본 브랜치는 master 이므로 브랜치를 삭제하려면 master 브랜치에서 해야 합니다. 사용하지 않기 때문에 브랜치를 삭제했지만 같은 이름으로 다시 브랜치를 만들면 예전에 작업했던 내용이 그대로 다시 나타납니다. 즉, 브랜치를 삭제한다는 것은 완전히 저장소에서 없어지는 것이 아니라 깃의 흐름 속에서 감추는 것이라고 생각하면 됩니다.

5. 브랜치 관리하기


HEAD와 브랜치

  • HEAD는 현재 작업 트리(워킹 디렉터리)가 어떤 버전을 기반으로 작업 중인지를 가리키는 포인터입니다. HEAD는 기본적으로 master 브랜치를 가리킵니다. checkout 을 이용하면 HEAD가 가리키는 브랜치를 변경할 수 있습니다.
  • 브랜치는 기본적으로 브랜치에 담긴 커밋 중에서 가장 최근의 커밋을 가리킵니다.

브랜치에서 reset의 작동 원리

브랜치가 여러 개일때는 현재 브랜치가 아닌 다른 브랜치에 있는 커밋을 골라서 최신 커밋으로 지정할 수 있습니다.

$ git checkout apple // apple브랜치가 있다고 가정  
$ git reset 커밋해시 // 여기서 커밋해시는 master branch의 커밋해시

apple 브랜치의 최신 커밋이 master 브랜치의 최신 커밋으로 바뀌게 되고 HEAD는 그대로 apple을 가리킵니다. 이때 apple 브랜치가 원래 가리키고 있던 커밋은 연결이 끊어지면서 삭제됩니다. 이렇게 git reset 명령을 통해 현재 브랜치가 가리키는 커밋을 여러 브랜치 사이를 넘나들면서 제어할 수 있습니다.

수정 중인 파일 감추기 및 되돌리기

$ git stash
  • 브랜치에서 파일을 수정하고 커밋하지 않은 상태에서 급하게 다른 파일을 커밋해야 할 경우에 사용합니다.
  • git stash 명령을 사용하려면 파일이 tracked 상태여야 합니다.


$ git stash list

stash로 감춘 목록을 확인할 수 있습니다. 가장 최근에 보관한 것이 stash@{0}에 담기고 이전에 있던 것은 stash@{1}에 담기게 됩니다. 가장 최근에 감춘 것을 위에 쌓기 때문에 stash stack이라고도 표현합니다.

$ git stash pop

가장 최근 항목을 되돌립니다.

$ git stash apply

목록에서 가장 최근 항목을 되돌리지만 저장했던 내용은 그대로 stash@{0}에 남겨둡니다. stash 목록에 저장된 수정 내용을 나중에 또 사용할 경우있을 때 사용하면 유용합니다.

$ git stash drop

stash 목록에서 가장 최근 항목을 삭제합니다.


본 포스팅은 ‘지옥에서 온 문서 관리자 깃 & 깃허브’를 읽고 공부한 내용을 바탕으로 작성하였습니다.


© 2021. By Backtony