[Git] Git Branch 총 정리

chaevivi·2023년 9월 28일
1
post-thumbnail

Git Branch(깃 브랜치) 총 정리


🙌 들어가며

개발하면서 기능을 구현하고 커밋할때마다 '이 기능은 제대로 구현하지 못했는데 커밋해도 되는걸까?'라는 생각이 들었습니다. Git Branch를 사용하면 main 브랜치에 검증된 코드들만 커밋할 수 있고, 동시 다발적으로 기능 개발을 할 수 있습니다. Git을 조금 더 편라하고 유용하게 사용할 수 있는 Git Branch에 대해 자세히 알아보고 알기 쉽게 정리해보려 합니다.



1. Git Branch란?

Git의 브랜치는 커밋 사이를 가볍게 이동할 수 있는 어떤 포인터 같은 것이다. (Git Book)


1.1. Git이 데이터를 저장하는 방법

Git이 브랜치를 다루는 과정을 이해하려면 우선 Git이 데이터를 어떻게 저장하는지 알아야 합니다.


Git은 데이터를 스냅샷의 스트림처럼 취급합니다. 다시 말해, Git은 데이터를 파일 시스템 스냅샷의 연속으로 취급하고 크기가 아주 작습니다. Git은 커밋하거나 프로젝트의 상태를 저장할 때마다 파일이 존재하는 그 순간을 중요하게 여깁니다. 파일이 달라지지 않았으면 Git은 성능을 위해서 파일을 새로 저장하지 않습니다.

커밋하면 Git은 커밋 객체(Commit Object)를 저장합니다. 커밋 객체는 현 Staging Area에 있는 데이터 스냅샷에 대한 포인터, 저자나 커밋 메시지 같은 메타데이터, 이전 커밋에 대한 포인터 등을 포함합니다. 커밋 객체에 이전 커밋에 대한 포인터가 있기 때문에 현재 커밋이 무엇을 기준으로 바뀌었는지를 알 수 있습니다.

Git의 브랜치는 커밋 사이를 가볍게 이동할 수 있는 포인터 같은 것입니다. 기본적으로 Git은 main 브랜치를 만듭니다. 처음 커밋하면 이 main 브랜치가 생성된 커밋을 가리킵니다. 이후 커밋을 만들면 main 브랜치는 자동으로 가장 마지막 커밋(가장 최근 커밋)을 가리킵니다.


1.2. Git Branch의 장점

  • Git의 브랜치는 매우 가볍습니다.
  • 브랜치를 쉽게 새로 만들 수 있고 브랜치 사이를 이동할 수 있습니다.
  • 다른 버전 관리 시스템과 달리 Git은 브랜치를 만들어 작업하고 나중에 Merge 할 수 있습니다.
  • 브랜치를 만들면 여러 개발자들이 병렬적으로 개발이 가능합니다.
  • main 브랜치에는 기능에 문제가 없고 정확하게 검증딘 코드들만 포함되어야 합니다. 브랜치는 검증을 마친 코드들만 main 브랜치에 merge 할 수 있습니다.


2. 기본 사용법


2.1. 새 브랜치 생성

$ git branch testing
  • git branch 명령어로 testing이라는 이름을 가진 브랜치를 새로 생성할 수 있습니다.
  • 새로 만든 브랜치는 지금 작업하고 있는 마지막 커밋을 가리킵니다.
  • git branch 명령은 브랜치를 만들기만 하고 브랜치를 옮기지 않습니다.
    - 현재 작업 중인 브랜치를 파악하기 위해서 Git에는 'HEAD'라는 특수한 포인터가 있습니다.
    • 'HEAD' 포인터는 현재 작업하는 로컬 브랜치를 가리킵니다.


2.2. 브랜치 이동하기

$ git chaeckout testing
$ git switch testing
  • git checkout 이나 git switchtesting 브랜치로 이동할 수 있습니다.
  • 브랜치를 이동하면 'HEAD'는 testing 브랜치를 가리킵니다.


$ git commit -a -m 'made a change'
$ git checkout main
  • 새로 커밋을 하면 testing 브랜치는 새로운 커밋을 가리키고 main 브랜치는 계속 이전 커밋을 가리킵니다.
  • 커밋 후 다시 main 브랜치로 돌아옵니다. 따라서 'HEAD'는 main 브랜치를 가리킵니다.
  • main 브랜치가 가리키는 커밋을 'HEAD'가 가리키게 하고 워킹 디렉토리의 파일도 그 시점으로 되돌려 놓았습니다.
    • 브랜치를 이동하면 워킹 디렉토리의 파일이 변경됩니다.
    • 이전에 작업했던 브랜치로 이동하면 워킹 디렉토리의 파일은 그 브랜치에서 가장 마지막에 했던 작업 내용으로 변경됩니다.
  • 커밋을 하면 다른 브랜치의 작업들과 별개로 진행되기 때문에 testing 브랜치에서 임시로 작업하고 원래 main 브랜치로 돌아와서 하던 일을 계속할 수 있습니다.


$ git commit -a -m 'made other changes'
  • 파일을 수정하고 다시 커밋을 하였습니다.
  • 현재 main 브랜치에서 파일을 수정하고 커밋했기 때문에 이전에 수정한 내용은 다른 브랜치(testing)에 존재합니다.
  • 커밋 사이를 자유롭게 이동하다가 때가 되면 두 브랜치를 merge 할 수 있습니다.


2.3. 새 브랜치 생성후 이동

$ git checkout -b testing
$ git swtich -C testing
  • git checkout -bgit switch -C 명령어로 새로운 브랜치를 생성하고 해당 브랜치로 이동할 수 있습니다.

2.4. 브랜치 확인

(1) 로컬 브랜치 확인

$ git branch
  iss53
* master
  testing
  • git branch 명령어로 현재 레포지터리에 있는 브랜치를 확인할 수 있습니다.
  • * 기호기 붙은 브랜치는 현재 Checkout 해서 작업하는 브랜치를 나타냅니다.

(2) 브랜치와 커밋 메시지 확인

$ git branch -v
  iss53   93b412c fix javascript issue
* master  7a98805 Merge branch 'iss53'
  testing 782fd34 add scott to the author list in the readmes
  • git branch -v 명령어로 브랜치와 함께 최신 커밋 메시지를 확인할 수 있습니다.

(3) 원격 브랜치 확인

$ git branch --all
  • git branch --all 명령어로 원격 서버에 있는 모든 브랜치를 확인할 수 있습니다.

2.5. 머지된 브랜치 확인

$ git branch --merged
  iss53
* master
  • git branch --merged 명령어로 현재 브랜치에 머지된 브랜치를 확인할 수 있습니다.
  • iss53 브랜치는 앞에서 이미 merge 했기 때문에 목록에 나타납니다.
  • * 기호가 붙어 있지 않은 브랜치는 이미 다른 브랜치와 merge 했기 때문에 git branch -d 명령으로 삭제해도 되는 브랜치 입니다.

2.6. 머지되지 않은 브랜치 확인

$ git branch --no-merged
  testing
  • git branch --no-merged 명령어로 현재 브랜치에 머지되지 않은 브랜치를 확인할 수 있습니다.
  • 아직 merge 하지 않은 커밋을 담고 있기 때문에 testing 브랜치는 git branch -d 명령으로 삭제되지 않습니다.

2.7. 브랜치 삭제

$ git branch -d testing
  • git branch -d 명령어로 testing 브랜치를 삭제할 수 있습니다.

$ git push origin --delete testing
  • git branch -d 명령어로 브랜치를 삭제했다면 원격 저장소에 업데이트해야 합니다.
  • git push origin --delete 명령어로 원격 저장소의 브랜치를 삭제할 수 있습니다.
  • 서버에서 가비지 컬렉터가 동작하지 않는 한 데이터는 사라지지 않기 때문에 의도치 않게 삭제한 경우에도 커밋한 데이터를 살릴 수 있습니다.

2.8. 브랜치 이름 변경

$ git branch --move testingA testingB
  • git branch --move 명령어로 브랜치 이름을 testingA에서 testingB로 변경할 수 있습니다.

$ git push --set-upstream origin testingB
  • 브랜치 이름을 변경했다면 원격 저장소에 업데이트해야 합니다.
  • git push --set-upstream origin 명령어로 변경된 브랜치를 push 합니다.


3. Rebase 하기

  • Git에서 한 브랜치에서 다른 브랜치로 합치는 방법에는 Merge와 Rebase가 있습니다.
  • Rebase는 three-way merge를 해야 하는 상황일 때 사용할 수 있습니다.
    • three-way merge: main 브랜치에서 새로운 브랜치가 생성된 이후에 main 브랜치에 변동 사항이 생겼을 때 새로운 브랜치를 main 브랜치로 merge 하는 것을 말합니다.
  • Rebase는 새로운 브랜치를 main 브랜치의 가장 최신 커밋으로 이동시키는 것입니다.

3.1. 그림

그림으로 Rebase의 과정을 자세히 살펴보겠습니다.

  • main 브랜치의 c에서 새로운 브랜치인 new_branch가 생성되었습니다.
  • new_branch가 생성된 이후 main 브랜치에 새로운 커밋 f가 생겼습니다.
  • 이때는 three-way merge를 해서 새로운 커밋을 만들어 merge 할 수 있습니다.

  • three-way merge를 해서 새로운 커밋g를 만들어 main 브랜치에 merge 하였습니다.

  • rebase는 three-way merge와 다르게 새로운 커밋을 만들지 않습니다.
  • rebase는 new-branch의 커밋인 de를 main 브랜치의 새로운 커밋인 f로 포인터(HEAD)를 옮기는 것을 말합니다.
  • 여기서 주의할 점은 f로 옮겨진 de기존의 커밋이 아니라 새롭게 만들어진 커밋입니다.

  • 그 후, main 브랜치를 Fast-forward 합니다.
  • Fase-forward란 main 브랜치에서 새로운 브랜치가 생성된 이후에 main 브랜치에 변동 사항이 없다면 main 브랜치를 가리키고 있는 포인터(HEAD)를 머지할 곳으로 옮기고 해당 브랜치를 삭제하는 것을 말합니다.
  • 다시 말해, 이전에 브랜치를 rebase했기 때문에 main 브랜치의 f 이후에는 변동 사항이 없습니다. 그래서 c에 있던 포인터를 e로 옮기고 new-branch를 삭제합니다.

3.2. 코드

위의 Rebase 과정을 코드로 살펴보겠습니다.

  • new-branch로 이동합니다.
    $ git checkout new-branch
  • 브랜치를 rebase 합니다.
    $ git rebase main
  • main 브랜치로 이동합니다.
    $ git checkout main
  • fast-forward를 합니다.
    $ git merge new-branch
    $ git branch -d new-branch

3.3. 장점과 주의점

  • 장점
    • three-way merge를 하면 새로운 커밋을 일일이 만들어 주어야 합니다.
    • 하지만 rebase를 사용하면 새로운 커밋을 만들어 주지 않고 쉽게 머지할 수 있습니다.
  • 주의점
    • rebase를 할 때는 로컬이나 혼자서 작업할 때만 사용해야 합니다.
    • rebase를 하면 기존의 커밋을 유지하는 것이 아니라 새로운 커밋을 생성하기 때문에 다른 개발자와 작업할 때 머지 충돌이 발생합니다.
    • 위의 예시를 다시 활용하겠습니다. rebase를 하면 de는 새롭게 생성됩니다. 그렇기 때문에 다른 개발자가 가지고 있는 de와는 완전히 다른 커밋이 됩니다. 이는 나중에 머지 충돌을 발생시킬 위험이 있습니다.

3.4. rebase --onto

rebase --onto로 브랜치 위에 새로운 브랜치들이 체이닝 되어 있을 때 쉽게 머지할 수 있습니다.


그림으로 더 자세히 살펴보겠습니다.

  • c에서 새로운 브랜치인 server 브랜치를 만들고, 그 브랜치에서 client 브랜치를 만들었습니다.
  • client 브랜치가 sever 브랜치 없이 main 브랜치에 머지하고 싶을 때 rebase --onto를 사용할 수 있습니다.

  • rebase --onto로 client 브랜치를 main 브랜치에 머지하였습니다.
  • 이때 rebase된 client의 gh 커밋은 기존의 커밋이 아니라 새롭게 생긴 커밋입니다.

코드로 작성하면 아래와 같습니다.

git rebase --onto main server client
  • git rebase --onto 명령어로 client 브랜치를 server 브랜치 없이 main 브랜치에 머지하였습니다.


4. cherry pick

마지막으로 살펴볼 것은 cherry pick 입니다. cherry pick을 사용하면 필요한 커밋만 main 브랜치로 가져올 수 있습니다.


그림으로 더 자세히 살펴보겠습니다.

  • cherry pick으로 server 브랜치의 e 커밋을 main 브랜치로 가져올 수 있습니다.

코드로 작성하면 아래와 같습니다.

$ git cherry-pick '해시코드'
  • main 브랜치로 가져올 커밋의 해시코드를 복사하고 git cherry-pick 명령어로 해당 커밋을 main 브랜치로 가져옵니다.



출처

🔗 https://git-scm.com/book/ko/v2/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98-%EB%B8%8C%EB%9E%9C%EC%B9%98%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80

profile
직접 만드는 게 좋은 프론트엔드 개발자

0개의 댓글