1. git merge
2. git rebase
//1. master 브랜치로 이동
$git checkout master
//2. 병합할 브랜치를 master브랜치에 merge
$git merge [master에 병합할 브랜치 명]
//위 1,2를 한번에 표현 가능
$git merge [master에 병합할 브랜치 명] master
병합을 하면 합쳐진 브랜치의 커밋 메시지가 중복으로 쌓이게 됩니다.
커밋 순서를 바꾸지 않습니다.
존재하는 브랜치가 변경되지 않습니다.
새로운 merge commit을 생성합니다.
git merge --abort : 병합을 취소하는 명령어
위 이미지는 Main 브랜치에 Feature 브랜치를 병합하는 과정을 나타냅니다.
커밋 순서가 변경되지 않고, 기존 분기는 유지되는 모습을 확인할 수 있습니다.
Feature 브랜치를 Main 브랜치에 병합을 나타내는 이미지 입니다.
위 그림처럼 Feature 브랜치의 커밋은 Main 브랜치가 가지고 있던 기존의 커밋 뒤에 위치하게 됩니다.
//master에 rebase 할 브랜치로 이동
$git checkout [rebase 할 브랜치]
$git rebase master
//rebase 할 브랜치를 master 브랜치에 merge
$git checkout master
//git rebase -i [수정을 시작할 커밋의 이전 커밋] 형식으로 입력
$git rebase -i HEAD~4
//4개의 커밋 리스트 노출
hint: Waiting for your editor to close the file...
pick 907c451 commit1
pick 1a7c765 commit2
pick v07c952 commit3
pick 40jc438 commit4
//사용할수있는 명령어 리스트
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c <commit> to reword the commit message.
-커밋을 사용하겠다는 의미, 이를 이용해 커밋의 순서를 바꿀 수 있고, 커밋의 해시값을 이용해 특정 커밋을 가져올 수 있습니다.
rebase 명령어를 실행하면 기본적으로 pick으로 설정돼있기 때문에 아무것도 변경하지 않고 종료한다면, 커밋에 대하여 어떠한 변경도 일어나지 않게 됩니다.
위 코드에서 commit2와 commit3의 순서를 바꾼다면, 커밋 순서와 커밋 해시값까지 변경됩니다.
커밋 메시지를 변경하는 명령어
커밋 메시지를 변경할 커밋 앞에 reword 명령으로 수정하고, 저장하면 해당 커밋의 메시지를 다시 작성하는 에디터 창이 열리게 됩니다.
커밋 메시지와 커밋의 해시값 또한 변경됩니다.
reword 명령어는 커밋 메시지만 변경하는 명령이라면, edit 명령어는 커밋 메시지뿐만 아니라 커밋의 작업 내용까지 변경할 수 있습니다.
commit4라는 커밋을 edit으로 바꾸고 저장 후 종료하면, 변경할 커밋으로 checkout됨, 그 상태에서 변경 작업을 수행하면 됩니다.
그 후 변경사항을 저장하기 위해 아래와 같은 명령어 입력
//staged 상태 변경
$git add .
//변경할 커밋메시지 입력
$git commit --amend -m "commit4-amend"
//rebase처리
$git rebase --continue
- 커밋 내용과 메시지 모두 변경됩니다.
pick 907c451 commit1
pick 1a7c765 commit2
squash v07c952 commit3
pick 40jc438 commit4
commit3 커밋을 직전 커밋인 commit2 커밋과 합치기 위해 squash로 변경합니다.
저장 후 종료하면 커밋 메시지를 수정할 수 있는 에디터 창이 뜹니다.
합쳐질 커밋들의 메시지를 확인한 후 그대로 종료하면 아래와 같이 이전 커밋과 하나로 합쳐진 것을 볼 수 있습니다.
pick 907c451 commit1
pick 73dc735 commit2
pick 40jc438 commit4
fixup 명령어는 squash와 동일하게 해당 커밋을 이전 커밋과 합치는 명령어이지만, 커밋 메시지는 합쳐지지 않습니다.
결과적으로 이전 커밋의 커밋 메시지만 남게 됩니다.
exec 명령어를 이용하면, 각각의 커밋이 적용된 후 실행할 shell 명령어를 지정할 수 있습니다.
각각의 커밋이 실행된다는 것을 확인하기 위해 중간중간에 메시지를 넣는 행위입니다.
drop 명령어는 커밋 히스토리에서 커밋을 삭제합니다.
drop으로 변경 후 저장하면, 해당 커밋이 drop 되는 것을 확인 가능합니다.
pick 907c451 commit1
drop 73dc735 commit2
pick 40jc438 commit4
이전의 커밋 히스토리를 변경하기 때문에 항상 주의가 필요합니다.
만약 이미 Github과 같은 원격 저장소에 push까지 한 커밋이라면, 변경한 커밋들은 원격 저장소에 push 되지 않을 것입니다.
이때 git push --force 혹은 git push -f 명령으로 강제로 원격 저장소에 커밋 히스토리를 덮어쓸 수 있습니다.
만약 이전에 push 한 커밋들을 다른 개발자들과 공유하고 있었다면, 커밋 히스토리의 불일치가 발생해 git이 꼬이는 현상이 발생할 수 있습니다.