본문 바로가기
코드프레소 체험단/실무자가 알려주는 Git

[실무자가 알려주는 Git 활용한 프로젝트 관리] Git 브랜치의 이해

by 의정부핵꿀밤 2022. 1. 16.
728x90

✨ 이 글은 [ 코드프레소 Java 웹 개발 체험단 활동 ] 내용입니다 ✨

💜 코드프레소 이러닝 강의 수강 중 - 실무자가 알려주는 Git 활용한 프로젝트 관리 💜

😎 아래의 링크를 통해 프리미엄 IT 교육 서비스, 코드프레소를 확인해보세요 😎

https://www.codepresso.kr/

 

프리미엄 IT 교육 서비스 - 코드프레소

 

www.codepresso.kr


브랜치(branch)

  • 원래 코드에 영향을 주지 않고 개발을 진행할 수 있는 공간
  • 본래의 소스코드로 부터 파생한 독립적인 작업 공간
  • 최신 커밋을 가리키는 일종의 포인터이다
  • 쉽게 만들고 없앨 수 있을만큼 매우 가볍다
  • 생성, 이동, 병합(merge)이 매우 쉽다

 

 

master 브랜치

  • Git은 기본적으로 master 브랜치를 생성한다
  • 아마 main 브랜치와 같은 듯..?
  • master 브랜치는 첫번쨰 커밋을 만들어야 생성된 커밋을 가리킬 수 있다
    • 원래는 커밋을 하지 않고 branch를 확인해보면 아래와 같이 아무것도 나타나지 않는다
    • 하지만 커밋을 생성하고 브랜치를 확인해보면 그제서야 main(master) 브랜치가 커밋을 가리키는 것을 확인할 수 있다
  • 현재 작업중인 브랜치는 아래의 명령어를 통해 확인할 수 있다
  • $ git branch

 


HEAD

  • 현재 작업중인 브랜치를 가리킨다
  • 현재 브랜치를 가리키는 일종의 포인터 역할을 한다
  • 현재 브랜치의 마지막 커밋에 대한 스냅샷이다
  • 즉, HEAD는 현재 작업중인 브랜치의 최신 커밋을 가리키는 포인터이다!
  • 만약 HEAD가 다른 브랜치를 가리킨다면, 현재 작업중인 브랜치가 변경되었음을 의미한다

2번쨰 커밋 후 확인

  • 2번째 커밋을 한 후 확인해보면 HEAD가 2번째 커밋을 가리키고 있는 걸 확인할 수 있다
  • 그림으로 도식화해보면 아래와 같이 HEAD는 커밋이 생성될 때마다 자동으로 가장 최신 커밋을 가리키게 된다

 

 

 

새로운 기능 개발이 시작되면?

  • 브랜치는 목적에 따라 분기할 수 있다 -> 기능에 따라 분기 가능!
  • 브랜치 분기 전략은 일종의 운영 전략이기 떄문에 조직에 따라 달라진다

 

 

브랜치 생성

  • 브랜치를 생성할 때는 아래의 명령어를 통해 생성할 수 있다
$ git branch "생성할 브랜치 명"
  • 브랜치가 생성된 직후, 현재 상황을 도식화하면 아래의 그림과 같이 표현할 수 있다

 

 

 

브랜치 이동

  • 브랜치 이동을 하려면 아래의 명령어를 통해 이동할 수 있다
$ git checkout "이동할 브랜치 명"
  • 실제로 실습을 진행하면 아래와 같이 브랜치 생성 및 이동이 된 것을 확인할 수 있다

 

  • 브랜치 생성 및 이동 과정을 도식화하면 아래와 같다
  • 브랜치 생성만 한 경우에는 아래와 같이 HEAD는 그대로 master 브랜치를 가리키고 feature-login이라는 새로운 브랜치가 생성된다
  • 브랜치 생성
  • 하지만 브랜치 이동을 하게 되면 아래와 같이 HEAD가 새로 생성된 브랜치를 가리키게 되는 것이다
  • 브랜치 이동
  • HEAD는 checkout 대상 브랜치로 이동한다
  • 로컬 저장소의 상태는 HEAD가 가리키는 마지막 커밋이 최신이 되고, 작업 디렉토리의 파일 상태도 변경된다
  • 만약 내가 'feature-login' 브랜치에서 'LoginService.java'라는 파일을 생성하고 다시 main 브랜치로 checkout 하면 로컬 저장소에는 새로 생성된 'LoginService.java'파일이 존재하지 않게 되는 것이다!

브랜치 이동 시 로컬저장소 상태 변화

 


// git의 모든 커밋 히스토리를 확인하고 싶은 경우
$ git log --all

// git의 커밋 히스토리를 그래프 형식으로 확인하고 싶은 경우
$ git log --graph

 

 

 

 

개발 중 이슈가 발생하면?

  • master 브랜치에서 이슈가 발생하면 issue 브랜치를 생성하여, 발생한 이슈는 해당 브랜치에서 해결하는 방법이 있다
  • 하지만 브랜치 전략은 조직마다, 개인마다 모두 다르기 때문에 이는 그냥 해결 방법 중 하나로 생각하면 된다!

 

 

브랜치 생성 및 이동

  • 브랜치를 생성함과 동시에 이동까지 하려면 아래의 명령어를 사용하면 된다!
$ git checkout -b "생성 및 이동할 브랜치명"

 


이슈 해결이 완료되면?

  • issue 브랜치에서 이슈가 해결이 완료되면, merge를 통해 master 브랜치와 합쳐준다!

 

 

 

브랜치 병합(merge)

  1. 기준이 되는 브랜치로 이동해서 병합해야 한다
    • issue 브랜치를 merge하려면 main 브랜치로 이동해서 merge를 진행해야 한다
  2. 합쳐질 브랜치를 병합한다
    • $ git merge "병합할 브랜치명"
    • 실제 실습을 진행하면 아래와 같이 병합이 성공적으로 된 것을 확인할 수 있다
  3. 브랜치 병합이 끝나면 작업이 완료된 브랜치는 삭제해주는 것이 좋다!

 

 

 

 

 

Fast-forward Merge

  • 브랜치의 위치만 최신 커밋으로 이동시키는 merge 방식이다

 


(참고)

각각의 브랜치들이 어떤 커밋을 가리키고 있는지 확인할 때는 아래의 명령어를 사용하면 된다!

$ git bracnh -v


브랜치 삭제

  • 더 이상 사용되지 않는 브랜치는 삭제하는 것이 좋다
  • $ git branch -d "삭제할 브랜치명"
  • 브랜치를 삭제하면 아래와 같이 확인할 수 있다
  • 실습으로 브랜치 삭제를 설명해보자면, 브랜치 삭제를 진행하기 전에는 아래와 같은 상황일 것이다
  • issue 브랜치 삭제 전
  • 여기서 issue 브랜치를 삭제하게 되면 커밋이나 코드가 삭제되는 것이 아닌 일종의 포인터인 issue 브랜치만 삭제되기 때문에 브랜치는 가볍게 생성 및 삭제가 가능한 것이다!
  • issue 브랜치

 


기능 개발이 완료되면?

  • issue 해결도 끝나고 feature에서도 기능 개발이 끝나게 되면, master 브랜치에서 이 모든 것들을 merge하면 된다!

 

 

 

3-way Merge

  • 아래 3개 커밋을 모두 고려하여 병합하는 방식으로, 3-way Merge 의 결과는 새로운 커밋으로 생성된다
    1. master와 feature-login 브랜치의 공통 부모 커밋 (Commit 2)
    2. master 브랜치의 최신 커밋 (Commit 5)
    3. feature-login 브랜치의 최신 커밋 (Commit 3)
  • 실제로 확인해보면 위의 그림과 같이 병합된 것을 알 수 있다

 

 

 

 

 

 

브랜치 병합은 항상 성공하는가?

  • 현업에서는 브랜치 병합이 아주 빈번하게 실패한다

 

 

변경사항의 충돌(conflict)

  • 내가 만약 실습에서 위와 같이 각각 다른 브랜치에서 같은 파일을 다르게 수정하게 되면,  merge를 진행할 경우 conflict가 발생하게 된다
  • conflict 발생
  • conflict이란 2개의 변경점이 합쳐질 때, 2개의 변경점 자체가 서로 충돌하는 상태를 의미한다
  • 이전에 merge를 진행할 때는 Git이 알아서 merge를 진행했지만, 위와 같은 경우에는 어떤 변경점을 선택해야할지 모르기 때문에 사용자에게 변경점을 선택해서 충돌을 해결하도록 하는 것이다
  • 개발하는 기능의 목적에 맞게 어떤 변경사항을 어떻게 반영할지를 결정하고 수정하여 반영하는 것을 "conflict을 해결하는 과정"이라고 한다
  • conflict을 해결하는 2가지 방법 
    1. conflict이 발생한 파일을 열어서 수정한 후 merge하기
    2. Tool을 사용하여 merge하는 방식

 

 

충돌의 해결

1) 직접 merge 하기

충돌이 발생한 파일을 열어보면 아래와 같이 코드 내용이 변경되어 있다

이제 위의 파일을 수정해서 저장한 후 merge하면 된다!

 

2) mergetool 사용하기

$ git mergetool

위의 명령어를 입력하면 아래와 같은 화면이 나타나는데, 여기서 vimdiff를 사용할 거니까 'vimdiff'를 입력한다


[Tip] bc is not available

만약에 'vimdiff'를 입력 시 아래 메시지가 발생하면 아래의 설정을 한 후 재시도 한다

$ git config merge.tool vimdiff


다시 vimdiff를 활용한 merge로 돌아와서!

vimdiff

위의 화면에는 총 4가지의 화면이 존재한다

왼쪽 위부터 1, 2, 3, 4라고 하면

  1. master 브랜치에서의 변경점
  2. master 브랜치와 feature-login 브랜치의 공통 분모가 되는 부분
  3. feature-login 브랜치에서의 변경점
  4. 실제 working directory에 있는 충돌된 파일의 상태

따라서 merge tool을 활용하면 3-way merge를 활용하여 쉽게 변경점을 비교하며 병합할 수 있다

파일 수정이 끝나면 4개의 화면을 모두 종료해준 후 git add -> git commit을 하면 된다!

 


Git 에서 태그란?

  • 태그는 특정 시점의 소스코드 정보를 기록한다
  • 프로젝트 진행 중 의미있는 시점의 커밋을 태깅한 것
  • 의미있는 시점이란?
    • 1차 목표 기능 개발 완료되었을 때
    • 매우 중요한 이슈가 해결되었을 때
    • 기능 개발 완료 및 테스트까지 모두 완료하여 통과하였을 때
    • 고객에게 소프트웨어를 배포할 때
  • Github에서의 태그

 

 

 

 

Git 태그 생성하기

  • Lightweight 태그 : 버전명과 같은 태그명만 남기는 태그
    • $ git tag [태그명]
  • Annotated 태그 : Git 데이터베이스에 태그를 만든 사람의 이름, 이메일, 태그 생성 날짜, 태그 메시지 등을 저장한 태그 
    • $ git tag - a [태그명] -m [태그 메시지]
  • Annotated 태그가 더 많이 쓰이는 편이다
  • 실제로 생성해보면 아래와 같이 태그명이 생성된다
  • $ git show v1.0
  • 위의 명령어를 통해 확인해보면 태그 정보를 확인할 수 있다

 

 

 

 

특정 시점의 커밋 태그하기

  1. 태깅하고자 하는 커밋의 ID 값 확인
    • $ git log --oneline
  2. 커밋 ID 값을 인자로 태깅하기
    • $ git tag -a [태그명] [커밋ID] -m "태깅 메시지"

 

 

 

태그 활용 전략

  • Git을 이용한 태그 생성 시점은 조직마다 다를 수 있다
    • 태그 생성 시점
    • 태그명 규칙
    • 태그 메시지 규칙
  • 중요한 것은 소스코드으; 효율적인 관리를 위해 태그 생성 시점과 방법에 대해서 일관성 있는 규칙(프로세스)을 정해, 프로젝트 팀원 모두가 준수할 수 있도록 정책화 해야 한다

 

 

728x90

댓글