Git & Git Workflow

bearMin·2024년 7월 4일

들어가면서

제목만 봐도 알겠지만 개발자들이 무조건 사용할 줄 알아야 하는 도구인 Git에 대해서 알아보는 시간을 가져보도록 하겠다. 햣 아니 git에 대해서 알아보자고~


Git이란?

정의는?

Git은 형상 관리 도구(Configuration Management Tool) 중 하나이다.

버전 관리 시스템이라고도 하는데 컴퓨터 파일의 변경사항을 추적하고 여러 명의 사용자들 간에 파일에 대한 작업을 조율하는데 사용된다.

이러한 특징 때문에 여러 명의 개발자가 하나의 소프트웨어 개발 프로젝트에 참여하여 소스 코드를 관리할 때 주로 사용하게 되는 것이다!

때문에 협업을 하는 개발자라면 Git은 기본적으로 알고 있어야하는 것이다..


버전 관리란?

위에서 버전 관리 시스템이라고 했는데 그럼 이 버전 관리가 무엇이고 어떻게 하길래 사용하기 좋은 것일까?

버전 관리파일의 변경사항들을 시간의 순서에 따라 흐름에 따라 저장하고, 이후에 원하는 시점의 버전을 다시 가져올 수 있는 것을 말한다.

즉, 내가 개발을 하다가 어떠한 시점에서 파일의 변경사항들을 저장을 한다면 하나의 버전이 되는 것이고 그 버전은 계속 저장이 되어있으며 필요없거나 문제가 되는 버전들을 버리거나 그 이전 버전으로 돌아갈 수 있는 것이다!


장점은?

이렇게 버전 관리를 하게 된다면 장점으로는 무엇이 있을까?

  1. 원하는 버전 상태로 자유롭게 움직일 수 있다.
  2. 작업물의 변경 이력을 관리할 수 있다.
  3. 버전에 따라 수정 내용을 비교할 수 있다.
  4. 누가 문제를 일으켰는지 추적이 가능하다.
    이게 가장 장점이자 단점(?)이지 않을까? 내가 잘하면 상관없지만 잘못하면 바로 들통이 날 수 있다ㅎㅎ….
  5. 파일을 잃어버리거나 잘못 고쳤을 경우에도 쉽게 복구가 가능하다.
  6. 예상치 못한 문제가 발생했을 때 빠르게 대처가 가능하다.

이렇게 많은 장점들이 있지만 이 장점들이 있을 수 있는 이유는 결국 이전의 버전을 기억한다는 것에서부터 시작한다.


단점은?

이렇게 좋은 Git, 그럼 단점은 없을까?

당연히, 있다..

  1. 저장소의 크기가 점점 커진다.
    : Git은 모든 변경 이력을 저장한다. 이전의 버전들을 기억한다는 뜻은 모든 내용을 다 저장하고 있다는 뜻과 동일한다. 때문에 저장소의 크기가 점점 커질 수 있다. 특히 큰 프로젝트의 경우 디스크 공간을 효율적으로 관리해야 할 필요가 있다.

  2. Git은 초보자가 사용하기에는 꽤 어려울 수 있다.
    : Git은 처음 사용자에게는 진입장벽이 있을 수 있다. 특히 Git의 명령어와 작업 흐름을 익히는 데 시간이 걸릴 수 있다.

하지만 이러한 단점들은 사실 현재 크게 중요하지 않은 사항들이다. 때문에 개발을 하려고 한다면 Git은 꼭 사용할 줄 알아야한다..!


용어는?

Git을 꼭 사용할 줄 알아야한다고 했으니, Git을 조금이나 쓸 수 있도록 만들어야한다는 책임감이 생긴다.. 때문에 진입장벽을 조금이나마 낮춰보고자 한다. 우선 Git의 진입장벽을 높이는 두가지 중 첫번째인 Git에서 사용하는 용어들과 명령어들에 대해서 간단하게 소개하겠다.

commit이란?

우리가 하나의 버전을 만든다고 했을 때 그 버전을 commit이라고 생각하면 된다. 이때 이 파일의 버전이 저장되는 곳repository(저장소)라고 하며 그 저장하는 과정을 commit을 한다고 얘기한다. 보통은 commit을 찍는다라고 한다ㅎㅎ

이렇게 commit은 사람마다 다르긴 하지만 보통 하나의 버전을 만드는 것이기 때문에 변수 하나 적었다고, 코드 1줄 적었다고, 조금씩 할 때마다 찍지 않고, 하나의 기능 단위로 commit을 한다.


예를 들어, 공지를 읽고 수정하고 삭제하는 기능을 만들고 싶을 때
공지를 읽는 기능을 만들었다면 commit,
수정하는 기능을 만들었다면 commit,
삭제하는 기능을 만들었다면 commit.
이런 식으로 기능의 단위로 commit을 찍는다.


이때 사용하는 명령어는

git commit -m "커밋 메시지"

이다.


이 명령어는 commit을 찍음과 동시에 해당 commit이 어떠한 내용을 담고 있는지 메시지도 같이 적어서 저장을 하는 것이다.

단, 이때 무작정 commit을 찍는 것이 아니라 commit을 하기 전 준비 과정이 필요하다. 이때 필요한 것이 staging이다.


staging이란?

commit을 하기 전에 작업을 하고 있던 working directory에서 어떠한 파일들을 저장을 할 것인지 선택하여 명령어를 통해 staging area로 파일들을 넣는다. 이때 이 행위를 staging한다 라고 표현한다.


이때 사용하는 명령어는

git add <파일명>

이다.
이때 단순한 파일명이 아니라 dev/main.java 이런 식으로 경로와 파일명을 모두 작성해주어야한다. 폴더명만 작성할 경우 해당 폴더 안의 모든 파일이 모두 staging 된다.


어떤 파일을 특정할 필요없이 변경된 모든 파일을 선택하고자 한다면

git add .

을 사용하면 된다.


branch란?

branch에서 작업을 한다고 하는데 그렇다면 이 Branch는 무엇이길래 어떻게 사용할지에 대한 규칙을 정의해야하는 것일까?

흔히 가지치기라고 많이 얘기를 하는데 독립적으로 어떤 작업을 진행하기 위한 개념을 뜻한다.

협업을 하면서 다른 사람의 코드에 영향이 가지 않도록 따로 공간을 마련하는 것을 branch를 파서 작업한다 라고 생각하면 편하다.

branch에서 branch를 만들 수도 있고, 기존의 코드를 지키면서 수정본을 만들거나 새로운 기능을 만들 수 있으며 합칠 수도 있다.


브랜치를 만들 때 사용하는 명령어는

git switch -c <브랜치이름>

이다. 브랜치이름을 설정하고 해당 브랜치를 생성한 뒤 해당 브랜치로 변경이 된다.


단순한 브랜치를 이동하기 위해서는

git switch <브랜치이름>

명령어를 사용하면 된다.


merge란?

branch에서 모든 코드를 다 짜고 문제가 없이 동작이 된다면 뻗어나오기 전, 즉 원본 branch에 코드를 합쳐야한다. 이때 해당 branch에 합치는 것을 merge라고 한다.

이 merge는 협업을 하는 사람들 사이에서 매우 중요한 작업이다. 파일을 합치다가 생각치도 못한 오류가 발생할 수도 있고, 잘못 합치게 되면 걷잡을 수 없이 많은 문제가 발생하기 때문이다.

merge에는 여러가지 방식이 존재하는데 이 merge 전략에 대해서 알아보자.


Merge 전략이란?

정의는?

한 브랜치에서 작업한 내용을 Main 브랜치에 Merge(병합)할 수 있는 다양한 방법들을 제공하는데 이를 Merge 전략이라고 한다.

3-way merge

Main branch가 아닌 새로운 branch에 commit 한 것이 1개 이상 있을 경우 git merge 명령어를 사용하여 두 branch의 코드를 합쳐 하나의 새로운 commit을 만들어주는 방식이다. 그림에서는 commit4라는 commit이 새로 생겼다고 보면 된다.

이러한 방식을 3-way merge라고 하며 일반적인 merge의 동작 방식이다.

이 방식은 모든 branch의 commit이 history에 기록이 된다. 따라서 모든 commit의 정보를 상세하게 파악을 할 수 있지만 history가 복잡해지는 단점이 있다.


fast-forward merge

가끔 새로운 branch에는 commit이 있지만 main에는 신규 commit이 없는 경우가 있다. 이 경우에는 main branch와 새로운 branch가 합칠 것이 없기 때문에 commit들을 main 브랜치로 옮겨준다.

3-way merge 처럼 새로운 commit이 생기는 것이 아니라 새로운 branch의 commit들을 main branch로 옮기는 것이 차이가 있다.


rebase and merge

rebase란 branch의 시작점을 다른 commit으로 옮겨주는 행위이다. 이 rebase를 이용해서 새로운 branch의 시작지점을 main branch의 가장 최근 commit으로 옮긴 뒤에 fast-forward merge를 진행하는 것이다.

이렇게 한다면 3-way merge에서 있었던 history가 복잡해지는 단점을 줄일 수 있다. 다만 잘못 merge 했을 경우 충돌이 일어날 수 있고 이것을 해결하는데 오랜 시간이 걸릴 수 있다.


squash and merge

squash and merge 방식은 새로운 branch에서 커밋한 내용들을 main의 가장 최근 commit으로 옮겨주고 branch를 삭제하는 것이다.

3-way merge 방식을 사용해도 문제는 없지만 위의 방식을 사용하는 이유는 3-way merge 방식은 협업을 진행할 때 수많은 commit들이 생기면서 그 많은 branch들을 3-way merge 방식으로 사용하게 되면 진행상황을 한눈에 알아보기 매우 어렵다. 이를 방지하기 위해 rebase 혹은 squash의 방식을 사용하는 것이다!


Git Workflow란?

다음은 Git의 진입장벽을 높이는 두가지 중 하나인 작업흐름인 Workflow에 대해서 설명을 해보겠다.

정의는?

Git은 Branch에서 작업을 하는데 같이 개발을 하는 팀에서 Branch를 어떻게 사용할지에 대한 규칙을 정의한 것을 Git Branch Strategy라고 한다!

즉, 이 Git을 잘, 효율적으로 사용하기 위해서 Git Branch Strategy를 정의하고 작업하는 Workflow(작업흐름)가 존재하는 것이다.


Git Flow란?

branch를 5개의 종류로 나눠서 진행하는 방식이다.

각각의 branch가 하는 역할도 다르다.

  • main(master)
    • 서비스를 직접 배포하는 역할을 하는 branch
  • develop(개발)
    • feature에서 개발된 내용이 저장되는 branch
  • feature(기능)
    • 각 기능별 개발 branch
    • branch 나오는 곳 : develop
    • branch 들어가는 곳 : develop
  • release(배포)
    • 배포를 하기 전 내용을 품질 검사하기 위한 branch
    • branch 나오는 곳 : develop
    • branch 들어가는 곳 : develop, master
  • hotfix(빨리 고치기)
    • main branch로 배포하고 나서 버그가 생겼을 때 빨리 고치기 위한 branch
    • branch 나오는 곳 : develop
    • branch 들어가는 곳 : develop, master

이렇게 많은 branch가 있다. 그럼 어떻게 Workflow는 어떻게 될까?

  1. main branch에서 develop branch를 분할
  2. 개인 작업은 develop branch에서 feature branch를 따서 작업. 이때 개인 작업이 끝나면 develop에 합침
  3. develop branch에서 배포 준비가 끝나면 release branch로 분할
  4. release branch에서 디버깅하고 문제가 없으면 master branch와 develop branch에 합침
  5. master branch를 배포
  6. 만약 배포 버전에서 문제가 생겨 급하게 수정해야 하면 hotfix branch를 따서 작업
  7. hotfix branch에서 bug fix가 끝나면 master branch와 develop branch에 합침

이렇게 사용을 한다면 프로젝트의 전반적인 흐름을 알 수 있게 된다. 버전의 정보는 main branch에서 확인할 수 있고 현재 개발 중인 기능은 feature branch에서 버그의 정보는 hotfix branch에서 확인이 가능하다. 즉, branch의 역할이 명확하다!

다만 Branch가 많아 처음 Git을 사용하는 개발자들은 이 workflow를 따라가는데 어려움이 있을 수 있다..


GitHub Flow란?

위의 Git Flow가 매우 복잡하기 때문에 사람들이 많이 실수를 하고 헤매게 된다. 이를 막기 위해서 조금 더 간편한 GitHub Flow가 탄생했다. GitHub Flow라는 이름에서부터 알 수 있듯이 GitHub를 사용해서 작업을 하는 Flow로 GitHub 환경에서 사용하기 적합한 전략이다.

특히, PR을 이용하여 토론을 하고 코드 리뷰를 주고 받으며 토론과 리뷰가 끝났다면 main branch과 topic branch를 병합하게 된다.


Branch는 2 종류로 매우 간편화 되어있다.

  • main(master)
    • 항상 stable한 상태
      : 모든 커밋은 언제 배포하든 문제 없어야하며, 언제든 새로운 브랜치를 새로 만들어도 문제가 없어야함
  • Topic
    • 새로운 기능을 개발
    • Git Flow에서 Feature 브랜치와 동일한 역할
    • 버그 수정도 여기서 함
    • 기능이 완성되지 않더라도 꾸준히 Push를 진행
      → 노트북 분실, 작업 컴퓨터의 고장 등의 위험으로 코드 유실 방지
      → 꾸준한 Push를 통해 구성원 모두가 끊임없이 커뮤니케이션 가능

Branch가 단순한 만큼 Workflow도 단순하다.

  1. 개인 작업은 Feature branch에서 작업하며 작업이 끝나면 Pull Request를 생성
  2. Pull Request에서 코드 리뷰 후에 문제가 없으면 master branch로 병합
  3. master branch에 병합되면 바로 배포 작업을 수행

이 GitHub Flow는 branch 전략이 매우 단순하기에 처음 Git을 접하는 사람들에게는 좋은 시스템이다. 또한 PR(Pull Request)를 사용하기 때문에 자연스럽게 코드 리뷰를 사용할 수 있다!

그러나 규모가 큰 서비스나 지속적으로 배포를 해줘야하는 서비스에서는 적합하지 않다..


GitLab Flow란?

위쪽은 pre-production branch가 없는 전략이며, 아래쪽은 pre-production branch를 두어 staging 단계를 가지는 전략이다.

위의 GitHub Flow가 너무 간단해서 배포, 릴리즈 등의 조금 복잡한 이슈를 보완하기 위해서 나온 전략을 GitLab Flow라고 한다.

  • master
    • 안정적인 코드가 저장되는 branch
    • git flow의 develop branch와 동일
  • feature
    • 기능이 개발되는 branch
    • 브랜치 나오는 곳 : master
    • 브랜치 들어가는 곳 : master
  • production
    • git flow의 master branch와 동일
    • 테스트가 끝난 기능에 대해 배포를 하기 위한 branch
    • 브랜치 나오는 곳 : master
  • pre-production
    • master → prodution branch 사이에 branch를 두어 변경 사항을 바로 배포하지 않고 test server에 배포하여 테스트를 진행하거나 시간을 두고 반영하는 branch
    • 배포를 하기 전에 생성되며, 준비가 완료되면 prodution 브랜치에 병합

Workflow는 과연 어떻게 될까?

  1. master branch에서 feature branch를 생성하여 기능을 개발
  2. 개발이 끝나고 master branch로 병합
  3. 병합이 끝났다면 pre-production branch로 병합하여 test를 진행
    (이때, pre-production이 없다면 바로 4번으로 넘어감)
  4. test가 끝났다면 production branch로 병합하여 배포 작업을 수행

Git Flow는 너무 복잡하고 GitHub Flow는 너무 단순하다는 문제들 때문에 나온 전략으로 소규모부터 대규모까지 다양한 규모의 프로젝트에서 사용이 가능하며 유연한 작업흐름을 제공한다.


정리하자면?

Git은 형상 관리 도구 중 하나로 버전 관리 시스템이다!

이 버전 관리를 통해서 Git의 다양한 장점들이 있다!

Git에는 다양한 명령어들이 존재하며 위의 명령어들을 사용해서 협업을 진행할 수 있다!

다양한 Merge 전략과 Git Workflow를 활용하여 협업을 진행할 수 있다!

profile
소소한 공부기록

0개의 댓글