4. Branch 관리

JSLEE·2024년 4월 12일

저번 포스트의 마지막에서, branch 가 무엇이고, branch의 생성 및 branch 간 이동에 대해서 알아보았다.
Git과 Github 이용하기 (VsCode)

브랜치는 기본적으로 main이나 master 브랜치를 갖고,
추가적으로 branch를 생성해서 사용하는데,
branch를 생성할 때의 이름에 대해서는 규칙이 존재한다.

branch 이름 작성 요령

branch는 3가지 목적에 따라 이름을 정한다.

1. 기능 개발 (feature)

특정 기능을 구현하고자 할 때, 해당 기능을 이름으로 사용한다.

ex) feature/login , feature/show-list ...

2. 출시 (release)

이번 버전을 출시하고자 할 때, release를 이름으로 사용한다.

ex) release-1.0 ,  release-1.1 ...

3. 버그 수정 (hotfix)

출시한 버전에서 버그가 발견되어 수정하고자 할 때 사용한다.

ex) hotfix-1.0.1 , hotfix-1.1.1

위의 규칙을 사용하면서 이름을 지어보면서
오타 등의 이유로 branch를 지우고자 할 때,
다음의 명령어로 브랜치를 삭제할 수 있다.
git branch -d 브랜치명


지금까지 공부한 내용들로, 우리는 branch를 왔다갔다 하면서 작업을 할 수 있다.
하지만, vscode를 이용해서 작성해보면 A 브랜치로 이동해서 기존 파일의 내용을 수정했는데 B 브랜치로 이동해보면 B에서도 수정되어 있는 것을 볼 수 있다. 왜 그럴까?

<상황>
브랜치목록 :
main
A
B

A브랜치로 들어가서, 기존의 파일 test.txt 를 수정 후 저장.
B브랜치로 이동.
B의 test.txt파일도 수정되있음 <-- 문제 사항

그 이유는 commit을 하지 않았기 때문이다.
각 브랜치에서 작성한 후에, 반드시 그 브랜치에서 commit을 진행해야한다.
즉, A에서 작성한 후에 commit을 눌러서야 완전히 브랜치가 생성된다는 의미이다.

실습을 위하여 feature/login이라는 브랜치를 만들고 commit까지 해보았고,
다음과 같은 history 를 확인할 수 있었다.

맨 위의 Login Branch Commit이 feature/login 브랜치에서 commit한 커밋메시지이다.

이제 로컬(PC) git에서 작성을 완료했으니 github로 업로드해보자.
저번에 배웠던 명령어인 git push 리포지토리이름 브랜치이름를 이용한다
git push origin feature/login 을 작성했다.

Github에 접속하여 확인해보면,

정상적으로 브랜치가 업로드 되어있는 것을 확인할 수 있다.
또한, vscode 터미널에서 깃허브에 어떤 브랜치가 존재하는지 확인도 가능하다.
git branch -r 을 입력하여 깃허브의 브랜치를 확인한다.


branch는 최종적으로는 하나의 브랜치로 합쳐져야 한다.
문제없이 잘 합쳐지는 경우도 있겠지만, 충돌이 발생하는 경우도 생길 것이다.
따라서 우리는 브랜치를 작성할 때 전략적으로 구성해야한다.

Branch 전략

branch 전략에는 대표적으로 2가지가 존재한다.

1. fast-forward

main 이라는 브랜치가 있다. 여기서 새로운 브랜치(A)를 만들 것이다.
main 은 건드리지 않고, A에서 코드 작성, 파일생성 등 작업을 진행한다.
이 후, main과 A 브랜치를 합친다.
이것이 fast-forward이다.
단순하게 main 브랜치에 A 브랜치를 붙여서 사용하는 전략이다.

다만, 협업에서는 하나의 브랜치에서 구현하는 동안 다른 브랜치가 쉬는 경우는 거의 없으므로 잘 사용되지 않는다.

2. 3-way

따라서, 다양한 브랜치에서 업무를 수행하여 합치는 전략이 3-way 전략이다.
일반적으로 가장 많이 사용하는 전략이다.
main 브랜치가 있고, A브랜치와 B브랜치를 생성한다.
A에서도 기능을 구현하고, B에서도 기능을 구현한다.
그리고, A브랜치를 main에 merge 시킨다. (이 때는 fast forward 가 일어나는 것과 같다 )
또한 B브랜치를 main에 merge 시킨다.

이러한 전략을 3-way 전략이라고 한다.

전략에 대해 알아보았고, 실제로 병합을 진행해볼 차례이다.


pull request 와 merge

정상적으로 진행하였으면,
github 리포지토리에서 노란박스가 생성되어 compare & pull request 버튼이 있을 것이다.
클릭하면 다음의 화면이 나온다.

상단을 보면, base:main <- compare:feature/login 이 되있고, Able to merge라고 되어있다.
이것은 병합을 원하는 브랜치(feature/login)에서 main에게 당겨달라고 요청한다는 의미이다.

여기서 우리는 P(pull)R(request) 메시지를 작성할 수 있다.
이 부분에는 구현 내용과 문제점 등 다양한 사항을 적는다.

마크업 언어를 이용해서 가독성있게 꾸밀 수도 있으니, 그렇게 하면 좋다.

정상적으로 진행했다면 하단의 Merge pull request 를 눌러 merge 한다.
이상이 없다면,

성공적으로 merge 되었다는 메시지가 나온다. 이제 불필요해진 feature/login 브랜치는
Delete branch 버튼을 눌러 제거한다.

이후 깃헙 리포지토리를 확인하면,
브랜치가 main밖에 안남아있고, login 브랜치에서 수정했던 내용이 적용되어 있는 걸 확인 가능하다.

branch protect

병합하면서 다양한 문제가 생길 수 있기 때문에, 방지책으로 branch protect가 존재한다.
이는 깃허브 상단의 Setting > Branches 에서 설정이 가능하다. 다양한 옵션이 존재하며 선택하여 기능을 적용할 수 있다.

merge된 Github를 Git으로 가져오기

모든 브랜치가 합쳐졌다.
우리는 이걸 다시 Git으로 가져와서 확인할 수 있다.
먼저, git branch -r로 원격리포지토리의 브랜치를 확인해보면,
우리는 github 홈페이지에서 브랜치를 지웠는데 feature/login 브랜치가 여전히 존재한다.

따라서, 현재 로컬 git이 알고 있는 github의 브랜치에 대한 상태와,
실제 github의 브랜치 상태를 똑같게 만들어줄 필요가 있다.
이 명령어가 바로 git fetch -p 명령이다.

그리고나서 다시 git branch -r 을 해보면, 원격리포지토리와 로컬리포지토리가 같아짐을 확인 가능하다.

이제 원격리포지토리의 브랜치목록과 로컬리포지토리의 브랜치목록은 같아졌는데,
git branch 를 통하여 확인해보면 로컬리포지토리의 브랜치가 남아있다.
그래서 git branch -d feature/login 을 입력했는데, 오류가 발생한다.

이는 git log 를 이용하여 확인해보면, github 의 커밋히스토리와 다르게 merge commit이 없기 때문이다. 따라서 main 브랜치도 동기화가 필요하다.
git pull origin main 을 입력하여 main 브랜치도 github의 수정내역과 같이 동기화한다.

이후 다시 git branch -d feature/login 을 입력하여 브랜치를 삭제한다.
이로써 merge된 프로젝트를 얻게 된다.


충돌

위의 branch 전략에서, 3-way 방식을 생각해보면 충돌하는 경우가 발생할 수도 있다.
예를 들어, A브랜치에서 test.txt 파일의 내용을 수정했다.
B브랜치에서도 test.txt 파일의 내용을 수정했다.
그리고 두 브랜치 모두 github에서 merge 한다면 어떻게 될까?
예상대로, test.txt파일에서 문제가 발생할 것이다.
A브랜치의 내용을 쓸 지, B브랜치의 내용을 쓸 지에 대한 문제이다.

Can't automatically merge 라고 하긴하지만, pr메시지를 작성할 수 있다.
create pull request 를 누르면 다음과 같이 된다.

충돌 사항에 대한 문제를 해결해야 한다는 소리이다.
Resolve conflicts를 누르고 수정하여, 어떤 내용을 쓸 지 수정한 뒤에,
mark as resolved 버튼을 클릭하고, merge하면 해당 내용으로 정상적으로 merge 됨을 확인할 수 있다.

profile
공부한 내용들을 정리하기 위해 사용하는 블로그입니다.

0개의 댓글