깃을 직접 배워볼 수 있는 애플리케이션이 있습니다. 만들어주신 분께 진심으로 감사드립니다!
1) commit : Git 저장소에 디렉토리에 있는 모든 파일에 대한 스냅샷을 기록하는 것입니다. 디렉토리 전체를 복사하여 붙여넣는 것과 유사하지만 훨씬 유용합니다.
Git은 가능한 커밋을 가볍게 유지하기 때문에, 커밋할 때 마다 디렉토리 전체를 복사하지 않습니다. 각 커밋은 저장소의 이전 버전과 다음 버전의 변경내역(called as "delta")을 저장합니다. 그래서 대부분의 커밋이 그 커밋 위의 부모 커밋을 가리킵니다.
git commit
2) branch : Git의 브랜치도 가볍습니다. 브랜치는 특정 커밋에 대한 참조에 불과합니다. 브랜치를 많이 만들어도 메모리나 디스크 공간에 부담이 되지 않기 때문에 커다른 브랜치로 만들기 보다 작은 단위로 잘게 나누는 것이 좋습니다
git branch [브랜치명]
git checkout [브랜치명]
3) Merge : Git의 Merge는 두 개의 부모를 가리키는 특별한 커밋을 만듭니다. 두 개의 부모가 있는 커밋이라는 것은 "한 부모의 모든 작업 + 다른 부모의 모든 작업 + 그 두 부모의 모든 부모들의 작업을 포함한다"는 의미입니다.
git merge
4) Rebase : 브랜치끼리의 작업을 접목하는 두번째 방법은 리베이스(rebase)입니다. 리베이스는 기본적으로 커밋들을 모아서 복사한 뒤, 다른 곳으로 이동시키는 겁니다. 리베이스의 장점은 커밋들의 흐름을 보기 좋게 한 줄로 만들 수 있습니다 리베이스를 쓰면 저장소의 커밋 로그와 이력이 한결 깨끗해집니다.
만약, main 브랜치를 선택한 후, git rebase "tmp" 를 하게 되면 main브랜치가 tmp브랜치 아래로 이동하게 됩니다.
git rebase main
1) HEAD : HEAD는 현재 체크아웃된 커밋을 말합니다. (쉽게 말해 현재 작업 중인 커밋) HEAD는 항상 작업트리의 가장 최근 커밋을 가리킵니다. 작업트리에 변화를 주는 git 명령어들은 대부분 HEAD를 변경하는 것으로 시작합니다. 일반적으로 HEAD는 브랜치의 이름을 가리킵니다.(위의 bugFix처럼) 커밋을 하게 되면, bugFix의 상태가 바뀌고 이 변경은 HEAD를 통해서 확인이 가능합니다.
2) 상대참조 : Git에서 여기저기 이동할 때 커밋의 해시를 사용하는 방법은 매우 귀찮습니다. 매번 해시를 확인하려고 git log 명령어를 치고 있을 겁니다. 다행히 Git은 해시가 커밋의 고유한 값임을 보여줄 수 있을 만큼만 명시해주면 됩니다.
예를 들어 커밋의 해시 : "fed2da64c0efc5293610bdd892f82a58e8cbc5d8" 라면
"fed2"만 입력해도 되는 것입니다.
그러나 이 역시 불편하기 때문에 Git의 상대 참조(Relative Ref)가 등자합니다. 상대참조로 우리가 기억할만한 지점(브랜치 bugFix or HEAD)에서 출발해서 이동하여 다른 지점에 도달해 작업을 할 수 있습니다.
한번에 한 커밋 위로 움직이는 : ^
한번에 여러 커밋 위로 올라가는 : ~숫자
먼저 캐럿 (^) 연산자 부터 보며느 참조 이름에 하나씩 추가할 때마다, 명시한 커밋의 부모를 찾습니다. 예를 들어, main^ 는 "main의 부모"와 같습니다.
git checkout main^
다음으로 틸드 (~) 연산자는 위로 여러 단계 올라가고 싶을 때 사용합니다.
git checkout HEAD~4
2-1) 브랜치 강제로 옮기기 : 상대 참조를 사용하는 가장 일반적인 방법은 브랜치를 옮길 때입니다. -f 옵션을 이용해서 브랜치를 특정 커밋에 직접적으로 재지정 할 수 있습니다.
예) 강제로 main 브랜치를 HEAD에서 세번 뒤로 옮겼습니다.
git branch -f main HEAD~3
3) 작업 되돌리기 : Git에서 작업을 되돌리는 방법은 여러가지가 있습니다. 변경내역을 되돌리는 것도 커밋과 마찬가지로 낮은 수준의 일(개별 파일이나 묶음을 스테이징 하는 것)과 높은 수준의 일(실제 변경이 복구되는 방법)이 있습니다.
git reset HEAD^
git revert HEAD
4) 작업 옮기기
4-1) cherry-pick
git cherry-pick <Commit1> <Commit2> <...>
현재 위치(HEAD) 아래에 있는 일련의 커밋들에 대한 복사본을 만들겠다는 명령어입니다.
4-2) Git 인터렉티브 리베이스(Interactive Rebase)
git cherry-pick은 원하는 커밋이 무언인지 알 때 유용합니다. 하지만 원하는 커밋을 모른다면? 이럴 때 인터렉티브 리베이스를 사용하면 됩니다. 인터렉티브 리베이스를 사용하기 위해서는 rebase 명령어를 사용할 때 -i 옵션을 같이 사용하면 됩니다. 이 옵션을 추가하면, git은 리베이스의 목적지가 되는 곳 아래에 복사될 커밋들을 보여주는 UI를 띄웁니다. 갓 커밋을 구분할 수 있는 각각의 해시들과 메세지도 보여줍니다.
"실제" Git에서는 UI창을 띄우는 것 대신에 VIM 과 같은 텍스트 편집기에서 파일을 엽니다.
상황1) 개발 중에 이런 상황이 생깁니다. 눈에 잘 띄지 않는 버그를 찾아서 해결하려고, 어떤 부분의 문제인지를 찾기 위해 디버그용 코드와 프린트 코드를 몇 줄 넣습니다. 디버깅용 코드나 프린트 명령어가 그 브랜치에 그대로 들어간 채 합쳐졌습니다. 이 문제를 해결하기 위해선
git rebase -i
git cherry-pick
을 사용할 수 있습니다. 대화형(-i) 리베이스(rebase)로는 어떤 커밋을 취하거나 버릴지를 선택할 수 있습니다. 또 커밋의 순서를 바꿀 수도 있죠. 체리픽(cherry-pick)은 개별 커밋을 골라서 HEAD위에 떨어뜨릴 수 있습니다.
상황2) 'newimage'와 'caption' 브랜치에 각각의 변경내역이 있고 서로 관련이 있어서 저장소에 차례로 쌓인 상황입니다. 때로는 이전 커밋의 내용을 살짝 바꿔야하는 골치아픈 상황에 빠졌습니다. 이번에는 디자인 쪽에서 우리의 작업 이력(history)에서는 이미 한참 전에 커밋 내용에 있는 'newimage'의 크기를 바꿔달라는 요청이 들어왔습니다.
아래 git을 정리하여 다음 목표를 이뤄보자.
{다음 목표}
git rebase -i HEAD~2
git commit --amend
git rebase -i HEAD~2
git branch -f main C3''