본문 바로가기
Git

[Git] Git 개념 및 명령어와 브랜치 전략 및 배포 프로세스

by 도전하는 린치핀 2024. 1. 17.

0. 로컬 코드 및 협업 시 문제 관리

우리는 여러가지 파일을 생성하고 변경한다.

이때, 최종, 최최종, 찐최종, 찐찐최종... 등 다양한 이름으로 파일을 구분하면서 계속해서 변경하고는 한다.

이러한 파일(코드)를 관리하는 과정과 어떤 방법으로 파일을 수정하고 저장하고 관리하는지 아래의 그림을 통해 확인해보자

  • 로컬 코드 관리
    • 다양한 버전 : 하나의 코드(파일)에서 다양한 케이스의 구현을 테스트 해볼 때
    • 히스토리 추적 : 작업 시 문제 발생했을 때 직전 버전으로 롤백
    • 안전히 원격 저장 : 만약 내 노트북(or usb 등)이 도난 당한다면?
  • 협업 관리 : 하나의 프로젝트(파일)에 참여하는 사람이 많아진다면 어떻게 관리해야 할까?
    • 만약 내가 어떤 변경사항이 있는데 다른 사람도 그것에 대해서 다르게 바꿨다면????

 

1. 로컬 코드 관리 : Git & 협업 관리 : Github

 

  • Local Repositoy와 Remote Repository의 차이는 무엇일까?
  • Git(Local Repository) : 로컬 코드(파일) 관리
    • 다양한 버전 : 로컬에서 작업한 내용을 적용
    • 히스토리 추적 : 이전 작업(적용내용) 확인
    • 안전하게 원격 저장 가능 : 로컬 작업물을 모두 원격으로 백업 간으
  • Github(Remote Repository) : 협업 관리
    • 다른 사람과 함께 작업 할 때 다른 사람의 작업물이 적용된 최신 작업물을 이어 받아 작업 가능

  • Conflict 충돌이 발생한다는 것은 위의 그림처럼 같은 기준을 바라보며 작업을 진행했을 때 생길 수 있다.
  • 아래의 그림처럼 같은 기준을 바라보며 생길 수 있는 Conflict의 문제가 있다.

 

  • 이러한 2개의 Conflict 충돌에 대한 해결책
    1. Rebase :  현재 내 작업물의 (기준이 되는) ①Base를 다시 재설정 한뒤, ②다시 커밋을 쌓는다.
      • 단점 : 내가 작업했던 커밋들이 다시 생성되기에, 히스토리가 리셋된다.
    2. Merge : 현재 내 작업물과 Remote에 업로드 되어있는 상대 작업물 모두 존중하고, 머지 커밋을 만든다.
      • 단점 : 머지 커밋이 덕지덕지 생성되어 머지 수가 많아져 작업별로 커밋을 쌓기 힘들다.

2. Git 시작하기 - Remote에서 가져오기 및 Local에서 시작하고 올리기

  • 가져오기 : Remote Repository 에서 시작하기 (일반적)
    • 이미 누군가가 자신의 Local 에서 git init 을 통해 Git 설정한 뒤 Remote 에 업로드한게 있다면
    • 내 로컬에 그것을 가져와서 이어서 작업을 진행하면 된다
  • 새로 만들기 : Local Repository 에서 시작하기 (처음, 역순)
    • Local 에서 git init 을 통해 현재 내 디렉토리에 .git 디렉토리를 생성하여
    • 현재 내 디렉토리를 Git 으로 추적하겠다는것을 선언한다

 

 

3. Git Remote 및 Branch 기본 설정

Git Remote 설정

  • [ Key : Name - Value : URL ] Pair를 통해 Remote Repository 관리
    • 설정 : git remote set-url <Name> <URL>
    • 추가 : git remote add <Name> <URL>
    • 삭제 : git remote remove <Name>
    • 조회 : git remote -v
  • 명칭 : Origin - 일반적으로 많이 사용, 일반적으로 하나만 사용
    • Gerrit / Bitbucket 등으로 이름 지어 연결 혹은 Backup  같은것도 사용
    • 언제 다중 Remote로 사용할까? -> 특정 코드를 내 개인 Repository에 백업하여 추후 학습에 사용 가능

 

Git Branch 설정

각 Repository에는 다수의 Branch로 구성되어 있음 / Branch = 기능에 따른 구별

  • [Repository - 다수 Branch] Pair로 구성되어 있음
    • Git을 시작할 때 다음과 같이 Repository 구성에서 시작한다.
      • Local Repository - 다수 Branch (A)
      • Global Repository - 다수 Branch (B) (위의 Branch와 싱크)
        • Local Git에서는 (A)와 (B)를 한번에 리스트하여, 혹은 구별하여 Branch 조회 가능
  • Branch 관리 : Remote & Local Repository
    • 원격 Branch 조회 : git branch -r
    • 원격 Branch 삭제 : git push --delete/-D origin bc
    • 로컬 Branch 조회 : git branch -l
    • 로컬 Branch 삭제 : git branch -d/-D bc
    • 로컬 Branch 생성 및 선택(이동) : git checkout -b be

 

 

4. Git 구조 (영역)

  • 1. Remote
  • 2. Local
    • Working Directory (1)
      • Tracked
        • 4. Staging Area, Index (2) : Commit 되기위해 대기중인 파일들(대기조)
          • Git Commit 명령어 시 여기에 있는 파일들이 스냅샷 찍힘
        • Unstaged(3) : (Git이 추적하는 파일 중) 수정된 파일들의 집합
          • 이 중에서 Commit하고자하는 것들을 Staging Area(2)로 올린다.
      • Untracked(4) : Git 이 추적하지 않는 파일들의 집합

5. Git 구조 (영역) 의미 및 용례

Working Directory 작업 공간 : 로컬 공간에서 작업할 브랜치 선택하기

  • 브랜치 선택(이동) : git checkout ba
  • 브랜치 새로 생성 후 선택(이동) : git checkout -b be
    • -b : branch creating

Remote Repository 에서 최신 브랜치 가져오기 : Pull = Fetch + Merge

  • 기본적인 Merge 종류
    1. Fast-Forward
    2. 3-Way Merge
    3. Squash Merge

  • Fast-Forward : Remote 에 내 작업과 겹치는 어떠한 타인의 작업도 없을때, 그대로 이어 붙이기
  • 3-Way Merge : Remote 에 있는 타인의 작업 그대로, 내 작업 그대로 보존하고 머지 커밋 생성
  • Squash Merge : Remote 에 있는 타인의 작업 기준으로 다시 내가 작업하여 하나의 커밋으로 뭉쳐 생성

 

 

Local Repository 내 파일 조작(삭제, 추가, 수정) 시나리오 별 Git 영역에 파일 적재 방법

 

 

파일 삭제 시나리오 (deleted ↔ untrackted) : Git RM

  • Git이 추적하고 있는 파일 중 삭제
    1. git rm <File> : Staging Area로 바로 올려서 Commit 시 바로 삭제될 수 있도록
      • = Git Repository에서 삭제 예정(Staging) + Local에서 삭제
    2. 파일을 그냥 삭제하는 경우 (마우스 우클릭, 리눅스 명령어) : Unstaged에 올려 한번 검토 요청
      • = Git Repository에서 삭제 검토 (Unstaged) + Local에서 삭제
    3. git rm -- cached <File> : Staging Area로 바로 올림과 동시에 Untracked에 올려 나만 보
      • Git Repository에서 삭제 예정 (Staging) + Local에서 사용
      • Git에서만 확실하게 없애고, 로컬에서는 나만 사용할 파일에 사용
      • 민감 정보가 포함되어 있는 Credential이나 .env와 같은 개인 설정 파일들

파일 추가 시나리오 (new file ↔ untrackted)

  • 파일을 그냥 추가하는 경우 : Git이 전혀 알지 못하는 새로운 파일이라 Untracked에 추가됨
    • Untracked 내 이 파일을 나만 로컬에서 쓸건지? Git에 등록할 것인지 검토 필요
      1. 나만 써야하는 파일이라면 → Untracked 내 추가된 상태로 사용(.gitignore를 통해 무시해야함)
      2. Git에 등록할 것이라면 Staging Area로 전달(git add를 통해)

파일 수정 시나리오

여기서 '수정'의 정의는 Git을 통해 추적되고 있는 Tracked 파일에서 수정이 일어 났을 때를 의미한다.

  • 파일 변경 내용은 Unstaged 상태에서 Commit 할 내용만 선택적으로 Staging Area로 전달(git add를 통해)

Git Add : 어떤 상태에서든 Staging Area로 보낼 때 사용

Git RESTORE : Staging Area 혹은 Unstaged에서 복구할 때 사용

  • --staged 옵션이 있다면 Staging Area에서 그 전의 상태로 복구
    • delete (삭제할 파일) : Staging Area → Unstaged 
    • modified (수정된 파일) : Staging Area → Unstaged
    • new file (추가된 파일) : Staging Area → Untracked
  • --staged 옵션이 없다면 Unstaged에서 복구 (아무일도 없던 것처럼 깨끗하게 롤백 = 직전 Git에서 추적하던 상태로 롤백)
    • deleted (삭제할 파일) : Unstaged → 기존 Git 내 삭제되기 전 파일 존재 상태로 롤백
    • modified (수정된 파일) : Unstaged → 기존 Git내 수정되기 전 파일 상태로 롤백

Git 트러블슈팅

Commit이 의도와 다를 때, Commit의 수정이 필요할 때 어떤 방법으로 수정해야 할까?

  • 단일 문제 발생 : 바로 직전 커밋을 수정해야 할 때
    1. 간단 수정 : Ammend - git commit --amend
    2. 다시 생성(롤백) : Reset - git reset HEAD~1
      • --soft : Staging Area로 보낸다.
      • --mixed(Default) : Unstaged/Untracked(기존 상태)로 보낸다.
      • --hard : 완전히 없애고 전의 상태로 돌아간다.
      • 단방향으로만 수정 가능하다(git reset HEAD~3 : 3번째 전으로 3개의 커밋 모두 롤백)
      • HEAD의 상대 표현법
        1. ~(Tilde) : N번째 조상 - 수직
        2. ^(Caret) : N번째 부모 - 수평
        3. @(At-sign) : Reflog
  • 다수 문제 발생 : 이전 커밋들을 다시 재정의할때
    • 다시 생성 : Rebase - git rebase -i HEAD~3
      • Cherry-Picking 가능
      • 예를 들어, 총 5개의 커밋 중 2개는 지우고, 2개는 합치고 1개는 살리고
        1. Reword : 커밋 메시지 변경
        2. Edit : 커밋 내용 변경 및 충돌 발생 시 추가 작업을 위한 Rebase 작업
        3. Drop : 커밋 빼기
        4. Squash : 불필요하게 많아진 커밋의 수를 줄이기 위해 몇개의 커밋을 합치기
  • 날려먹었을 때 : Reflog - git reflog --no-abbev
    • 수행하는 모든 커밋들은 저장되어 어떤 치명적인 문제가 발생해도 대응할 수 있다.
    • HEAD 상대 표현법 중 Reflog에서 표기되어 있는 @(At-Sign)

 

Git 중간 작업 임시 저장 : Stash

작업 중 잠깐 지금의 작업을 어딘가에 임시 저장했다가 나중에 다시 활용하고 싶을 때 사용한다.

간단한 예시로 A 브랜치에서 작업하던 작업물을 잠깐 저장 후, B 브랜치로 이동하여 커밋 조작 후 다시 이어 작업할 때를 들 수 있다.

 

 

테스트 및 배포를 위한 Zone 구성 및 Git 브랜치 전략 (git-flow)

개발 결과물 테스트를 위한 Develop Zone과 실제 유저들이 사용하기 위해 배포하는 Production Zone

그리고 이러한 Zone과 연동하여 관리하는 Git 브랜치 전략을 알아보자(git-flow)

 

  • Git 브랜치 및 Zone 전략
    • Develop과 Master(Production)를 분리하는 이유와 Staging이 필요한 이유를 확인하자
    • Develop Zone과 Production Zone을 분리하는 이유와 Staging이 필요한 이유를 확인하자

 

실제 프로젝트 내 테스트 및 배포를 위한 Zone 구성하는 방법

  • Local : 실제 개발을 진행하는 로컬 환경
    • Local DB : 가벼운 테스트를 위해 개발자가 직접 적재 혹은 로컬 실행을 통해 적재되는 정보
    • 때때로 개발자간 데이터베이스 내 데이터 일관성을 위해 Migration SQL 구문으로 주고 받을 때가 있다.
    • 원시적인 방법으로 CSV(Comma Seperated Value)파일을 주고받을 수 있으나 크기가 크다
    • Localhost 웹 브라우저를 통한 Frontend 테스트
    • Localhost Postman을 통한 Backend 테스트
  • Develop Zone : 마무리 된 개발에서 누락된 테스트 케이스는 없는지 내부 사용자(개발자 및 QA)에게 노출(배포)
    • Develop Zone DB : 테스트를 위해 개발자들이 직접 적재 혹은 테스트를 통해 적재되는 정보
    • 로컬에서보다 적재된 데이터량이 많고, 개발자들이 테스트를 진행하여 더 다양한 유즈케이스를 커버한다.
    • 개발자간 데이터를 주고 받을 필요없이 마음껏 단일 Develop DB에 적재할 수 있다.
    • 로컬에서 개발을 완료했다는 것은 개발자 개인이 수행해볼 수 있는 최대한의 유즈케이스를 커버했다는 뜻이다.
  • Staging Zone : 운영 존에 가장 가까운 환경으로 최종 배포 전 네트워크 및 인프라 환경에 대한 마지막 테스트
    • Staging Zone DB : 운영존과 가장 가까운 수준의 데이터량을 적재
    • 일반적으로 Develop Zone과 Production Zone의 DB에 적재된 데이터량의 편차가 심하다
  • Production Zone : 실제 유저가 사용하는 환경에서 개발 및 수정 등에 신중해야하며, 제약이 심하다.
    • Production Zone DB : 실제 유저가 사용하는 운영 DB
    • 데이터베이스에 대한 ALTER 명령어는 매우 신중해야 한다.

Git 브랜치 전략 (git-flow)

원칙은 모든 배포는 격리된 브랜치에서 작업을 완료한 뒤, PR을 통해 배포를 위한 브랜치에 머지해야 한다.

중요도에 따라 3가지 타입의 브랜치로 나눈다.

  • Master / Main : 배포 브랜치
    • 버그 발생에 대한 불확실성이 낮고, 무결하여 운영존에 치명적 문제 발생 시 롤백할 수 있는 커밋 집합
  • Develop (Staging) : 테스트 브랜치
    • 테스트의 의미는 로컬에서 테스트 및 개발을 완료한 뒤 마지막 테스트를 하는 것을 의미한다.
    • Staging Zone을 위한 Staging 브랜치를 따로 또 둘 수 있지만 조금은 과할 수 있다.
  • Feature : 개발 브랜지 - Develop브랜치를 기점으로 새 브랜치를 만들어서 개발함
    1. feature/HELLO-001 : 기획과 디자인에 따라 개발자에게 발행된 티켓으로 브랜치명을 설정
    2. feature/login-with-oauth : 어떤 작업인지 바로 알 수 있도록, 기능 내용에 대한 요약 브랜치명(추가적으로 개발자 이름을 붙여넣기도 함)

 

추가적으로 Git Commit 메세지의 경우 그냥 막 적는 것이 아니라 주어진 작업과 설명을 명확히 적어야 한다.

'Git' 카테고리의 다른 글

[Git] Git 구조와 용어  (0) 2024.01.17