📌 연습 중인 git branching 사이트
Learn Git Branching
An interactive Git visualization tool to educate and challenge!
learngitbranching.js.org
다음 단계로
Level 1. HEAD 분리하기
Git의 고급기능들에 대해 더 알아보기 전에, 프로젝트를 표현하는 커밋 트리(commit tree)에서 이동할 수 있는 여러가지 방법들을 알고 넘어가자!
HEAD란 현재 체크아웃된 commit을 가리킨다. 즉, 현재 작업 중인 commit이라는 뜻이다.
HEAD는 항상 작업트리의 가장 최근 커밋을 가리킨다. 작업트리에 변화를 주는 git 명령어들은 대부분 HEAD를 변경하는 것으로 시작한다.
일반적으로 HEAD는 브랜치의 이름을 가리킨다. (e.g. bugFix) Commit을 하게 되면, 그 브랜치의 상태가 바뀌고, 이 변경은 HEAD를 통해서 확인이 가능하다.
HEAD를 분리한다는 것은 HEAD를 브랜치 대신 commit에 붙이는 것을 의미한다.
아래의 왼쪽 상황에서 git checkout C1
명령어를 실행하면 오른쪽과 같이 main 브랜치가 아닌 C1 commit에 붙게 되는 것을 볼 수 있다. 이것이 HEAD가 분리된 상태가 되는 것이다!!
✅ 각 commit은 해시값으로 특정지을 수 있다!
🗒️문제🗒️
다음 레벨로 넘어가기 위해서는, HEAD를 bugfix에서 분리하고 그 커밋에 붙이세요. 각 커밋은 그것의 해시값으로 특정지을수 있습니다. 각 커밋의 해시값은 각 커밋을 나타내는 원안에 나타나있습니다.
위의 예제에서처럼 git checkout C4
를 해주면
HEAD가 bugFix 브랜치에서 C4 커밋으로 이동하면서 HEAD 분리가 된다.
Level 2. 상대 참조(^) (Relative Refs)
Git에서 여기저기 이동할 때 commit의 해시를 사용하는 방법은 조금 귀찮다..
매번 해시를 확인하려면 git log
명령어를 쳐야 한다..
더욱이 실제 Gti에서는 해시들이 훨씬 길다. 지금은 보기 쉽게 C1, C2와 같은 식으로 나타내고 있지만 실제로는 fed2da64c0efc5293610bdd892f82a58e8cbc5d8
이런 형태이다.
다행히도 이 값을 전부 입력할 필요 없이, 해시가 commit의 고유한 값임을 보여줄 수 있을 만큼만 명시해주면 된다! 위의 해시값의 경우 fed2
만 입력해도 되는 것이다.
그러나 어찌됐든 commit들을 해시로 구분하는 것은 여전히 불편하다. 그래서 등장한 것이 상대 참조(Relative Ref)이다.
상대 참조로 우리가 기억할 만한 지점 (브랜치, HEAD..)에서 출발해서 이동하여 다른 지점에 도달해 작업을 할 수 있다.
여기서는 2가지 간단한 방법을 해 볼 것이다.
(1) ^
(캐럿) 연산자 : 한번에 한 커밋 위로 움직임
- main^ : main의 부모
- main^^ : main의 조부모 (부모의 부모)
(2) ~<num>
(틸드) 연산자 : 한번에 여러 커밋 위로 올라감
🗒️문제🗒️
이 레벨을 완료하기 위해서는 bugFix의 부모 커밋을 체크아웃 하세요. 이렇게 하면 HEAD가 분리될 것입니다. 해시를 이용해서도 할 수 있지만, 상대 참조를 활용하는 것을 연습해 보세요!
git checkout bugFix^
: bugFix 브랜치의 부모 commit( = C3)으로 이동
Level 3. 상대 참조(~) (Relative Refs) #2
여기서는 위에서 2번으로 얘기한 ~ (틸드) 연산자를 사용할 것이다.
상대 참조를 사용하는 가장 일반적인 방법은 브랜치를 옮길 때이다. -f
옵션을 이용햇 브랜치를 특정 commit에 직접적으로 재지정 할 수 있다.
예를 들어..
git branch -f main HEAD~3
: (강제로) main 브랜치를 HEAD에서 3번 뒤로 옮겼다.
🗒️문제🗒️
상대 참조와 브랜치 강제의 조합을 봤으니 다음 레벨을 해결해 보자. 이 레벨을 통과하기 위해서, HEAD와 main과 bugFix를 제시되는 골지점으로 옮겨 주세요.
1) git branch -f main C6
: main 브랜치를 C6 commit으로 강제로 이동시킴
2) git branch -f bugFix HEAD~2
: bugFix 브랜치를 HEAD에서 2번 뒤인 C0 commit으로 강제로 이동시킴
3) git checkout HEAD^
: HEAD의 부모 commit인 C1으로 이동
Level 4. Git에서 작업 되돌리기
Git에는 작업한 것을 되돌리는 여러가지 방법이 있다.
변경내역을 되돌리는 것도 커밋과 마찬가지로 낮은 수준의 일(개별 파일이나 묶음을 스테이징 하는것)과 높은 수준의 일(실제 변경이 복구되는 방법)이 있는데, 여기서는 후자에 집중해서 볼 것이다.
Git에서 변경한 내용을 되돌리는 방법은 크게 2가지가 있다.
(1) git reset
- 브랜치로 하여금 예전의 커밋을 가리키도록 이동시키는 방식으로 변경 내용을 되돌린다.
- "히스토리를 고쳐 쓴다"
- 마치 애초에 커밋하지 않은 것처럼 예전 커밋으로 브랜치를 옮기는 것
- 각자의 컴퓨터에서 작업하는 로컬 브랜치의 경우 reset을 잘 쓸 수 있지만, "히스토리를 고쳐 쓴다"는 점 때문에 다른 사람이 작업하는 리모트 브랜치에는 쓸 수 없다.
- e.g. git reset HEAD~1
=> 로컬 저장소에는 마치 C2 commit이 아예 없었던 것과 마찬가지 상태가 된다!
(2) git revert
- 변경분을 되돌리고, 이 되돌린 내용을 다른 사람들과 공유하기 위해서는 git revert를 써야한다.
- e.g. git revert HEAD
🗒️문제🗒️
local 브랜치와 pushed 브랜치에 있는 최근 두 번의 커밋을 되돌려 보자. pushed는 리모트 브랜치이고, local은 로컬 브랜치임을 신경써서 작업하자.
1) git reset HEAD^
: local 브랜치가 부모 commit인 C1을 가르키게 함으로써 작업을 되돌린다. (로컬이기 때문에 reset 사용 가능)
2) git checkout pushed
: pushed 브랜치로 이동
3) git revert HEAD
: 변경된 만큼을 되돌려서 새로운 commit C2' 생성 (리모트 브랜치에서는 revert 사용해야 함)