Git&GitHub
깃(Git)은 버전 관리 시스템으로 우리가 쉽게 버전을 관리할 수 있도록 도와주는 하나의 버전 도구입니다. 평소 약간의 깃 명령어를 숙지하고 사용하던 나에게 가끔 마주치는 Git 에러는 머리 아픈 골칫거리였습니다. 그럴 때마다 나는 버전에 대한 이해가 부족하다는 것을 느꼈지만 당장 큰 문제는 아니었기에 쉬쉬했었습니다. 하지만 이번에 RPG 게임에서 내실을 다지는 것처럼 버전에 대한 개념을 올바르게 배우고자 합니다. 그리고 앞으로 쓸 글은 내가 공부했던 것에 대한 기록입니다. 시중에 판매하는 “모두의 깃&깃허브”라는 책으로 공부했습니다.
버전 관리 공간
깃은 세 개의 분리된 공간을 이용하여 버전을 관리합니다. 작업 디렉터리(working directroty), 스테이지(stage), 저장소(repository)로 사용자마다 부르는 명칭이 다를 수도 있습니다.
먼저 작업 디렉터리는 우리가 개발하는 공간입니다. 파일 또는 폴더를 수정, 삭제, 생성하는 곳입니다. 다음으로 스테이지 공간은 책의 글을 빌려서 적자면 다음 버전이 될 후보가 올라가는 곳입니다. 작업 디렉터리에서 굳이 새로운 버전으로 만들 필요가 없는 파일이 존재할 수도 있습니다. 그래서 새로운 버전의 항목이 될 파일들을 작업 디렉터리에서 선별하고 스테이지로 옮깁니다. 마지막으로 저장소는 버전이 만들어지고 관리되는 공간입니다. 추가적으로 저장소와 스테이지는 사용자에게 명시적으로 보이지 않습니다.
git bash 프로그램에서 자주 쓰는 명령어인 add, commit 명렁어는 파일들을 스테이지, 저장소로 옮기는 커맨드입니다. 우선 add는 작업 디렉터리에서 버전으로 만들고 싶은 파일들을 선택해서 스테이지로 옮깁니다. 이때 스테이지로 올라간 파일들은 추적 대상(tracked file)이 됩니다. 다음으로 commit은 저장소에 새로운 버전을 만드는 명령어로 흔히 ‘커밋한다’라고 표현합니다. 사용자들 사이에서는 버전을 커밋으로 대체해서 말하기도 합니다. 커밋할 때, 메세지를 낢길 수 있습니다. 이때 제목, 본문을 적어 버전에 대한 설명을 명시할 수도 있습니다. 이때 제목과 본문은 한 줄 띄어서 적습니다.
커밋에는 고유한 커밋 해쉬가 있습니다. 사용자는 커밋 해쉬를 이용해서 버전을 비교하고, 되돌리고, 삭제합니다. 커밋이 여러 개 쌓이다 보면 커밋 해쉬와 커밋 메세지를 보고 원하는 커밋을 찾는 것은 힘들고 비효율적입니다. 그래서 태그를 붙여 중요한 커밋(버전)을 구분합니다. 흔히 vX.Y.Z 로 표시되며 X영역은 주 버전이라고 부르고, 일반적으로 새롭게 내놓은 버전이 기존에 내놓은 버전과 호환되지 않을 정도로 큰 변화가 있을 때 증가합니다.
Y영역은 부 버전이라 부르고, 새로운 기능이 추가했을 때등 증가합니다. Z영역은 수(Patch) 버전이라 부르고, 버그를 수정한 정도의 작은 변화가 있을 때 증가합니다.
.gitignore이라는 파일은 작업 디렉터리에서 스테이지로 옮길 파일들 중에서 무시할 파일들의 목록을 적는 파일입니다.
버전 비교 되돌리기 스태쉬
깃을 사용하면 .git파일 History에 이전에 커밋된 버전들의 정보가 저장되어 있습니다. 그래서 사용자는 많이 쌓여있는 커밋들을 비교하거나 이 전의 커밋으로 되돌릴 수 있습니다. 또한 스태쉬를 이용하여 ctrl + c를 사용해서 캐시 보드에 저장하는 것과 비슷하게 작업 내용들을 임시 저장할 수 있습니다.
비교
말 그대로 최근 커밋과 스테이지 또는 작업 디렉터리를 비교합니다. 혹은 커밋과 커밋, 브랜치와 브랜치를 비교할 수도 있습니다. Git 명령어로는 git diff 명령어가 있고 옵션을 선택해서 비교 대상을 설정할 수 있습니다. git diff, git diff –staged, git diff <커밋> <커밋>, git diff <브랜치> <브랜치>이 있습니다.
브랜치>브랜치>커밋>커밋>
되돌리기
변경 사항, 버전을 되돌리는 방법은 크게 두 개가 있습니다. reset과 revert가 있습니다.
먼저, reset은 soft, mixed, hard가 있습니다. 하나의 커밋(버전)을 만들기 위해서 올리고 싶은 파일은 작업 디렉터리에서 스테이지, 스테이지에서 저장소로 두 번의 이동 과정이 필요합니다. 먼저 soft는 커밋만 되돌립니다. mixed는 스테이지까지 되돌립니다. hard는 작업 디렉터리까지 되돌립니다.
마지막으로, revert는 해당 커밋을 취소한 새로운 커밋을 추가하는 방식입니다. reset은 뒤에 되돌아갈 커밋을 명시하지만 revert는 뒤에 취소할 커밋을 명시합니다.
스태쉬
파일을 스테이지에 올리기 전에 git stash 명령어를 사용하여 작업 내용을 임시 저장할 수 있습니다. git stash (apply|drop|list)을 통해 스태쉬들을 적용하거나 삭제하거나 목록을 확인할 수 있습니다.
브랜치
브랜치는 버전의 분기로써 여러 흐름으로 나누어 관리하는 방법입니다. 브랜치는 여러 사람이 함께 개발하는 상황에서 필요합니다. 만약 하나의 브랜치에서 작업을 하게 된다면 직렬적으로 커밋들을 작성해야하는 상황이 생길 수도 있습니다. 3단계의 과정으로 여러 브랜치를 관리합니다. 브랜치를 나누고, 각자의 브랜치에서 작업을 하고, 필요한 경우 합칩니다.
나누기
git branch <브랜치 이름=""> 명령어로 현재 커밋에서 새로운 분기점을 만들 수 있습니다. 새로운 분기점은 기존의 분기점의 history를 가집니다.
브랜치>
합치기
git merge <병합할 브랜치=""> 명령어로 브랜치를 병합할 수 있습니다. 만약 새로운 분기점이 새로운 커밋을 쌓아올릴 동안 main 분기점에서 새로운 커밋 작업들이 없을 경우 fast-foward 병합이 가능합니다. 다른 말로 새로운 분기점이 만들어 지는 시점에서의 main 분기점의 상태와 병합할 시점에서의 main 분기점의 (커밋)상태가 같다면 fast-foward 병합이 가능합니다.
병합할>
충돌
커밋 충돌은 두 분기점의 커밋에서 같은 이름의 파일에서 같은 부분을 수정했다고 가정하고 병합 할 시에 일어납니다. 충돌이 일어났을 시 깃은 충돌이 일어난 부분을 명시해줍니다. 따라서 사용자는 해당 부분을 편집하고나서 병합시키면 됩니다. 추가적으로 git rebase라는 명령어는 브랜치가 뻗어나온 기준점을 옮겨줍니다.
GitHub
깃 허브는 원격 저장소 호스팅 서비스입니다. 이는 로컬 PC 저장소에서 작업하는 것들을 원격에서 할 수 있다는 것을 의미합니다. 따라서 여러 사용자들이 원격 저장소를 clone, fork 수 있습니다. 그리고 PullRequest를 통해 다른 사람의 커밋을 자신의 원격 저장소에 병합하거나 fork한 내용을 수정 커밋해서 PullRequest를 fork한 원격 저장소에 요청할 수 있습니다. 자주 사용되는 깃허브와 관련된 git 명령어로는 clone, fetch, merge, pull, push, remote등이 있습니다. 내가 헤매었던 부분을 따로 정리하자면 fetch는 원격 저장소의 최근 커밋들을 들고 오기만 합니다. merge는 fetch로 들고온 커밋들을 병합합니다. pull은 fetch와 merge를 한번에 수행합니다.
마지막으로 PullRequest를 보내는 과정은 다음 5단계를 거칩니다.
- 기여하려는 깃허브 저장소를 본인 깃허브 저장소로 포크
- 포크한 저장소를 본인 로컬 pc로 클론
- 브랜치를 생성 후 작업
- 작업한 브랜치를 본인의 원격 저장소에 푸쉬
- 깃 허브에서 풀 리퀘스트 요청하기