brunch

매거진 Git과 Github

You can make anything
by writing

C.S.Lewis

by anonymDev Mar 01. 2019

3. Branch를 활용해보자.

git branch

1. command line에 $git branch  입력해보자.



~/my-git-project$ git branch

*master


*master 가 출력된다. 지금 내가 master 브랜치에 있다는 의미다. 우리는 지금까지 master에서 커밋을 했다.

master 에서 index.html을 만들고 제목도 넣고 메인 이미지도 추가(트와이스)해봤다.


index.html

<html>
    <title>트와이스</title>
    <h1>트와이스 홈페이지</h1>
    <div>트와이스 메인사진</div>
</html>





2. 브랜치(Branch) 만들기


이번 실습에서는 메인 이미지를 트와이스에서 방탄소년단으로 바꿔보도록 하자. 단, master가 아닌 새로운 브랜치에서 변경을하고 commit을 해보자.

master에서 분기하는 브랜치



브랜치 만들기


방탄소년단 사진을 메인 이미지로 넣을 Commit 이기 때문에 브랜치 이름은 bts-image로 했다.


~/my-git-project$ git branch bts-image

~/my-git-project$ git branch

bts-image  <====브랜치가 만들어졌다.

*master


~/my-git-project$ git checkout bts-image

~/my-git-project$ git branch

*bts-image  <====브랜치 이동을 했다.

master


$git branch <name>은 현재 base브랜치(master)에서 분기하는 새로운 브랜치를 만드는 명령어다.

$git checkout <name> 은 <name>브랜치로 이동하는 명령어다.


bts-image 브랜치를 만들어서 이동까지 해봤다.

이제부터 staging된 내용을 bts-image 브랜치에서 커밋할 수 있다.




잠깐!

일단 시켜서 따라하긴 했는데 '왜 굳이 브랜치를 따로 만들어서 작업을 하는가? '

근본적인 (혹은 원초적인) 이유는 master 변경 내용을 반영하지 않기 위해서다.

master가 대체 뭐길래? master 완전무결한 완제품이어야 한다(보통 master 브랜치를 최종 버전으로 서비스를 배포한다).


완제품이 무엇일까?

출처: 네이버 국어사전

제작 공정을 완전히 마친 제품, 즉 출시/배포 될 완성품이다. 배포나갈 완제품에 불완전한(혹은 검증되지 않은) 변경사항을 적용한다면 어떻게 될까? 어디선가 사고가 터지고 말것이다. 그렇기 때문에 master와 격리된 공간에서 수정하고 테스트하기 위해 브랜치를 만들어서 작업을 한다.


(고딕체) 약속하자. master 손대지 않기로=커밋 하지 않기로




3. bts-image 브랜치에서 commit 해보기


(실습)

bts-image 브랜치에 두 개의 커밋을 만들어보자.

1) 홈페이지 제목과 메인 이미지 방탄 소년단으로 바꾸기

2) 방탄소년단 소개글 본문에(<body></body>) 추가하기



(메인 이미지 변경)

~/my-git-project$ git commit -m "이미지변경(방소단)"

[bts-image f949149] 이미지변경(방소단)

1 file changed, 1 insertion(+), 1 deletion(-)


(방탄 소년단 소개글 추가)

~/my-git-project$ git commit -m "방탄소년단 소개글 추가"

[bts-image f949149] 이미지변경(방소단)

1 file changed, 1 insertion(+), 1 deletion(-)



bts-image 브랜치 커밋 후 index.html

<html>
    <title>방탄소년단</title>
    <h1>방탄소년단 홈페이지</h1>
    <div>방탄소년단 메인사진</div>
    <body>방탄소년단 어쩌구 저쩌구</body>
</html>


커밋을 했으니 커밋로그도 확인해보자.


~/my-git-project$ git log --online

* 4486ec2 (master) 방탄소년단 소개글 추가

* f949149 (HEAD -> bts-image) 이미지 변경(방소단)

.....


master로 이동해서 커밋로그를 확인해보자. bts-image 브랜치에서 추가한 로그가 보이지 않는다.

당연하지만 master브랜치에서 커밋을 안했기 때문에 반영이 안된 것이다. 우리가 앞서 의도한대로 변경 내역이 master에 영향을 끼치지 않고 있다.

다시 bts-image 브랜치로 이동해서 브라우저에서 페이지를 열어보자. 방탄소년단으로 이미지가 잘 변경된 걸 확인했는가?





4. bts-image 브랜치를 마스터로 병합(Merge)하기.


master로 왜 병합해야하나요? 앞에서 말했듯이 master는 완제품이라고 했다. 즉, 최종결과물이기 때문이다. bts-image(자식 브랜치)에서 잘 작동하는걸 확인했다면 master에 반영해도 좋다.


브랜치를 병합하는 방법으로 두 가지 Merge 와 Rebase 가 있다.


$git merge 와 $git rebase 모두 두개 브랜치의 작업 내용을 병합하는 명령어다. 'Merge와 Rebase 중 무엇을 선택하는가'는 커밋로그를 관리하는 방법에 따라 다르다. 두 개의 차이점에 대해서는 별도 글에서 다루겠다. (글: Merge 와 Rebase의 차이점에 대한 개인적 정리)



이번 글에서는 $git merge로 실습을 해보자

커밋로그를 확인해보니 master의 Head가 bts-image의 Head와 같은 곳에 위치해있다.


대상 브랜치(bts-image)가 베이스 브랜치(master)의 모든 커밋로그를 갖고 있다면?

    베이스 브랜치의 HEAD를 대상 브랜치의 Head로 이동하는 방식으로 병합을 한다. 이를 fast-forward merge라고 한다.



너무 쉬운데? bts-image 브랜치와 master의 커밋로그를 충돌시켜보자.



bts-image 브랜치와 충돌시키기 위해 master에 트와이스 소개글을 추가해보자.

새롭게 실습하기 전에 git reset --hard HEAD~2 로 병합하기 전으로 돌아가자.

(실습)

index.html 파일 안에  <body>태그에 트와이스 소개글을 간단하게 작성해서 추가해본다.)

<html>
..........
    <body><div>트와이스 어쩌구 저쩌구<div></body>  <-----새로 추가할 내용
</html>

~/my-git-project$ git checkout  master

~/my-git-project$ git commit -am "메인페이지 본문글 추가"

[master c098] 메인페이지 본문글 추가

1 file changed, 1 insertion(+)




이제 bts-image 브랜치를 master로 병합해보자.


(현재 위치 master)

~/my-git-project$ git merge bts-image  

Auto-merging index.html

CONFLICT (content): Merge conflict in index.html(1)

Automatic merge failed; fix conflicts and then commit the result.(2)


~/my-git-project$ git merge bts-image  

......

Unmerged paths:

  (use "git add <file>..." to mark resolution)

both modified:   main.html



Merge Conflict 라니!

두 브랜치가 같은 파일/부분에 각자 변경/커밋을 하게되면 다음과 같이 충돌하게 된다. git 입장에서 같은 부분이 다른 내용으로 수정(both modified)이 됐는데 어떻게 병합할 지 모르기 때문에 Conflict(충돌)를 낸것이다. 그래서 "네가 하세요~(fix conflicts and then commit the result)" 떠넘긴격이다.


충돌이 생긴 index.html을 열어보자.


<html>
===HEAD (1)
    <title>트와이스</title>
    <h1>트와이스 홈페이지</h1>
    <div>트와이스 메인사진</div>
    <body>트와이스 어쩌구 저쩌구</body>
===(2)
    <title>방탄소년단</title>
    <h1>방탄소년단 홈페이지</h1>
    <div>방탄소년단 메인사진</div>
    <body>방탄소년단 어쩌구 저쩌구</body>
===bts-image (3)
</html>

(1)~(2)까지는 master의 내용이고 (2)~(3)까지는 bts-image의 내용인데 두 부분이 충돌이 났다.


그래서 충돌난 부분을 수정하면서 직접 병합해보자. 수동 병합은 작성자의 재량이다. 내가 어떻게 하냐에 따라 병합 내용도 달라진다.


실습에서는 트와이스 내용을 없애고 bts-branch에서 작업한 내용으로 병합하겠다.


수동 병합 후 index.html

<html>
    <title>방탄소년단</title>
    <h1>방탄소년단 홈페이지</h1>
    <div>방탄소년단 메인사진</div>
    <body>방탄소년단 어쩌구 저쩌구</body>
</html>



다시 Commit 하면 실패했던 Merge가 완료된다.

~/my-git-project$ git add index.html

~/my-git-project$ git commit  //이번에는 -m 옵션을 사용 안하고 해보겠다.


// 에디터에 아래 내용이 이미 준비가 돼있다.

Merge branch 'bts-image'

# Conflicts:

#       index.html

:wq   // 저장하고 나가자. ( esc -> ':wq' 누른 후 엔터)

[master b123456] Merge branch 'bts-image'



이제 commit tree가 아래 그림처럼 만들어졌다.

실습 끝!





5. 마무리


git을 사용할 때 흔히 말하는 '브랜치 따서 커밋하고 merge한다.' 의 실습 예제였다.

git checkout -b bts-image => (변경 & 커밋) -> git checkout master => git merge bts-image => (파일 병합) =>git commit


지금까지는 내 로컬 저장소에서 혼자 북치고 장구치면서 Git의 A to Z를 해봤다.

다음 글에서는 Github을 활용 해서 협업이란걸 해보자.

(끝)


되짚기: Commit 응용편


다음글: Git&Github은 왜 사용하는걸까 4 Github 기초편



브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari