TIL

Git / GitHub 톺아보기 (2)

0. Overview ✍️ 1편에 이어서, 오늘은 '깃과 브랜치' 그리고 '원격 저장소 연결'에 대해 정리하고자 합니다. 브랜치는 독립적인 작업 공간을 만들어 메인 코드에 영향을 주지 않고 새로운 기능을 개발하거나 실험할 수 있게 해주며, 작업 완료 후 merge

2025년 7월 7일10min read

0. Overview ✍️

1편에 이어서, 오늘은 '깃과 브랜치'에 대해 정리하고자 합니다.

브랜치는 독립적인 작업 공간을 만들어 메인 코드에 영향을 주지 않고 새로운 기능을 개발하거나 실험할 수 있게 해주며, 작업 완료 후 merge를 통해 통합할 수 있습니다.

1. 깃과 브랜치 ✍️

1-1. 브랜치 알아보기 ✅

1-1-1. 브랜치가 필요한 이유 🚀

버전 관리 시스템에서 '브랜치'란, 나무가 가지에서 새 줄기를 뻗듯이 여러 갈래로 퍼지는 데이터 흐름을 가리키는 말로 사용합니다. 제품 사용 설명서를 만든다고 가정해 봅시다. 개발 순서에 따라 제품 사용 설명서를 작성했습니다.

그런데 고객사의 요구사항을 반영하다 보면 제품이 달라질 것이고, 그에 따라 사용 설명서도 달라질 것입니다. 버전 관리를 어떻게 하면 좋을까요?

이미 작업한 저장소를 여러 개 복사해서 고객사마다 버전 관리를 따로 하는 방법이 가장 먼저 생각납니다.

그런데 구글에 추가된 제품 사용 설명의 일부 내용(GG)이 애플에서도 필요한 내용이라면 어떻게 될까요?

GE와 GF 내용이 반영되지 않아 오류가 발생하거나, AE 버전에서 GG를 덮어버리는 과정에서 내용이 의도치 않게 바뀌거나 사라지게 될 수 있습니다.

여러 저장소로 버전 관리를 분리하면 공통 변경 사항의 반영과 충돌 관리가 어려워 오류와 누락이 발생할 수 있고, 이를 해결하기 위해 브랜치 기능이 도입되었습니다.

1-1-2. 브랜치 기능 살펴보기 🚀

브랜치는 '커밋을 가리키는 포인터'로 이해할 수 있습니다.

핑크색 선은 '분기', 연두색 선은 '병합'을 나타냅니다.

깃으로 버전 관리를 시작하는 순간, 기본적으로 main 브랜치가 생성됩니다.

이때, main 브랜치의 기존 내용을 유지하면서, 새로운 브랜치에서 기존 파일 내용을 수정하거나 새로운 기능을 추가할 수 있습니다.

A1으로 뻗어가는 핑크색 선이 브랜치고, 해당 브랜치는 C2 커밋을 가리키는 포인터라고 볼 수 있습니다.

수정과 기능 추가에 대한 변경 사항을 다시 main 브랜치에 합치는 것을 '병합'이라고 하고, 연두색 선에 해당합니다.

1-2. 브랜치 만들기 및 이동하기 ✅

1-2-1. 실습 상황 만들기 🚀

manuals 디렉터리를 생성한 후 초기화를 하겠습니다.

code
(base) wonminkwan@wonmingwan-ui-MacBookAir manuals % git init
Initialized empty Git repository in /Users/wonminkwan/Desktop/manuals/.git/

이제 work.txt 파일을 생성 후, 'content 1'을 입력하고 저장한 뒤, "work 1"이라는 커밋 메세지와 함께 커밋을 하겠습니다.

code
(base) wonminkwan@wonmingwan-ui-MacBookAir manuals % git add work.txt
(base) wonminkwan@wonmingwan-ui-MacBookAir manuals % git commit -m "work 1"
[main (root-commit) 8c64160] work 1
 1 file changed, 1 insertion(+)
 create mode 100644 work.txt

같은 방식으로 'content 2', 'content 3'에 대한 작업을 진행하겠습니다.

code
(base) wonminkwan@wonmingwan-ui-MacBookAir manuals % git log
commit bbbf2cc506252dcf27629df80d7efba7bdd08f2e (HEAD -> main)
Author: 원민관 <mkwan5741@gmail.com>
Date:   Mon Jul 7 15:42:27 2025 +0900

    work 3

commit 9035f9f5a19a67b40502180656be7dc9fd942bcf
Author: 원민관 <mkwan5741@gmail.com>
Date:   Mon Jul 7 15:42:09 2025 +0900

    work 2

commit 8c64160d89dbfb8ef7102ad100a708d1d757eced
Author: 원민관 <mkwan5741@gmail.com>
Date:   Mon Jul 7 15:40:04 2025 +0900

    work 1

가장 최신 커밋인 work 3에 (HEAD -> main)가 표시된 것을 확인할 수 있습니다.

1-2-2. 새 브랜치 만들기 🚀

apple, google, ms라는 고객사가 있다고 가정하고 새 브랜치를 만들겠습니다.

code
$ git branch <브랜치 명>

브랜치 명을 제외하면, 브랜치를 확인할 수 있습니다.

code
$ git branch
code
(base) wonminkwan@wonmingwan-ui-MacBookAir manuals % git branch apple
(base) wonminkwan@wonmingwan-ui-MacBookAir manuals % git branch google
(base) wonminkwan@wonmingwan-ui-MacBookAir manuals % git branch ms
(base) wonminkwan@wonmingwan-ui-MacBookAir manuals % git branch
  apple
  google
* main
  ms

1-2-3. 새로운 커밋 추가하기 🚀

code
(base) wonminkwan@wonmingwan-ui-MacBookAir manuals % git log
commit bbbf2cc506252dcf27629df80d7efba7bdd08f2e (HEAD -> main, ms, google, apple)
Author: 원민관 <mkwan5741@gmail.com>
Date:   Mon Jul 7 15:42:27 2025 +0900

    work 3

브랜치는 '커밋을 가리키는 포인터'로 이해할 수 있다고 했습니다. 모든 브랜치가 work 3 커밋을 가리키고 있고, 현재 브랜치는 main입니다.

work.txt 파일에 'main content 4'를 추가하고 "main work 4"라는 커밋 메세지와 함께 커밋을 해보겠습니다.

code
$ git log --oneline

--oneline 옵션을 통해 커밋을 한 줄씩 확인해 보죠.

code
(base) wonminkwan@wonmingwan-ui-MacBookAir manuals % git log --oneline
df374da (HEAD -> main) main work 4
bbbf2cc (ms, google, apple) work 3
9035f9f work 2
8c64160 work 1

새로 만든 커밋은 main에만 적용되고, 나머지 브랜치에는 적용되지 않은 것을 확인할 수 있습니다. 브랜치 별로 커밋을 따로 관리할 수 있다는 의미입니다.

1-2-4. 브랜치 전환하기 🚀

code
$ git switch <브랜치 명>

브랜치를 전환할 때에는 위 명령을 사용합니다. apple 브랜치로 이동한 뒤 로그를 확인하겠습니다.

code
(base) wonminkwan@wonmingwan-ui-MacBookAir manuals % git switch apple
Switched to branch 'apple'
(base) wonminkwan@wonmingwan-ui-MacBookAir manuals % git log --oneline
bbbf2cc (HEAD -> apple, ms, google) work 3
9035f9f work 2
8c64160 work 1

편집 창에서 work.txt를 확인하면, 'main content 4'는 나타나지 않습니다. apple 브랜치는 work 3까지의 커밋을 가리키는 포인터이기 때문입니다.

1-3. 브랜치에서 커밋하기 ✅

1-3-1. 전환한 브랜치에서 커밋하기 🚀

appple 브랜치에서, work.txt 파일에 'apple content 4'를 입력합니다.

추가적으로, apple만의 제품 사용 설명서도 필요하기에 apple.txt를 생성한 후 동일하게 'apple content 4'를 입력한 후 커밋 합니다.

code
(base) wonminkwan@wonmingwan-ui-MacBookAir manuals % git add .
(base) wonminkwan@wonmingwan-ui-MacBookAir manuals % git commit -m "apple work 4"
[apple 1e8de32] apple work 4
 2 files changed, 3 insertions(+), 1 deletion(-)
 create mode 100644 apple.txt
(base) wonminkwan@wonmingwan-ui-MacBookAir manuals % git log --oneline
1e8de32 (HEAD -> apple) apple work 4
bbbf2cc (ms, google) work 3
9035f9f work 2
8c64160 work 1

apple branch의 최신 커밋이 apple work 4라는 것을 알 수 있습니다.

1-3-2. 브랜치와 커밋의 관계 🚀

code
$ git log --oneline --branches --graph

--branches 옵션으로 브랜치마다 최신 커밋을 한눈에 살펴볼 수 있고, --graph 옵션을 통해 브랜치와 커밋의 관계를 그래프 형태로 확인할 수 있습니다.

code
(base) wonminkwan@wonmingwan-ui-MacBookAir manuals % git log --oneline --branches --graph
* 1e8de32 (HEAD -> apple) apple work 4
| * df374da (main) main work 4
|/  
* bbbf2cc (ms, google) work 3
* 9035f9f work 2
* 8c64160 work 1

1-3-3. 브랜치 간의 차이점 🚀

브랜치마다 커밋이 점점 쌓이면, 브랜치 간에 어떤 차이가 있는지 확인하기 어려워집니다. 아래 명령을 통해, 1번 브랜치에는 없고 2번 브랜치에는 있는 커밋을 확인할 수 있습니다.

code
$ git log <1번 브랜치 명>..<2번 브랜치 명>
code
(base) wonminkwan@wonmingwan-ui-MacBookAir manuals % git log main..apple
commit 1e8de3232bfb41e4f330950cecddb8377566b718 (HEAD -> apple)
Author: 원민관 <mkwan5741@gmail.com>
Date:   Mon Jul 7 15:57:00 2025 +0900

    apple work 4

main 브랜치에는 없고, apple 브랜치에는 있는 커밋이 'apple work 4'라는 것을 확인할 수 있습니다.

1-4. 브랜치 병합하기 ✅

1-4-1. 서로 다른 파일 병합하기 🚀

manual-2라는 새로운 디렉터리를 만든 후, 초기화를 했습니다. 그 후 work.txt를 생성한 뒤 '1'을 입력하고, "work 1"이라는 메세지와 함께 커밋을 진행했습니다.

code
(base) wonminkwan@wonmingwan-ui-MacBookAir manual-2 % git init
Initialized empty Git repository in /Users/wonminkwan/Desktop/manual-2/.git/
(base) wonminkwan@wonmingwan-ui-MacBookAir manual-2 % git add work.txt
(base) wonminkwan@wonmingwan-ui-MacBookAir manual-2 % git commit -m "work 1"
[main (root-commit) b11fa7f] work 1
 1 file changed, 1 insertion(+)
 create mode 100644 work.txt

다음으로 'o2' 브랜치를 생성합니다.

code
(base) wonminkwan@wonmingwan-ui-MacBookAir manual-2 % git branch o2
(base) wonminkwan@wonmingwan-ui-MacBookAir manual-2 % git branch
* main
  o2

main 브랜치에 main.txt 파일을 생성하고, 'main 2'라고 입력한 뒤, "main work 2"라는 메세지와 함께 커밋을 진행합니다.

code
(base) wonminkwan@wonmingwan-ui-MacBookAir manual-2 % git add main.txt
(base) wonminkwan@wonmingwan-ui-MacBookAir manual-2 % git commit -m "main work 2"
[main 285d599] main work 2
 1 file changed, 1 insertion(+)
 create mode 100644 main.txt

이제 o2 브랜치로 전환한 뒤, o2.txt 파일을 만들고, '2'라는 내용을 입력한 뒤 "o2 work 2"라는 메세지와 함께 커밋을 진행합니다.

code
(base) wonminkwan@wonmingwan-ui-MacBookAir manual-2 % git add o2.txt
(base) wonminkwan@wonmingwan-ui-MacBookAir manual-2 % git commit -m "o2 work 2"
[o2 b62396e] o2 work 2
 1 file changed, 1 insertion(+)
 create mode 100644 o2.txt

현재 커밋 상태를 확인하면, 다음과 같습니다.

code
(base) wonminkwan@wonmingwan-ui-MacBookAir manual-2 % git log --oneline --branches --graph
* b62396e (HEAD -> o2) o2 work 2
| * 285d599 (main) main work 2
|/  
* b11fa7f work 1

이제 main 브랜치로 이동한 뒤 o2를 병합합니다.

code
$ git switch main
$ git merge o2

위 과정을 도식으로 표현하면, 다음과 같습니다.

1-4-2. 서로 다른 브랜치에서 한 문서의 다른 부분을 수정했을 때 병합하기 🚀

이번에는 한 문서에서 서로 다른 부분을 수정했을 때 병합하는 과정을 살펴보겠습니다.

manual-3라는 디렉터리를 생성한 후 초기화를 진행하겠습니다.

work.txt를 생성한 뒤 아래 내용을 입력합니다.

code
#title
content

#title
content

위 내용을 "work 1"이라는 메세지와 함께 커밋 합니다.

그다음, o2 브랜치를 생성합니다. 그리고 main 브랜치에서 첫 번째 content 다음 줄에 'main content 2'라고 입력한 뒤 "main work 2"라는 커밋 메세지로 커밋 하겠습니다.

code
(base) wonminkwan@wonmingwan-ui-MacBookAir manual-3 % git commit -am "main work 2"
[main 096a701] main work 2
 1 file changed, 1 insertion(+)

이제 브랜치를 o2로 전환한 뒤, 두 번째 content 다음 줄에 "o2 content 2"라고 입력하고 "o2 work 2"라는 커밋 메세지로 커밋 하겠습니다.

code
(base) wonminkwan@wonmingwan-ui-MacBookAir manual-3 % git commit -am "o2 work 2"
[o2 7e5dd59] o2 work 2
 1 file changed, 1 insertion(+)

이제 main으로 이동해서 o2를 merge 하겠습니다.

code
#title
content
main content 2

#title
content
o2 content 2

서로 다른 브랜치에서 한 문서의 다른 부분을 수정한 뒤 병합을 해봤습니다.

1-4-3. 서로 다른 브랜치에서 한 문서의 같은 부분을 수정했을 때 병합하기 🚀

이번에는 manual-4를 만들죠. work.txt 파일을 생성 후 다음과 같이 입력합니다. 그 후 "work 1"로 커밋 하겠습니다.

code
#title
content

#title
content

이제 o2 브랜치를 생성합니다.

main에서 첫 번째 content 아래에 'main content 2'를 추가한 뒤, "main work 2"로 커밋 하겠습니다.

code
(base) wonminkwan@wonmingwan-ui-MacBookAir manual-4 % git branch o2
(base) wonminkwan@wonmingwan-ui-MacBookAir manual-4 % git add work.txt
(base) wonminkwan@wonmingwan-ui-MacBookAir manual-4 % git commit -m "main work 2"
[main 3b513ba] main work 2
 1 file changed, 1 insertion(+)

이제 o2 브랜치로 이동해서 같은 위치의 내용을 'o2 content 2'로 수정한 뒤 "o2 work 2"로 커밋 하겠습니다.

code
(base) wonminkwan@wonmingwan-ui-MacBookAir manual-4 % git switch o2
Switched to branch 'o2'
(base) wonminkwan@wonmingwan-ui-MacBookAir manual-4 % git commit -am "o2 work 2"
[o2 b5a4b89] o2 work 2
 1 file changed, 1 insertion(+)

이제 main으로 이동해서 o2를 merge 하겠습니다.

같은 내용을 수정했기에, 병합하는 과정에서 충돌이 발생했습니다. 당황하지 않고, '병합 편집기에서 확인'을 클릭합니다.

'현재 수락'을 통해 main 브랜치의 수정 사항을 적용할 수도, '수신 수락'을 통해 o2 브랜치의 수정 사항을 적용할 수도 있습니다. 조합 수락을 하되, 현재를 우선하겠습니다. 결과는 다음과 같습니다.

code
#title
content
main content 2
o2 content 2

#title
content
code
(base) wonminkwan@wonmingwan-ui-MacBookAir manual-4 % git commit -am "merge o2 branch"
[main 0734b5a] merge o2 branch
(base) wonminkwan@wonmingwan-ui-MacBookAir manual-4 % git log --oneline --branches --graph
*   0734b5a (HEAD -> main) merge o2 branch
|\  
| * b5a4b89 (o2) o2 work 2
* | 3b513ba main work 2
|/  
* 970bf75 work 1

1-4-4. 병합이 끝난 브랜치 삭제하기 🚀

병합이 끝난 뒤 브랜치를 삭제할 때에는 아래의 명령을 입력합니다.

code
$ git branch -d <브랜치 명>
code
(base) wonminkwan@wonmingwan-ui-MacBookAir manual-4 % git branch -d o2
Deleted branch o2 (was b5a4b89).
(base) wonminkwan@wonmingwan-ui-MacBookAir manual-4 % git branch
* main

1-4-5. cherry-pick으로 병합하기 🚀

cherry-pick이라는 또 하나의 병합 방법이 있습니다.

위 상태에서 두 브랜치를 병합하면, main과 topic 브랜치 '전체 변경 사항'이 반영된, mt3라는 새로운 버전이 생성됩니다.

cherry-pick은 다른 브랜치에서 특정 버전의 내용만 합칠 때 사용하는 기능입니다.

cherry-pick이라는 디렉터리를 생성한 뒤, init.txt 파일을 만들고, 빈 파일을 "init"이라는 메세지와 함께 커밋 하겠습니다.

code
(base) wonminkwan@wonmingwan-ui-MacBookAir cherry-pick % git commit -m "init"
[main (root-commit) 5560e45] init
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 init.txt

이 상태에서 topic 브랜치를 생성합니다.

code
$ git branch topic

touch는 빈 파일을 만드는 명령어입니다. 위 명령을 main 브랜치에서 입력해 보겠습니다.

code
$ touch m1; git add m1; git commit -m "m1" 
$ touch m2; git add m2; git commit -m "m2"
$ git log --oneline --all --graph
code
(base) wonminkwan@wonmingwan-ui-MacBookAir cherry-pick % git log --oneline --all --graph
* c2666dd (HEAD -> main) m2
* fc7a01d m1
* 6975486 (topic) init

이번에는 topic 브랜치에서 t1 / t2 / t3 버전을 생성하겠습니다.

code
$ git switch topic
$ touch t1; git add t1; git commit -m "t1" 
$ touch t2; git add t2; git commit -m "t2"
$ touch t3; git add t3; git commit -m "t3"
$ git log --oneline --all --graph
code
(base) wonminkwan@wonmingwan-ui-MacBookAir cherry-pick % git log --oneline --all --graph
* 96484a5 (HEAD -> topic) t3
* b4b4591 t2
* c6a8305 t1
| * c2666dd (main) m2
| * fc7a01d m1
|/  
* 6975486 init

이 상태에서 cherry-pick 방식으로 t2 버전을 main 브랜치에 병합하겠습니다.

code
$ git switch main
$ git cherry-pick <t2 커밋 해쉬>
$ ls
code
(base) wonminkwan@wonmingwan-ui-MacBookAir cherry-pick % ls
init.txt        m1              m2              t2

2. 핵심 요약 ✍️

⚠️ Git의 브랜치(Branch) 기능에 대해 살펴봤습니다. 브랜치가 왜 필요한지부터 시작하여, 브랜치 생성·전환·커밋하는 방법과 서로 다른 브랜치의 작업 내용을 병합(merge)하는 과정을 실습을 통해 학습했습니다. 특히 병합 시 발생할 수 있는 충돌 상황과 해결 방법, 그리고 특정 커밋만 선택적으로 가져오는 cherry-pick 기능까지 다뤄 Git의 브랜치 관리 전반을 이해할 수 있었습니다.

⚠️ 다음 글에서는 GitHub의 개념과 활용법에 대해 다룰 예정입니다. 로컬 저장소(지역 저장소)와 GitHub 원격 저장소를 연결하는 방법부터 시작하여, push와 pull을 통한 동기화 과정을 학습하게 됩니다. 또한 보안성과 편의성을 높이는 SSH 키를 이용한 원격 접속 설정 방법까지 다뤄 Git과 GitHub를 활용한 효율적인 코드 관리와 협업 환경 구축의 기초를 익힐 수 있습니다.