깃(Git)을 공부 하기 전에는 git = github 이라고 생각했지만 사용하고자 하는 용도가 많이 달랐습니다. 다른 자료들을 참고하여 공부 한 내용을 다시한번 복습하며 정리 해보려고 합니다.
깃(Git)은 버전 관리 시스템(VCS, Version Control Systems) 중 하나 입니다.
여러명의 개발자가 프로젝트에 참여할 때, 폴더, 파일들의 버전 관리를 위해 사용됩니다.
버전 관리 시스템(VCS)이란?
버전 관리 시스템(VCS, Version Control System) 은 파일 변화를 시간에 따라 기록하며 특정 시점의 버전을 다시 불러올 수 있는 시스템을 의미합니다.
파일을 이전 상태로 되돌릴 수 있고, 변경 사항을 비교하며, 변경한 사람 및 변경 시기를 추적할 수 있습니다.
Git은 분산 버전 관리 시스템(DVCS) 입니다.
1. 로컬 버전관리(Local VCS)
Local VCS 는 간단한 데이터베이스를 사용해서 파일의 변경 정보를 관리하며 로컬 컴퓨터에서 파일을 관리하는 방식으로 동작합니다.
2. 중앙집중식 버전 관리 시스템(CVCS)
CVCS(Centralized VCS) 는 파일을 관리하는 서버가 별도로 존재하고 클라이언트가 중앙 서버에서 파일을 받아서 사용합니다.
3. 분산 버전관리 시스템 (DVCS)
DVCS(Distributed VCS) 는 클라이언트가 파일의 마지막 스냅샷을 사용하지 않고 저장소를 히스토리와 더불어 전부 복제합니다.
서버에 문제가 생기면 이 복제물로 다시 작업을 할 수 있고 클라이언트 중에서 아무거나 골라도 서버를 복원할 수 있습니다.
깃(Git)의 장점
깃(Git)은 브랜치(branch)와 병합(marge)이 있으며, 트리 구조 작업이 가능합니다. 브랜치는 가지(branch) 라고 볼 수 있으며 나무에서 여러 갈래로 가지가 뻗어나가는 것처럼, 소스코드도 여러 개의 가지로 뻗어나갈 수 있습니다.
깃은 인터넷 연결이 되지 않는 곳에서도 개발 진행을 할 수 있으며, 분산 버전관리 이기 때문에 중앙 저장소가 삭제되어도 원상복구가 가능합니다.
소스코드를 주고 받을 필요 없이, 같은 파일을 여러명이 동시에 작업하는 병렬 개발이 가능합니다.
깃은 거의 모든 동작이 로컬에서 진행되기 때문에 다른 VCS 처럼 서버와의 통신에 많은 비용을 들이지 않으며 C언어로 작성되어 있어서 속도가 빠릅니다.
Git 관련 용어
Repository : 저장소를 의미하며, 저장소는 히스토리, 태그, 소스의 가지치기 혹은 브랜치(Branch)에 따라 버전을 저장합니다. 저장소를 통해 작업자가 변경한 모든 히스토리를 확인할 수 있습니다.
Working Tree : 현재 작업이 일어나는 작업자의 현재 시점 입니다.
Staging Area : 저장소에 커밋하기 전 커밋을 준비하는 위치 입니다.
Commit : 현재 변경된 작업 상태 점검을 마치면 확정하고 저장소에 저장하는 작업 입니다.
Head : 현재 작업중인 브랜치의 최근 커밋된 위치 입니다.
Merge : 다른 브랜치의 내용을 현재 브랜치로 가져와 합치는 작업을 의미합니다.
Branch : 가지 또는 분기점을 의미하며, 작업을 할 때 현재 상태를 복사하여 브랜치에서 작업을 한 후 완전하다 싶을 때 병합(Merge)을 하여 작업을 진행합니다.
Git은 3가지 종류의 작업 영역을 가지고 있습니다.
1. Working Directory
Working Directory는 사용자의 작업 공간으로, 로컬 저장소에 접근할 수 있으며 실제 파일을 수정하거나 생성하는 공간 입니다.
작업 폴더에서 .git 디렉토리를 제외한 나머지 부분 입니다.
현재 작업중인 소스코드를 담고 있으며, 워킹 디렉토리 내부의 파일만 접근 및 수정이 가능합니다.
워킹 트리, 워킹 디렉토리, 작업 디렉토리 등으로 불립니다.
워킹 디렉토리에서는 파일들을 추적(tracked)/비추적(untracked) 상태로 구분합니다.
1. 비추적(untracked) 상태
저장소 내에서 새로 만들어진 모든 파일들은 untracked 상태로 시작합니다.
untracked 상태인 저장소 내의 파일들은 git이 코드 변경 이력을 추적하지 않습니다.
2. 추적(tracked) 상태
tracked 상태의 파일들은 git에 의해서 파일의 변경 이력이 추적됩니다.
모든 파일들의 변경 이력을 추적할 경우에는 시스템의 부하가 커지게 되므로 git에서는 요청받은 파일들만 변경 이력을 추적합니다.
2. Staging Area
Staging Area는 워킹 디렉토리에서 제출된 tracked 상태의 파일들을 관리 및 임시로 저장하는 공간 입니다.
스테이지 영역에서는 파일의 콘텐츠 내용을 직접 가지고 있는 것이 아닌, 커밋하려는 파일의 추적 상태 정보들만 기록 합니다.
스테이지가 만들어진 이유는 커밋을 빠르게 처리하기 위함 입니다.
스테이지 내의 파일들은 stage/unstage 상태로 구분합니다.
1. stage 상태
stage 영역에 들어온 파일들은 tracked 상태의 파일 입니다.
stage 영역에서 나간 파일들은 untracked 상태의 파일 입니다.
깃이 변화 이력을 기록하기 위해서는, 파일의 초종 상태가 반드시 stage 상태가 되어야 합니다.
2. unstage 상태
파일 내에 변화가 있을 경우 해당 파일은 unstage 상태가 됩니다.
워킹 디렉토리에서의 파일과 스테이지 영역에서의 파일 간 내용 차이가 존재한다면, 해당 파일은 unstage 상태 입니다.
스테이지 영역으로 등록하지 않은 워킹 디렉토리의 파일들도 unstage 상태로 볼 수 있습니다. (untracked & unstage)
3. Repository
Git은 작성한 소스코드 파일의 모든 변경 사항을 관리하며, 파일들의 변경 내역을 저장소(Repository)에 저장 합니다.
저장소는 로컬 저장소와 원격 저장소로 나누어 집니다.
로컬 저장소(Local Repository): 내 PC에 파일이 저장되는 개인 전용 저장소 입니다.
원격 저장소(Remote Repository): 파일이 원격 저장소 전용 서버에서 관리되며 여러 사람이 함께 공유하기 위한 저장소입니다.
Git-flow 는 Git으로 개발 할 때 표준과 같이 사용되는 브랜치(Branch) 전략 입니다.
Git-flow 는 기능이 아닌 서로간의 약속인 방법론 이며 개발 환경에 따라 수정 및 변형해서 사용하면 됩니다.
Git Flow 브랜치 종류
Master : 기준이 되는 브랜치로 제품을 배포하는 브랜치 입니다.
Hotfix : master 브랜치로 배포를 했는데 버그가 생길 시 긴급 수정하는 브랜치 입니다.
Release : 배포를 위해 master 브랜치로 보내기 전 먼저 QA(품질검사)를 하기위한 브랜치 입니다.
develop : 개발 브랜치로 개발자들이 브랜치를 기준으로 각자 작업한 기능들을 병합(Merge)합니다.
feature : 단위 기능을 개발하는 브랜치로 기능 개발이 완료되면 develop 브랜치에 병합 합니다.
master , develop 두가지가 중요한 매인 브랜치이고 나머지는 필요에 의해서 운영하는 브랜치 입니다.
1. Master Branch
Master Branch는 제품으로 출시될 수 있는 브랜치 입니다.
배포(Release) 이력을 관리하기 위해 사용하며 배포 가능한 상태만 관리합니다.
2. Develop Branch
Develop Branch는 다음 출시 버전을 개발하는 브랜치 입니다.
기능 개발을 위한 브랜치들을 병합하기 위해 사용 되며 모든 기능이 추가되고 버그가 수정되어 배포 가능한 상태라면 develop 브랜치를 master 브랜치에 병합(Merge) 합니다.
3. Feature Branch
Feature Branch는 기능을 개발하는 브랜치 입니다.
feature 브랜치는 새로운 기능 개발 및 버그 수정이 필요할 때마다 develop 브랜치로부터 분기합니다.
feature 브랜치에서의 작업은 기본적으로 공유할 필요가 없기 때문에, 자신의 로컬 저장소에서 관리하며 개발이 완료되면 develop 브랜치로 병합하여 다른 사람들과 공유합니다.
✍🏻 작업 과정
1. develop 브랜치에서 새로운 기능에 대한 feature 브랜치를 분기합니다.
2. 새로운 기능에 대한 작업을 수행합니다.
3. 작업이 끝나면 develop 브랜치로 병합합니다.
4. 더 이상 필요하지 않은 feature 브랜치는 삭제합니다.
5. 새로운 기능에 대한 feature 브랜치를 중앙 원격 저장소에 올립니다. (push)
4. Release Branch
Release Branch는 이전 출시 버전을 준비하는 브랜치 입니다.
배포를 위한 전용 브랜치를 사용함으로써 한 팀이 해당 배포를 준비하는 동안 다른팀은 다음 배포를 위한 기능 개발을 계속할 수 있습니다.
✍🏻 작업 과정
1. develop 브랜치에서 배포할 수 있는 수준의 기능이 모이면, 정해진 배포 일정이 되면 release 브랜치를 분기한다.
release 브랜치를 만드는 순간부터 배포 사이클이 시작됩니다.
release 브랜치에서는 배포를 위한 최종적인 버그 수정, 문서 추가 등 release와 직접적으로 관련된 작업을 수행합니다.
직접적으로 관련된 작업들을 제외하고는 release 브랜치에서 새로운 기능을 추가로 병합하지 않습니다.
2. release 브랜치에서 배포 가능한 상태가 되면 (배포 준비가 완료 되면)
master 브랜치에 병합합니다.
3. 배포를 준비하는 동안 release 브랜치가 변경되었을 수 있으므로 배포 완료 후 develop 브랜치에도 병합합니다.
4. 다음 배포(Release)를 위한 개발 작업은 develop 브랜치에서 게속 진행합니다.
5. Hotfix Branch
Hotfix Branch는 출시 버전에서 발생한 버그를 수정하는 브랜치 입니다.
배포한 버전에 긴급하게 수정을 해야 할 필요가 있을 경우, master 브랜치에서 분기하는 브랜치 입니다.
develop 브랜치에서 문제가 되는 부분을 수정하여 배포 가능한 버전을 만들기에는 시간도 많이 소요되고 안정성을 보장하기도 어려우므로 바로 배포가 가능한 master 브랜치에서 직접 브랜치를 만들어 필요한 부분만 수정한 후 다시 master 브랜치에 병합하여 배포 하는 것 입니다.
# 현재 directory 의 모든 파일을 Staging Area 로 이동
git add .
# Staging 된 파일들 commit 하기
git commit -m "message"
# 저장소에 commit 반영 하기
git push <remote> <branch>
# 저장소에서 commit 가지고 오기
git pull <remote> <branch> // 기본적으로 origin을 원격 저장소, main 브랜치를 사용합니다.
# file 들의 tracking 상태 보기
git status
# commit 히스토리 보기
git log
# 새로운 저장소 초기화 하기
git init
# 전역 사용자명/이메일 구성하기
git config --global user.name "Your name" git config --global user.email "Your email address"
# 저장소별 사용자명/이메일 구성하기 (해당 저장소 디렉토리 이동 후)
git config user.name "Your name" git config user.email "Your email"
# 전역 설정 정보 조회
git config --global --list
# 저장소별 설정 정보 조회
git config --list
# 새로운 저장소 초기화 하기
git remote add <원격저장소> <저장소 url>
아래 명령어에서 [ ]는 선택적인 매개변수를 의미합니다.
# 새로운 파일을 추가하거나 존재하는 파일 스테이징 및 커밋하기
git add <파일명> git commit -m <메세지>
# 파일의 일부를 스테이징 하기
git add -p [<파일>] [<파일>]
# 수정되고 추적되는 모든 파일의 변경 사항 커밋하기
git commit -m <메세지> -a
# 작업 트리의 변경 사항 돌려놓기
git checkout HEAD <파일> [<파일>]
# 커밋되지 않고 스테이징 된 변경 사항 재설정 하기
git reset HEAD <파일> <[파일]>
# 마지막 커밋 고치기
git commit -m <메세지> --amend
# 커밋되지 않고 스테이징 된 변경 사항 재설정 하기
git reset HEAD <파일> <[파일]>
# 지역 브랜치 목록 보기
git branch
# 원격 브랜치 목록 보기
git branch -r
# 지역과 원격을 포함한 모든 브랜치 목록 보기
git branch -a
# 현재 브랜치에서 새로운 브랜치 생성하기
git branch <새로운 브랜치>
# 다른 브랜치로 옮기기
git switch <브랜치>
# 다른 시작 지점에서 브랜치 생성하기
git branch <새로운 브랜치> <브랜치를 생성할 위치>
# 기존의 브랜치를 새로운 브랜치로 덮어쓰기
git branch -f <기존 브랜치> [<브랜치를 생성할 위치>]
# 다른 브랜치를 현재 브랜치로 합치기
git merge <브랜치>
# 커밋하지 않고 합치기
git merge --no-commit <브랜치>
# 브랜치 삭제하기
git branch -d <삭제할 브랜치>
# 원격 브랜치 삭제하기
git push origin -d <삭제할 브랜치>
# 모든 이력 보기
git log
# 변경 사항을 보여주는 패치와 함께 로그 표시하기
git log -p
# 1개의 항목만 보이도록 로그 개수 제한하기
git log -1
# 20개의 항목과 패치만 보이도록 로그 제한하기
git log -20 -p
# 1개의 항목만 보이도록 로그 개수 제한하기
git log -1
# 각 항목의 로그 이력 한 줄씩 보기
git log --pretty=oneline
# 각 항목마다 영향 받은 줄의 통계 보기
git log --stat
# 커밋할 시점의 파일 상태 보기
git log --name-status
# 현재 작업 트리와 인덱스의 차이점 보기
git diff
# 인덱스와 저장소의 차이점 보기
git diff --cached
# 작업 트리와 저장소의 차이점 보기
git diff HEAD
# 현재 작업 트리와 인덱스의 차이점 보기
git diff
# 파일의 커밋 정보 줄 단위로 보기
git blame <파일>
# 저장소 복제하기
git clone <저장소>
# 새로운 원격 저장소 추가하기
git remote add <원격 저장소> <저장소 url>
# origin 저장소에서 합치지 않고 지역 브랜치로 변경 사항 가져오기
git fetch
# 원격 저장소에서 합치지 않고 지역 브랜치로 변경 사항 가져오기
git fetch <원격 저장소>
# origin 저장소에서 합치지 않고 지역 브랜치로 변경 사항 가져오기
git fetch
# origin 저장소에서 변경 사항을 가져와 현재 브랜치에 합치기
git pull
# 로컬 브랜치를 원격 저장소에 푸시 하기
git push <원격 저장소> <지역 브랜치>
# 원격 저장소에서 사용 안하는 원격 브랜치 제거하기
git remote prune <원격 저장소>
# 원격 저장소를 제거하고 관련되 브랜치도 제거하기
git remote rm <원격 저장소>
References
훌륭합니다 역시 프론트의 장인