Merge, Squash and Merge, & Rebase and Merge

9rganizedChaos·2021년 12월 15일
2

드디어 개발자가 된 나, 의외의 난관, 깃헙 💥

그간 취준 포스팅으로 점철된 나의 블로그에 드디어 개발자라이프에 대한 글을 작성할 수 있게 되었다...! (대충... 취업했다는 이야기...) 회사생활에 대한 이야기나 취준 회고는 따로 하도록 하고, 오늘은 회사에서 개발을 시작하며 마주했던 첫 난관에 대해 간략히 포스팅을 해보려고 한다.

첫 출근일이 확정되고 나는 부랴부랴 NextJS, GraphQL, Apollo 등 회사에서 사용중인 스택을 간단하게나마 훑어보기 시작했다. 당장 개발에 투입되었을 때, 가능한 허둥대지 않고 싶었다! (👈🏼 이건 어디까지나 희망사항이었던 것...)

내 예상과는 달리, 회사에서 개발을 하며 부딪힌 첫 난관은 Github이었다!
GitHub을 하나의 기술/스택이라고 여겨본 적이 있었나... 생각해본다.
사실상 부트캠프에서 협업을 할 때는 모두가 서툴었기 때문에 깃 로그를 제대로 관리해봐야겠다거나 브랜치 전략을 세워봐야겠다는 생각을 할 여유가 없었다. 부트캠프 이후에 했던 작업은 솔로 사이드 프로젝트였기 때문에 협업에 대해 고민해볼 기회가 없었다.

<부트캠프 파이널 프로젝트와 솔로 사이드 프로젝트의 커밋 로그>

가히 대환장의 로그 그래프라 하지 아니 할 수 없다 😇
이런 (노)베이스로 협업을 시작하다 보니 당연히 당황할 때가 많았다. 내가 알고 있는 깃허브 관련 지식이라곤 git add . + git commit -m "[깃모지] + 동사 + 커밋내용" + git push origin [브랜치] + git pull origin [브랜치] 가 전부라해도 과언이 아니었으니까. 사실 이미 개발이 끝난 브랜치를 삭제해서 로그를 깔끔하게 유지하는 부분이나, 커밋들을 합쳐 하나의 유의미한 단위의 커밋들을 만들어내는 것보다는 그때그때의 컨플릭을 해결하는데 집중해왔었다.

"머지 커밋, 스쿼시 머지, 리베이스 머지에 대해 아세요?"라는 질문은 정말이지 천지가 개벽하는...까지는 조금 오바고... 아무튼 이세계 질문처럼 느껴졌다. 창피하지만... 정말 그냥 처음 듣는 이야기였다.

그래서 오늘은 깃헙 클라이언트 "소스트리"와 함께 깃헙의 세 가지 머지 방식에 대해 블로깅을 해보고자 한다.

🍽 머지 실습 세팅하기!

세 가지 커밋 방식을 이해하는데, 애를 먹었던 이유는 개념 자체에 대한 이해보다는 실습 경험이 부족했기 때문이었다. 그래서 직접 깃헙에 레포를 만들고 실습을 해보았고, 그 내용을 여기에 적어보고자 한다.

🥏 소스트리

오늘 창피한 고백을 여러 번 하게 되는데, 나는 깃 클라이언트라는 것이 존재하는지도 몰랐다. 찾아보니, 깃허브 데스크탑, 소스트리 등에 대해 알 수 있었다. 그동안 cli 명령어로만 분투해온 내 자신이 좀 안쓰러워졌다.

우선 깃 클라이언트 소스트리부터 설치해주자.
아래 링크를 통해 소스트리 페이지에 접속하면 쉽게 다운 받을 수 있다!
설치 방법에 대해서는 좋은 블로그 글들이 많으니 "소스트리 설치"라고 구글링하면 금방 찾을 수 있을 것이다.

소스트리 공식페이지

깃허브 데스크탑도 설치해보았는데, 깃 로그 그래프가 예쁘게 출력되지 않아서 소스트리로 갈아타보았다.
뭔가 Jira와 같은 개발 협업툴을 만든 Atlassian에서 만든 깃 GUI라 신뢰도도 큰 폭으로 상승... 아무튼!

<깃허브 데스크탑 (아래에서 소스트리의 UI를 보게 될텐데 나한테는 소스트리가 더 매력적이었다!)>

💽 실습레포 생성하기

소스트리를 설치했다면, 깃헙에 머지 실습 레포지토리를 생성해준다!

나는 아래와 같이 세팅했다. 이름이나 설명은 각자 원하는 방식으로 작성해도 무관할 것!

위에 작성해놓은 Repository name: mergin-practice
위에 작성해놓은 Description: merge commit / squash merge / rebase merge를 연습하기 위한 레포지토리입니다.
(귀찮으시면 복붙하세요~)

레포를 생성해주고나서, 실습을 진행할 로컬 디렉토리에서 새로 생성한 레포를 클론해주자!

git clone [새로 생성한 깃헙 레포 url]

이 포스팅에서는 create-next-app을 활용해 간단한 NextJS 앱으로 실습을 진행할텐데..!
사실 꼭 NextJS 앱을 활용할 필요도 없거니와, 이 실습에서는 NextJS에 대해 모르더라도, 실습을 하는데 전혀 상관이가 없다.

먼저 아래와 같이 입력해준다.

cd merging-practice(본인이 생성한 레포이름)

npx create-next-app ./

NextJS 설치가 끝났다면 아래와 같은 폴더구조의 프로젝트를 확인할 수 있을 것이다!

실습을 위한 세팅이 완료되었다!

로컬에 설치된 소스트리를 열고 로컬에 설치한 프로젝트를 소스트리에 드래그앤드랍해주면!
위와 같은 모습을 확인할 수 있을 것이다.
그리고 mergin-practice를 클릭하면!

아직 레포를 생성하고 딱히 해준 것이 없기 때문에 당연히 히스토리 내역은 깔-끔✨
대기 중인 파일에는 우리가 아직 레포에 커밋해주지 않은 내역들이 보이는 것을 알 수 있다.
이 부분은 사실 vscode에서도 살펴볼 수 있는 소스컨트롤 창과 같다!

그렇다면 먼저 이 내역들을 main branch에 커밋 + 푸쉬 해주자!

git add .
git commit -m "init: MAIN 이니셜 커밋"
git push origin main

(cli 명령어로 하지 않고, 소스트리 이용해도 좋다!)

이렇게 해주고 나면 드디어 소스트리 히스토리에 내역이 생긴 것을 볼 수 있다.

🫂 Merge Commit

이제부터 개발 브랜치를 따로 따서 작업을 하는 상황을 가정해보자!
먼저 체크아웃을 통해 dev 브랜치를 생성해주자!

git checkout -b dev
git push origin dev

깃 원격 레포에 dev 브랜치가 생성된 것을 확인할 수 있고,

소스트리에서도 체크아웃 내역을 확인할 수 있다.

현 상황에서 우리에게 주어진 업무가 다음과 같이 있다고 가정하자.

1) page10 추가하기
2) page11 추가하기
3) page12 추가하기

page10 추가하기

먼저 루트 디렉토리의 pages 폴더의 내부에 page10.js 파일을 생성해준다.
그리고 내부에 아래와 같은 내용을 작성한다.

function Page10() {
    return <h1>The Page10</h1>;
  }
  
  export default Page10;

이렇게 커밋되지 않은 변화가 생기면 소스트리에 Uncommitted changes라고 표시되는 것을 살펴볼 수 있다.

자 이제 하나의 작업을 끝냈으니 dev 브랜치에 작업 내용을 커밋 푸쉬해주자!

git add .
git commit -m "feat: DEV page10 추가"
git push origin dev

자 이제 소스트리의 히스토리가 조금 바뀐 것을 살필 수 있다!

page11 & page12 추가하기

같은 방식으로 두 개의 커밋 내역을 더 생성해주자!

메인 브랜치로 돌아와 커밋 내역 만들기

우리는 이제 다시 메인 브랜치로 돌아와서 커밋을 하나 생성해준다.
index.js에서 홈페이지를 만들어줄 것이다.

먼저 체크아웃!

git checkout main

사실 소스트리에서 좌측 내브바의 브랜치를 더블클릭해도 된다!
모쪼록 메인 브랜치로 돌아온 후에, index.js를 수정해준다.

function HomePage() {
  return <h1> Home Page</h1>;
}

export default HomePage;

page10, page11, page12에 빨간줄이 그어진 것은 얘네가 대단한 죄를 지어서는 아니고... ㅈㅅ;;
저 파일들은 우리가 dev 브랜치에서 작업해준 애들이기 때문에 당연히 아직 메인에는 내역이 없는 것!

모쪼록 이렇게 작업을 해주고 커밋을 날려준다!

git add .
git commit -m "fix: MAIN 홈페이지 수정"
git push origin main

이제 부터가 관건이다!
소스트리를 확인해보자!

이렇게 위와 같은 로그 그래프를 확인할 수 있다!
지금이 바로!! 머지 타임!!
이런 상황에 머지를 해주어야 하는데, 우리는 앞서 깃허브에는 세 가지 머지 방식이 있다는 사실을 알아보았다. 개념은 미리 익혀도 까먹기 마련이므로 이 실습에서 세 가지 머지를 모두 시도해볼 것이다

우리에게 익숙한 머지 커밋을 시도하자!

먼저 풀리퀘스트를 생성해준다.

해당 PR의 베이스 브랜치가 어디인지 늘 확인하자... 두 번... 세 번 하자...!

제목은 재량껏 작성한다!
PR이 올려지고 나면 아래와 같이 드롭다운을 클릭해 머지 방식을 선택할 수 있다.

우리는 머지 커밋을 시도할 것이니까 별 다른 것을 건드려줄 필요는 없다!
위 상태에서 Merge pull request를 클릭하고 나면 아래와 같은 화면을 확인할 수 있다!
여기서 한 번 더 confirm merge를 클릭한다.

작업이 끝났으므로 브랜치도 삭제해준다.

Delete branch 클릭!

자, 이제 소스트리를 확인할 차례이다!

여기서 눈여겨 볼 지점은 dev 브랜치의 커밋내역이 다 잘 살아남아있다는 점과
두 브랜치의 내용을 병합한 하나의 커밋이 별도로 로그에 생겼다는 점이다!

모쪼록 머지를 했으니 원격의 메인을 당겨오자!

빨간줄이 다 사라지고 코드가 잘 병합된 것을 볼 수 있다.

자 이제 로컬에서 역시 dev 브랜치에 대한 한 뭉치의 작업이 마무리되었으므로 로컬의 dev 브랜치를 삭제해주자!

git branch -D dev

여기서 삭제하지 않고 계속해서 작업을 이어나가면 기존에 갖고 있던 커밋 내역이 계속해서 남게 된다!

🌯 Squash and Merge

자 이제 스쿼시 머지를 살펴볼 것이다!

당신에게는 아까와 동일한 작업이 주어졌다.
다만 페이지의 이름이 조금 다르다!

1) page20 추가하기
2) page21 추가하기
3) page22 추가하기

page20 & page21 & page22 추가하기

dev 브랜치로 다시 한 번 체크아웃해서 위 태스크를 진행해준다.
위와 같이 한 태스크를 진행할 때마다 커밋을 하나씩 만들어주자!
위와 동일하게 작업을 진행해주고 나면 아래와 같은 깃 로그를 소스트리에서 확인할 수 있을 것이다.

메인 브랜치에 커밋 내역 만들어주기

이 역시 위와 같다.
머지하는 상황을 연출해주기 위해서 메인브랜치로 돌아와 메인브랜치에도 커밋 내역을 만들어주자.
어떤 커밋 내역을 만들든 자유이지만, 고민이 된다면, 정해드리겠읍니다~
index.js의 text 내용을 수정해줍니다!

function HomePage() {
  return <h1>My Home Page</h1>;
}

export default HomePage;

이렇게 수정한 내역을 동일하게 커밋으로 날려주고 원격메인에 푸쉬해줍니다!

git add .
git commit -m "chore: MAIN 홈페이지 텍스트 수정"
git push origin main

아까와 비슷한 상황이 연출된 것을 깃 로그 그래프를 통해 확인할 수 있다!

스쿼시 머지 시도하기!

다시 한 번 돌아온 머지타임!
이번에도 머지를 해주기 위해 PR을 생성해준다.

New pull request를 클릭해준다!

Create pull request 클릭!

그리고 나서 내용입력을 해 pr을 마저 생성해준다.

이번에는 스쿼시 커밋을 시도할 것이기 때문에 드롭다운에서 스쿼시 앤 머지를 클릭한다!

클릭하면 위와 같이 내용입력창이 한 번 더 등장한다!
이 부분이 위에서 다루었던 머지 커밋과 약간 다르다. 왜 다른지는 나중에 알게 된다!
모쪼록 Confirm squash and merge를 클릭해주고, 브랜치 역시 마저 삭제해준다.

자 벌써 무언가 다른 점을 발견할 수 있다!
잘 보면 dev 브랜치에서 작업했던 세 개의 커밋 내용이 병합되어
메인 브랜치에 하나의 커밋으로 생성이 되었다!

자 이제 메인 브랜치에서 원격 메인의 내역을 당겨오자!

git pull origin main

그리고 기존에 로컬에서 작업했던 dev 브랜치를 아까와 같은 방식으로 삭제해준다.

또 하나 놀라운 점 있다!
스쿼시 머지를 실행하고 로컬의 브랜치를 삭제해주면, 머지 커밋과 달리 dev 브랜치의 커밋 내역이 말끔히 사라진다!!!

🫐 Rebase and Merge

드디어 마지막이다!
다시 한 번 여러분께 세 가지 태스크가 주어졌다!!!

1) page30 추가하기
2) page31 추가하기
3) page32 추가하기

위 태스크 + 메인브랜치에 커밋만들기 + PR 생성까지는 위와 동일한 과정이므로 생략한다!

메인브랜치에는 아래와 같이 홈페이지를 수정해 커밋을 만들었다.
(이 부분은 재량껏 해도 된다.)

function HomePage() {
  return <h1>My Fabulous Home Page</h1>;
}

export default HomePage;

다시 한 번 위와 같은 깃 로그 그래프를 확인할 수 있다!!

리베이스 머지 시도하기!

자 이번에는 생성해놓은 PR에서 위와 같이 Rebase and merge를 클릭한다!

리베이스 머지와 같은 경우에는 따로 내용을 입력받지 않는다!
이 역시 왜인지 곧 알게 된다!

모쪼록 Confirm rebase and merge를 클릭해준다.
(물론 브랜치도 말끔히 삭제! 개발이 끝났으므로...!)

이제 소스트리를 살펴보면!
(업데이트가 안 되었으면 페치를 해오자!)

위와 같은 깃 로그 그래프를 살펴볼 수 있다!
스쿼시머지와 비슷한 점은 데브 브랜치에 있던 내역들이 메인으로 옮겨졌다는 점인데,
다른 점은 하나의 커밋으로 병합되지 않았다는 것이다!

자 이제 로컬에서 데브 브랜치를 정리해보자!

git pull origin main
git branch -D dev

그러면 데브 브랜치 역시 말끔하게 정리된 깃 로그 그래프를 살펴볼 수 있게 된다!

자 이렇게 실습이 마무리 되었다!!

한 눈에 살펴보면 다음과 같다!!

profile
부정확한 정보나 잘못된 정보는 댓글로 알려주시면 빠르게 수정토록 하겠습니다, 감사합니다!

0개의 댓글