출처: GIT1, Git CLI - 버전관리 by 이고잉, 생활코딩, CC BY
버전 관리: 파일이 변경됐을 때 그 변경 사항들을 버전으로 만들어서 관리한다.
백업: 데이터를 원격 저장소에 안전하게 보관하고, 오픈소스로 공유할 수도 있다.
협업: 깃허브라는 원격 저장소에서 버전 관리를 해주기 때문에 서로 다른 컴퓨터에서 push, pull로 공동 작업을 할 수 있다.
참고로, 버전 관리가 제대로 되지 않는 지옥을 직접 맛보고 와야, Git의 필요성을 절실히 느낄 수 있다! 그때 Git을 공부하는 것이 가장 좋다!
git init .
→ 현재 디렉토리(.)를 git에게 버전 관리시킨다.
.git
→ 앞으로 생성될 파일들의 버전 정보를 관리하는 숨은 파일
→ 이걸 지우면 프로젝트의 역사, 근본이 사라지는 것이다.
- Working tree: 파일을 수정하는 곳
- Staging Area: 버전으로 만들어질 파일들을 올려놓는 곳
- Repository: 버전이 저장되는 곳
명령어 | 설명 |
---|---|
git status | working tree status 확인 |
Untracked files: ... | Staging Area에 올라가지 않았고, 한번도 버전 관리를 하지 않은 파일들 (git은 staging area에 올린 파일들만 track한다.) |
git add [파일명] | add to staging area |
Changes to be commited: ... | Staging Area에 올라간, 버전이 될 파일들의 목록 |
git commit -m "커밋 메시지" | create version (git에게 버전으로 만들 파일들을 제출한다) |
git log | show version (커밋 히스토리 확인하기) |
Changes not staged for commit: ... | Staging Area에 올라가지 않았지만, 적어도 한번은 버전 관리를 한 적이 있는 파일들 |
cf) git add .
// 현재 디렉토리 아래에 있는 모든 파일들을 add
cf) git commit -am
// add와 commit을 한번에!
→ 그렇지만, 적어도 한번은 add를 해서 tracked 상태가 되어야 -am 옵션을 사용할 수 있다. 이는 추적하고 싶지 않은 파일을 실수로 추적하는 일을 막기 위한 것이다.
→ git commit
만 치면 텍스트 에디터가 뜨기 때문에 커밋 메시지를 길게 작성할 수 있다. 참고로 git config --global core.editor "에디터명"
명령어로 자신의 컴퓨터 전체에서 사용될 텍스트 에디터도 변경할 수 있다. ex) vim, nano
→ git commit --amend
는 가장 최근 커밋의 메시지를 수정할 수 있다.
cf) git log --stat
→ 각 커밋이 어떤 파일들을 버전 관리하고 있는지 확인
→ 중요한 건 서로 관련되어 있는 여러 개의 파일들을 하나의 버전으로 그룹화 할 수 있다는 것! (여러 개의 파일을 하나의 버전으로 관리하기)
명령어 | 설명 |
---|---|
git diff | show changes: 파일을 수정한 뒤에 Working tree와 마지막 버전 간의 차이점을 파악하여, 최종 커밋 이전에 변경사항을 검토할 수 있게 해준다. |
git reset --hard | 작업한 것을 취소하고 싶을 때 (뒤에서 자세히 설명할 예정) |
git log -p | 각 커밋의 diff 결과를 보여준다. |
checkout은 특정 버전으로 working tree를 변경시키는 방법이다. 이를 통해 버전과 버전을 넘나들 수 있다. (헷갈리지 말아야 할 것은 checkout을 통해 과거로 돌아갔다고 해서 변경사항이 실제로 사라지는 게 아니라는 것이다. git checkout master
명령어를 치면, 가장 최신 상태의 버전으로 다시 돌아갈 수 있다.)
버전 관리는 의미 있는 변경점들을 기록하는 것이다. 과거로 갔다가 미래로 다시 돌아오는 시간 여행을 할 수 있다는 건 버전 관리의 중요한 효용이다.
git checkout [commit id]
→ 해당 커밋 아이디를 갖는 버전으로 이동하기
→ 커밋 아이디는 git log에서 확인할 수 있다.
git reset --hard [커밋 아이디]
// 해당 버전'으로' 리셋하겠다.
→ 해당 버전'을' 리셋하는 게 아니라는 점 주의하기
→ checkout은 HEAD의 위치는 그대로이고 버전의 과거, 미래만 넘나드는 것이지만, reset은 HEAD의 위치가 아예 바뀌면서 버전이 삭제되는 것이다.
→ hard 대신 soft, mixed 등의 다른 모드로 바꿀 수 있다. git reset --help
명령으로 자세한 설명을 볼 수 있다.
→ 이미 다른 사람과 공유된 버전에 대해서는 reset하면 안 된다. 공유되기 전 단계의 버전에 대해서만 reset을 해야 협업할 때 엉키지 않는다.
우리 주위를 둘러보면 모든 시스템이 CRUD를 제공하는 것은 아니다. 역사에서 기록을 지우면 후세에게 지탄 받고, 회계에서 기록을 지우면 쇠고랑을 찬다. 이처럼 어떤 시스템은 CR만 제공하고 UD는 엄격하게 통제하거나 아예 못하게 한다. 이와 비슷하게 reset도 버전을 삭제하는 것이라 주의해서 사용해야 한다. 삭제와 보존이라는 목적을 동시에 달성할 수 있는 것이 revert 명령어이다. 다시 말해서, 버전을 삭제하지는 않지만 해당 버전의 변경 사항은 취소할 수 있는 것이다.
한번에 이해하기 어려우므로 강의 설명을 참고하는 것이 좋다.
https://opentutorials.org/course/3839/22597
R3'로' reset하면, R4 버전은 삭제되고 R3로 가게 된다. 하지만 R4'를' revert하면, R4 버전은 보존된 상태로 그 변경 내용만 취소하여 R3로 갈 수 있다.
git reset [커밋 아이디]
// 해당 버전'으로' reset 한다.
git revert [커밋 아이디]
// 해당 버전'을' revert 한다.
git revert [R4의 아이디]
를 실행한 뒤, 커밋 로그를 확인해보면 다음과 같다. (revert 명령을 실행하면 텍스트 에디터가 뜨며, 그 상태에서 커밋 메시지를 수정할 수 있다.)
즉, R4 버전은 살아있는 상태로 revert가 된 것이다.
git log -p
로 각 커밋의 diff를 확인해보면, R4가 revert 되어서 R3의 상태로 파일 내용이 돌아간 것을 볼 수 있다.
아래 커밋 로그에서, Message 2
를 revert하여 Message 1
상태로 돌아가고 싶다면 어떻게 해야 할까? 예상과 달리, git revert [Message 2의 커밋 아이디]
명령을 치면 conflict가 발생한다! 왜냐하면 revert 명령은 Message 2
의 변경 사항만 취소하는 것이므로, Message 2
이후에 만들어진 R3, R4 버전은 어떻게 처리해야 할지 몰라서 깃이 우리에게 불평을 하는 것이다! 따라서, Message 2
를 충돌 없이 revert 하고 싶다면, R4, R3부터 먼저 순차적으로 revert를 해줘야 한다!
https://opentutorials.org/course/3839/22752
.gitignore
파일에 넣으면 된다.