[Git & GitHub] -7- 브랜치 병합하기, 맙소사!

Shy·2023년 3월 13일
0

깃&깃허브

목록 보기
7/13

이 섹션에서 가중 중요한것

Critical!

  • Fast Forward Merges
  • Git Merge & Merge Commits
  • Resolving Merge Conflicts

Important

Nice To Have

  • Using VSCode To Resolve Conflicts





병합 명령어 소개

  • Merging은 브랜치를 사용하여 독립적된 contexts에서 쉽게 작업할 수 있다.
  • 서로 다른 부분을 작업하다, 작업이 잘 진행되면 한 브랜치에서 다른 브랜치로 작업한 것을 통합한다.

Merging(병합)에 대해서 혼동할 수 있는 몇가지가 존재한다.

  • 특정 커밋이 아니라 브랜치를 병합한다.
  • 항상 현재 HEAD브랜치에 병합한다.

예를 들면, Bugfix브랜치를 병합하려 한다면

Bugfix에 있는 HEAD를 Master브랜치에 옮겨준다.

git merge [branch-name]

  • [branch-name]을 HEAD 브랜치에 병합해준다.

그럼 이제, 위와 같이 Master는 이제 이제 2456... 커밋을 가르킨다.
아래와 같이 생각해도 된다.

Fast-Forward merge는 단순히 commit의 위치만 바꾸게 된다.

  • 별다른 분기점이 없다.
  • 그냥.. 뭔가 빨리감기 처럼 앞으로 쭉 이동하는 것이다.
  • 위와 같은 경우 Master는 기존 Master과 Bugfix사이의 작업도 모두 포함한다.





Fast-Forward merge 수행하기

포인터를 특정 숫자의 커밋으로 옮기면 되기 때문에 가장 간단하다.

  • 먼저 병합할 브랜치로 switch를 한다.
  • 그 다음, git merge 명령에 master로 병합하고 싶은 브랜치 이름을 추가한다.
  • 만약, bugfix에는 없고, master에만 존재하는 커밋이 있는 경우에는 추가적인 작업을 해야 하고 또는 충돌 정보가 있을 수 있다.

전 강의에서 썼던 repo를 master브랜치로 이동하고 log를 보면 두개의 커밋이 존재하는 것을 볼 수 있다.

아래는 master브랜치의 playlist이다.

그리고 oldies브랜치가 있는데, 그것을 master브랜치에 병합하겠다.
아래는 oldies브랜치의 log와 playlist파일이다.

병합을 하기 위해 아래와 같이 한다.

위를 살펴보면, Fast-forward라고 되어있는 것을 볼 수 있다.

이제, git log와 playlist파일을 살펴보면

oldies브랜치와 같아진 것을 볼 수 있다.

하지만 git branch명령을 써서 branch목록을 살펴보면 여전히 oldies브랜치가 존재하는 것을 볼 수 있다.

만약, oldies로 돌아가서 새로운 작업을 하면 그것은 master에 작업되는 것이 아니다.
(즉, 영원히 동기화 되는 것이 아니라 merge했을 때 한 순간 동기화 되는 것이다.)





병합 시각화하기 (Kraken)

이번 섹션에서는 브랜치를 시각화하기 위한 방법으로 깃 크라켄을 사용한다.
(병합 과정의 시각화)

oldies로 바꾼 후에, 아래와 같이 playlist를 수정하고 커밋한다.

만약, Kraken에서 switch를 하려면 아래의 빨간색 원을 클릭해서 바꿔주면 된다.

oldies브랜치에서 playlist파일을 다음과 같이 수정한다.

그리고 커밋을 해준다.

커밋을 해준 뒤, 그래프를 살펴보자.

oldies가 master에 병합된 것을 볼 수 있다.
다르게 생각하면 master가 빨리 감기해서 이 두 커밋을 따라잡은 것이다.

하지만, 모든 병합이 Fast-Forward Merge가 되는 것은 아니다.
다음 섹션부터는, 다른 병합에 관해 소개하겠다.





병합 커밋 생성하기

모든 병합이 Fast-Forward Merge인 것은 아니다!

위와 같은 경우에는 Fast-Forward가 통했지만... 다음과 같은 경우가 발생한다면?

Bugfix브랜치에는 없는 새로운 정보들이 있고, Bugfix가 갖고 있는 정보들은 master에는 존재하지 않는다.

  • 만약 충돌 정보가 있는데, 예를 들어 master브랜치에서 파일의 59번째 라인을 편집했고, bugfix에서 같은 라인을 편집 했을 때, 충돌했을때 누가 이길까? 그것은 다음 예제에서 다룬다.
  • 하지만 지금은, 충돌하지 않는 상황만 다룰 것이다.
  • 이럴 경우, 깃이 자동으로 병합을 시행할 것이다.

위와 같이, 병합 커밋이라는 것이 생성된다.
새 커밋을 만들고 커밋 메시지를 포함하라는 메시지를 표시한다.

또 하나 주목해야 할 것은, 우리가 처음 본 이 Merge Commit은 두 개의 다른 parent commit을 가진다는 것이다.

위처럼, 커밋들은 다수의 부모 커밋들을 가질 수 있고, 실제 우리가 커밋을 병합할 때마다 그렇다.

실습을 위해 아래와 같이 새로운 repo를 만든다.

이제 아래와 같이 작업을 해 준다.
(2개의 ABBA 노래를 추가한 뒤, 브랜치 추가 후 맘마미아, 댄싱 퀸 커밋을 추가한다.)

여기서, Master 브랜치에서 새로운 파일을 만들어 준 다음 새로운 커밋을 만들어 본다.

podcasts라는 파일을 만든 후에, 새로운 브랜치로 만든다.

위 그래프를 보면, master엔 새로운 commit이 생겼지만, ABBA는 그것과 떨어져 있다.

podcasts파일을 수정한 뒤에, 아래와 같이 커밋을 해준다.

아래와 같은 그래프가 된다.

이제, ABBA브랜치를 master브랜치에 병합해 본다.

git switch master를 한 후, git merge ABBA를 입력하면 에디터가 나온다.

새로운 merge commit이 만들어지고, 거기에 사용 될 메세지가 입력되는 것이다.
수정하고 싶으면 노란색 글자 부분 [Merge branch 'ABBA']를 수정하면 된다.

  • 창을 나올때는 esc + :wq를 누르면 된다.

아래와 같이 그래프가 바뀐다.

git log를 살펴보면 아래와 같다.

충돌하지 않는 상황에서는 자동적으로 병합이 되었고, 우리는 메시지만 남겼을 뿐이다.
어떤 문제도 발생하지 않았다.





이런, 병합 중에 충돌이 발생했다!

병합이 실행 될 때, 깃은 자동적으로 모든 변경사항들을 병합하기 위해 최선을 다한다.
(위에서 다룬 Fast-Forward, Make Merge Commit이 그 예이다.)
하지만 변경사항들이 충돌한다면, 예를 들어 같은 파일이 두 브랜치에서 서로 다를 경우 혹은, 한 파일에는 존재하는 파일이 다른 브랜치에서 삭제되었을 경우
이럴 경우 문제를 직접 해결해야 한다.

파일에서 충돌이 발생했을 경우, 자동 병합은 실패되고 충돌을 해결한 다음에 결과를 커밋하라고 나온다.

이것은 다단계 과정이다.
깃이 충돌이 발생했다고 알려주면, 발생한 파일을 열어 해결해야 한다. 그런 다음 변경사항을 커밋해야 한다.

충돌이 발생한 파일은 표시가 된다.

위에서 나타내는 것은, HEAD가 가리키는 브랜치에서 가져올 컨텐츠이다.

위에서 나타내는 것은, 병합해서 넣으려는 기준 브랜치이다.

즉 위는 master브랜치이고 아래는 bugfix라 생각하면 된다.

우리가 코드를 컴토하고 작성하고 충돌을 해결해서 commit을 하면 완료이다.





병합 충돌 해결하기

일단, 실습에 앞서 위에어 변경사항들을 병합했기 때문에, ABBA브랜치를 삭제할거다

git branch -d ABBA

그런 다음, serena라는 브랜치를 새로 만들고 다음으로 또 다른 브랜치인 bjorn을 만들어 본다.

세 브랜치가 같은 위치를 참조하는 것을 볼 수 있다.

그런 다음, bjorn브랜치에서 playlist를 다음과 같이 변경하고 커밋을 해 준다.

bjorn 브랜치에서 playlist를 한 번 더 수정하고 커밋하여준다.

serena브랜치르 스위치 한 다음에, 파일을 다음과 같이 수정하고 커밋을 해 준다.

serena브랜치에서 Dolly Parton노래를 추가한 뒤 커밋한다.

  • 위의 그래프를 살펴보면, serena는 bjorn이 갖지 않는 2개의 커밋을 갖고있고, bjorn도 serena가 갖지 못하는 2개의 커밋을 갖는다.

  • 이 브랜치는 같은 파일을 수정했으므로, 병합할 때 충돌이 발생한다.

우선, bjorn브랜치에서 새로운 브랜치 'combo'를 만든다.

그다음 serena를 병합한다.

충돌이 발생하여 자동 병합은 실패했고, 충돌을 해결한 뒤 커밋해야 한다.

위와 같이 songs파일이 변경된 것을 볼 수 있다.
이제 병합을 위해 파일을 수정해주자.

파일을 수정한 뒤에 add, commit을 해주면 된다.





VSCode를 사용하여 충돌 해결하기

실습을 위해, master브랜치로 이동한 뒤에 silence브랜치를 만든다.

silence브랜치에서는, songs와 podcast파일 내용을 모두 삭제한 뒤에, 커밋을 한다.

그런 다음, master브랜치로 스위치 해 준다음에 아래와 같이 podcasts, songs파일을 수정한다.

그런 다음, master브랜치에 silence브랜치를 병합해본다.

2개의 파일이 충돌하는 것을 볼 수 있다. 수정해서 등록하고 커밋을 해야 한다.
여기서, VScode를 사용해서 해결할 수 있는데, 내장된 인터페이스가 존재한다.

현재 변경 사항 수락/수신 변경 사항 수락/두 변경 사항 모두 수락을 할 수 있다.

전 섹션에서 했던 것 처럼 직접 편집을 할 수도 있지만, 두 파일중 하나만 고르거나 두 파일을 합칠 수도 있다.

아래는 현재 변경 사항을 수락한 경우

아래는 수신 변경 사항 수락을 한 경우이다.

아래는 두 변경사항을 모두 수락한 경우이다

변경사항을 수락한 뒤에, 코드를 이어서 수정할 수도 있다.

git kraken에서도 충돌을 볼 수 있다.

이제 커밋을 한다.





병합 연습하기





profile
스벨트 자바스크립트 익히는중...

0개의 댓글