git branch, merge // conflict

woolee의 기록보관소·2022년 10월 24일
0

개발환경

목록 보기
5/17

git branch

코드에 새로운 기능을 추가해보고 싶으면, 원본 파일에 추가하면 문제가 생길 수도 있으니, 복사본을 만들어서 테스트해보고 원본에 적용하는 게 좋다. branch는 프로젝트 복사본임.

branch 만들려면 git branch <생성할 브랜치명>
특정 브랜치로 변경하려면, git switch 브랜치이름
(git checkout 브랜치명도 가능)

근데 새로운 브랜치를 만들고 그 브랜치로 이동하는 게 명령이 2개인데, 이걸 한번에 하려면 git checkout -b <생성할 브랜치명>

기본 브랜치명을 바꾸고 싶다면(보통 master에서 main으로 바꿀 때)
=> git branch -M main
또는 git branch -m master main (m은 move)

브랜치 목록 확인하려면 git branch 또는 git branch -r
브랜치 삭제하려면 git branch -d <삭제할 브랜치명>

다시 메인 branch로 돌아가고 싶으면,
git switch main(혹은 master)
(현재 브랜치 어딘지 까먹었으면 git status)

다른 branch에서 커밋을 하다보면 가지가 다르게 뻗어가는 걸 확인할 수 있음. HEAD가 내가 만든 다른 branch로만 향해 있고, 내 메인인 master는 HEAD로 향해 있지 않음.

따로 작업한 걸 원본 파일에 합치고 싶으면 merge


merge 하고 싶으면
1. main/master 브랜치로 다시 이동하고
2. git merge 브랜치이름 입력하면 합쳐진다.

합쳤을 때, merge conflict가 발생할 수 있다. 겹치는 부분이 있을 경우, 아래 사진처럼 뜬다.

<<<>>>>==== 이런 쓸데 없는 거 지우고 add/commit 하거나 혹은 vscode의 경우 하단에 Resolve in Merge Editor 버튼을 누르면 된다. 그러면 아래처럼 뜬다.

Accept Incoming, Accept Current, No Changes Accepted 셋 중 하나를 누르고 좌측 하단에 Complete Merge 버튼을 누르고 add/commit 하면 충돌을 해결할 수 있다.

마지막으로 push까지 해주면, origin이 위로 올라온다. 여기서 origin은 원격저장소를 의미한다.

conflict 실습

원격저장소가 있고, 여러 브랜치에서 각자 코드를 개발하고 있는 상황이라고 해보자. 다른 브랜치에서 특정 코드를 수정해서 원격저장소에 push를 한 상태에서.

다른 브랜치에 있는 내가 그 push된 사실을 모르고 내 로컬에서 똑같은 부분의 코드를 수정하고 commit으로 버전을 생성한 뒤, 원격저장소에 push를 하려고 하면 아래와 같이 rejected 경고가 뜬다.

어떻게 해야 하냐면,

첫번째 방법
git reset --hard HEAD~1 로 버전을 한 단계 뒤로 되돌린 다음, 원격저장소에 있는 내용을 그대로 가져오면 된다.
하지만 내가 만든 커밋이 되돌리기에는 너무 아깝다면? 그래서 원격저장소의 것과 내가 만든 것을 잘 섞어서 새로운 버전으로 만들고 싶다면?

두번째 방법
push가 원격저장소로 밀어넣는 거라면, pull은 원격저장소의 내용을 가져오는 것이다.
git pull origin main 로 원격저장소의 main 브랜치 내용을 가져온다. 바로 아래처럼 뜰 수도 있고 아니면, 중간 과정을 거치고 나서 다시 git pull origin main을 입력하면, 충돌(conflict)라는 경고 문구와 함께 아래처럼 뜨게 된다.

중간 과정으로는 3가지가 있다.

힌트: git config pull.rebase false # merge
힌트: git config pull.rebase true # rebase
힌트: git config pull.ff only # fast-forward only

여기서 git config pull.rebase false를 입력해주면, pull 명령을 실행했을 때 로컬과 원격의 내용이 다를 경우 두 내용을 비교해서 merge하라는 환경설정을 하는 것과 같은 것 같다. 이걸 했더니 됐다.

알아보니
git config pull.rebase false는 pull할 때 rebase하지 않고 merge하는 것이고
git config pull.rebase true는 pull할 때 rebase를 하는 것이고
git config pull.ff only는 fast-forward일 때만 pull한다는 의미이다.

코드를 보면,
일단 초록색 위로 현재 변경사항 수락(accept current change), 수신 변경사항 수락(accept incoming change), 두 변경사항 모두 수락(accept both changes), 변경사항 비교(compare changes)이 떠 있다. 이 4가지 버튼은 vscode에서 제공하는 기능이며 에디터에 따라 다를 수 있다.

초록색으로 현재 변경사항(current change)가 뜨고
HEAD라는 게 내가 작성한, 로컬 환경에서의 내용, 즉 내가 push하려했던 내용이고.

아래로 파란색으로 수신 변경사항(incoming change)이 뜨는데, 이게 원격저장소에 push되어 있는 내용이다. 이상한 문자들은 커밋 내역 id라고 보면 된다.

컴퓨터가 이렇게 보여주면 내가 직접 이 부분을 결정해줘야 한다.
어떻게 충돌을 해결할지. 로컬에서 내가 만든 걸로 선택하고 싶다면 나머지 부분을 다 지워주면 된다. 원격저장소의 내용으로 하고 싶다면 그부분을 남기고 내가 작성한 것들을 지워주면 되는 것이다.

어쨌든 코드를 임의로 잘 정리한 다음, 이걸 토대로 버전 생성을 다시 해서 원격저장소에 push하면 이번엔 정상적으로 원격저장소로 push되는 걸 확인할 수 있다.

그리고 다른 브랜치에서 git pull origin main으로 가져오면 conflict를 이미 다른 브랜치에서 해결했으므로 문제없이 가져올 수 있다.

참고

코딩애플 - 쉽게 설명하는 Git 기초 3. git branch

profile
https://medium.com/@wooleejaan

0개의 댓글