0. 로컬 코드 및 협업 시 문제 관리
우리는 여러가지 파일을 생성하고 변경한다.
이때, 최종, 최최종, 찐최종, 찐찐최종... 등 다양한 이름으로 파일을 구분하면서 계속해서 변경하고는 한다.
이러한 파일(코드)를 관리하는 과정과 어떤 방법으로 파일을 수정하고 저장하고 관리하는지 아래의 그림을 통해 확인해보자
- 로컬 코드 관리
- 다양한 버전 : 하나의 코드(파일)에서 다양한 케이스의 구현을 테스트 해볼 때
- 히스토리 추적 : 작업 시 문제 발생했을 때 직전 버전으로 롤백
- 안전히 원격 저장 : 만약 내 노트북(or usb 등)이 도난 당한다면?
- 협업 관리 : 하나의 프로젝트(파일)에 참여하는 사람이 많아진다면 어떻게 관리해야 할까?
- 만약 내가 어떤 변경사항이 있는데 다른 사람도 그것에 대해서 다르게 바꿨다면????
1. 로컬 코드 관리 : Git & 협업 관리 : Github
- Local Repositoy와 Remote Repository의 차이는 무엇일까?
- Git(Local Repository) : 로컬 코드(파일) 관리
- 다양한 버전 : 로컬에서 작업한 내용을 적용
- 히스토리 추적 : 이전 작업(적용내용) 확인
- 안전하게 원격 저장 가능 : 로컬 작업물을 모두 원격으로 백업 간으
- Github(Remote Repository) : 협업 관리
- 다른 사람과 함께 작업 할 때 다른 사람의 작업물이 적용된 최신 작업물을 이어 받아 작업 가능
- Conflict 충돌이 발생한다는 것은 위의 그림처럼 같은 기준을 바라보며 작업을 진행했을 때 생길 수 있다.
- 아래의 그림처럼 같은 기준을 바라보며 생길 수 있는 Conflict의 문제가 있다.
- 이러한 2개의 Conflict 충돌에 대한 해결책
- Rebase : 현재 내 작업물의 (기준이 되는) ①Base를 다시 재설정 한뒤, ②다시 커밋을 쌓는다.
- 단점 : 내가 작업했던 커밋들이 다시 생성되기에, 히스토리가 리셋된다.
- Merge : 현재 내 작업물과 Remote에 업로드 되어있는 상대 작업물 모두 존중하고, 머지 커밋을 만든다.
- 단점 : 머지 커밋이 덕지덕지 생성되어 머지 수가 많아져 작업별로 커밋을 쌓기 힘들다.
- Rebase : 현재 내 작업물의 (기준이 되는) ①Base를 다시 재설정 한뒤, ②다시 커밋을 쌓는다.
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 조회 가능
- Git을 시작할 때 다음과 같이 Repository 구성에서 시작한다.
- 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)로 올린다.
- 4. Staging Area, Index (2) : Commit 되기위해 대기중인 파일들(대기조)
- Untracked(4) : Git 이 추적하지 않는 파일들의 집합
- Tracked
- Working Directory (1)
5. Git 구조 (영역) 의미 및 용례
Working Directory 작업 공간 : 로컬 공간에서 작업할 브랜치 선택하기
- 브랜치 선택(이동) : git checkout ba
- 브랜치 새로 생성 후 선택(이동) : git checkout -b be
- -b : branch creating
Remote Repository 에서 최신 브랜치 가져오기 : Pull = Fetch + Merge
- 기본적인 Merge 종류
- Fast-Forward
- 3-Way Merge
- Squash Merge
- Fast-Forward : Remote 에 내 작업과 겹치는 어떠한 타인의 작업도 없을때, 그대로 이어 붙이기
- 3-Way Merge : Remote 에 있는 타인의 작업 그대로, 내 작업 그대로 보존하고 머지 커밋 생성
- Squash Merge : Remote 에 있는 타인의 작업 기준으로 다시 내가 작업하여 하나의 커밋으로 뭉쳐 생성
Local Repository 내 파일 조작(삭제, 추가, 수정) 시나리오 별 Git 영역에 파일 적재 방법
파일 삭제 시나리오 (deleted ↔ untrackted) : Git RM
- Git이 추적하고 있는 파일 중 삭제
- git rm <File> : Staging Area로 바로 올려서 Commit 시 바로 삭제될 수 있도록
- = Git Repository에서 삭제 예정(Staging) + Local에서 삭제
- 파일을 그냥 삭제하는 경우 (마우스 우클릭, 리눅스 명령어) : Unstaged에 올려 한번 검토 요청
- = Git Repository에서 삭제 검토 (Unstaged) + Local에서 삭제
- git rm -- cached <File> : Staging Area로 바로 올림과 동시에 Untracked에 올려 나만 보기
- Git Repository에서 삭제 예정 (Staging) + Local에서 사용
- Git에서만 확실하게 없애고, 로컬에서는 나만 사용할 파일에 사용
- 민감 정보가 포함되어 있는 Credential이나 .env와 같은 개인 설정 파일들
- git rm <File> : Staging Area로 바로 올려서 Commit 시 바로 삭제될 수 있도록
파일 추가 시나리오 (new file ↔ untrackted)
- 파일을 그냥 추가하는 경우 : Git이 전혀 알지 못하는 새로운 파일이라 Untracked에 추가됨
- Untracked 내 이 파일을 나만 로컬에서 쓸건지? Git에 등록할 것인지 검토 필요
- 나만 써야하는 파일이라면 → Untracked 내 추가된 상태로 사용(.gitignore를 통해 무시해야함)
- Git에 등록할 것이라면 Staging Area로 전달(git add를 통해)
- Untracked 내 이 파일을 나만 로컬에서 쓸건지? Git에 등록할 것인지 검토 필요
파일 수정 시나리오
여기서 '수정'의 정의는 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의 수정이 필요할 때 어떤 방법으로 수정해야 할까?
- 단일 문제 발생 : 바로 직전 커밋을 수정해야 할 때
- 간단 수정 : Ammend - git commit --amend
- 다시 생성(롤백) : Reset - git reset HEAD~1
- --soft : Staging Area로 보낸다.
- --mixed(Default) : Unstaged/Untracked(기존 상태)로 보낸다.
- --hard : 완전히 없애고 전의 상태로 돌아간다.
- 단방향으로만 수정 가능하다(git reset HEAD~3 : 3번째 전으로 3개의 커밋 모두 롤백)
- HEAD의 상대 표현법
- ~(Tilde) : N번째 조상 - 수직
- ^(Caret) : N번째 부모 - 수평
- @(At-sign) : Reflog
- 다수 문제 발생 : 이전 커밋들을 다시 재정의할때
- 다시 생성 : Rebase - git rebase -i HEAD~3
- Cherry-Picking 가능
- 예를 들어, 총 5개의 커밋 중 2개는 지우고, 2개는 합치고 1개는 살리고
- Reword : 커밋 메시지 변경
- Edit : 커밋 내용 변경 및 충돌 발생 시 추가 작업을 위한 Rebase 작업
- Drop : 커밋 빼기
- Squash : 불필요하게 많아진 커밋의 수를 줄이기 위해 몇개의 커밋을 합치기
- 다시 생성 : Rebase - git rebase -i HEAD~3
- 날려먹었을 때 : 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브랜치를 기점으로 새 브랜치를 만들어서 개발함
- feature/HELLO-001 : 기획과 디자인에 따라 개발자에게 발행된 티켓으로 브랜치명을 설정
- feature/login-with-oauth : 어떤 작업인지 바로 알 수 있도록, 기능 내용에 대한 요약 브랜치명(추가적으로 개발자 이름을 붙여넣기도 함)
추가적으로 Git Commit 메세지의 경우 그냥 막 적는 것이 아니라 주어진 작업과 설명을 명확히 적어야 한다.
'Git' 카테고리의 다른 글
[Git] Git 구조와 용어 (0) | 2024.01.17 |
---|