Skip to content

Instantly share code, notes, and snippets.

@timetobye
Last active December 26, 2018 19:03
Show Gist options
  • Save timetobye/c580f6d4cf06bbadc085cbab008693c5 to your computer and use it in GitHub Desktop.
Save timetobye/c580f6d4cf06bbadc085cbab008693c5 to your computer and use it in GitHub Desktop.

Git chapter3 Study

  • branch
  • progit의 내용을 다 옮기기 보다 정독하고 중요하다고 생각되는 부분만 정리한다.
    • 자세한 사항은 링크로 대체한다.
  • 평소에 브랜치를 만들고 merge or push 후 pull request도 하지만..그래도 중요하니까 적자!!
    • 제대로 못하면서...ㅡㅡ

브랜치란 무엇인가?

새 브랜치 생성하기

git branch testing
  • 지금 작업 중인 브랜치가 무엇인지 Git은 어떻게 파악할까. 다른 버전 관리 시스템과는 달리 Git은 'HEAD’라는 특수한 포인터가 있다.
  • 이 포인터는 지금 작업하는 로컬 브랜치를 가리킨다. 브랜치를 새로 만들었지만, Git은 아직 master 브랜치를 가리키고 있다.
  • git branch 명령은 브랜치를 만들기만 하고 브랜치를 옮기지 않는다.

alt text

$ git log --oneline --decorate
f30ab (HEAD -> master, testing) add feature #32 - ability to add new formats to the central interface
34ac2 Fixed bug #1328 - stack overflow under certain conditions
98ca9 The initial commit of my project

브랜치 이동하기

git checkout testing

alt text

$ vim test.rb
$ git commit -a -m 'made a change'

alt text

git checkout master

alt text

  • head가 가리키는 곳이 다르다!!

alt text

$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) made other changes
| * 87ab2 (testing) made a change
|/
* f30ab add feature #32 - ability to add new formats to the
* 34ac2 fixed bug #1328 - stack overflow under certain conditions
* 98ca9 initial commit of my project
  • 실제로 Git의 브랜치는 어떤 한 커밋을 가리키는 40글자의 SHA-1 체크섬 파일에 불과하기 때문에 만들기도 쉽고 지우기도 쉽다. 새로 브랜치를 하나 만드는 것은 41바이트 크기의 파일을(40자와 줄 바꿈 문자) 하나 만드는 것에 불과하다.

브랜치가 필요할 때 프로젝트를 통째로 복사해야 하는 다른 버전 관리 도구와 Git의 차이는 극명하다. 통째로 복사하는 작업은 프로젝트 크기에 따라 다르겠지만 수십 초에서 수십 분까지 걸린다. 그에 비해 Git은 순식간이다. 게다가 커밋을 할 때마다 이전 커밋의 정보를 저장하기 때문에 Merge 할 때 어디서부터(Merge Base) 합쳐야 하는지 안다. 이런 특징은 개발자들이 수시로 브랜치를 만들어 사용하게 한다.

이제 왜 그렇게 브랜치를 수시로 만들고 사용해야 하는지 알아보자.

브랜치와 Merge 의 기초

실제 개발과정에서 겪을 만한 예제를 하나 살펴보자. 브랜치와 Merge는 보통 이런 식으로 진행한다.

1.웹사이트가 있고 뭔가 작업을 진행하고 있다. 2. 새로운 이슈를 처리할 새 Branch를 하나 생성한다. 3. 새로 만든 Branch에서 작업을 진행한다.

이때 중요한 문제가 생겨서 그것을 해결하는 Hotfix를 먼저 만들어야 한다. 그러면 아래와 같이 할 수 있다.

  1. 새로운 이슈를 처리하기 이전의 운영(Production) 브랜치로 이동한다.
  2. Hotfix 브랜치를 새로 하나 생성한다.
  3. 수정한 Hotfix 테스트를 마치고 운영 브랜치로 Merge 한다.
  4. 다시 작업하던 브랜치로 옮겨가서 하던 일 진행한다.

브랜치의 기초

alt text

git checkout -b iss53

위 명령은 브랜치를 만들면서 한 번에 git checkout 까지 할 수 있는 명령어이다.

git branch iss53
git checkout iss53

alt text

브랜치의 기초 & merge

$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
 index.html | 2 ++
 1 file changed, 2 insertions(+)
  • hotfix 브랜치를 마스터 브랜치에 병합
  • 필요가 없어진 브랜치는 아래의 명령어로 삭제한다.
git branch -d hotfix
  • 이 챕터는 본 페이지에서 읽는 것이 훨씬 낫다.
  • 요점을 정리하면 hotfix가 생길 때는 작업 후 master 브랜치에 병합
  • iss53은 그냥 자기 자신 작업 하고 있는 상태
    • 중요한 것은 iss53이 hotfix가 병합된 master branch에 영향을 미치지 않는다는 점이다.
    • 아니면 iss53을 먼저 합치고 hotfix를 master에 합치는 것도 방법이다.

merge의 기초

$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html |    1 +
1 file changed, 1 insertion(+)

alt text

alt text

  • 물론 merge 후에는 당연히 git branch -d iss53

충돌의 기초

가끔씩 3-way Merge가 실패할 때도 있다. Merge 하는 두 브랜치에서 같은 파일의 한 부분을 동시에 수정하고 Merge 하면 Git은 해당 부분을 Merge 하지 못한다. 예를 들어, 53번 이슈와 hotfix 가 같은 부분을 수정했다면 Git은 Merge 하지 못하고 아래와 같은 충돌(Conflict) 메시지를 출력한다.

$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

Git은 자동으로 Merge 하지 못해서 새 커밋이 생기지 않는다. 변경사항의 충돌을 개발자가 해결하지 않는 한 Merge 과정을 진행할 수 없다. Merge 충돌이 일어났을 때 Git이 어떤 파일을 Merge 할 수 없었는지 살펴보려면 git status 명령을 이용한다.

$ git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")

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

    both modified:      index.html

no changes added to commit (use "git add" and/or "git commit -a")

충돌이 일어난 파일은 unmerged 상태로 표시된다. Git은 충돌이 난 부분을 표준 형식에 따라 표시해준다. 그러면 개발자는 해당 부분을 수동으로 해결한다. 충돌 난 부분은 아래와 같이 표시된다.

<<<<<<< HEAD:index.html
<div id="footer">contact : [email protected]</div>
=======
<div id="footer">
 please contact us at [email protected]
</div>
>>>>>>> iss53:index.html

======= 위쪽의 내용은 HEAD 버전(merge 명령을 실행할 때 작업하던 master 브랜치)의 내용이고 아래쪽은 iss53 브랜치의 내용이다. 충돌을 해결하려면 위쪽이나 아래쪽 내용 중에서 고르거나 새로 작성하여 Merge 한다. 아래는 아예 새로 작성하여 충돌을 해결하는 예제다.

<div id="footer">
please contact us at [email protected]
</div>

충돌한 양쪽에서 조금씩 가져와서 새로 수정했다. 그리고 <<<<<<<, =======, >>>>>>>가 포함된 행을 삭제했다. 이렇게 충돌한 부분을 해결하고 git add 명령으로 다시 Git에 저장한다.

다른 Merge 도구도 충돌을 해결할 수 있다. git mergetool 명령으로 실행한다. 다른 Merge 도구도 있는데(Mac에서는 opendiff 가 실행된다), “one of the following tools.” 부분에 보여준다. 여기에 표시된 도구 중 하나를 고를 수 있다.

  • 이 부분은 페이지를 그대로 복사해왔다.

브랜치 관리

브랜치 관리

  • git branch 명령은 단순히 브랜치를 만들고 삭제하는 것이 아니다. 아무런 옵션 없이 실행하면 브랜치의 목록을 보여준다.
$ git branch
  iss53
* master
  testing
  • git branch -v 를 사용하면 마지막 커밋 메시지도 함께 보여준다.
$ git branch -v
  iss53   93b412c fix javascript issue
* master  7a98805 Merge branch 'iss53'
  testing 782fd34 add scott to the author list in the readmes
  • 각 브랜치가 지금 어떤 상태인지 확인하기에 좋은 옵션도 있다. 현재 Checkout 한 브랜치를 기준으로 --merged 와 --no-merged 옵션을 사용하여 Merge 된 브랜치인지 그렇지 않은지 필터링해 볼 수 있다. git branch --merged 명령으로 이미 Merge 한 브랜치 목록을 확인한다.
$ git branch --merged
  iss53
* master
$ git branch --no-merged
  testing

브랜치 워크플로

브랜치 워크플로

-- https://git-scm.com/book/ko/v2/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98-%EB%B8%8C%EB%9E%9C%EC%B9%98-%EC%9B%8C%ED%81%AC%ED%94%8C%EB%A1%9C

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment