[ Session ] Git flow & Rebase

Hailee·2020년 12월 31일
0

 > wecode 

목록 보기
11/11
post-thumbnail

세션을 시작하기에 앞서, 개발자의 가장 중요한 자질인 백업하기

랜섬웨어 걸려서 운영중인 회사 프로젝트를 통째로 날린 직원을 본 기억이 있다. 🤯

기본 전제는 뭐 "git 천재이다"라면 더할 나위 없이 좋겠지만, 현실은 그리 쉽지 않고
나는 아직 git이 너무 무섭기에.

그리고 오늘 정말 내 commit을 다 날려버렸기 때무네!!!!

열심히 정리해보는 Rebase 세션🥵


우리가 겪은 행복한 git 모험기.
정리하자면 대략 이런 모양새다.

Basic Git flow

Develop, Main이라는 운영, 개발환경 branch가 있고,
각 기능을 구현하는 feature branch들이 존재한다.

구현해야할 기능이 있을 때 Develop branch에서 pull받아온 뒤, feature branch들에서 작업을 진행한다.
이 중 먼저 완성된 feature branch에서 Develop branch로 push하고, merge되고나면 Release라는 배포용 branch가 생성된다.

여기서 Main branch로 아름답게 merge된다면 정말 좋겠지만,
슬프게도 bug의 발생 가능성을 무시할 수는 없는 법!

bug가 발생하게 되면 Release branch에서 수정을 하게 되고, 이 commit이력을 하위 branch들인 Develop, feature branch들이 pull 받아와야한다.

이렇게 되면, 매 순간 받아온 다른 branch들의 commit이력이 나의 commit이력과 뒤섞이게 되어, git log가 몹시 지저분해진다.
이걸 혁신적으로 간결하게, 깨끗하게 만들어주는 것이 바로 Rebase!


이제 우리를 슬프게 할 Rebase에 대해서 알아보자


👉🏻👉🏻 두리님의 친절한 rebase 정리!

0. backup, 정말 중요해!

cp -rpv adwards-frontend adwards-frontend2
cp -rpv왼쪽 👉🏻 현재의 폴더명 / 오른쪽 👉🏻 새로 생성할 폴더명

🥵 경로 조심하기!
내 폴더가 속하기 바로 전 단계의 경로에서 저걸 실행해야 동일한 위치의 디렉토리에 쌍둥이 폴더가 생성된다.

1. gcm

git checkout main, git pull origin main
👉🏻 pull을 완료하고 나면, main 👉🏻 원래 branch로 바꾸기!

rebasepush 전 단계에서 진행하는 것이기때문에, 내가 반영하고자 하는 수정 내용들이 모두 commit되었는지 잘 확인할 것!

아, 그리고 rebase는 여러 commit들을 하나의 commit으로 합쳐주는 것이기 때문에,
commit내역이 하나뿐일 때에는 하면 안된다.

내가 어제 그렇게 했다가... 크게.. 날릴뻔했거든...

2. Rebase

git rebase -i HEAD~2
👉🏻 HEAD 뒤에는 내가 통합하고자 하는 commit 개수를 적어주면 된다.

(저 commit의 고유 번호를 통해 다시 commit이력을 되돌리거나 할 수 있다)

나같은 경우는 commit이력이 하나뿐이기 때문에 내역이 하나만 뜨는 상황.
commit이력이 여러개인 경우, pick을 하나만 두고 나머지를 s 혹은 squash로 바꿔주면 된다.
👉🏻 이렇게 되면 하나의 commit 이력만 남길 수 있다.

이후 어떤 커밋 메세지를 남길 것인지 확인하는 화면에서 커밋 메세지를 수정하면 끗!

Rebase 잘못했을 때 되돌리려면?

👉🏻 reflog를 이용한 rebase 취소 / push 취소
git reflog

👉🏻 이 명령어를 통해 지난 모든 commit 이력을 볼 수 있다.
내 branch명을 입력하면 내 branch에서의 commit이력만 볼 수도 있구!


git reset --hard 'commit번호'
👉🏻 이 명령어를 입력하면 해당 commit의 시점으로 되돌아간다. (과거여행 뿅!)


git rebase --abort
👉🏻 이 명령어를 입력하면 rebase를 시도하려는 현재 상태를 벗어날 수 있다.


Merge 와 Rebase의 차이점?

git merge와 비슷하다고 하지만 약간 다르다.

  • merge두개의 branch를 합치는 것!
    👉🏻 main + feature

    👆🏻 feature/sign-up의 commit들이 main으로 merge되면서 main branch에는 feature/sign-up의 commit들과 merge commit이 생성된다.

    👆🏻Git merge main을 하고 나면 feature/sign-in branch 내 어느 부분에 merge되는걸까?
    처음엔 3번이라고 생각했다 (그래서 제때 제때 pull 받는 것에 집착했던 나!)

    👆🏻 사실은, 이랬던 것.
    main branch를 feature/sign-in으로 merge 하면서 commit log가 각 시점에 맞게 자동으로 들어간다.

    👆🏻 모든 feature branch마다 main branch 내 merge commit을 남기기 때문에,
    main branch를 공유하는 개발자가 많을 수록 main의 branch history가 지저분해진다.

🌟 개별 feature branch에서 로직 하나를 작성하고 수정하더라도 다른 작업과 그 내역이 겹쳐 구분하기 어려워진다 ("history가 복잡하다")🌟

그래서 Rebase가 좋은 이유가 뭔데?

base : 아무런 작업도 하지 않은 main branch의 최초 상태
rebase : 다른 branch의 완전한 작업이 끝난 commit을 합쳐서 다시 base화 한 후 commit 내역을 일렬로 잘 정리하는 것

지저분한 merge commit을 남기지 않고, 기능별로 통합할 수 있따.
branch의 commit들을 모아서 보여주는 것!

👇🏻 이렇게 각 개인이 sign-in, sign-up 작업중인 상황이라고 할 때,

commit은 앞 6자리의 고유 번호로도 인식할 수 있다고 한다.


👆🏻 git Merge를 하면 타인의 작업 commit log가(불필요한 commit) 내 commit history에도 들어오게 된다.


👆🏻 리베이스 후 보이는 로그 기록의 시간 순서는 뒤죽박죽으로 정렬이 되어 있다.
(가장 완성도 높은 이전 commit이 앞선 log로 기록되고, 작업중인 불완전한 commit은 가장 최신 commit log로 기록된다.)


내가 sign-in branch라고 했을 때, commit 자체는 나의 commit이 가장 최신 commit이지만, 코드 수정 시간은 sign-in과 비슷하기 때문에
rebase해서 sign-in의 모든 commit 시점이 뒤로 밀려났다고 해도, 나의 모든 commit들에서 conflict가 난다.
👉🏻 ex)
1. 29일 15:30의 sign-up commit이 완성된 최종 commit같은 거고
2. 그 이후로 밀린 sign-in의 commit들과 충돌을 해결하는 게 맞나요
3. main의 sign-up 최종 commit과 나의 commit이 충돌이 날 것.


git merge만 하면 이렇게 commit log가 하단부의 history처럼 지저분해진다.
하지만 rebase를 하면 상단부처럼 깔끔한 history만 남는다.

결국, 같은 파일을 수정한 것이 아니라면 conflict 날 일이 없는 것은 merge와 비슷하지만
git history의 깔끔함을 생각했을 때 rebase가 매우 나은 것!
👉🏻 rebase는 다른 모든 커밋들에 대해 전부 충돌을 해결해야 해서 더 충돌이 많이 일어날 가능성이 있는 것,
👉🏻 merge는 시간 기준 몇몇 이전 커밋들에 대해서만 해서 충돌을 해결하면 되서 충돌이 적을 수 있는 것!


Squash

모든 변경사항이 하나의 commit으로 합쳐지는 것!
👉🏻 commit 언패킹으로 찾아갈 수 있고,
👉🏻 일부 commit만 골라서 합칠수도 있다.


앞으로 git merge란 없다.


main을 pull받은 뒤 작업에 있어서
앞서 git merge main 하던 것을 git rebase -i main라고 하면
새로운 창이 뜨면서 어떤 commit을 rebase할 것인지 선택할 수 있다.

??????
rebase만으로 commit이 합쳐지는 것은 아니고
squash를 통해야 하나의 commit과 충돌 해결을 하는 것
그렇지 않다면 여러번 충돌해결을 하는것


예를들면 세개의 commit message를 한줄로 합쳐주는 것!


시간 날 때마다 rebase를 계속 해주면 나의 base가 계속 바뀌는 것.
git 입장에서는 기록이 계속 달라지기 때문에 "너 원래 이런 애 아니었잖아.. " 이렇게 되는 상황!
그래서 force push를 해줘야 할수도..


Rebase중 충돌 해결하기

가장 중요한건 매 순간 파일 백업, commit은 충실히 하기!
그렇지 않으면 다 날아갈~~ 수도 있다는 거!


rebase 중 충돌이 발생하면 merge할 때와 비슷한 conflict message가 발생한다.

(rebase ~ 1/6)
👉🏻 6개의 충돌이라는 뜻이 아닌, 1번째 대상이 충돌했다는 뜻!
하지만 해결하고 나면 2/6 이런식으로 될 수도 이써..ㅇㅇ...

충돌일 뿐, 무언가가 뻗어버린 건 아니니까 ^^
해당하는 코드를 수정한 후 다시 git add .

무튼 앞으로는 하나의 pull request에 여러 commit들이 딸려있었다면,
앞으로는 소소한 변화들에 따른 commit들은 ( ex) 변수명 수정, 주석 삭제... )
rebase를 통해서 하나의 commit만 존재하도록 할 수 있게 되는 것!


Git Rebase 명령어 총 정리!

- Git reset soft vs hard
- Git log
- Git reflog
- Git checkout <commit> 	--> 그때 그 시절 commit을 볼 수 있다는 거!
- Git stash & git stash apply & git stash clear


- git rebase -i HEAD~커밋개수 	--> 내가 한 커밋들 rebase 하기
- git rebase -i main		--> main 에서 pull 해온 이후 내 branch로 rebase하기 (merge가 필요없다)
- git add .
- git rebase --continue		--> 이후 commit, commit 메세지 하나로 통합하는 과정으로 꼬!
profile
웹 개발 🐷😎👊🏻🔥

0개의 댓글