본문 바로가기
시작/TIL(Today I Learned)

221124 Linux와 Git / Branch(브랜치)합치기 /merge hell

by 백씨네 2022. 11. 25.

오늘 내가 배운 것

1.  Branch 합치기 (브랜치 병합)

2. GitHub 

3. 과거 커밋(commit) 수정

 

1. Branch 합치기 (브랜치 병합)

브랜치를 합치는 방법은 2가지가 있다. merge , rebase 

merge는 그래프가 합쳐지는 것이 보이는데 rebase는 1개로 합쳐진다.

 

콜백 지옥에 이은 머지 지옥....

git merge hell : 병합하는 그래프가 남다 보니 위와 같은 현상이 나타날 수 있다....

 

 

merge와 rebase의 특징


merge는 히스토리가 남는다. 대신 화면에 복잡하게 그려지기 때문에 한눈에 보기가 어렵다.
rebase는 1개 기준으로 붙기 때문에 어떤게 어떻게 붙었는지는 한눈에 볼 수 없지만 기록은 남아있다.
둘 중에 뭐가 더 좋으니 써라 라는 느낌이 아니고 두가지의 방법이 있다는 것을 알기 위한 것이다.

 

 

develop브랜치는 완성이 되면 그때 main 브랜치에 넣을 예정이다.
develop브랜치를 완성시키는 것이 목적 주 브랜치를 develop으로 해서 나머지를 다 당겨올 예정

1. develop에서 feature합치고 (merge이용)
2. develop에 hotfix 합치고 (merge이용)
3. 마지막에 main과 develop을 다 합칠 예정 (rebase이용)

 

1. merge

1. develop에서 feature합치고 (merge이용)
2. develop에 hotfix 합치고 (merge이용)

4가지의 branch를 하나씩 병합할 예정이다.

4가지(main, hotfix, feature, develop)의 Branch를 하나씩 병합할 예정이다.

일단 develop에 feature와 hotfix를 merge를 이용하여 병합할 것이다.

 

# 주브랜치(develop)를 선택한 상태에서
git merge [붙여질브랜치명]

# 예시
git merge feature

feature의 브랜치가 develop 브랜치로 붙었다.

feature Branch가 develop Branch로 붙었다. 이제 이 둘은 병합 된 상태이다.

그리고 병합이 된 후 feature은 지워주도록 하자.

git branch -d feature

 

이제 병합된 develop에 hotfix를 한번 더 병합시킬 예정

근데 위에 커밋된 내용을 보면 develop에서도 setting.json이 수정되었고 hotfix에서도 setting.json이 수정되었다.

이렇게 되면 충돌이 발생하게 된다.

 

충돌 

merge 시도 중에 각 브랜치에서 중복된 파일에 대해 다른 값을 넣어  자동 병합 과정에서 어떤 데이터를 쓸지 컴퓨터가 판단하지 못하여 충돌 메시지를 띄운다.

자동 병합 중 충돌로 인해 병합 과정을 취소하고 싶은 경우

#merge 충돌 발생시 merge를 중단하고 싶을 때 사용

git merge --abort

 

수동으로 원하는 값을 병합 해준다.

수동으로 원하는 값만 남겨서 저장한다. 저장 후 커밋을 진행하고 hotfix 브랜치는 삭제

 

원하는 값을 수정한 뒤 저장 후 commit 과정까지 진행하면 commit을 하면 된다. 병합이 완료된 후 hotfix는 지워 주면 된다.

 

순서 : merge -> 충돌 -> 충돌 파일 정리 -> add -> commit

 

 

 

이제 main과 develop만 남았고, 그걸 rebase를 이용해서 병합할 예정이다.

 

2. rebase

3. 마지막에 main과 develop을 다 합칠 예정 (rebase이용)

커밋들을 한 줄로 모아서 깔끔하게 보려는 것이 목적이다.

 

merge와 rebase를 사용할 때 차이점

merge는 주된 브랜치에서 명령어를 실행하는 반면
rebase는 이동시키고 싶은 브랜치를 선택하고 명령어를 실행시킨다.
merge는 가져오는 것, rebase는 보내는 것

git switch develop

git rebase main

# 병합 충돌과정이 생기면 --abort로 취소 가능

 

충돌 발생

 

 

순서 : rebase -> 충돌 -> 충돌 파일 정리 -> add -> rebase --continue

 

 

 

develop이 main보다 상위에 있다.


merge를 이용하여 develop을 main에 붙인다.
main과 develop 브랜치가 나란히 있는 모습은  main과 develop의 코드 진행이 같아서 똑같은 단계인 상태라는 것으로 이해하면 된다.

 

현업에서는 충돌을 최대한 안 나게 하기 위해 파일을 최소 단위로 잘 나누고,

중복된 페이지에서 작업하지 않게 파일도 분리를 한다.

 

 

2. GitHub

GitHub 전송하기 / GitHub 받아오기 / GitHub 복사하기

# 로컬 저장소에서 원격 저장소로 보내기 
# git push [원격 저장소 이름] [보낼브랜치]
git push origin main


#원격 저장소에서 로컬 저장소로 받아오기
# git pull [원격 저장소] [보낼 브랜치]
git pull origin main


# 전체 가져오기 (로컬 저장소가 없는 폴더에 깃허브 내용 복사하기)
# git clone [원격저장소 주소][폴더명(선택사항)]
git clone https://~~~~~~~

 

 

내가 로컬 저장소에서 원격 저장소로 보내려 할 때 로컬 저장소에 내가 새로 원격 저장소로 올릴 커밋을 제외한 나머지 커밋은 동일해야 한다!!!

 

Q 1. 내가 working directory에 파일을 추가해서 작업을 하는 중일 때 원격 저장소에서 pull을 해서 받아올 수 있나?

가능하다, 내 working directory의 변화까지는 알 수 없다.

 

 

Q 2.  내 로컬에 새로운 커밋이 추가되어 있는데, 원격 저장소에서도 다른 사람이 새로운 커밋을 올렸다면 내 새로운 커밋을 push 할 수 있는가?

불가능하다, 중간단계(add까지)로 돌아가서 pull로 동일하게 맞춰준 상태에서 push 하자.


main과 origin/main 차이점

main은 내 로컬 저장소에서의 위치를 말하고 origin/main은 내가 pull을 받았던 당시의 main을 나타낸다.

내가 계속 작업을 진행하면 pull 받기 전까지는 origin/main은 그 위치에서 고정되어 있고 main만 위로 커밋이 생기면서 이동한다.

하지만!!!! main에 직접적으로 작업을 하면 안 된다. 브랜치를 생성해서 브랜치로 작업을 진행하자.

 

 

 

3. 과거 커밋(commit) 수정

 

VScode 터미널을 이용하는 과정에서 메시지가 나올 때 vi 방식으로 보이는 것이 아닌 에디터가 열렸다면 vi로 바꿔보자.

 

git config --global core.editor "vi"

 

rebase -i

4가지 기능을 구현해보자.

1. 메시지 커밋 변경 / 2. 커밋 삭제 / 3. 커밋 합치기 / 4. 커밋 나누기

 

# 문법

git rebase -i [수정할 커밋의 이전 커밋해시]

명령어

- p, pick : 커밋 그대로 두기
- r, reword : 커밋 메시지 변경
- e, edit  : 수정을 위해 정지, 커밋 나누기
- d, drop  : 커밋 삭제
- s, squash : 이전 커밋에 합치기

rebase -i 진입 "수정페이지 완료 " 해시값으로 진입했기 때문에 위에 있는 README 커밋만 컨트롤 할 수 있다.

 

rebase -i 진입 "수정 페이지 완료 " 해시값으로 진입했기 때문에 위에 있는 README 커밋만 컨트롤할 수 있다.

insert 모드로 진입  첫번 째 줄의 pick를 수정할 예정

 

insert 모드로 진입  첫 번째 줄의 pick를 수정할 예정

pick를 r로 수정하였고 저장하고 종료하면 된다. (r 은 커밋메세지 변경이기 때문에 종료하면 커밋메세지 바꿀 수 있는 에디터가 뜬다.)

 

pick를 r로 수정하였고 저장하고 종료하면 된다.

(r 은 커밋 메시지 변경이기 때문에 종료하면 커밋메세지 바꿀 수 있는 에디터가 뜬다.)

댓글