git branch

김태완·2023년 10월 24일
0

독서 스터디

목록 보기
1/8

깃 브랜치란

  • 기존의 코드와 상관없이 독립적인 개발을 진행 할 수 있음
  • git 데이터를 변경사항으로 저장하지않고 일련의 스냅샷으로 기록함.

git commit

  • 커밋은 현 stage area 데이터의 스냅샷 + 포인터 + 저자 + 메타데이터 등을 포함하는커밋객체를 저장한다. 따라서 현재 커밋이 이전 커밋을 바라보고있어 어떤 커밋을 기준으로 바뀌었는지 알 수 있다.
  • git commit시 루트디렉토리, 하위 디렉토리의 트리, 체크섬을 저장한다. 따라서 언제든 스냅샷을 만들 수 있다.

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

브랜치 생성

git branch [브랜치01]

현재 작업하고있던 마지막 커밋을 기준으로 새로운 브랜치01 을 생성한다.

git은 HEAD라는 특수한 포인터가 현재 작업중인 로컬 브랜치를 가르킨다.

git log --decorate

--decorate 옵션으로 브랜치가 어떤 커밋을 가르키는지 확인할수있음.

브랜치 이동

git checkout [브랜치02]
git commit -m "C4"

HEAD를 브랜치02로 이동한다.
이때 이동한 브랜치02에서 commit을 하게되면 HEAD가 C4로 이동한다.

만약 다시 브랜치01으로 체크아웃한다면 HEAD도 C3으로 이동하게된다.

git checkout [브랜치01]

만약 이 상황에서 브랜치01에서 추가 작업을 커밋한다면 브랜치가 분기될것이다.

git commit -m "C5"

  • 실제 git 브랜치는 어떤 한 커밋을 가리키는 40글자의 SHA-1체크섬 파일 에 불과해서 매우 가볍다.(총 41바이트)

브랜치 병합

git checkout -b [이슈53]

// git branch [이슈53]
// git checkout [이슈53]

위와같이 이슈 53브랜치를 생성과 동시에 체크아웃할수있다. 아래와 같은 상황을 가정해보자.

이때 master에 급하게 수정해야 할 사항이 생겼을떄 hotfix 브랜치를 만들어서 고쳐야한다.

  • 단 이때 이슈53에서 작업중이던 내용은 워킹디렉터리에서 지워야함 git stash
git checkout master
git checkout -b hotfix

그런 다음 master로 체크아웃한다음 git merge를 해준다

  • 이때 fast-forward 로 merge하는데 이는 C4가 C2기반으로 만들어졌기때문에 브랜치과정에서 merge를 생략하고 최신 커밋으로 이동한다(?).
  • 즉 같은 선상의 커밋을 Merge하는경우엔 복잡한 계산없이 master브랜치를 hotfix브랜치를 가르키도록 변경만 한다는뜻.
git checkout master
git merge hotfix

이후 hotfix 브랜치는 삭제한다

git branch -d hotfix

그런 다음 이슈 53으로 체크아웃한뒤 커밋을 하고, master에 이슈53을 merge 하는 경우는 3-way-merge를 하게된다

git checkout [이슈53]
git commit -m "C5"
git checkout master
git merge [이슈53]

충돌

3way Mergerk 실패할때도있는데 두 브랜치에서 같은 파일의 한 부분을 동시에 수정하게되면 충돌이 발생한다.

이때 git staus를 사용해 충돌 내역을 확인할수있다.

 $ git status
  On branch master
  You have unmerged paths.
    (fix conflicts and run "git commit")
  Unmerged paths:
    (use "git add <file>..." to mark resolution)
      both modified:      index.html
  no changes added to commit (use "git add" and/or "git com
....

이때 개발자가 수동으로 충돌부분을 해결해야한다. 충돌난 부분은 아래처럼 표기된다.

 $ git status
  On branch master
  You have unmerged paths.
    (fix conflicts and run "git commit")
  Unmerged paths:
    (use "git add <file>..." to mark resolution)
      both modified:      index.html
  no changes added to commit (use "git add" and/or "git com

이때 git mergetool을 사용해 다른 merge 도구를 사용가능하다.

브랜치 관리

  • git branch : 브랜치 리스트 보여줌 (*이 붙은게 현재 브랜치)
  • git branch -v : 각 브랜치의 상태 조회
  • git branch --merged : 현재 브랜치 기준으로 merge 한 브랜치 리스트
  • git branch --no-merged : 현재 브랜치 기준으로 merge 하지 않은 브랜치 리스트
  • git branch -d [브랜치명] : 브랜치 삭제

브랜치 워크플로우

  1. Long Running 브랜치
  2. 토픽 브랜치

리모트 브랜치

리모트 Ref

  • 리모트 저장소에 있는 포인터인 레퍼런스. 브랜치 태그 등등을 의미함 git ls-remote로 조회가능

리모트 트래킹 브랜치

  • 리모트 브랜치를 추적하는 레퍼런스이면서 브랜치임
  • 로컬에 있지만 임의로 움직일수없다. 즉 리모트 업데이트시에 자동으로 업데이트됨
  • 리모트 트래킹 브랜치의 이름은 / 형식이며 default론 origin/master와 같다.

기존의 origin remote의 master브랜치를 clone했을때 내 로컬에는 origin/master라는 리모트 트래킹 브랜치가 생성되며 이는 remote 의 master브랜치를 가르킨다.

다른 동료가 remote에 커밋을 push하면 origin/master포인터와 리모트의 master의 히스토리는 달라진다.
이때 git fetch origin으로 동기화 할 수 있다.

  • fetch는 로컬에서 가지지않은 정보를 모두 내려받고, 업데이트한다음 origin/master 트래킹브랜치 포인터를 최신 커밋으로 이동시킨다.

PUSH

로컬 브랜치의 데이터를 명시적으로 push해야 업데이트됨.
git push <remote> <branch>로 사용하며 로컬브랜치명과 리모트 서버 브랜치명이 다를때
git push origin serverfix:awesomebranch 형태로도 쓸 수 있다

브랜치

Pull

  • fetch와 merge를 한번에 실행하는것과 같다
  • rebase는 선형의 깔끔한 히스토리를 만들어준다.

Rebase

위는 기존의 3way merge인데, experiment브랜치에서 master를 rebase 하면

git checkout experiment
git rebase master

아래처럼 공통된 C2커밋으로 부터 각 브랜치의 diff를 임시공간에 저장한뒤, 그런다음 experiment가 master의 커밋을 가르키게한뒤 변경사항을 차례대로 병합한다.

병합하면 아래처럼 두 브랜치가 같은 커밋을 바라보게되고 마지막으로 fast-forward 병함시키면된다

git checkout master
git merge experiment

Rebase의 활용 과 주의점

아래 원칙만 지키면 rebase는 문제될게없다.

  • 이미 공개 저장소에 Push 한 커밋을 Rebase 하지 마라

    rebase의 활용예시는 이해가 안되어 다시 읽어보겠음..

Rebase VS merge

  • 상황에 따라 다르다
  • 로컬브랜치에서 작업할때는 rebase를 할수있지만 리모트에 push로 내보낸 커밋에 대해서는 절대 rebase해서는 안된다!
profile
프론트엔드개발

0개의 댓글