- 깃을 사용하다 보면 이전 커밋을 변경해야 하는 경우들이 종종 있다.
- 커밋 메시지를 수정하고 싶다거나 변경된 파일 일부를 되돌릴 수 있다.
- 현재 작업 중인 커밋(HEAD)을 간단하게 수정할 때
git commit --amend
를 사용한다. - 아래에 있는 커밋 중 일부를 수정하거나 변경할 때
git rebase --interactive
를 사용한다. git revert
의 경우 대상 커밋을 되돌리는 새로운 커밋을 만드는 기능이며, 커밋 자체를 변경하지 못한다.
git commit --amend
--amend
는 현재 커밋(HEAD) 위에 변경사항을 덮어씌울 때 사용하는 옵션이다.- 커밋을 한 후 추가적인 변경사항이 생겼거나 커밋 메시지를 변경하고 싶을 때 많이 사용한다.
- 만약 변경사항을 추가하고 싶다면 커밋을 할 때와 마찬가지로 스테이징(index)에 올린 후 명령어를 입력하면 된다.
1 |
|
- 리모트 레포지토리로 푸시하고 싶다면, 포스 푸시(
push --force
)를 이용해야 한다.
1 |
|
- 만약 커밋 메시지만 수정하고 싶다면 변경사항 없이 바로
git commit --amend
를 사용하면 된다. - 커밋 메시지의 수정이 필요하지 않는 경우
--no-edit
옵션을 붙이면 된다.
1 |
|
git rebase --interactive {커밋 ID}
git rebase
명령어는 브랜치 병합 과정에서 자주 사용된다.- 하지만 동시에 과거 커밋 히스토리를 변경할 수 있는 기능도
--interactive
옵션을 통해 제공한다. - 해당 옵션은
-i shortcut
으로 많이 사용한다. -
커밋 히스토리의 수정 범위는 현재 최신 커밋부터 {커밋 ID} 바로 위 커밋까지 적용된다.
- 총 3개의 커밋이 존재하며 각각 a, b, c 파일을 추가했다고 가정한다.
1 |
|
- 이때 두 번째 커밋에 b2 파일을 추가하고 세 번째(마지막) 커밋에 a파일을 삭제해야 하는 상황이 생겼다.
- 그러면 아래 커밋인
455f883
을 범위로 적용해줘야 한다.
1 |
|
- 입력 후, vi 에디터를 확인할 수 있다.
- 대표적인 커맨드는 아래와 같다.
pick
: 별다른 변경 사항없이 그냥 커밋으로 두겠다.edit
: 해당 커밋 내용을 변경할 것이며 커밋 메시지도 변경할 수 있게 하겠다.reword
: 해당 커밋의 메시지만 변경하겠다.drop
: 해당 커밋을 제거하겠다.- 이 외에도 커밋들을 합칠 때 사용하는
squash
, 브랜치를 머지시키는merge Command
등이 존재한다.
- 우선 커밋의 변경사항을 수정하기 위해 해당 커밋 라인의
pick
을edit
으로 변경한 후 저장한다.(:wq)
1 |
|
- 그러면 해당 커밋으로 HEAD가 옮겨지며, 자유롭게 코드를 추가/삭제/변경할 수 있다.
1 |
|
- 모든 코드 변경을 마친 후
git commit --amend
를 입력하면, 현재 최신 커밋(HEAD)에 덮어씌우는 작업을 하게 된다. - 커밋 메시지도 같이 수정할 것이다.
1 |
|
- 최종적으로 커밋을 마친 후 모든 변경 사항을 적용했다면
git rebase --continue
로 다음 작업 대상으로 넘어가면 된다. - 그렇게 되면 HEAD는 위에서
edit
을 입력한 커밋으로 올라가게 된다. - 이후 변경 작업은 동일하다.
1 |
|
- 만약 해당 커밋의 변경 사항을 주지 않고 다음으로 넘어가고 싶다면
git rebase --skip
을 사용하면 된다.
1 |
|
- 만약
rebase
하는 과정에서 전체를 취소하고 싶을 수 있다. - 이때
git rebase --abort
를 사용하면 된다.
1 |
|
- 중간에 있는 커밋을 변경하는 과정에서 상위 커밋과의 변경 사항이 충돌할 수도 있다.
- 그럴 때는 충돌난 부분을 수정한 후
git add
로index
에 충돌을 수정한 부분을 올린 후git rebase --continue
를 사용하면 된다.