7.[git] 커밋 이력 조작하기
다른 브랜치의 커밋을 작업 브랜치에 추가하기: git cherry-pick
- 두 브랜치를 병합하는 대신 다른 브랜치의 커밋을 선택적으로 작업 브랜치에 추가해야할 때도 있다
git cherry-pick "추가하려는 커밋 체크섬"
- 이미 배포된 기능에서 치명적인 결함 발견
결함을 수정한 커밋만 서비스 운영에 사용되는 브랜치에 추가
feature/a, feature/b 두 브랜치
- feature/b에 커밋이 feature/a에서 작업되었어야했음
- feature/a를 작업 브랜치로 변경한 후 해당 커밋을 추가할 수 있다
git checkout feature/a
git cherry-pick c14d00893dde3sg34t529
이전 커밋으로 작업 브랜치의 최종 커밋 변경하기 : git reset
이미 생성된 커밋을 취소하고 이전 커밋으로 최종 커밋을 변경하고 싶을 때
기능 개발을 완료했는데 갑자기 기획이 변경되어 일부 기능을 제외해야한다
- 제외할 기능과 관련된 커밋을 취소할 수 있다
git reset "이전 커밋 체크섬"
예시)
git log --pretty=oneline --graph
// 커밋3
// 커밋2
// 커밋1
- 커밋3를 취소하고 마지막 커밋을 커밋2로 하고 싶을 때!
git reset 커밋2
- 커밋3의 변경 사항이 포함된 파일을 취소되면서 Unstaged인 Modified 상태가 된다
결과물)
git log --pretty=oneline --graph
// 커밋2
// 커밋1
변경 사항 되돌리는 커밋 생성하기 : git revert
- 이미 생성된 커밋을 취소하는 또 다른 방법
- git reset 과의 차이점: 취소하고자하는 커밋의 변경 사항을 되돌리는 새로운 커밋이 생성된다
git revert "되돌리려는 커밋 체크섬"
예시)
git log --pretty=oneline --graph
// 커밋3
// 커밋2
// 커밋1
git revert 커밋3
결과물)
git log --pretty=oneline --graph
Revert "커밋3"
// 커밋3
// 커밋2
// 커밋1
- Revert "커밋3" 라는 커밋이 하나 생성된다
커밋3의 변경사항을 되돌려놓는 내용을 포함한다
git reset은 취소하려는 커밋 자체를 커밋 이력에서 제외하고
- git revert는 커밋의 변경 사항을 되돌렸다는 새로운 커밋을 추가한다
- git reset이 커밋 이력을 깔끔하게 유지하나 여러 개발자가 협업하면 작업을 되돌리는 이력도 서로 확인할 수 있어서 좋다
- 가능하면 git revert 추천!
브랜치 커밋 이력 재정렬하기: git rebase
- 기준 브랜치에서 여러 브랜치를 생성하여 작업 후, 계속해서 병합하면 커밋 이력을 한눈에 알아보기 어려운 상태가 될 수 있다
- 특정 브랜치의 커밋 이력을 기준으로 작업 브랜치의 커밋 이력을 재정렬할 때 깃 명령어 git rebase를 사용한다
git rebase "재정렬을 위한 기준 브랜치"
- main 브랜치와 feature/a 브랜치가 있음
- 그 후 각각 새로운 커밋이 생성됨
예시)
- main 브랜치
git log --pretty=oneline --graph
// 커밋2
// 커밋1
- feature/a 브랜치
git log --pretty=oneline --graph
// 커밋3
// 커밋1
- 두가지 방법 비교
feature/a 브랜치 병합
- 메인 브랜치에서 merge하는 방법
git checkout main
git merge feature/a
결과물)
git log --pretty=oneline --graph
// Merge branch "feature/a"
// 커밋2 (feature/a)
// 커밋3 (main)
// 커밋1 (공통)
- main 브랜치와 feature/a 브랜치에 각각 추가된 새로운 병합 커밋이 생김
feature/a 브랜치 커밋 이력 재정렬 후 병합
피쳐 브랜치에서 rebase를 하고 메인에서 merge를 하는 방법
feature/a 브랜치를 작업 브랜치로 바꿈
- main 브랜치를 기준으로 커밋 이력을 재정렬
git checkout feature/a
git rebase main
결과물)
git log --pretty=oneline --graph
// 커밋3 (main)
// 커밋2 (feature/a)
// 커밋1
- feature/a 브랜치에 main의 최신 커밋 이력인 커밋3이 가장 최근 커밋으로 재정렬됨
git checkout main
git merge feature/a
결과물)
// 커밋3 (main)
// 커밋2 (feature/a)
// 커밋1 (공통)
- 병합 커밋 이력이 없어서 깔끔해짐
마무리
git cherry-pick (커밋 훔치기)
- 다른 브랜치의 커밋 추가
- git cherry-pick "추가하려는 커밋 체크섬"
git reset
- 이전 커밋으로 최종 커밋 변경
- git reset "이전 커밋 체크섬"
git revert
- 변경 사항 되돌리는 커밋 변경
- git revert "되돌리려는 커밋 체크섬"
git rebase
- 커밋 이력 재정렬
- git rebase "재정렬을 위한 기준 브랜치"
- 피쳐에서 rebase 후 메인에서 merge를 한다