이전까지는 혼자, 혹은 둘이서만 프론트 프로젝트를 진행하거나 / 다수로 진행하더라도 촉박한 기간으로 인해 협업을 위한 컨벤션 정하기 및 세팅에 소홀했었던 것 같다.
이번에 디프만 프로젝트를 진행하면서 협업에 더욱 신경써야할 것 같았고, 이를 위해 효율적인 협업을 위한 세팅을 진행해보고 Git 복습도 진행하기로 했다.
Merge / Squash & Merge / Rebase & Merge
나는 지금껏 일반적인 Merge만 사용해왔었다.
그런데 Merge에도 여러 종류가 있고, 팀의 컨벤션에 맞게 적절한 Merge 방안을 선택한다면 수많은 commit들을 더욱 효율적으로 관리할 수 있을 것 같았다.
PR을 날린 후 Merge에 종류를 보면
위처럼 3가지의 merge 방식 중 하나를 택할 수 있다.
그럼 각 방식에 대해 좀 더 자세히 알아보자!
Merge(Fast Forward)
가장 일반적인 방식이다.
위의 사진은 일반적인 Merge 방식 중 Fast Forward 방식을 나타낸다.
my-branch 라는 브랜치가 main 브랜치에서 분기한 이후 main 브랜치에 새로운 커밋이 없는 상태라면, my-branch 는 main 브랜치 보다 최신 브랜치가 된다.
이러한 상황에서 Merge를 하게되면 my-branch의 변경 이력을 그대로 main에 가져올 수 있다.
실습 레포를 파서 한번 실습을 진행해보았다.
실습 레포의 디폴트 브랜치인 main 브랜치에는 위와 같이 ㄹ세팅 커밋이 들어가있다.
우리는 일반적으로 기능 구현을 할 때 feature 브랜치를 파서 진행하게 된다.
그 상황을 가정하여 feature/a 브랜치를 파서 위와 같이 2개의 추가 commit을 포함시켰다.
지금이 위와 같은 상황이다.
main브랜치에서 feature/a 브랜치가 분기한 후 feature/a 브랜치에만 추가 커밋이 올라왔고, main 브랜치에는 추가 작업이 없었으므로 main 브랜치와 비교하여 feature/a 브랜치가 최신 브랜치가 된다.
이제
git checkout main
git merge feature/a
위 명령어를 사용하여 Merge(fast-forward)를 해보자.
위와 같이 feature/a 브랜치의 커밋이 main에 추가적인 merge 커밋 없이 그대로 합쳐진 것을 확인할 수 있다.
git push origin main
명령어를 통해 원격에도 똑같이 적용시켜줄 수 있다.
Merge(Recursive)
위의 Merge(fast forward) 와는 차이점이 있다.
my-branch 브랜치가 main 브랜치로부터 분기한 이후, 위와 달리 main 브랜치에도 추가적인 작업이 있었다.예를 들어 여러개의 PR이 올라왔고, 이를 차례대로 merge 해야 하는 상황일 때 위 사진과 같은 branch 구조가 발생할 수 있을 것이다.
이런 상황에서는 my-branch의 commit들을 main에 그대로 적용할 수 없고 main에 추가된 commit들도 같이 합쳐줘야 하므로 새로운 하나의 merge commit을 통해 merge를 진행해야한다.
이러한 방식을 Recursive Merge라고 한다.
우선 실습을 위해 merge 과정을 reset하여 머지하기 전 상태로 되돌려 주자.
git reset --merge ORIG_HEAD
git push -f origin main
위 명령어들을 통해 머지하기 전으로 돌려주었다.
그 후 feature/b 브랜치를 파서 작업을 진행했다고 가정 후, main 브랜치에 Fast Forward Merge를 진행해주었다.
feature/a 브랜치에는 초기에 세팅해준 것처럼 별개의 작업을 진행했다고 가정한 상황이다.
즉, 위와 같이 feature/a 브랜치가 분기한 이후 main 브랜치에도 추가적인 작업이 진행된 상황이다.
마찬가지로 merge 명령어를 통해 merge를 진행해보자.
Fast Forward Merge와 달리, 새로운 merge commit이 하나 추가된 것을 확인할 수 있다.각 브랜치의 commit들은 각각 그대로 들어있는 것도 볼 수 있다.마찬가지로 push명령어를 통해 원격에도 merge를 적용해줄 수 있다.
Fast Forward Merge가 가능한 상태에서도 Recursive Merge처럼 merge commit을 생성하고 싶다면 git merge 명령어에 --no-f 옵션을 주면 된다.
Squash & Merge
이제 Squash & Merge에 대해 알아보자.
Squash는 단어 그대로 commit들을 하나로 뭉친다고 보면 된다.
main 브랜치에서 분기한 my-branch 브랜치의 commit들을 main에 merge 하려고 할 때, my-branch 브랜치에서 진행한 모든 커밋들을 굳이 살려둘 필요가 없을 때 사용한다.
위 구조처럼 my-branch의 모든 commit 이력들이 하나의 commit으로 합쳐지며 사라지게된다.
Squash & Merge를 실습해보기 위한 초기 구조이다.
main은 feature/b 브랜치의 작업들이 merge된 상태이고, feature/a 브랜치는 여러 commit들이 올려진 채 아직 merge되지 않은 상태이다.
이 때 나는 feature/a 브랜치를 main이 merge하고 싶지만, 굳이 feature/a 에 있는 commit들의 내역은 더이상 필요 없다고 가정했다.
git checkout main
git merge --squash feature/a
git commit -m "a 기능 merge"
위 명령어들을 통해 Squash & Merge를 진행해보자.
위처럼 main 브랜치에는 feature/a 브랜치의 commit들은 들어가지 않고 통합된 하나의 commit만 포함된 것을 확인할 수 있다.
Rebase & Merge
마지막으로 Rebase & Merge에 대해 알아보자.
위처럼 my-branch 브랜치가 main 브랜치의 A commit에서 분기되었다.
딱 분기된 초기 상황에서 my-branch 브랜치의 base는 A commit이 된다.
나는 merge 할 때 my-branch 브랜치의 모든 commit을 main 브랜치 commit들의 뒤에 그대로 가져다 붙이고 싶다.
이 때 방법은 단순하다.
기존 Base였던 A commit에서 Base를 main의 최신 commit으로 옮겨준 뒤, base뒤에다가 my-branch 브랜치의 commit들을 붙이면 되는 것이다.
위에서 Squash & Merge 실습을 위한 초기 상태와 동일하게 맞춰주었다.
이제 feature/a의 내용을 main에 Rebase Merge하려고 한다.
git checkout feature/a
git rebase main
git checkout main
git merge feature/a
위 명령어들을 통해 Rebase Merge를 실행할 수 있다.
결국 base를 바꿔주면 Fast Forward Merge 상황과 동일하게 변하므로, 마지막 단계에는 Fast Forward Merge를 진행하는 것을 확인할 수 있다.
위 결과에서 볼 수 있듯이 feature/a 브랜치의 commit들이 main의 base 뒤에 붙는 형식으로 merge 된 것을 확인할 수 있다.
상황별 적합한 Merge 방법
feature -> develop
보통 우리는 기능별로 feature 브랜치를 파서 작업을 진행한 후, 배포 전에 develop 브랜치에 머지를 한다.
이 때 feature 브랜치에서 진행한 수많은 commit들을 굳이 develop 브랜치에 전부 남길 필요성은 낮아보인다.
게다가 어짜피 일반적으로 feature 브랜치는 해당 기능을 구현한 후 삭제하게 된다.
대신 기능 하나의 대한 새로운 commit을 만들어서 merge해준다면, develop 브랜치에는 기능단위로 commit이 들어가도록 깔끔하게 정리할 수 있다.
즉, feature 브랜치에서 develop 브랜치로 merge를 진행할 때는 Squash & Merge가 적합할 것 같다.
develop -> main
모든 기능을 develop에 모아 테스트 및 QA를 진행한 후, main 브랜치에 merge 하여 배포하게 된다.이 때 만약 Squash & Merge를 진행하게 되면 만약 특정 기능에 이상이 생겼을 때, 롤백할 수 없게 될 것이다.또한 굳이 Merge commit을 남길 필요는 없으므로 추후 롤백 가능성을 고려하여 Rebase & Merge가 적합해보인다.
위 내용들을 공부하고 실습해보며 역시 기본기가 가장 중요하다고 깨달았다.탄탄한 기본기를 유지해나가며 협업 실력을 키워나가야 겠다~~
※ reset & revert
reset과 revert 명령어도 알아두면 돌발 상황에서 유용하게 사용할 수 있을 것 같다.
[Git] reset과 revert 알고 사용하기
Git으로 협업프로젝트를 진행하였다.깃으로 협업하는데 익숙치 않은터라 한번 push를 잘못하거나, 로컬의 main 브랜치에서 원격저장소로부터 pull하고 거기서 의도와 다르게 다른 브랜치와 merge 해
velog.io
위 블로그에 해당 내용이 정리가 매우 잘 되어있어 참고해서 공부해보았다.
필요할 때 마다 참고해서 적용해야겠다!!
참고
https://hudi.blog/git-merge-squash-rebase/
'FrontEnd > React' 카테고리의 다른 글
무한 스크롤(Infinite Scroll) 도입하기 (feat: useInfiniteQuery, Virtuoso) (8) | 2024.09.03 |
---|---|
효율적인 협업을 위하여 - 2 (Feat: 컨벤션) (0) | 2024.07.04 |
HTTP 캐시 다루기 (2) | 2024.06.13 |
아토믹 디자인(Atomic Design) 도입하기 (0) | 2024.05.08 |
React 렌더링 최적화에 대한 고찰 (2) | 2024.04.10 |