팀원들과 사이드 프로젝트를 한다면 필수적으로 알아야하는 git 사용법에 대해서 다뤄보고자 한다. 최근 친구와 사이드 프로젝트를 진행하면서 서로 각자 기능을 구현하고 합치려할 때 직접 파일을 넘겨주고 해당 파일을 어느 한쪽에 합치는게 불편하다고 느껴졌다. 매번 파일을 고치거나 새로 만들때마다 파일을 넘겨주면 어떤 파일이 최근파일인지 구별하기도 힘들고 합치는 과정도 하나의 task로 쌓여 피로도가 높아진다.
또는 이미 상용되고 있는 다른 프로젝트에 추가적으로 내가 원하는 기능을 구현해보고 싶을 때, 원본 프로젝트를 건들이지 않고 만들수 있는 기능이 필요하기도 하다.
이를 해결하기 위해 (각자 다른 버전의 코드를 관리해주기 위해...등) 알아야하는 개념이 git branch다.
여러 브랜치를 사용한 git graph (출처: Git Beginner's Guide for Dummies)
브랜치는 그 특징에 따라 나눠지는데 대체로 해당 작업의 특징에 따라 나눠진다.
배포될 소스가 기록되는 브랜치는 통합 브랜치(Integration Branch)/ 기능 추가 및 버그 수정을 위한 브랜치는 피처 브랜치(Feature Branch, Topic Branch)로 해당 브랜치에서 작업을 완료하면 통합 브랜치에 병합하여 사용한다.
기능 | git 명령어 |
---|---|
새로운 브랜치 생성 | $ git branch 브랜치이름 |
새로운 브랜치 생성 후 브랜치 전환 | $ git switch -c 브랜치이름 또는 $ git checkout -b 브랜치이름 |
브랜치 목록 확인 | $ git branch |
브랜치 목록과 각 브랜치의 최근 커밋 확인 | $ git branch -v |
브랜치 삭제 | $ git branch -d 삭제할 브랜치이름 |
병합하지 않은 브랜치 강제 삭제 | $ git branch -D |
브랜치 전환 | $ git branch switch 브랜치이름 또는 $ git checkout 브랜치이름 |
브랜치 병합 (master 브랜치로 전환 후 병합) | $ git checkout master $ git merge dev |
로그에 모든 브랜치를 그래프로 표현 | $ git log --branches --graph --decorate |
아직 커밋하지 않은 작업을 스택에 임시 저장 | $ git stash |
프로젝트를 진행하기에 앞서 팀원들이 각자 맡은 파트의 개발을 하기 위해서는 각각의 branch를 파서 개발을 진행해야 한다. branch를 만들고 작업하는 과정을 자세히 살펴보자.
진행할 프로젝트의 repository
프로젝트의 remote repository에서 fork를 해 나의 remote repository로 가져온다. 그런 후 코드 작업을 위해 local repository로 git clone 명령을 통해 소스코드를 가져온다.
local repository로 git clone을 해왔다면 이제 브랜치를 파는 작업을 하면 된다.
위의 그림과 같이 remote repository에서 main, dev 브랜치만 있던 저장소를 local repository로 clone해온 후 login기능을 구현한 개발을 하기 위해 feat/login 브랜치를 새로 생성하려 한다.
로그인 기능을 구현하다가 oauth인증을 받아 login하는 기능을 구현하고 싶을 때, 기존에 feat/login 브랜치에서 만들어둔 코드를 건드려 망가지게 할 수는 없으므로 feat/login-oauth 브랜치를 따로 만들어 준다.
feat/login-oauth 브랜치에서 기능 구현이 완료되었다면 작성한 코드를 합치기 위한 과정이 필요하다. feat/login-oauth에 있었던 브랜치에서 feat/login 브랜치로 다시 git checkout feat/login
한다.
feat/login에서 feat/login-oauth 브랜치를 생성하고 merge
feat/login 브랜치에서 따로 commit한 내역이 있는 경우
feat/login-oauth 브랜치를 합치면서 겹치는 부분은 없는지 확인 하고 merge
feat/login 브랜치에서 따로 commit한 내역이 없을 경우
fast-foward 방식으로 feat/login 브랜치에서 바로 feat/login-oauth 브랜치를 merge. (위의 그림 참고)
이 경우를 빨리 감기 merge라고 하며 feat/login-oauth 브랜치는 login 브랜치와 같은 히스토리가 들어있기 때문에, 따로 수정사항(commit)이 없었다면, feat/login의 최신상태를 feat/login-oauth가 합쳐진 상태로 빨리 감아주는 것이다.
merge가 완료된 feat/login 브랜치는 내 remote repository로 push한다.
origin local에서 origin remote repository로 push된 feat/login 브랜치
이때 명령어는 git push origin feat/login(푸시하고자 하는 브랜치이름)
.
push된 브랜치를 원본 프로젝트에 pull request
새로운 브랜치를 파서 login 기능을 만든 후에 원래 프로젝트에 넣고 싶다면 pull request로 원본 remote repository에 pull request를 보내 코드를 해당 프로젝트를 함께하는 팀원들과 확인도 가능하다.
만약 origin local에서 작업하던 도중 project remote repository에서 수정사항이 생긴다면 작업하고 있던 origin local repository로 pull해서 변경사항을 반영하여 그걸 바탕으로 진행해야 한다.
위의 과정을 전부 종합하면,
다음과 같은 git branch workflow가 나오는 걸 확인할 수 있다.
특정 시점으로 branch가 가리키는 곳을 변경하는 기능으로, 말그대로 branch base를 다시 정해주는 것이다. branch 통합의 개념으로 merge와 유사하나, merge와 달리 변경내역의 이력이 그대로 남아있지 않는다. 변경 로그를 더 깔끔하게 유지하고 싶을 때 사용하게 된다.
git rebase
첫번째 feat/login(검은글씨)에서 feat/login-oauth가 분기되었으나 각각의 브랜치에서 commit 내역이 생겼다. 만약 이 상황에서 git rebase feat/login feat/login-oauth
를 한다면 두 브랜치를 통합하기 위해, 가장 최신 커밋인 두번째 feat/login(빨간색글씨)로 base가 옮겨지면서 feat/login-oauth 브랜치도 두번째 시점으로 branch를 통합한다.
git rebase로 커밋 수정하기
git rebase -i HEAD~~
: HEAD(현재 브랜치 위치)에서 최근 2개까지의 commit내역을 보여준다.
-> 에디터가 열린다.
-> pick 커밋1(수정하려는 커밋)
에서 pick
을 edit
으로 수정하고 :wq
로 편집기를 나온다
-> git commit --amend
로 수정하려 했던 커밋을 편집기에서 수정한다
-> 커밋 수정을 마친뒤,git rebase --continue
를 하면 수정이 완료된다.
git rebase로 커밋 통합하기
git rebase -i HEAD~~
: HEAD(현재 브랜치 위치)에서 최근 2개까지의 commit내역을 보여준다.
-> 에디터가 열린다.
-> pick 커밋2(수정하려는 커밋)
에서 pick
을 squash
으로 작성하고 :wq
로 저장하고 편집기를 나온다
-> 커밋 통합에 관한 설명이 화면에 보여진다.
-> 통합 완료! (* git rebase는 커밋 로그는 합쳐지면서 수정되기 전 커밋 내역은 보여지지 않는다)
+) VScode에서 git graph 보는 법
extension에서 git graph 설치
추가적으로 학습 가능한 자료
와! 너무 유용한 글 감사합니다~