branch 생성, 합치기(merge, rebase), conflict해결

도토리·2023년 4월 5일
0

git & github

목록 보기
4/10
post-thumbnail

git으로 프로젝트를 관리하면, 기본적으로 main(과거에는 master)이라는 하나의 브랜치에서 커밋들이 생성된다.


  1. 새로운 branch 생성하기
git branch 브랜치명

EX. add-coach라는 이름의 브랜치 만들기

git branch add-coach

기존에는 *.yaml에 team, manager, members만 존재했다. 그런데, 새로운 branch를 만들면서 *.yaml에 coach를 추가하고자 한다.

  1. 다른 branch로 이동하기
git switch 브랜치명

EX. main 브랜치 -> add-coach 브랜치로 이동하기

git switch add-coach



add-coach 브랜치로 이동했기 때문에, 소스트리에서 add-coach가 main보다 앞에 오는 것이다.

참고. git 2.23 버전부터 checkout -> checkout, switch, restore로 분리되었다. (이전에는 checkout 명령어가 수행하는 기능이 너무 많았음)

2-2. branch 생성과 동시에 이동하기

git switch -c 브랜치명
참고. git 2.23 버전 이전에는 git checkout -b 브랜치명

EX) new-teams라는 브랜치를 생성하고, 이동하기

git switch -c new-teams

  1. branch 목록 확인하기
git branch


main, add-coach라는 2개의 브랜치가 존재하고, 현재 브랜치는 main이다.

  1. 브랜치 삭제하기
git branch -d 브랜치명

EX) to-delete라는 브랜치를 삭제하기

git branch -d to-delete

참고1) 현재 브랜치가 to-delete일 때는 to-delete 브랜치를 삭제할 수 없다. 다른 브랜치에 있을 때, to-delete 브랜치를 삭제할 수 있다(다른 브랜치로 이동해야 함).

참고2)merge 또는 rebase가 된 브랜치(브랜치의 내용들이 다른 브랜치에 전부 적용되어 있음)를 삭제하는 것은 문제되지 않는다. 그런데, merge 또는 rebase되지 않은 브랜치를 삭제하려고 하면 기본적으로 삭제를 막는다(필요한 브랜치인데 사용자가 실수로 삭제하는 것일까봐). 이때, 브랜치를 삭제하려면,

git branch -D 브랜치명
이때, 소문자 d가 아닌 -D
  1. 브랜치 이름 변경하기
git branch -m 기존브랜치명 새브랜치명

EX) 브랜치 이름을 to-branch -> to-erase로 변경하기

git branch -m to-branch to-erase

각 브랜치에서 커밋을 만들어보자.

  1. 현재 커밋 상태는 다음과 같다.

  2. add-coach, new-teams라는 2개의 브랜치를 추가하였다.

git branch add-coach
git branch new-teams


  1. main 브랜치에서 2개의 커밋을 추가하였다.
    leopards.yaml의 members에 'Olivia' 추가
    panthers.yaml의 members에 'Freddie' 추가

  2. add-coach 브랜치에서 3개의 커밋을 추가하였다.
    tigers.yaml에 'coach: Grace' 추가
    leopards.yaml에 'coach: Oscar' 추가
    panthers.yaml에 'coach: Teddy' 추가

  3. new-teams 브랜치에 2개의 커밋을 추가하였다.
    pumas.yaml 추가
    jaguars.yaml 추가

최종) git의 시점에서 현재 프로젝트

참고) 'git log' 명령어는 위치한 브랜치에서의 커밋만 볼 수 있다.

예를 들어, 현재 new-teams 브랜치에 있기 때문에, new-teams 브랜치에서의 커밋만 볼 수 있다.


branch를 합치는 방법 - merge, rebase

목표: add-coach 브랜치에서 coach를 추가한 것, new-teams 브랜치에서 팀을 추가한 것이 모두 채택되어, main branch에 추가하겠다.


add-coach branch는 merge, new-teams branch는 rebase해볼 것이다.

  • merge: 두 branch를 한 커밋을 통해 이어붙인다.
    4nd 파랑이에 대해, 1st, 2nd, 3rd 초록이에서 수행한 것이 한 번에 적용되어, 노랑이가 생성된다고 보면 된다.
    merge를 하면 새로운 커밋이 하나 생성된다.
  • rebase: 한 브랜치를 다른 브랜치에 이어붙인다.
  • 차이점: merge는 브랜치의 흔적을 남기는 반면, rebase는 히스토리를 깔끔하게 한 줄로 나타낼 수 있다.
    -> 프로젝트 성격에 따라, 브랜치 사용 내역을 남겨둘 필요가 있다면 merge, 히스토리를 깔끔하게 만드는 것이 중요하다면 rebase를 선택하는 것이 좋다.
    추가적으로, 협업할 때, 팀원 간에 공유된 커밋에 대해서는 rebase를 사용하지 않는 것이 좋다.

add-coach 브랜치를 main 브랜치로 merge

ⅰ. main 브랜치로 이동 -> 'git merge 합칠브랜치'

git switch main
git merge add-coach

ⅱ. 병합된 브랜치 삭제하기

git branch -d add-coach


new-teams 브랜치를 main 브랜치로 rebase

ⅰ. new-teams 브랜치로 이동 > 'git rebase main'

git switch new-teams
git rebase main


주의! merge는 main 브랜치로 이동 후, 'merge 합칠브랜치'

ⅱ. 뒤쳐저 있는 main 브랜치를 new-teams 브랜치 위치로 옮겨주기
이 과정은 'merge' 명령어를 사용한다(자세한 내용은 branch 심화편에서 다룰 것).

git merge new-teams

ⅲ. new-teams 브랜치 삭제하기

git branch -d new-teams


branch 간 충돌 해결하기

branch 간 충돌이 발생하는 경우: 같은 파일의 같은 위치에 서로 다른 내용이 입력된 경우

branch 간 충돌이 발생하는, 충돌을 해결하는 과정을 살펴보자.

  1. 현재 상황: main, conflict-1, conflict-2 브랜치 존재

  2. main, conflict-1, conflict-2 브랜치에 각각 커밋을 추가했다.

이때, 다음과 같은 conflict가 발생한다.

  • main에서 tigers.yaml의 manager를 Kenneth, conflict-1에서는 Deborah
  • main에서 leopards.yaml의 coach를 Nicholas, conflict-2(1차)에서는 Melissa
  • main에서 panthers.yaml의 coach를 Shirley, conflict-2(2차)에서는 Raymond

  1. conflict-1 브랜치를 main 브랜치에 merge할 때, conflict 발생
git switch main
git merge conflict-1


tigers.yaml의 manager에 'Deborah'를 입력하는 방향으로 conflict를 해결하겠다.

git add .
git commit
(vim 모드로 진입하면서, 자동으로 커밋 메시지가 생성됨)

참고) 발생한 conflict를 당장 해결할 수 없는 경우(EX. conflict가 너무 많이 발생함), merge를 중단한다.

git merge --abort

  1. conflict-2 브랜치를 main 브랜치에 rebase(이때, 두 커밋을 한 번에 main 브랜치에 rebase하는 것이 아니라, 한 개씩 rebase)할 때, conflict 발생
  • conflict 1
git switch conflict-2
git rebase main


  • conflict 1 해결: leopards.yaml의 coach에 'Melissa'를 입력하는 방향으로 conflict를 해결하겠다.
git add .
git rebase --continue
  • conflict 2

  • conflict 2 해결: panthers.yaml의 coach에 'Shirley'를 입력하는 방향으로 conflict를 해결하겠다.

git add .
git rebase --continue

  • 현재 히스토리는 다음과 같다.

    참고. 2nd 커밋이 생성되지 않은 이유는, 2nd 커밋을 만들 필요가 없기 때문이다. 1st commit에서 panthers.yaml의 coach는 'Shirley'이다. conflict 2에서 panthers.yaml의 coach로 'Shirley'를 택했고, 따라서, 2nd 커밋은 1st 커밋과 동일하기에, 2nd 커밋을 만들 필요가 없는 것이다.

  • 뒤져친 main 브랜치를 conflict-2 브랜치 위치까지 이동시키고,
    conflict-1, conflict-2 브랜치 삭제하기

git switch main
git merge conflict-2

git branch -d conflict-1
git branch -d conflict-2

참고1) 발생한 conflict를 당장 해결할 수 없는 경우, rebase를 중단한다.

git rebase --abort

참고2) 다음에 대해 merge, rebase가 다른 방식으로 처리하는 것을 발견했다.

  • merge: 어떤 커밋에 대해, 다음 커밋이 해당 커밋과 동일해도, 커밋이 생성된다. 예를 들면, conflict-1 branch를 main branch에 merge할 때. tigers.yaml의 manager로 'Kenneth'를 선택한 경우, 이전 커밋과 같음에도 새로운 커밋이 생성되었다. 단, 소스트리가 다음과 같이 된다(이전 커밋과 비교했을 때, 바뀐 것이 없으니까).
  • rebase: 어떤 커밋에 대해, 다음 커밋이 해당 커밋과 동일하면, 커밋이 생성되지 않는다.

GUI(소스트리) 통해서 branch 다루기

  1. 브랜치 생성하기
    상단 '브랜치' > '새 브랜치' 필드에 브랜치명 작성 > '브랜치생성'

    '새 브랜치 체크아웃'(스위치)이 클릭되어 있기 때문에, 브랜치 생성과 동시에 해당 브랜치로 이동되는 것이다.

  2. 브랜치 목록보기

  3. 브랜치 이동하기
    브랜치 목록에서 이동하고 싶은 브랜치를 더블클릭

  4. 브랜치 삭제하기
    브랜치 목록에서 브랜치 우클릭 > 브랜치 삭제

참고) merge 또는 rebase되지 않은 브랜치를 삭제하려고 하면 기본적으로 삭제를 막는다. 이때, 브랜치를 삭제하려면, 브랜치 삭제에서 '강제 삭제' 옵션을 체크하면 된다.


to-merge 브랜치를 main 브랜치로 merge하기

ⅰ. main 브랜치로 이동(main 브랜치 더블클릭)
ⅱ. to-merge 우클릭 > '현재 브랜치로 to-merge 병합'

to-rebase 브랜치를 main 브랜치로 rebase

ⅰ. to-rebase 브랜치로 이동(to-rebase 브랜치 더블클릭)
ⅱ. main 우클릭 > '현재 변경 사항을 main에 재배치'

ⅲ. 뒤져친 main을 ro-rebase 브랜치 위치까지 이동하고,
to-merge, to-rebase 브랜치 삭제하기:
main 브랜치로 이동
to-rebase에 대해 재배치(git merge to-rebase)


GUI로 merge의 conflict 해결하기

rebase는 conflict 발생 시, CLI로 진행하는 것을 권장한다.

현재 상황은 다음과 같다.
'Edit Tigers members' 커밋에서, main 브랜치에는 tigers.yaml의 members에 'Kim' 추가, conflict 브랜치에는 'Park' 추가하였고, tigers.yaml의 memebers에서 마지막 줄에서 conflict가 발생하였다.

conflict 발생 -> conflict 해결 후, add & commit

0개의 댓글