git의 다양한 명령어.
commit
branch
checkout
cherry-pick
reset
revert
rebase
merge
git commit :
커밋할 때마다 디렉토리 전체를 복사하진 않음.
각 커밋은 저장소의 이전 버전과 다음 버전의 변경내역("delta"라고도 함)을 저장합니다. 그래서 대부분의 커밋이 그 커밋 위의 부모 커밋을 가리킵니다.
저장소를 복제(clone)하려면 모든 변경분(delta)를 풀어내야 하는데, 이 때문에 명령행 결과로 아래 문구를 볼 수 있습니다.
resolving deltas
브랜치는 특정 커밋에 대한 참조(reference)에 지나지 않습니다.
단순히는 "하나의 커밋과 그 부모 커밋들을 포함하는 작업 내역"이라고 기억하시면 됩니다.
브랜치를 많이 만들어도 메모리나 디스크 공간에 부담이 되지 않기 때문에, 여러분의 작업을 커다른 브랜치로 만들기 보다, 작은 단위로 잘게 나누는 것이 좋습니다.
브랜치와 커밋을 같이 쓸 때, 어떻게 두 기능이 조화를 이루는지 알아보겠습니다.
git branch branchName
git checkout branchName; git commit
Git의 합치기(merge)는 두 개의 부모(parent)를 가리키는 특별한 커밋을 만들어 냅니다. 두개의 부모가 있는 커밋이라는 것은 "한 부모의 모든 작업내역과 나머지 부모의 모든 작업, 그리고 그 두 부모의 모든 부모들의 작업내역을 포함한다"라는 의미가 있습니다.
bugFix라는 새 브랜치를 만듭니다
git checkout bugFix
를 입력해 bugFix 브랜치로 이동(checkout)합니다.
커밋 한 번 하세요
git checkout
명령어를 이용해 main브랜치로 돌아갑니다
커밋 또 하세요
git merge
명령어로 bugFix브랜치를 main에 합쳐 넣습니다.
브랜치끼리의 작업을 접목하는 두번째 방법은 리베이스(rebase)입니다. 리베이스는 기본적으로 커밋들을 모아서 복사한 뒤, 다른 곳에 떨궈 놓는 것입니다.
조금 어렵게 느껴질 수 있지만, 리베이스를 하면 커밋들의 흐름을 보기 좋게 한 줄로 만들 수 있다는 장점이 있습니다. 리베이스를 쓰면 저장소의 커밋 로그와 이력이 한결 깨끗해집니다.
c3에 있는 bugFix를 옮기기 위해 'git rebase main'
사용.
아직 master로 고정되어있을때는 다시 'git rebase'
를 사용하면됨.
HEAD Git의 고급기능들에 대해 더 알아보기 전에, 여러분의 프로젝트를 표현하는 커밋 트리(commit tree)에서 이동 할 수 있는 여러가지 방법들을 아는것이 중요합니다.
먼저"HEAD"에 대해 이야기해 봅시다. HEAD는 현재 체크아웃된 커밋을 가리킵니다. -- 다시 말하자면 현재 작업중인 커밋입니다.
HEAD는 항상 작업트리의 가장 최근 커밋을 가리킵니다. 작업트리에 변화를 주는 git 명령어들은 대부분 HEAD를 변경하는것으로 시작합니다.
일반적으로 HEAD는 브랜치의 이름을 가리키고있습니다(bugFix와 같이). 커밋을 하게 되면, bugFix의 상태가 바뀌고 이 변경은 HEAD를 통해서 확인이 가능합니다.
HEAD 분리하기
HEAD를 분리한다는 것은 HEAD를 브랜치 대신 커밋에 붙이는 것을 의미합니다. (git checkout commitName)
상대참조(Relative Ref)
git의 해시를 매번 확인할 수도 없음.
실제 Git에서는 해시들이 훨씬 더 깁니다. 예를 들어 이전 레벨에 소개했던 커밋의 해시는 fed2da64c0efc5293610bdd892f82a58e8cbc5d8
입니다. 쓰기 쉬워 보이진 않네요....
다행히도, Git은 똑똑합니다. 해시가 커밋의 고유한 값임을 보여줄 수 있을 만큼만 명시해주면 됩니다. 위의 긴 문자열 대신 fed2
만 입력해도 되는 겁니다.
상대커밋
먼저 캐럿 (^) 연산자 부터 알아보겠습니다. 참조 이름에 하나씩 추가할 때마다, 명시한 커밋의 부모를 찾게 됩니다.
main^
는 "main의 부모"와 같은 의미 입니다.
main^^
는 "main의 조부모(부모의 부모)"를 의미합니다
커밋트리에서 위로 여러 단계를 올라가고 싶을 수 있습니다. ^
를 계속 입력해서 올라가는것 말고 좋은 방법이 있습니다. Git 에는 틸드 (~) 연산자가 있습니다.
(~) 틸드 연산자는 (선택적) 올라가고 싶은 부모의 갯수가 뒤에 숫자가 옵니다. 직접 확인해 보죠.
git checkout HEAD~4
브랜치 강제로 옮기기
-f 옵션을 이용해서 브랜치를 특정 커밋에 직접적으로 재지정 할 수 있습니다.
git branch -f main HEAD~3
git branch -f master c6
git checkout HEAD~1
git branch -f bugFix HEAD~1
Git에는 작업한 것을 되돌리는 여러가지 방법이 있습니다. 변경내역을 되돌리는 것도 커밋과 마찬가지로 낮은 수준의 일(개별 파일이나 묶음을 스테이징 하는 것)과 높은 수준의 일(실제 변경이 복구되는 방법)이 있는데요, 여기서는 후자에 집중해 알려드릴게요.
Git에서 변경한 내용을 되돌리는 방법은 크게 두가지가 있습니다 -- 하나는 git reset을 쓰는거고, 다른 하나는 git revert를 사용하는 것입니다. 다음 화면에서 하나씩 알아보겠습니다.
git reset
은 브랜치로 하여금 예전의 커밋을 가리키도록 이동시키는 방식으로 변경 내용을 되돌립니다. 이런 관점에서 "히스토리를 고쳐쓴다"라고 말할 수 있습니다. 즉, 이전에 커밋하지 않은것처럼 예전 커밋으로 브랜치를 옮기는 것.
각자의 컴퓨터에서 작업하는 로컬 브랜치의 경우 리셋(reset)을 잘 쓸 수 있습니다만, "히스토리를 고쳐쓴다"는 점 때문에 다른 사람이 작업하는 리모트 브랜치에는 쓸 수 없습니다.
변경분을 되돌리고, 이 되돌린 내용을 다른 사람들과 공유하기 위해서는, git revert
를 써야합니다.
(copy of 원본의 개념)