Git Merge 게시글과 Merge 이해하기게시글, 커밋 히스토리를 이쁘게 단장하자 게시글, Squash&Merge 전략 비교 게시글, 누구나 쉽게 이해할 수 있는 GIT 입문을 적극 !! 참조했습니다!
브랜치를 직관적으로 이해하는데는 Learning Git Branch 사이트를 활용했습니다 :)
차용한 이미지의 경우 링크를 걸어놨습니다! 이미지를 클릭하시면 원본 링크를 확인하실 수 있습니다.
도움을 주셔서 감사합니다🍀
당연하게.. 눌러왔던 Merge 버튼에 이렇게 다양한 옵션이 있다는 것을 처음(^^..) 알게 되어 해당 주제를 이번 발표 주제로 선정하게 되었습니다.
"코드를 되돌리는" Git의 기능을 적절히 활용하기 위해선, 적절한 merge 전략을 채택하여 브랜치를 관리하는 것은 매우 중요한! 일이라고할 수 있습니다. 😶
커밋 로그가 이와 같은 경우 (상위 브랜치의 변경사항이 없을 경우),
bugfix 브랜치를 master 브랜치로 병합할 때, 새로 merge 커밋을 생성할 필요없이 단순히 master 브랜치가 이동하기만해도 bugfix 브랜치의 내용을 적용할 수 있습니다.
이와 같은 merge를 fast-forward merge라고 부릅니다.
Github에서는 fast-forward merge를 지원하지 않는다고 합니다.
뭔 이유가 있어서 지원 안하는건가 해서 찾아봤더니, 해당 링크를 보면 걍 애초부터 지원이 안된 것 같네요?!
BitBucket은 해당 옵션을 지원하고 있다고 합니다.
이미지를 클릭하셔서 해당 링크에 들어가시면 CLI로서 fast forward 하는 방법을 적어놓으신 분이 계십니다아 관련해서 정리를 해봐야 할 것 같아요🙄
(+) 조금 더 찾아보니, git merge는 이미 fast-forward 방식을 default로 사용하고 있어서 --no-ff라는 방식의 옵션을 제공하고 있다고 하네요?!
실제로 상황을 재현해보니
위와 같은 상황에서git merge minju
를 진행하면
요렇게 ff 방식이,
git merge --no-ff minju
를 진행하면
요런 방식으로 no-ff로..진행되기는 합니다.
git hub에선 제공을 안하는데, git에서는 디폴트로 ff 머지를 선택한다는 느낌인가..싶은데 관련 내용 좀 더 찾아봐야할 것 같습니다.
더 찾아볼 내용이 많네요💧
이와 같이, 상위 브랜치에서 변경이 발생하여 하위 브랜치가 그 변경 내용을 알지 못하는 상황이 발생한다면 위에서 설명한 fast-forward 방식은 유효하지 못하게 됩니다.
따라서 양쪽의 변경을 가져온 merge commit이 생기며 병합되는 방식이 채택됩니다. 이러한 방식을 non fast-forward merge 방식이라 칭합니다.
fast-forward 방식이 가능한 첫 번째 예제 상황에서도 non-fast-forward 병합 옵션을 선택할 수 있습니다.
이렇게 되면 브랜치가 그대로 남으니 그 브랜치에서 실행한 작업 확인 및 관리면에서 더 유용하겠죠!
위와 같은 커밋 종류를 기반으로,
깃허브의 merge 옵션에 대해 알아보고자 합니다.
기본으로 선택되어 있는 옵션입니다.
이름에서부터 알 수 있듯 위에서 설명한 non fast-forward 방식의 머지를 의미합니다.
해당 방식은, 어떤 브랜치에서 어떤 커밋이 진행되었고, 어떻게 머지되었는지 기록이 그대로 남기 때문에 자세한 정보를 얻을 수 있음에 의미가 있습니다.
하지만 너무 자세하기 때문에, 브랜치가 많아지고 머지가 많아지면 히스토리 그래프의 가독성이 떨어지게 됩니다.
이런식으로 . . 😶
변경사항을 말 그대로 으깨어(?) 하나로 만드는 방식을 말합니다.
분기 된 후
master 브랜치 -> add a.py
minju 브랜치 -> add m.py
, modify m.py
일때
git merge --squash minju
를 진행하고
git commit -m "squash merge"
를 진행하면
이와 같이! minju 브랜치의 변경사항이 합쳐진! 커밋이 master 브랜치에 생성됐음을 확인할 수 있습니다.
이렇게 된다면, 머지 커밋이 남기 때문에 머지가 됐구나라는 사실은 알 수 있고, 분기 브랜치를 삭제하게 되면 히스토리가 깔끔해진다는 장점이 있지만 누가 어떤 커밋을 통해 어떤 라인을 수정했는지와 같은 자세한 상황은 알 수 없다는 단점이 존재합니다.
베이스를 바꿔주는 것입니다!
뭔가 순서가 웃기지만, 여튼 이런 상황이 있다고 봅시다.
master 브랜치 -> add e.py
minju 브랜치 -> add d.py
, add c.py
이런상황에서 rebase를 해주면
요렇게, master 브랜치의 add e.py
위로 베이스가 옮겨짐을 확인할 수 있습니다
해당 글은 세 가지의 방식을 비교하기 위함이므로 rebase에 대한 더 자세한 내용은 해당 블로그를 참고하시면 좋을 것 같습니다. 저는 이 글로 도움을 많이 받았습니도 ~..
여튼 이렇게 rebase를 하게 된다면 따로 머지커밋이 생성되지 않으므로 "어느 시점에" "어떤 브랜치가" 머지됐는지 알 수 없습니다. 참조 블로그에선 tag를 활용해 명시하는 방식을 추천하시네요 !
또한 충돌이 발생하게 되면 각각의 커밋에 하나씩 충돌이 발생한다는...! 문제점도 존재합니다. 신중해야한다는 의미겄지요 . .. .
참조 블로그에서 rebase와 squash 전략의 차이를 명확하게 보여주는 그림을 찾았습니다
이것이 squash 전략
이것이 rebase 전략이 되는 것입니다!
이렇게 다양한 머지 전략이 있으므로, 이를 적절히 사용하여 예쁜 커밋 히스토리를 만드는 능력도 개발자에겐 필수적인 능력이겠죠!!
git을 더 적재적소에 활용할 수 있도록 연습해야겠다 라는 생각이 들었던 정리였습니다
:)