Codesigner

[Git] Git Branching - fast forward 본문

Git /git

[Git] Git Branching - fast forward

eunsukimme 2019. 4. 9. 14:37

이전까지의 포스팅에서는 master(마스터)라고 불리는 단 하나의 브랜치 상에서만 작업하였다. Git에서는 실험적으로 테스트하기 위함이나 기능별로 프로젝트를 분리할 수 있는 branch(브랜치)들을 만들 수 있게 해 준다. 우리가 소설을 쓰면서 해피엔딩과 배드 엔딩 두 가지를 고려하고 있다고 생각해보자. 우리는 'happy'라는 새로운 브랜치를 만들어서 해피 엔딩으로 소설을 써내려 갈 수 있고, 같은 맥락으로 'bad'라는 브랜치를 만들어서 배드 엔딩 스토리를 써내려 갈 수 도 있다. 이 'happy' 브랜치와 'bad'브랜치에서 작업한 내용들은 당신이 master 브랜치에 merge(병합) 하기 전까지는 서로 독립적으로 존재한다. 즉, 아무 영향을 끼치지 않는다. 이번 포스팅에서는 Git의 branch를 활용하여 여러 가지 버전의 이력서를 작성한다고 가정하고, branch에 대해 간단히 알아보도록 하자.

 

 

 

git branch

 

먼저 다음과 같은 명령을 입력해보자

C:\Users\glafu\Desktop\git_test>git branch
* master

C:\Users\glafu\Desktop\git_test>

위 명령은 현재 Git 프로젝트에서 존재하는 브랜치들을 보여주고, asterisk( * ) 문자는 우리가 현재 위치하고 있는 브랜치를 나타낸다. 지금은 브랜치가 master 브랜치 뿐이다. 

 

 

 

branching overview

 

아래의 그림은 Git 브랜치가 무엇인지 보여주고 있다

 

<그림 1> git branching(출처: codecademy.com)

 

  • 커밋 히스토리를 나타내고 있으며, 원들은 커밋을 의미한다

  • New Branch는 Git 프로젝트의 또 다른 버전을 의미한다. 이 브랜치는 현재 master 브랜치의 커밋들을 포함하면서 동시에 master 브랜치가 포함하지 않는 커밋들을 포함하고 있다

 

 

 

git branch 2

 

현재 우리는 master 브랜치만 보유하고 있음을 조금 전에 확인했다. 새로운 브랜치를 만들기 위해선 다음과 같이 명령한다

git branch branch_name

branch_name 은 만들고자 하는 브랜치의 이름이고, 우리의 경우 여러 가지 이력서를 지원하고자 하는 여러 회사의 특성에 맞게 작성하고자 하므로 회사 이름으로 작성해보자. 즉, 각 브랜치에서 이력서를 회사가 찾고자 하는 인재상에 맞추어서 작성하고자 한다. 주의할 것은, 일반적인 프로젝트에서는 브랜치의 이름의 목적성이 명확해야 하고, 공백을 포함해선 안된다는 것이다. 우선 resume.txt라는 파일을 만들고 간단한 내용을 작성한 뒤 커밋하도록 하자.

C:\Users\glafu\Desktop\git_test>vim resume.txt

C:\Users\glafu\Desktop\git_test>cat resume.txt
i want to be a programmer!

C:\Users\glafu\Desktop\git_test>git add resume.txt

C:\Users\glafu\Desktop\git_test>git commit -m "Add simple resume"
[master 6816d01] Add simple resume
 1 file changed, 1 insertion(+)
 create mode 100644 resume.txt

C:\Users\glafu\Desktop\git_test>

그런 다음, samsung 이란 브랜치를 만들어보자

C:\Users\glafu\Desktop\git_test>git branch samsung

C:\Users\glafu\Desktop\git_test>git branch
* master
  samsung

C:\Users\glafu\Desktop\git_test>

git branch 명령의 결과로 이제 두 브랜치가 나타나는 것을 주목하자

 

 

 

git checkout

 

master 브랜치와 samsung 브랜치는 독립적이지만 현재는 같은 커밋 히스토리를 공유하고 있다. 우리는 현재 위치하고 있는 브랜치를 다음 명령으로 쉽게 변경할 수 있다

git checkout branch_name

우리의 경우엔 branch_name은 samsung 이 될 것이다. 일단 브랜치를 변경하고 나면, 우리는 master에 아무런 영향을 주지 않으면서 samsung 브랜치에서 커밋을 생성할 수 있다. samsung 브랜치로 이동해보자

C:\Users\glafu\Desktop\git_test>git checkout samsung
Switched to branch 'samsung'
M       hello.txt

C:\Users\glafu\Desktop\git_test>

samsung 브랜치로 이동했음을 확인할 수 있다. 여기서는 hello.txt 가 Modified 된 채로 브랜치를 이동해서 Git이 이를 알려주고 있다. 다시 git branch 명령으로 현재 위치하고 있는 브랜치를 확인해보자

C:\Users\glafu\Desktop\git_test>git branch
  master
* samsung

C:\Users\glafu\Desktop\git_test>

samsung 앞에 asterisk(*) 문자가 붙어있음을 확인할 수 있다

 

 

 

commit on a new branch

 

우리는 현재 samsung 브랜치에 위치하고 있다. master 브랜치에서 수행한 모든 작업들을 현재 위치한 브랜치에서도 동일하게 수행할 수 있다. 예를 들어, 다음과 같이 파일들을 Staging Area에 올릴 수 있다

git add filename

그리고 커밋도 가능하다

git commit -m "Commit message"

이때, 우리는 samsung 브랜치에서 커밋을 생성하게 된다. 그러면 Git 프로젝트의 브랜치의 모습은 아래 그림과 같다

 

<그림 2> commit on new branch(출처: codecademy.com)

 

우리는 samsung 브랜치에서 resume.txt에 한 줄을 더 추가한 다음 커밋하도록 하자

C:\Users\glafu\Desktop\git_test>vim resume.txt

C:\Users\glafu\Desktop\git_test>cat resume.txt
i want to be a programmer!
i want to work at samsung!

C:\Users\glafu\Desktop\git_test>git add resume.txt

C:\Users\glafu\Desktop\git_test>git commit -m "Add new line at resume on samsung"
[samsung cf674b9] Add new line at resume on samsung
 1 file changed, 1 insertion(+)

C:\Users\glafu\Desktop\git_test>

그런 다음 git log 명령을 실행해보자

C:\Users\glafu\Desktop\git_test>git log
commit cf674b944e325c4eb7d8a45485ac3f2c424c9799 (HEAD -> samsung)
Author: eunsukimme <eunsu.dev@gmail.com>
Date:   Tue Apr 9 14:01:35 2019 +0900

    Add new line at resume on samsung

commit 6816d01351383de2619c18d61f0a5789192f3d57 (master)
Author: eunsukimme <eunsu.dev@gmail.com>
Date:   Tue Apr 9 13:46:16 2019 +0900

    Add simple resume

commit 7495fd8b75091d2c2193acc89fa4542da3b2d9c2
Author: eunsukimme <eunsu.dev@gmail.com>
Date:   Mon Apr 8 23:18:56 2019 +0900

    Add third line

commit d9e17f2638100c8f50866c811efda95909973c5c
Author: eunsukimme <eunsu.dev@gmail.com>
Date:   Mon Apr 8 22:12:06 2019 +0900

    Add first commit

C:\Users\glafu\Desktop\git_test>

출력 결과를 보면 master 위에 커밋 로그가 하나 더 생긴 걸 확인할 수 있다. samsung 브랜치가 master의 모든 커밋 이력을 상속받았고, 이는 master 브랜치의 커밋들을 samsung 브랜치도 보유하고 있음을 의미한다.

 

 

 

git merge

 

만약에 당신이 여러 회사들 중 samsung 회사에 입사하기로 결심했다면, samsung 브랜치에서 만든 이력서의 변화들을 master 브랜치에 적용하고 싶을 것이다. 우리는 단순히 브랜치를 merging 함으로써 두 브랜치를 합칠 수 있다

git merge branch_name

이때 몇 가지 기억해야 할 것은:

  • 우리의 목적은 master 브랜치의 내용을 samsung 브랜치의 그것으로 업데이트시키는 것이다

  • samsung 브랜치는 그런 맥락에서 giver branch이다. 변화를 제공하는 브랜치이기 때문이다

  • master 브랜치는 그런 맥락에서 receiver branch이다. 변화를 받아들이는 브랜치이기 때문이다

자, 이제 다시 master 브랜치로 이동하여 samsung 브랜치에서 작성한 이력서를 merge 하도록 하자. git checkout 명령으로 master 브랜치로 이동하자

C:\Users\glafu\Desktop\git_test>git checkout master
Switched to branch 'master'
M       hello.txt

C:\Users\glafu\Desktop\git_test>

그런 다음, git merge 명령으로 브랜치를 병합하자

C:\Users\glafu\Desktop\git_test>git merge samsung
Updating 6816d01..cf674b9
Fast-forward
 resume.txt | 1 +
 1 file changed, 1 insertion(+)

C:\Users\glafu\Desktop\git_test>

출력 결과를 보면 "Fast-forwad"라는 용어가 나온다. 이는 Git이 master 브랜치의 가장 최근에 만들어진 커밋에서 samsung 브랜치가 가장 최근에 만든 커밋에 도달 가능한 상태일 때 이를 감지하고 서로 다른 내용을 merge 할 필요가 없으므로 단순히 커밋 포인터를 앞으로 이동할 뿐을 의미한다. Git document에서는 이를 다음과 같이 설명하고 있다.

 

 

when you try to merge one commit with a commit that can be reached by following the first commit’s history, Git simplifies things by moving the pointer forward because there is no divergent work to merge together — this is called a “fast-forward.”

 

 

 

 지금까지 새로운 브랜치를 생성하고 브랜치를 변경하며, 변경한 브랜치에서 수행한 작업을 merge 하는 방법을 알아보았다. 또한 초보자들이 이해하기 어려워하는 fast-forward 용어에 대해서도 간단히 알아보았다. 다음 포스팅에서는 브랜치를 merge 할 때 접할 수 있는 merge conflict 문제란 무엇이고 이를 해결하는 방안에 대해서 알아본 뒤 branch에 대해 배운 내용을 정리해 보도록 하자. 

 

 

 

Comments