Ben'space

Git 시작하기

· gitvcs

Git 의 시작

누가 만들었나요?

리누스 토발즈 라는 리눅스를 만든 사람이 Git 도 만들었어요. 리누스가 리눅스 커널을 만들다가 분산 버전관리 시스템이 필요해서 Git 을 2주만에 만들었다고 합니다. 왜 이름이 Git 인지? 도 궁금한데 그건 그냥 유닉스 명령어 리스트에 없는 아무 의미 없는 세글자 알파벳 중에 골랐다고 하는데 기분이 좋으면 “global information tracker”라고 하면 된다고 했다고. (으잉)

Git 을 처음 설명하기 전에 그 이전의 버전관리 시스템(이하 VCS)에 대해 설명해보겠습니다.

SVN 과 차이

Git 이 유행하기 전에 VCS 에서 가장 많이 사용되었던 건 SVN 입니다. SVN 과 Git 의 차이는 아래의 그림으로 설명이 가능한데요.

Git vs SVN

가장 큰 차이점이라면 Git 은 로컬 저장소가 별도로 존재한다는 것입니다. 일단, 저장소가 내 컴퓨터에 왜 필요한데? 와 같은 의문부터 시작해서 몇가지 단점이 있습니다.

  • 배우기가 어렵다. (로컬에 저장했는지 리모트에 저장했는지..)
  • 쓰기가.. 어렵다? 같은말 같네요.

로컬 저장소가 있으면 어떤 장점이 있을까요?

Git 의 장점

  • 원격저장소의 변경사항에 자유롭다.
  • 브랜치를 독립적으로 관리가 용이해진다.

그 외에도 Git 은 몇가지 장점이 더 있는데요.

  • 머지가 훨씬 쉽다! 변경사항 추적이 파일이 아니라 라인 단위로 이루어지기 때문.
  • 리모트가 망가져도 괜찮다. (로컬 리포지토리가 정상이라면)

Github 에서 PR 을 보다보면 아래와 같이 변경사항 을 리뷰하게 되는데 Git 은 이렇게 변경사항 + 변경 시각 으로 관리하기 때문에 시간 순서대로 작업을 정렬해서 충돌(Conflict)을 줄일 수 있습니다.

Git Diff

SVN 은 변경사항 에 대해 시각으로 관리하지 않다보니 여러 사람이 작업할 경우 메인저장소 (trunk) 에 머지할 때 충돌이 발생하는 경우가 정말 많습니다. (과장님이 밤새 머지만 했던 기억이..)

SVN Diff

자 그럼 이제 Git 의 큰 특징들을 알았으니 신규 기능을 개발하는 프로세스를 설명해볼게요.

Git 활용

브랜치 생성(Checkout)

먼저 신규 기능을 개발할 때 main 브랜치에서 새로운 기능 브랜치를 생성합니다. 명령어는 다음과 같습니다. -b 를 붙이면 새로운 브랜치를 생성합니다.

Terminal window
(main) git checkout -b boo-feature

여기서 중요한 것은 새로 생성한 boo-feature 라는 브랜치는 생성한 시점의 부모 브랜치 커밋을 가지고 온다는 것입니다. 이를 다르게 설명하면 부모 브랜치에 새로운 커밋들이 추가되어서 자란다고 해도 기능 브랜치에는 영향을 주지 않습니다.

브랜치 푸시(Push)

작업을 하다보니 잔여 업무가 있어서 다른 장소에서 추가 개발을 해야하는 경우가 생길 수 있어요. 때로는 작업을 백업하고 싶을 때도 있고요. 이를 위해 새로 생성한 브랜치를 원격 저장소에 올리려면 어떻게 해야 할까요? git push 명령을 사용하면 됩니다.

Terminal window
# --set-upstream 대신에 -u 사용 가능
> (boo-feature) git push --set-upstream origin boo-feature

origin 이 원격 저장소를 의미하고 그 뒤에 붙는 boo-feature 는 원격 저장소에서의 위치를 의미 합니다. 다른 머신에서 해당 브랜치를 가져오려면 어떻게 해야 할까요? 아래와 같이 하면 됩니다.

Terminal window
> git checkout -b boo-feature origin/boo-feature

boo-feature 라는 브랜치를 생성할 건데 origin/boo-feature 를 따라갈거야~ 라는 의미입니다.

커밋(Commit)

열심히 코드를 업데이트 했다면 어떤 파일들의 변경사항을 스테이지에 올릴지 결정합니다. 여기서 스테이지에 올린다는 말은 택배로 보낼 물건을 담는다고 생각하시면 되는데요. 이때 사용하는 명령어가 git add 입니다. 아래처럼 . 을 붙이면 지금 변경한 모든 파일들을 스테이지로 올린다는 의미입니다.

Terminal window
> (boo-feature) git add .

어떤 변경사항이 추가될지 불안하다면 현재 상황을 미리 점검해볼 필요가 있습니다.

Terminal window
git status
On branch boo-feature
Your branch is up to date with 'origin/boo-feature'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
_posts/2022-05-03-git.md
nothing added to commit but untracked files present (use "git add" to track)

물건을 다 담았으면 박스에 내용물이 뭔지 메모하고 포장을 마무리합니다. 이 과정이 git commit 입니다.

Terminal window
(boo-feature) git commit -m "commit message"

브랜치 병합(Merge)

아래 예시는 기능 브랜치에서 3개의 커밋을 병합하는 예시입니다.

Diff

병합을 할 때에는 병합을 받을 브랜치로 체크아웃 된 상태에서 병합할 브랜치를 불러옵니다.

Terminal window
(main) git merge boo-feature

브랜치를 병합할 때 로컬 저장소와 원격 저장소에 차이가 있는지 점검해야 나중에 원격 저장소로 내용을 전달(Push)할 때 충돌(Conflict)을 줄일 수 있겠죠. 미리 원격 저장소의 차이를 로컬로 가져오는 명령어(pull)와 원격으로 저장하는 명령어(push)를 추가한다면 다음과 같습니다.

Terminal window
(main) git pull
(main) git merge boo-feature
(main) git push

매우 간단하죠?

이렇게 머지하는 방법을 Merging commits 라고 부릅니다. 참고로 Github 에서 제공하는 브랜치 병합전략은 그 외에 Squash merging, Rebase merging 이 있는데 이에 대해서는 다음 포스트에서 설명해보도록 하겠습니다.

On this page