회사에서는 SVN을 사용하다보니 git을 사용할 기회가 점차 적어졌습니다.
그러다가 다음 프로젝트에서 사용할 표준을 만드는 과정에서 git을 적극적으로 도입하게 되었습니다.
이전에 git을 사용한 적은 있지만 본격적으로 이해해서 사용하기보다는 야생적으로 그때그때 휘뚜루마뚜루 사용했던 기억이 많습니다. 몇몇 명령어를 이해하고는 있었으나 큰 틀에서 각각의 개념을 잡지 못하고 있다보니 다시 사용해보면서 지식부채에서 오는 한계를 느끼게 되었습니다.
'팀개발을 위한 Git,GitHub 시작하기'를 읽는 것으로 학습을 시작하였고, 현재 해당 도서와 도서에서 추천한 'Learning Git Branching' 게임을 완료한 단계에 있습니다. 이제 작업 중인 프로젝트에 적극적을 활용만 해보면 됩니다.
아래의 내용을 학습과정에 중요하다고 느낌 부분에 대한 정리입니다.
클론을 받아올 때마다 디렉토리가 한 단계 더 깊이 들어갔고, 이 때문에 불편함을 느끼고 있었습니다. 책을 읽다보니 이는 불가항력적인 부분이 아닌 clone 구문에서 마지막 부분에 . 을 추가하는 것으로 현재 디렉토리를 기준으로 한다는 사실을 명시해 주어 해결 할 수 있는 부분이었습니다.
SVN은 델타 방식으로 접근하여 모든 변화된 내용을 누적하여 저장 했다가 필요시 모두 불러와 합쳐서 전달해주는 방식입니다. 이는 속도가 느리고, 브랜치를 사용하기 어렵다는 단점이 있습니다. 반면에 git은 스냅샷이라는 개념으로서 모든 순간순간을 통으로 사진 찍듯이 저장하여 사용합니다.
이는 Stage라는 명령어 및 표현에서 대두 되는데 스냅샨을 stage에 올려놓은 파일들을 찍어 기록한다는 의미가 됩니다. 작업해 놓은 파일을 git add 명령어를 사용하여 stage에 올릴 수도 있고, git reset을 사용하여 내릴 수도 있습니다.
merge를 진행하면 세가지 중 하나의 상황에 부딪히게 됩니다.
1. merge commit: 각각의 브랜치에 충돌이 발생할 교집합이 없어 이상없이 병합됩니다.
2. fast-forward: 한쪽의 브랜치가 다른한쪽의 부분집합관계로 더 큰 집합으로 병합됩니다.
3. conflict: 두 브랜치 사이에 교집합이 있어 충돌이 발생한 상황으로 직접 코드를 정리해주어야 합니다.
git에서는 브랜치들 간의 병합하는 방법이 3가지 입니다.
1. merge : A브랜치와 B브랜치를 별도의 A'브랜치에 합쳐 병합합니다.
2. rebase : A브랜치를 통으로 뽑아 내가 원하는 커밋 위치에 연결합니다.
3. cherry-pick : 커밋들을 받을 브랜치에서 원하는 커밋들을 뽑아 하나하나 연결합니다.
독서를 통해 학습한 이론을 간단한 예시를 보면서 학습할 수 있어서 너무나도 만족스러운 학습이었습니다. 특히 여러명이서 동시의 사용하는 과정에서 만나게 되는 상황들의 경우 재현하기 어려워 연습해보기 어려웠고, 막상 그렁 상황이 생겨도 이론과 관계 지어가며 내재화 되는 학습이 어려웠는데, 이 게임이 도움이 많이 되었습니다.
git fetch -> git merge -> git rebase로 원격 저장소의 커밋을 받아온 후 충돌을 해결하는 방식의 명령어 입니다. 단순히 하나의 명령어가 아닌 내부적인 동작 원리를 알 수 있어 이해가 쉬웠습니다.
여러 병합 방법들을 여러차례 연습하게 해주어 차이에서 오는 장단점을 명확하게 느낄 수 있었습니다. 저는 local 브랜치에서는 rebase를 선호하되, 오류 발생시 cherry-pick을 적극적으로 사용며 원격 저장소를 고려해야 되는 상황에서는 merge 방식을 사용하게 되지 않을까 싶습니다.
HEAD^의 경우 부모를 찾되 뒤의 숫자가 올 경우 부모가 여럿인 상태에서 선택할 수 있습니다.
HEAD~의 경우 부모와 조부모에 이어 해당 숫자만큼 위의 조상님들 만나러 가게 됩니다.