기초
버전 관리 도구 Git에 대해 알아보자
들어가기에 앞서 버전 관리란 무엇이며, 왜 해야 하는 걸까?
대개 단순히 변경 내용을 저장하면 이전 내용에서 현재 내용으로 덮어쓰게 된다. 이러한 방법의 문제점은 변경 내역을 확인하기 어렵고, 버전을 되돌리기 어렵고, 협력하기 어렵다. Git은 이 모든 것을 가능하게 한다.
버전 관리
버전이 만들어지는 과정을 이해하기 위해서 Git이 관리하는 세 개의 공간을 살펴보자.
Git이 관리하는 공간
1. 작업 디렉터리 (working directory)
로컬 저장소를 만들면 .git 이라는 숨김 폴더가 생성된다. 이 폴더가 놓인 곳이 프로젝트가 위치할 공간이다. 즉, 작업 디렉터리는 버전 관리의 대상이 위치하는 공간이다.
// 로컬 저장소 만들기
git init
// 작업 디렉터리 상태 확인
git status
상태 확인 결과
on branch master -> master 브랜치에 있다.
no commits yet -> 현재 아무런 커밋도 하지 않았다.
Untracked filed -> 깃이 기존에 변경 사항을 추적하지 않은 대상
modified : a.txt -> a.txt 파일이 수정되었다.
2. 스테이지 (stage)
만약 작업 디렉터리에 100개의 파일이 생성되거나 수정되거나 삭제되었을 때 모든 변경사항이 꼭 새로운 버전이 되어야 하는가? 그건 아니다.
변경된 파일 중에서 새로운 버전이 될 파일만 스테이지라는 공간으로 옮기게 된다. 즉, 변경 사항이 있는 파일 중 다음 버전 후보가 올라가는 공간인 것이다. 스테이지로 옮기는 것을 '스테이지에 추가한다(add)' 또는 '해당 파일을 스테이지시킨다(staged)'라고 표현한다.
// 스테이지에 올리기
git add a.txt // a.txt 파일을 스테이지에 추가
git add . // 한꺼번에 추가
git status 명령어로 상태를 확인했을 때 changes to be committed 항목에 추가한 항목기 표기됐다면 정상적으로 스테이지에 추가된 것이다.
3. 저장소 (repository)
스테이지에 있는 파일을 바탕으로 새로운 버전을 만들면 새 버전이 저장소에 추가된다. 작업 디렉터리에서 만들어진 모든 버전들의 내역이 저장소에 위치해 있다. 즉, 저장소는 버전이 만들어지고 관리되는 공간이다. 저장소에 새로운 버전을 만드는 것을 '커밋한다(commit)'라고 표현한다. 이후 스테이지는 깨끗하게 비워진다.
// 커밋하기
git commit -m "커밋 메시지"
git commit -am "커밋 메시지" // git add + git commit
"커밋 메시지"는 제목을 나타낸다. 본문까지 작성하고 싶다면 git commit 명령어를 사용한다.
// 저장소의 커밋 목록 출력 (커밋 해시, 만든 사람, 커밋 날짜, 커밋 메시지)
git log // 현재 브랜치의 버전 내역을 확인
git log --online // 커밋 목록을 단순한 형태로
git log --patch // 해당 커밋으로 어떤 파일이 어떻게 수정되었는지
git log --graph // 각 커밋을 그래프 형태로 출력
git log --branches // 현재 브랜치가 아닌 모든 브랜치의 커밋 목록
.gitigmore로 무시하기
git이 무시할 파일/폴더 목록을 적는 파일이다.
커밋 해시
프로젝트는 무수히 많은 커밋이 모여 만들어진다. 각각의 커밋을 구분하는 값이 커밋 해시이다.
태그를 붙여 릴리스하기
새로운 기능을 추가하는 커밋도 있고, 버그를 수정하는 커밋도 있고, 아주 사소한 변경 사항만 담은 커밋도 있을 것이다. 그러다가 충분히 개발되었다고 판단되면 사용자에게 결과물을 선보일 것이다. 이를 릴리스(release)라고 한다.
이때 사용자에게 선보일 서비스의 버전은 어떻게 나타내는 것이 좋을까?
커밋 해시는 무작위한 문자열과 같아서 가독성이 좋지 못하다. 이럴 때 사용할 수 있는 것이 태그(tag)이다. 릴리스되는 커밋에 태그를 붙인다면 커밋이 여러개 있는 상황에서도 의미 있는 커밋이 무엇인지 한눈에 알아보기 쉽다.
보통 릴리스 버전은 숫자 세 개로 표현한다.
vX. Y. Z
가장 앞에 나오는 숫자는 주(major)버전이라고 부른다. 일반적으로 새롭게 내놓은 버전이 기존에 내놓은 버전과 호환되지 않을 정도로 큰 변화가 있을 때 증가시킨다.
두번째 숫자는 부 (minor)버전이라고 부른다. 일반적으로 앞 버전과 문제없이 호환되지만 새로운 기능을 추가했을 때 증가한다.
마지막 숫자는 수(patch)버전이라 한다. 버그를 수정한 정도의 작은 변화가 있을 때 증가한다.
// 태그 추가/조회/삭제
git tag <태그> // HEAD가 가리키는 커밋에 태그를 붙임
git tag <태그> <커밋 해시> // 특정 커밋에 태그
git tag --list // 태그 조회
git tag --delete <태그> // 태그 삭제
버전 비교하기
git diff // 최근 커밋과 작업 디렉터리 비교하기
git diff --staged // 최근 커밋과 스테이지 비교하기
git diff <커밋> <커밋> // 커밋끼리 비교하기 (첫 번째 커밋을 기준으로 두 번째 커밋이 달라진 점)
매번 커밋 해시를 조회하고 붙여넣는 것이 번거롭다면 HEAD를 기준으로 비교하는 방법도 있다.
HEAD 뒤에 붙는 ^의 개수 또는 HEAD~ 뒤에 붙는 숫자는 HEAD에서 몇 번째 이전을 나타내는지를 의미한다. 예를 들어 HEAD^ 또는 HEAD~1은 현재 브랜치의 최신 커밋에서 하나 이전 커밋을 가리킨다. HEAD^^ 또는 HEAD~2는 최신 커밋에서 두 개 이전 커밋을 가리킨다.
git diff HEAD^ HEAD // 바로 이전 커밋을 기준으로 가장 최신 커밋 비교
// 브랜치끼리 비교하기
git diff <기준이 되는 브랜치> <기준과 비교할 브랜치>
git diff master foo // master 브랜치를 기준으로 foo 브랜치가 달라진 점 확인
작업 되돌리기
1. 스테이지로 올리지 않은 변경된 파일 취소하기
git restore <파일>
2. 스테이지로 올라간 파일 취소하기
해당 파일을 스테이지에서 제거한다. (수정한 내용은 작업 디렉토리에 남아있다.)
git restore --staged <파일>
3. 이미 커밋한 파일 취소하기
revert
버전을 되돌리되, 되돌아간 상태에 대한 새로운 버전(커밋)을 만드는 방식
기존의 버전은 삭제되지 않는다.
git revert <취소할 커밋>
reset
되돌아갈 버전의 시점으로 완전히 되돌아가는 방식
되돌아갈 이후의 버전은 삭제된다.
reset에는 세 종류가 있다.
soft : 작업 디렉터리 내 변경 사항과 스테이지에 추가된 변경사항은 유지하고, 커밋했다는 사실만 되돌리는 방법
mixed : 작업 디렉터리 내 변경 사항은 유지하고, 스테이지와 커밋을 되돌리는 방법
hard : 작업 디렉터리 내 변경사항까지 통째로 되돌리는 방식
git reset <되돌아갈 커밋>
git reset --soft <되돌아갈 커밋>
git reset --mixed <되돌아갈 커밋> // 기본
git reset --hard <되돌아갈 커밋>
물론 여기서도 HEAD^ 또는 HEAD~1을 사용해도 된다.
스태시(stash)로 작업 임시 저장하기
작업 내역이 썩 마음에 들진 않지만 버리기는 아까울 때, 갑자기 다른 중요한 일을 처리해야 할 때 사용할 수 있는 기능이다.
스태시를 하게 되면 작업 디렉터리에서 생성한 모든 변경 사항이 임시 저장되고, 작업 디렉터리는 변경 사항이 생기기 전의 깨끗한 상태로 돌아간다.
git stash // 변경 사항 임시 저장
git stash -m "메시지" // 메시지와 함께 임시저장
git stash list // 임시 저장한 내역 조회하기 (가장 작은 번호가 가장 최근에 저장된 항목)
git stash apply <스태시> // 임시 저장한 작업 적용하기
git stash drop <스태시> // 임시 저장한 작업 삭제하기
git stash clear // 임시 저장한 작업 전부 삭제
stash@{0}을 적용하려면 git stash apply stash@{0} 스태시 이름을 명시하지 않으면 가장 최근에 임시 저장한 항목, 즉 stash@{0}이 적용
stash@{0}을 삭제하려면 git stash drop stash@{0} stash@{1}이 있다면 이는 stash@{0}이 된다.
참고 문헌
강민철. 『모두의 깃 & 깃허브』. 길벗, 2022.
Last updated