Git은
파일의 변경이력을 기록하여 관리를 용이하게 해주는 버전 관리 시스템의 일종입니다
Git CLI Command를 기준으로 파일의 변경 이력을 저장하는 과정을 거쳐 보겠습니다
git config --global user.name <깃허브 username>
git config --global user.email <깃허브 email>
변경 이력을 누가 남기는 것인지 등록하는 과정입니다
PC 내 1회만 설정하면 계속 유지됩니다
git init
현재 폴더를 Git의 관리 하에 두겠다는 의미입니다.
초기화가 이루어지며 .git 폴더가 생성됩니다
git 저장소 내에 변경을 발생시킵니다
ex) 임의의 파일을 생성하고 수정합니다
git add <파일명>
해당 파일을 이번 변경이력저장(commit)에 적용할 Staging Area라는 곳에 등록합니다
commit하기 전, 중간저장 개념으로 이해해도 지금은 무방합니다
이번 commit에 포함시키고 싶지 않은 파일은 add
를 하지 않으면 됩니다
git commit -m <메시지>
메시지와 함께 현재까지의 변경이력을 저장합니다
타임스탬프를 찍는 개념으로 이해해도 좋습니다
그림을 보며 과정을 다시 살펴봅시다
Working Directory
사용자가 실제 작업 중인 로컬 공간을 의미합니다
Staging Area
최종적으로 commit되기 전, 일종의 준비 공간입니다.
이 곳에 올라와 있는 파일만 저장소로 commit될 수 있습니다
index 라고도 합니다
Commit
Git에서 변경이력의 단위를 말합니다
현재까지의 변경이력을 저장하는 행위나 변경이력 자체를 commit이라고 표현합니다
현재 Local Repository에 있는 파일들의 상태를 보거나 commit 내역을 확인할 수 있습니다
git status
git log
git log --oneline --graph --decorate --all
Repository(저장소)는 기능은 같지만 위치에 따라 두 종류가 존재합니다
지금까지 해본 것은 Local Repository 내에서만 동작하는 command들이었습니다
Remote Repository를 다루는 것은 추후 다룰 예정이니 지금은 넘어가도 됩니다
Local Repository
로컬 PC에 존재하는 저장소
Remote Repository
외부 서버에 존재하는 저장소.
ex) Github
어떤 파일은 Git으로 관리하고 싶지 않을 수도 있습니다
ex) 개발자의 개인정보 파일
현재 폴더에 .gitignore
라는 파일을 생성하고 이 파일에 나열된 파일들은 Git의 관리에서 배제됩니다
데스노트?
Git과 Github는 엄연히 다른 것입니다
Github은 단지 Git의 사용을 도와주는 서비스 중 하나입니다
Github을 이용해 아까 Local Repository에 저장했던 commit들을 Remote Repository에 저장시켜 보겠습니다
Remote로 저장하면 인터넷을 통해 다른 사람도 접근할 수 있게 됩니다
Github 사이트에서 Remote Repository를 생성합니다
git remote add origin <remote URL>
Remote Repository를 등록합니다
생성했던 Remote를 origin이라는 이름으로 등록합니다
git push origin master
Local Repository에 저장되어 있는 commit들을 origin(Remote)의 master(Remote's branch)로 밀어 넣습니다
여기까지 하면, Github 서버에 commit들이 저장된 것으로 사이트에서 코드와 변경사항을 확인할 수 있습니다
git clone <remote URL>
해당 remote의 코드와 commit을 현재 로컬 폴더로 복사합니다
Github 사이트에서 fork
를 찾아보세요
Git에서 과거로 돌아가는 command는 두 개가 존재합니다
git reset <commit번호>
git revert <commit번호>
다음 그림을 보며 Git의 구조를 복기해봅시다
아직 다루지 않은 merge
, fetch
, pull
은 다음 포스팅에서 다루어 보겠습니다
파일을 수정했다가 되돌리고 싶은 순간이 있다
예로, git reset
으로 commit을 되돌렸지만 로컬 파일은 그대로 남아 있는 경우이다
로컬 파일들을 commit 기반으로 refresh 하려면 git restore
를 사용하면 된다
git restore <파일명>
개발이 진행될수록 commit들이 쌓여갈 것입니다
이런 흐름을 commit flow라고 표현해보겠습니다
branch
commit flow를 여러 갈래로 만들 수 있습니다
각 flow들을 branch라 부르며 이름을 가집니다
또한, branch들은 서로 합쳐질 수도(merge) 있습니다
branch를 별도로 만들지 않으면 디폴트로 master 혹은 main이라는 이름의 branch 1개만 존재하게 됩니다
git branch
branch 목록을 출력합니다
git branch <branch명>
현재까지의 commit을 기점으로 branch를 생성합니다
git branch -D <branch명>
해당 branch를 삭제합니다
git checkout <branch명>
현재 다루는 branch를 전환합니다
git checkout -t <branch명>
git merge <branch명>
입력한 branch를 현재 branch에 합병시킵니다
git rebase <branch명>
입력한 branch를 현재 branch에 얹습니다
최종결과는 완전히 동일하지만
Rebase를 사용했을 때의 장점이 있습니다
그림에서 볼 수 있듯이 rebase를 사용하면 Git history를 깔끔하게 만들 수 있습니다
많은 branch가 발생하는 대규모 프로젝트에서 유용합니다
아래 2가지 경우가 발생하면 충돌이 발생하여 Git이 정상적으로 동작하지 않습니다
해결방법도 같이 알아보겠습니다
합병하려는 두 branch가 동일한 파일을 변경했다면 충돌이 발생합니다
합병의 결과로 어느 쪽을 따라야할지 알 수 없기 때문입니다
협업 시 같은 파일을 다른 branch에서 다루는 일은 최대한 피해야 합니다
해결방법
두 branch 중 하나를 되돌리면 됩니다
동일한 branch를 서로 다른 로컬에서 다루는 경우 충돌이 발생할 수 있습니다
한 로컬에서 Remote로 push를 했지만 다른 로컬에서 이를 업데이트 받지 않은 상태로 개발을 진행해버린 경우입니다
이 상황에서 다른 로컬이 뒤늦게 pull을 하더라도 commit flow가 어긋났기 때문에 충돌이 발생합니다
해결방법
잘 생각해보면 같은 파일을 건드린 것이 아니기에 merge가 충분히 가능한 상황입니다
그럼에도 충돌이 발생한 이유는 commit을 쌓는 순서가 어느 로컬의 commit이 먼저인지 알 수 없기 때문입니다
따라서, 각 로컬이 생성한 commit 간 순서만 정해주면 해결된다
add
+commit
하면 충돌상태가 해제되고 정상적으로 pull commit과 합병된다