지난 시간에는 브랜치의 개념과 브랜치를 다루는 방법, 서로 다른 브랜치에 같은 내용을 반영하는 merge 기능, 그리고 conflict에 대해 알아봤습니다.

이번 시간에는 브랜치에 대해 추가적으로 알아야 할 내용들을 함께 배워보겠습니다.

🌿 Remote Repository의 브랜치

우리는 앞서 Local Repository의 내용을 Remote Repository로 보내는 방법을 배우면서 GitHub에 Math_Box라는 Remote Repository를 만들고 Local Repository의 내용을 보내기 위해 아래와 같은 커맨드 두 개를 실행했습니다.

git remote add origin https://github.com/tataki/Math_Box.git
git push -u origin master

당시에는 그냥 복사/붙여넣기해서 실행만 하고 정확한 의미에 대해서 설명하지 않았는데요. 이제 그 의미를 알아봅시다.

❗ origin

첫번째 커맨드부터 볼까요?

git remote add origin https://github.com/tataki26/Math_Box.git

이 커맨드에서 remoteremote repository에 관한 작업을 할 때 사용합니다. 그 뒤의 add새로운 remote repository를 등록하는 커맨드이죠.

그 다음에는 origin https://github.com/tataki26/Math_Box.git이라고 써있는데요. 이는 https://주소의 remote repository를 origin이라는 이름으로 등록하겠다는 뜻입니다. 이 커맨드를 실행하고 나면 긴 주소를 origin으로 간단하게 나타낼 수 있습니다.

사실 origin 말고 다른 단어를 입력해도 동작에는 문제는 없습니다. 하지만 Git에서는 remote repository를 최초로 추가할 때 origin이라는 이름으로 설정하는 것이 관례화되어 있습니다. 따라서, 이 관례를 따르는 것이 좋겠죠?

origin은 '근원, 기원'이라는 뜻을 가지고 있죠? 다른 사람의 remote repository를 가져와서 작업을 하는 사람 입장에서는 remote repository가 프로젝트의 근원이 되는 존재이기 때문에 이러한 이름이 붙은 것으로 추측됩니다.

❗ remote repository에 있는 브랜치

다음으로 두번째 커맨드에 대해 설명하겠습니다.

git push -u origin master

이 커맨드의 뜻은 현재 local repository에 있는 master 브랜치의 내용 즉, master 브랜치와 관계된 모든 커밋들을 origin이라는 remote repository로 보낸다는 것입니다.

이때, 같은 이름의 브랜치로 전송하게 되는데 만약 origin이라는 remote repository에 master 브랜치가 없으면 master 브랜치를 새로 생성하고 push 합니다.

그렇다면 옵션 -u는 왜 필요한 걸까요? u 옵션은 --set-upstream이라는 옵션의 약자입니다. u 옵션을 주면 local repository에 있는 master 브랜치가 origin에 있는 master 브랜치를 tracking(추적)하는 것으로 설정됩니다.

tracking이라는 건 local repository의 한 브랜치가 remote repository의 한 브랜치와 연결되어 이를 계속 모니터링하는 상태가 되는 것이라 생각하면 됩니다. 이렇게 맺어진 연결 상태를 'tracking connection'이라고 합니다.

만약 local repository에 A라는 브랜치가 있고 remote repository에는 B라는 브랜치가 있을 때, 두 브랜치가 tracking connection으로 맺어진 경우에 B 브랜치를 A 브랜치의 upstream 브랜치라고 합니다. 지금은 구분을 위해 A, B라는 서로 다른 이름을 붙였지만 보통은 같은 이름인 경우가 많습니다.

이렇게 tracking connection이 설정되고 나면, 사용자가 현재 master 브랜치에 있을 때, git push라고만 써도 자동으로 remote repository의 master 브랜치를 대상으로 git push가 동작합니다. 이는 git pull도 마찬가지입니다.

사실 --set-upstream(-u) 옵션을 주지 않아도 그 후에 git push와 git pull이 가능하긴 합니다. 하지만 맨 처음에 이 옵션을 주지 않으면 tracking connection 상태가 아니기 때문에 나중에 git push를 하고 싶을 때,

git push origin master:master

이런 식으로 커맨드를 적어줘야 합니다. 여기서 originremote repository를 나타내고 master:master에서 먼저 나오는 master는 local repository의 master 브랜치, 뒤에 나오는 master는 remote repository의 master 브랜치를 나타냅니다.

다시 말해, tracking connection이 없으면 매번 이런 식으로 복잡하게 커맨드를 적어줘야 합니다. 따라서, 처음부터 tracking connection을 설정해서 그 이후부터는 간단하게 커맨드를 입력하는 것이 효율적입니다.

❗ origin/master

local repository에도 master 브랜치가 있고 remote repository에도 master 브랜치가 있다는 사실을 알았습니다. 이 둘은 같은 이름을 가졌지만 서로 다른 브랜치입니다.

그럼 remote repository에 있는 master 브랜치는 어떻게 볼 수 있을까요? 물론 GitHub 페이지에서 보면 됩니다. 하지만 자신의 컴퓨터에서도 확인할 수 있는 방법이 있는데요. 커밋 히스토리를 살펴봅시다.

git history

위를 보면 masterlocal repository의 master 브랜치이고 origin/masterremote repository의 master 브랜치를 나타냅니다.

이때까지 local repository의 master 브랜치에서 여러번 커밋을 했지만 그러고 나서 git push를 해 준 적이 없습니다. 따라서, 위와 같이 orgin/master가 master보다 이전의 커밋을 가리키고 있는 겁니다.

master, premium 브랜치 둘 다에서 remote repository로 git push하면 origin/master도 master와 같은 커밋을 가리키게 됩니다.

🌿 master/premium 브랜치 push

그럼 두 브랜치를 git push 해보겠습니다. 그전에 git history를 보죠.

local repository의 master 브랜치보다 remote repository의 master 브랜치가 더 이전에 있죠? git push를 하고 결과가 달라지는지 확인해보겠습니다. master 브랜치로 이동한 후, git push를 해주세요.

git checkout master
git push

성공적으로 잘 push 되었습니다. 다시 history를 확인해보겠습니다.

이번에는 두 브랜치가 같은 커밋을 가리키고 있네요.

그런데 아직 끝이 아닙니다. premium 브랜치의 작업도 push해야 되기 때문이죠.

git checkout premium

premium 브랜치로 이동한 후, git push를 합니다.

에러가 나네요! 자세히 살펴보니 premium 브랜치가 upstream 브랜치를 가지고 있지 않다고 합니다. 그리고 그 아래에 git push --set-upstream origin premium이라는 커맨드가 뜨네요.

우리는 앞서 local repository의 내용을 remote repository로 보내기 위해서는 --set-upstream이라는 옵션을 줘야 한다고 배웠습니다. 이렇게 해야 두 브랜치 간에 tracking connection이 생기고 간단한 커맨드로도 내용 교환이 가능하다고도 배웠죠.

premium branch는 remote repository에 처음 올리는 것이기 때문에 --set-upstream 옵션을 적어줘야 합니다.

위에서 제시한 커맨드를 그대로 입력하면 remote repository에도 premium 브랜치가 생성됩니다. 정말 생성되었는지 GitHub 페이지로 가서 확인해봅시다.

보시다시피 브랜치가 두 개로 나타나네요. 브랜치 탭을 클릭하면 premium 브랜치가 잘 추가된 것을 확인할 수 있는데요. premium 브랜치를 클릭하면,

지금까지 진행한 커밋이 12개라는 것을 알 수 있습니다. 커밋도 눌러보면,

커밋 히스토리를 확인할 수 있습니다. 터미널에서도 커밋 히스토리를 확인해보겠습니다.

그럼 remote repository의 premium 브랜치도 잘 보입니다.

🌿 HEAD와 브랜치의 관계

master 브랜치로 돌아가 커밋 히스토리를 살펴봅시다.

출력 결과를 보면, HEAD가 master 브랜치를 가리키고 있는 것을 확인할 수 있습니다. 여기서 화살표는 무엇을 의미할까요?

잠깐 복습을 해봅시다. HEAD는 어떤 커밋을 가리킨다고 했고 브랜치는 하나의 코드 관리 흐름이라고 했습니다. 이 둘 사이에는 어떤 관계가 있기에 화살표로 연결되어 있을까요? 둘 사이의 관계에 대해 알아보겠습니다.

사실 브랜치도 HEAD와 같이 특정 커밋을 가리키는 존재입니다. 이제부터는 이러한 존재를 포인터라고 부르겠습니다. HEAD와 유사하게 master 브랜치도 새로 커밋이 될 때마다 새로운 커밋을 가리키게 됩니다.

Git에서 커밋은 이전 커밋에 대한 정보를 가지고 있는데요. 그래서 master 포인터가 가장 최신의 커밋만을 가리키더라도 그 이전 커밋으로 하나씩 거슬러 올라갈 수 있기 때문에 이때까지 어떻게 프로젝트가 변화해 왔는지 추적이 가능합니다. 이러한 이유로 브랜치를 하나의 코드 관리 흐름이라고 부르는 것이죠.

HEAD 또한 포인터의 일종입니다. 그리고 HEAD가 가리키는 커밋의 내용대로 working directory의 내용이 바뀌죠. 하지만 정확히 말하자면, 보통 HEAD는 커밋을 직접적으로 가리키지는 않습니다. 사실 HEAD가 직접적으로 가리키는 것은 브랜치입니다. 다시 말해, HEAD는 master 브랜치를 통해 간접적으로 커밋을 가리키게 됩니다.

그럼 premium 브랜치가 생성된 다음에는 어떻게 될까요? 생성된 premium 브랜치도 master 브랜치가 가리키는 커밋을 가리킵니다. 여전히 HEAD는 master 브랜치를 가리키고 있구요.

이때, checkout 커맨드를 통해 master 브랜치로부터 premium 브랜치로 이동하면 그제야 비로소 HEAD가 premium 브랜치를 가리키게 됩니다. 따라서, 코드 관리 흐름이 master에서 premium 브랜치로 바뀐다는 말은 사실 HEAD가 가리키는 브랜치가 변경되었다는 뜻입니다.

이 상태에서 또 한 번 새로운 커밋을 진행하면 master 브랜치는 이전의 커밋을, premium은 새로운 커밋을, 그리고 premium을 가리키는 HEAD는 premium을 통해 간접적으로 새로운 커밋을 가리키게 됩니다.

이때, master 브랜치로 이동하면? HEAD가 다시 master 브랜치를 가리키고 master 브랜치를 통해 간접적으로 이전의 커밋을 가리키게 되는 것이죠. working directory의 내용 또한 이 이전의 커밋의 내용대로 바뀝니다.

그리고 이 상태에서 또 다시 새로운 커밋을 하면 커밋 히스토리의 흐름이 갈라집니다. premium 브랜치가 가리키는 새로운 커밋과는 다른 흐름으로 말이죠. 이를 '분기한다'라고 합니다.

이때 흐름별로 각각 커밋을 진행하고 merge를 하게 되면 두 커밋의 내용이 합쳐져 merge 커밋이라는 것이 생성됩니다. 따라서, merge는 HEAD가 가리키던 커밋에 다른 브랜치가 가리키던 커밋을 합쳐서 새로운 커밋을 만드는 작업이라고 할 수 있습니다.

내용이 좀 생소하죠? 그렇지만 중요한 내용이기 때문에 이해가 덜 되었다면 꼭 다시 한번 읽어보시길 바랍니다.


이번 시간에는 Remote Repository의 브랜치를 확인하는 방법과 두 개의 Local Repository의 브랜치를 push하는 방법, 그리고 HEAD와 브랜치의 관계에 대해 배웠습니다. 특히, 마지막 HEAD와 브랜치의 관계는 개념과 원리가 조금 복잡하게 느껴질 수 있습니다. 중요한 내용인만큼 반복해서 읽으면서 익숙해지셨으면 좋겠습니다.

다음 시간은 브랜치의 마지막 시간입니다. git reset과 브랜치의 관련성, git reset과 git checkout 커맨드의 차이 등 브랜치에 대해 알아두면 좋을 내용들을 추가적으로 배워보겠습니다.

* 이 자료는 CODEIT의 'Git으로 배우는 버전 관리' 강의를 기반으로 작성되었습니다.
profile
There's Only One Thing To Do: Learn All We Can

0개의 댓글