Git : Branch // Git(4)

2022. 2. 25. 20:03

Branch

  • git을 활용해서 차원을 다룰 수 있음
  • branch는 일종의 가지를 뜻함

 

1.branch 기초

  • 생성/목록확인 / 이동 / 삭제 / 생성과 동시에 이동하기 / branch 이름 바꾸기
#add-coach라는 브랜치 생성
git branch add-coach

#브랜치 목록 확인
git branch

#add-coach브랜치로 이동
git switch add-coach

#브랜치 생성과 동시에 이동하기
git switch -c new-teams

#브랜치 삭제하기
git branch -d (삭제할 브랜치명)

#브랜치 이름 바꾸기
git branch -m (기존 브랜치명) (새 브랜치명)

 

  • 삭제할때는, 삭제하려는 브랜치에 위치해서는 안됨(다른 브랜치에 위치한 상태에서, 브랜치 삭제 명령을 해야 함)
  • 다른 브랜치에 없는 내용의 커밋이 있는 브랜치를 삭제할 경우 있을 경우(즉, 다른 브랜치로 가져오지 않는 내용이 있는 브랜치를 삭제할 경우), 다음과 같이 명령하여 강제삭제를 진행해야 함
#브랜치 강제삭제
git branch -D (강제삭제할 브랜치명)

 

2.1서로 다른 branch를 합치는 방법 : merge 

  • merge : 말 그대로 병합
  • 두가지 branch를 합쳐서 새로운 하나의 커밋을 만들어 냄
  • merge는 reset으로 되돌리는 것이 가능하다!(merge가 하나의 포인트를 만들어내는 것이니까)
  • 합칠 브랜치로 이동 >> 대상 브랜치를 merge >> 병합된 브랜치는 삭제
#main branch로 이동
git switch main

#main branch에 합칠 branch입력
git merge add-coach

#병합된 브랜치는 삭제
git branch -d add-coach

 

2.2서로 다른 branch를 합치는 방법 : rebase

1)개요

  • rebase : base를 새로 옮김
  • 즉, 어떤 브랜치를 메인브랜치에 그대로 가져다가 옮기는 것
    • 예를 들어, A브랜치가 메인이고 A브랜치의 특정 시점에서 B브랜치가 뻗어나온 후  B브랜치에서 세개의 커밋이 있었다고 하자.
    • A브랜치(메인)에 B브랜치를 rebase해서 합치면, A브랜치에 B브랜치에서 했던 세개의 커밋을 적용하는 것과 다름없음
  • merge와의 차이는 다음과 같음
    • 일단 히스토리. rebase를 하면 브랜치들이 합쳐지면서 흔적이 사라지고 한줄로 정리가 되는 반면, merge는 브랜치의 흔적이 남음. 즉 내역을 남기려면 merge를, 히스토리를 깔끔하게 정리하려면 rebase라고 생각하면 편함
    • 또한, 협업과정에서는 reabse보다는 merge를 쓰는게 국룰(내역이 사라져버리니까 큰일나기 쉬움!)
    • rebase과정에서 어떤 걸 택하느냐에 따라 추가되는 노드의 개수가 달라질 수 있음

 

2)하는 법

  • 대상 브랜치(여기선 new-teams)로 이동  >> 메인이 될 브랜치(여기선 main)를 rebase
#대상 브랜치로 이동
git swtich new-teams

#rebase
git rebase main
  • 근데 이러면 한줄로 합쳐지긴 했는데, 대상 브랜치(rebase)가 앞에가 있음. 즉, 우리의 메인인 main branch가 뒤쳐져 있는 상황임

 

  • 우리의 메인은 main 브랜치이므로, main브랜치가 맨위로 올라가야함
  • 따라서, main브랜치로 이동 후, main브랜치를 new-teams화 merge해줌(그러면 new-teams의 커밋들이 main으로 달라붙으면서, 반대로 main이 위로 끌어당겨짐. 이부분이 이상하지만 일단 강사님이 받아들이고 넘어가라함..)
  • 그 후, new-teams branch를 삭제
#main으로 이동
git swtich main

#merge의 위치를 위로 끌어올려줌
git merge new-teams

#대상 branch삭제
git branch -d new-teams

merge로 끌어올린 후, new-teams 브랜치를 삭제

 

3.1 충돌 해결하기 

  • 파일의 같은 위치에 다른 내용이 입력되었을 경우, branch를 합치는 과정에서 충돌이 발생함
  • 컴퓨터가 해결할 수 없는 부분이므로, 우리가 정해줘야 함

 

1)merge

  • 충돌이 발생할 경우, 다음과 같은 창이 뜸

  • 현재 헤드는 manager:kenneth라고 하고, merge하려는 conflict-1 브랜치에서는 manager:deborah라고 하는데, 어떡할래? 라고 물어보는 것임
  • current change(head)를 받을 수도, incoming change(merge대상브랜치)를 받을 수도 , 혹은 둘다 받을 수도 있음

 

  • 위의 예시에서는 간단한데, 충돌하는 부분이 너무 많아서 merge를 중단해야 겠다~ 라는 생각이 들면 다음과 같이 하면 됨
git merge --abort

 

  • 충돌을 해결하고 나서, git add . >> git commit 해주면 merge완료

 

2)rebase

  • merge와 다르게, rebase는 커밋 하나하나를 메인브랜치 위에 올려두는 것임
  • 즉, 커밋하나하나에 대하여 충돌을 정리해줘야 하는 것

 

  • 정리하기가 너무힘들어서 rebase를 중단하고 싶으면 > abort
git rebase --abort

 

  • 정리가 되었으면 add로 더해준 후, reabse를 continue해주면 됨.
  • merge와 다르게 continue를 해주는 이유는, rebase는 merge처럼 하나의 커밋만 실행하는게 아니기 때문. 즉, 여러개의 커밋이 있기 때문에, rebase작업 자체가 여러번 진행 될 수도 있기 때문
#정리 후, 더해줌
git add .

#rebase를 계속 진행
git rebase --continue

 

4.merge를 하는 두가지 전략

1)3-way merge

  • 일반적인 merge에서, merge를 하는 이론적인 방법을 이야기함(그래서, 몰라도 사용하는데 상관X임)
  • 한 커밋에서 뻗어나온 A와 B두 브랜치를 merge할 때, git에서는 특정 파일의 변경내역이 A와 B브랜치 중 어디에서 바뀐건지 확인을 해야함
  • 근데 이걸 확인하려면 A와 B의 최신 커밋만을 비교해서는 불가능하고, 두 가지가 뻗어나온 마지막 공통 커밋을 확인해야함
  • 따라서, 'A와 B브랜치의 최신 커밋 + 마지막 공통 커밋' 총 세개의 커밋을 확인하기 때문에 3-way merge라고 함

 

2)Fastforward

  • 두 브랜치가 공통 커밋을 조상으로 가지고 있을 때, 한쪽 브랜치에만 이후의 커밋이 있는 경우에 merge실행시 자동으로 fastforward방식이 실행됨
  • 두 브랜치를 병합할 때, 굳이 둘을 병합하기 위한 다른 커밋을 만들지 않고 뒤에 있는 브랜치를 맨 앞으로 옮기는 것
  • 어차피 뒤쳐져 있는 브랜치와 앞서나간 브랜치 사이에 차이가 없으니까 굳이 새 브랜치를 만들 필요없다는 의미 
  • 다만, 기록이 사라진다는 단점이 있어서 이를 방지하려면 다음의 명령어를 실행하면 됨
git merge -no-ff (병합할 브랜치명)

 

5. 다른 브랜치의 커밋을 가져오는 다른 방법들

1)Cherry pick

  • 다른 브랜치의 딱 한 커밋만 들고오고 싶을 때
  • merge나 rebase로 들고오면 , 해당 브랜치의 내용전체를 들고오게 되니까 쓸 수 없음
  • 이럴때 'Cherry-pick'을 사용함
git cherry-pick (체리의 해시)
  • 이렇게 cherry-pick으로 들고온 커밋내역은, 들고온 커밋의 이름과 동일한 이름으로 현재 브랜치에서 바로 커밋이 됨.

 

2)다른 가지의 잔가지만 들고오기 : rebase --onto

  • 다른 브랜치의 브랜치만 들고 오고싶을 때
  • ex) main브랜치에, fruit브랜치에서 파생된 cirtus 브랜치(Lemon , Lime)만 들고오고 싶을 때
  • 만약 rebase를 쓰거나 하면, orange도 같이 딸려오게 됨
  • 참고) 만약 rebase --onto를 되돌리려면? : https://www.yalco.kr/@git-github-dive/10-3/
git rebase --onto (도착 브랜치) (출발 브랜치) (이동할 브랜치)

#예시 : main브랜치에 fruit브랜치로부터 citrus브랜치를 이동시키고 싶다!
git rebase --onto main fruit citrus

 

3)다른 가지의 마디들 묶어서 가져오기

  • 'git merge --squash'를 사용하면 특정 가지의 커밋들을  하나로 묶어서 복사 해올 수 있음
  • 들고온 커밋들의 내용은 스테이징 된 상태임
  • 기존 브랜치에는 커밋들이 그대로 남아 있음(merge처럼 사라지지 않음)
git merge --squash (대상 브랜치)

 

6. Git flow

  • 협업을 위해 브랜치를 활용하는 좀 널리 알려진 하나의 방법론.

  • 보통 5가지의 브랜치를 사용함.
    • master(main) : 제품의 출시 및 배포버전. 보통 버전이 태그로 달린다
    • develop : 출시/배포를 위한 개발을 진행하는 브랜치. 
    • feature : develop브랜치에서, 각각의 기능을 따로 빼서 작업하곤 함. 여러개가 있을 수 있고, 어느정도 기능이 완성되면 develop으로 다시 보내주는 것임
    • release : develop브랜치가 어느정도 완성되어서 출시해도(배포해도) 괜찮다고 느낄 때, 출시/배포 전 테스트를 진행하는 브랜치(Q/A). 수정사항이 생기면 develop으로, 문제가 없으면 main 브랜치로 나감(출시가 됨)
    • hotfix : 출시된 버전에서(main브랜치에서) 오류가 발견되면 이를 당장 고쳐야 함(hot fix). 이런 당장 고쳐야 하는 문제를 해결하는 브랜치 

BELATED ARTICLES

more