분리된 브랜치를 한 브랜치로 합치는 작업
주로 혼자 개발할 때 사용 => 변경 사항이 순차적으로 진행되기 때문에!
순차적 커밋에 맞추어 병합을 처리하는 방법
작업한 브랜치의 시작 커밋을 원본 브랜치 이후의 커밋으로 가리킨다. (단순히 커밋 위치를 최신으로 옮기는 것과 비슷)
병합 위치 : merge
명령어는 현재 브랜치를 기준으로 다른 브랜치의 모든 커밋을 병합하기 때문에 기준이 되는 브랜치로 이동해 병합해야 한다.
$ git merge 브랜치이름
// 예시
$ git checkout master
$ git merge feature // feature 브랜치 병합
Updating f121324...332dafd
Fast-forward // 병합 방식 표시
index.html | 6 ++++++
1 file changed, 6 insertions(+)
여러 개발자와 협업으로 작업하는 경우 사용
// 예시
// 현재 기준 브랜치 -> master
$ git merge hotfix // 기준 브랜치에 hotfix 병합
Auto-merging index.html
Merge made ny the 'recursive' strategy. // 3-way 병합
index.html | 3 +++
1 file changed, 3 insertions(+)
``
-> 깃은 두 브랜치를 병합 한 후에 새로운 커밋을 하면서 동시에 메시지를 자동 작성하는데, 그 외에 직접 커밋 메시지를 작성할 수 있다.
$ git merge 브랜치이름 --edit
$ git merge 브랜치이름 -e
지속적으로 통합과 개발을 해야 하는 브랜치는 병합 후에도 남겨두지만 필요 없는 브랜치는 삭제한다.
-> 브랜치 관리 기법으로 기본적으로 master
, feature
, develop
, release
, hotfix
브랜치가 있으며 develop
브랜치는 병합 후에도 삭제하지 않고 계속 유지한다. 이처럼 오랫동안 유지하는 브랜치를 long-running
브랜치라고 한다.
$ git branch -d 브랜치이름 // 병합을 완료한 브랜치만 삭제할 수 있다.
$ git branch -D 브랜치이름 // 병합을 완료하지 않은 브랜치 강제 삭제
// 예시
// 현재 기준 브랜치 master
$ git merge footer // 병합 실행
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result. // 충돌 발생
* 병합 충돌이 발생하면 자동으로 커밋이 생기지 않는다.
$ git status // 상태 확인
On branch master
You have unmerged paths. // 충돌 사항
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
$ git add index.html // 스테이지에 등록
$ git commit -m "resolve complicit" // 병합 커밋 직접 작성
[master 34332d] resolve complicit
* 방금 실행한 병합 취소 할 때
$ git merge --abort // 병합 명령 취소
* 충돌한 파일들의 집합 확인 할 때
$ git ls-files -u
$ git branch --merged // 브랜치 목록
feature
footer
* master
$ git branch --no-merged // 병합하지 않은 브랜치 목록
커밋 순서를 재배열하는 병합, 커밋의 트리 구조를 재배열한다. (실무에서 더 선호)
🔼 베이스를 커밋6으로 변경하고 모든 브랜치의 커밋들을 커밋6 이후로 재정렬
🔼 커밋 재배치
$ git rebase 브랜치
리베이스는 두 브랜치를 서로 비교하지 않고 순차적으로 커밋 병합을 시도한다. 리베이스는
병합 커밋
이 없다.
$ git checkout description // 리베이스 브랜치
Switched to branch 'description'
$ git rebase master // master 브랜치를 리베이스
Successfully rebased and updated refs/heads/description.
$ git checkout master // 브랜치 이동
$ git merge description // HEAD 포인터 조정(병합)
Updating 1231dfa...232dfd
Fast-forward // 병합 방식 확인
index.html | 1 +
1 file changed, 1 insertion(+)
$ git branch -d description // 필요 없는 브랜치 삭제
Deleted branch description (was 32d3rf).
병합 충돌과 같은 방식으로 해결
충돌 수정 후에--continue
명령어 사용
$ git add index.html // 등록
$ git rebase --continue // 계속 진행
Successfully rebased and updated refs/heads/menu. // 충돌 해결
$ git checkout master // 브랜치 이동
Switched to branch 'master'
$ git merge menu // 병합, HEAD 일치
Updating df24324..a232dd
Fast-forward
index.html | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
$ git branch -d menu // 브랜치 삭제
Deleted branch menu (was 1dafedf).
$ git rebase -i HEAD~3 // 커밋 묶기
Successfully rebased and updated refs/heads/master.
✅ 리베이스할 때 저장소를 외부에 공개했다면 공개된 순간부터 커밋은 리베이스를 사용하지 않는 것이 원칙이다.
-> 외부로 코드를 푸시하거나 공개하기 전에 로컬에서만 실행하는 것이 좋다. 외부에 공개된 커밋을 링베이스하면 커밋 위치와 해시 값이 변경되어 너무 혼란스럽기 때문에