4. Git commit 변경(revert,reset,rebase)

최강일·2022년 12월 2일
0

Git

목록 보기
5/8

목차

  • amend
  • revert
  • reset
  • cherry-pick
  • rebase

커밋 변경하기

1. 이전 커밋 수정하기(amend)

사용 케이스

누락된 파일을 새로 추가하거나 기존의 파일을 업데이트 해야할 때

사용법

--amend옵션 지정

  • git add <수정파일>
  • git commit --amend

2. 이전 커밋으로 되돌리기(revert)

사용 케이스

이전 커밋으로 되돌린 새로운 커밋을 만들고 싶을 때

사용법

revert명령어를 사용하여 과거의 이력으로 새로운 커밋을 생성한다.
reset 명령어로 커밋을 삭제할 수도 있지만, 커밋 이력 자체를 지우기보단 작업내용이 삭제된 새로운 커밋을 만든다.

  • 이전 커밋이 단순 커밋인 경우
    • git revert HEAD
  • 이전 커밋이 merge 커밋인 경우
    • git revert -m HEAD

3. 특정 커밋으로 되돌아가기(reset)

사용 케이스

  • 커밋만 되돌리고 싶을 때(soft)
  • 변경한 인덱스의 상태를 원래대로 되돌리고 싶을 때(mixed)
  • 최근의 커밋을 완전히 버리고 이전의 상태로 되돌리고 싶을 때(hard)

사용법

reset 명령을 사용하면 더 이상 필요 없어진 커밋들을 버릴 수 있다.
명령어 실행 시 어떤 모드로 실행할 지 지정하여 "HEAD"위치와 인덱스, 작업 트리 내용을 함께 되돌릴지 여부를 선택할 수 있다.
hard로 변경하여도 복원이 가능하다.

  • git reset --hard HEAD~~ : 최근 2개의 커밋 삭제
  • 원복 : git reset --hard ORIG_HEAD
모드명HEAD 위치인덱스작업 트리
soft변경 O변경 X변경 X
mixed(default)변경 O변경 O변경 X
hard변경 O변경 O변경 O

4. 다른 브랜치의 커밋을 가져와서 내 브랜치에 넣기(cherry-pick)

사용 케이스

  • 특정 브랜치에 잘못 추가한 커밋을 올바른 브랜치로 옮기려고 할 때
  • 다른 브랜치의 커밋을 현재 브랜치에도 추가하고 싶을 때

사용법

cherry-pick을 이용하여 다른 브랜치의 커밋을 복사하여 현재 브랜치로 가져올 수 있다.

  • 명령어 : git cherry-pick <커밋id>
    • 충돌이 발생할 수 있다. 수정한 후 커밋하면 된다.

5. 커밋 이력 편집하기(rebase)

사용 케이스

  • 그룹으로 묶을 수 있는 커밋들을 알기 쉽게 하나로 통합하려고 할때
  • 이전 커밋에 누락된 파일들을 나중에 추가하고자 할 때

사용법

rebase 명령어에 "i"옵션을 지정하면 커밋을 다시 쓰거나 다른 커밋과 바꿔 넣을 수 있으며 특정 위치의 커밋을 삭제하거나 여러 커밋을 하나로 통합하는 작업을 할 수 있다.

  • 커밋 통합
    • 명령어 : git rebase -i HEAD~~
    • HEAD~HEAD~~까지 과거의 커밋을 통합한다.
  • 이전 커밋 수정
    • git rebase -i HEAD~~
    • (수정)git add update.java
    • git commit --amend
    • git rebase --continue

Summary

1,5번과 같이 히스토리를 건드리는 작업을 권장하지 않는다.
2,3,4번은 종종 필요할 것 같다.

(2022-12-02 추가)

checkout vs reset

결론적으로 checkout commit의 주 목적은 특정 커밋에서 새로운 브랜치를 만들때 사용한다.


아래는 상세한 내용을 다룬다.
resetcheckout
HEAD가 가리키던 브랜치가 다른 커밋을 가리키도록 한다.HEAD 자체가 다른 커밋이나 브랜치를 가리키도록 한다.
HEAD도 결국 간접적으로 다른 커밋을 가리키게되는 효과가 생긴다.브랜치를 통하지 않고, 커밋을 직접적으로 가리키는 HEAD를 Detached HEAD라고 한다.

Attached/Detached HEAD

  • Attached HEAD : 커밋을 직접 참조. 보통 브랜치는 특정 커밋을 가리키고, HEAD가 이 브랜치를 가리킨다. HEAD->브랜치->커밋 상태를 attached HEAD라고 한다.
  • Detached HEAD : 커밋을 간접 참조. HEAD가 브랜치를 통해 간접적으로 커밋을 가리키지 않고, 직접 커밋을 가리키는 것을 말한다.

Detached HEAD 상태는 브랜치에 연결되어 있지 않아 관리가 불가능하다. 그래프에 보이지 않고, 브랜치를 이동하면 사라진다. 그저, 찾을 방법이 있다는 것이다.
reflog를 사용하여 브랜치를 만들면 된다. 그러면 커밋을 살릴 수 있다.

예제

1,2,3,4번 커밋 history가 있다. 현재 head는 4번 커밋을 향해있다.

  • 3번 커밋으로 reset
    • HEAD->master->3번 커밋 상태이다.
    • HEAD는 master 브랜치를 통해서 3번째 커밋을 가리킨다.
  • 3번 커밋으로 checkout
    • master -> 4번째 커밋
    • HEAD -> 3번째 커밋 상태이다.
    • 신규 브랜치 생성

상세 설명 참고

reflog

git에서 가리키는 referenced commit이 변경된 내역이다.
reflog를 기록하는 것은 대표적으로 HEAD와 branch이다.

  • HEAD reflog는 새로운 커밋이 생기거나, branch가 switch될 때마다 해당 브랜치의 가장 최신 커밋으로 reference가 바뀌게 된다.
  • branch reflog는 해당 브랜치의 commit이 변경되었을 때만 기록된다.

내용

HEAD의 업데이트 기록을 출력한다.
내용은 저장소 디렉토리의 .git/logs/refs/heads/. 혹은 .git/logs/HEAD에 기록

  • 명령어 : git reflog(동일한 명령 : git reflog show HEAD)
  • 특정 브랜치 reflog : git reflog [show] "브랜치명"
profile
Search & Backend Engineer

0개의 댓글