Git 명령어들
브랜치와 HEAD의 개념
-
기본적으로 git에서는 대부분 커밋들이 각자 단 하나의 부모 노드(커밋)를 갖는 단일한 노드로서 트리 구조로 이루어져 있으며(단, 일부 커밋은 둘 이상의 부모 커밋을 가질 수 있다), 최초의 커밋에서 여러 개의 커밋이 서로 독립적으로 만들어져 계속 부모-자식 관계를 만들어나가게 된다. 따라서 레포지토리의 어느 한 커밋을 지정하면 반드시 그 레포지토리에서 그 커밋으로 이어져오는 경로가 존재한다.
-
git에서 브랜치는 레포지토리 내 특정 커밋을 가리키는 일종의 alias인데, 그 커밋이 최초 커밋에서부터 이어져온 경로가 마치 나무에서 가지를 뻗어온 것처럼 보인다며 붙은 이름이다. 한 커밋에 둘 이상의 브랜치 이름을 붙일 수 있는데, 현재 작업하는 HEAD는 항상 어느 한 브랜치 또는 커밋을 가리키게 돼있다. (기본적으로는 브랜치를 가리키고 있으나, 커밋을 직접 가리키게 할 수 있으며 이 경우를 detached HEAD라 한다.)
-
현재 HEAD인 브랜치에서 예를 들어 새로운 커밋을 추가하는 경우 그 브랜치와 HEAD는 그 커밋을 가리키도록 변경된다. 이때 이러한 변경은 브랜치 사이에 서로 독립적이다.
-
다음 커맨드로 현재 HEAD 브랜치가 가리키는 커밋을 임의로 변경할 수 있다.
-
git reset <브랜치>/<커밋 해시>: 현재 HEAD 브랜치가 가리키는 커밋을 지정한 브랜치(커밋)와 일치하도록 변경한다. -
git branch -f <브랜치> <커밋 해시>: 지정한 브랜치가 가리키는 커밋을 지정한 커밋으로 변경한다.
-
git checkout
-
현재 로컬 레포지토리의 파일 상태를 지정한 커맨드에 맞춰 변경하는 커맨드. 기본적으로 HEAD를 변경하여 파일 상태를 바뀐 HEAD에 맞추는 기능이 있고, HEAD를 그대로 두고 지정한 브랜치/커밋 해시에 로컬 파일 상태를 맞추는 기능도 있다.
-
19년 발표된 Git 2.23부터
switch커맨드,restore커맨드가 도입되어,checkout의 두 기능을 각 커맨드에 각각 나누어서 사용할 것이 권장된다.
(1) git checkout <브랜치>/<커밋 해시>
-
현재 로컬 레포지토리의 HEAD를 해당 브랜치/커밋 해시로 변경하는 커맨드.
git switch로 대신 사용 가능하다. -
만약 target을 브랜치가 아니라 커밋 해시로 이 커맨드를 실행하면 HEAD가 브랜치가 아니라 지정된 커밋을 직접 가리키게 되며 이러한 상태를 detached HEAD라 한다. 특정 커밋해시를 알 때 로컬 파일 상태를 곧바로 그 상태로 변경하기 위해 사용되는 커맨드로, HEAD가 detached 된 경우에는 새로 커밋을 추가하는 등의 실수를 하지 않도록 주의해야 한다. (만약 이처럼 HEAD가 detached된 상태에서 새로 커밋을 하는 경우 새로 추가되는 커밋은 어떤 브랜치에도 속하게 되지 않아 관리가 어려워진다. 다만, 그 커밋을 위한 새로운 브랜치를 만들 수는 있다.)
(2) git checkout <브랜치>/<커밋 해시> -- <파일명>
- 이처럼 커맨드 뒤에
--연산자와 함께 파일명을 추가하면, 해당 파일의 내용을 주어진 브랜치/커밋의 내용에 맞춰 변경한다. (단, 이때 레포지토리의 HEAD가 바뀌는 것은 아니다.)
원격 레포지토리와의 동기화
1
git fetch
-
로컬 레포지토리 대비 원격 레포지토리의 새 커밋들을 로컬 레포지토리로 가져와 새로운 브랜치에 담는다. (새 브랜치의 이름은 원격 레포지토리의 이름과 새 커밋이 일어난 브랜치의 이름의 조합으로 만들어진다.)
-
로컬 레포지토리를 원격 레포지토리의 새 커밋에 완전히 동기화하려면 새 브랜치에 담긴 내용을 로컬 레포지토리에 merge하거나 rebase를 해야 한다.
git pull --rebase명령어를 사용하면 fetch와 rebase를 한번에 결합해서 할 수 있으나, 나누어서 할 것을 권하는 경우도 있다.
git revert <커밋 해시>
- 지정한 커밋의 변경을 취소하는 커밋을 현재 브랜치에 추가한다.