내가 보기 위해 다시 작성하는 Git workflow & rebase

Minju Kim·2022년 4월 24일
3

CS & Etc.

목록 보기
8/9
post-thumbnail

2차 프로젝트 때 Git rebase를 처음해 보면서, 스스로 notion에 작성해 두었던 것을 계속 참고했는데 미래의 나를 위해 다시 한 번 잘 정리하여 블로그에 작성해본다.

1. Git workflow

git workflow란 한마디로 하자면, “브랜치를 관리하는 전략"이다.

실제 프로젝트를 운영하고 개발하는데, 깃 브랜치들을 어떻게 관리할 것인가에 대한 전략이 여러 개가 있다. 그 중에 가장 많이 쓰이고 있고 모든 전략의 근간이 되는 것이 git flow 이다.

  • Main : 제일 핵심이 되는 줄기 - Main branch is used for production release (V1.0.0)
  • Develop : 개발할 때 사용하는 줄기. 왜 Main 이랑 따로 분리해서 쓸까? 단계를 하나 더 놓아서, 기능들을 이 브랜치에 합치는 것이다. 만약 바로 메인에 합치면 코드를 합쳤을때 서비스가 중단되어버릴 수 있는 위험성이 있다. Feature가 개발 완료되면 Main이 아니라 Develop에 합친다. develop이 업데이트 되면, feature branch로 다 합쳐줘야 한다.
  • Feature/F1 , Feature/F2 : 기능을 만드는 줄기

자 만약에, 우리가 user에게 개발된 것을 배포하고 싶어. 그러면 그 때는 어떤 브랜치를 쓰느냐?

  • Release : 우리가 기능 개발 완료되었다고 해서 바로 배포할 수 없다. QA(Quality Assurance)를 테스트하는 브랜치이다. 만약 테스트 하다가 버그가 발생되었다. 그러면 이 때 어떻게 해야 하나? release브랜치에서 BugFix하는 것이다. 그러고 나면 Release 브랜치에는 테스트 완료한 내용이 있지만 develop에는 없다. 그렇기에 develop에 가져오고, feature에 가져온다. 그러고 나서 비로소 main 브랜치에 합친다. 버전 2.0을!

그런데 갑자기 나에게 전화가 와. 갑자기 로그인이 안된다고! 배포가 되었는데! 그런데 이거 고치는 것은 진짜 급한 상황이다. 이 때 급해 죽겠는데, 언제 develop따고 또 위와 같은 과정을 하기엔 너무 시간이 많이 걸린다. 그럴 때 쓰는게 Hotfix 브랜치이다.

  • Hotfix : Main에서 바로 딴다. 그래서 minor한 업데이트를 하고 V2.0.1 이런식으로 가장 뒤에 숫자만 업데이트 해준다.
    그리고 나서 다시 Main에도 업데이트 해주고, Develop에도 업데이트 해준다.

2. Git Rebase vs Git merge

Both of these commands are designed to integrate changes from one branch into another branch - they just do it in very differnet ways.

그러면 왜 rebase와 merge 두 개나 있을까?
둘이 하는 역할이 다르기 때문이다.

Git merge

Q. main이 업데이트 되었다. 그럼 이제 뭐해야 하나?
A. 내 main git pull 하고 다시 내 브랜치로 이동해서 git merge main 명령어를 날릴 것이다.

Q. main 에 있던 새로운 다섯 개의 커밋은 어디로 들어갈까?
A. 시간 순서대로 내가 찍어놓은 커밋들 사이사이에 들어간다.

⛔️ 이렇게 되면 문제점이 있다.
1. 불필요한 merge commit이 생성된다.
2. history가 복잡해진다. 특정 커밋이 어떻게 생성되었는지 알아보기 어렵다.

Git rebase

위의 두 가지 문제점을 해결해 주는것이 바로 git rebase이다.‘Re-Base’ 다시 Base를 맞추어 주는 것이다! 다시 말해, 내 커밋의 base를 변경하여, commit history를 바꾸어준다.

git merge의 두 가지 단점을 아래와 같이 보완해준다.
1. 불필요한 merge commit이 제거된다.
2. 같은 작업을 진행한 commit끼리 모아주어, 최종적으로 특정 기능(커밋)이 어떻게 생겨났는지 확인할 수 있다.

⛔️ 그런데 Git rebase의 단점이 있다.

1. 커밋 아이디가 달라진다 ➡️ 별개의 커밋이 생겨버린다!

rebase를 하면서 옛날에 했던 커밋들을 다시 쓴다. 그래서 새로운 커밋이라고 생각해서 아이디를 다시 쓰는 것이다.

2. rebase를 자주 하지 않을 경우 연쇄 conflict가 생길 수 있다.

(0 - 1 에서 컨플릭트가 났는데, 해결했는데, 이제는 또다시 1-2에서 컨플릭트가 날 수 있다. 그 다음 2 - 3 ....) 따라서, 꼭! 반드시! 커밋이 두 세개 쌓였을 때, rebase를 한번씩 해야 한다!!! 자주 해야 conflict가 밀리지 않는다.


3. Squash

4-5개 있는 커밋을 하나로 합치는 것이다.
그러면 커밋을 왜 합쳐야 하나? 남길려고 커밋하는건데.

자. 내가 처음 커밋하나 하고, 리뷰반영을 하나 했어. 그런데 이게 다른 사람에게 보여주고 싶은 커밋은 아니잖아? 그래서 squash 라는 기능을 이용해서 하나로 합치고 메세지 한번 깔끔하게 정리하면 된다.

간편 정리!는 아래에 👇

새로운 커밋을 받으러~
git checkout main
git pull origin main 
git log // 잘 들어왔는지 확인

git checkout feature/minju
git rebase main // 두둥 충돌발생 - 실제로 Github에도 conflict가 떠있다. 
//기존과 동일하게 conflict 해결 해준다.

//conflict 해결 후 
git add .
git commit -m "Fix : conflict 해결"
git push origin feature/minju  //오류 뜬다!!!

//rebase는 커밋을 다시 쓰는 것이기에 받아들일 수 없다고 내뱉는 거라, 
--force블 붙여주면 된다.
git push origin feature/minju --force

//아직 squash는 안했다. 별도의 명령어가 있는게 아니다.
git rebase -i main
//맨 위에 커밋에 pick. 나머지는 s
//커밋 메세지도 맨 위에 커밋에 합쳐주고 나머지는 삭제해준다.
//Tip! i모드로 들어가지 않은 상태에서 지우고자 하는 커밋 앞에 커서를 두고
//dd를 두번 누르면 커밋이 삭제된다! 

상세 과정은 아래에! 👇

새로운 커밋을 받으러~
git checkout main
git pull origin main 
git log // 잘 들어왔는지 확인

git checkout feature/minju
git rebase main // 두둥 충돌발생

실제로 위와 같이 PR에도 충돌 발생해 있다.
당황하지 말고 터미널에 뜬 메세지를 읽어봐라

// 1 2 3
// base 1 ⇒ 현재 이과정에서 문제발생!
base 1 2
base 1 2 3

어떻게 해결해야 할까? 🧐
✅ rebase 전으로 돌아가고 싶다면, git rebase --abort

✅ conflict 해결 후 push 하고 싶다면!
나는 커밋을 3개 남겼는데, 확인해보면 하나만 떠 있는 것을 볼 수 있다. 당황하지 말자! 첫 번째 커밋에서 컨플릭트 떴기 때문에 아직 그 뒤의 내용이 없는 것 뿐이다! 해결하면 나타난다.

conflict 해결 후, 다시

git add
git rebase --continue


git log를 쳐보면 base가 다시 변경된걸 볼 수 있다.

자 이제 git push 로 마무리

rebase는 커밋을 다시 쓰는 것이라고 했지! 그렇기에 받아들일 수 없다고 내뱉는 거라, -force하면된다.

다음과 같이 github 상의 conflict 메세지도 사라진 것을 알 수 있다.

그런데, 아직 squash는 안했다.
squash는 별도의 명령어가 있는게 아니다.

git rebase -i main

다음과 같은 터미널창이 뜬다

전에 커밋이랑 합쳐야 하니까 무조건 제일 위에꺼가 pick이 되어야 한다. vi 에디터에서 i 누르고 들어가서 첫번째를 제외하고는 s 를 입력해줌 ➡️ esc ➡️
:wq 엔터

그러면 커밋메세지 정리창이 나온다.

첫번째 커밋 메세지를 제외한 나머지 두 개는 지워주고 필요에 따라 첫 번째 커밋 메세지에 추가하여 작성해준다.(i 로 수정, esc + :wq 로 저장후 나오기)

git log를 쳐볼까?

자, squash가 잘 되었다. github에도, 세 개로 나뉘어 있던 커밋들이, 다음과 같이 하나로 정리된 것을 볼 수 있다.

👇 before & after

profile
⚓ A smooth sea never made a skillful mariner

0개의 댓글