1. 되돌리기

프로그래밍 과정에서 실수는 필연적이며, 때로는 문제를 해결하는 것보다 이전 상태로 되돌리는 것이 효율적일 때가 있다. Git은 이를 위해 강력한 복구 기능을 제공한다.

  • 목적

    • 만일의 사태(심각한 오류, 오작동 등)를 대비하고,
    • 언제든지 원하는 시점으로 코드를 복구하기 위함
  • 주요 방법

    • 크게 reset(리셋)과 revert(리버트) 두 가지 방법이 있다.

2. Reset

2.1. 명령어

  • git reset [옵션] [커밋ID]: 특정 커밋 시점으로 되돌아간다. (HEAD 포인터 이동)

    • --soft: 변경된 파일들을 Staging Area에 남겨둔다.
    • --mixed (기본값): 변경된 파일들을 Working Directory에 남겨둔다.
    • --hard: 변경된 파일들을 모두 삭제한다.
  • 주의사항

    • 커밋 이력 자체가 사라지므로 신중하게 사용해야 하며,
    • 협업 중인 공유 저장소(원격 저장소)에 이미 push한 코드에는 가급적 사용하지 않아야 한다.

2.2. 주요 활용 사례

  • 커밋 수정/합치기 (soft)

    • git reset --soft HEAD^ 등을 사용하여 방금 한 커밋을 취소하고 내용을 유지한 채, 추가 작업을 더해 다시 커밋하거나 여러 커밋을 하나로 합칠 때 사용한다.
  • 스테이지 리셋 (mixed)

    • git reset [파일명]을 통해 add로 등록된 파일을 다시 Unstaged 상태로 내릴 때 사용한다.
  • 작업 취소 (hard)

    • git reset --hard HEAD를 통해 현재 작업 중인 지저분한 코드를 싹 지우고 마지막 커밋 상태로 돌아갈 때 사용한다.
  • 병합(Merge) 취소

    • 병합이 완료된 커밋을 리셋하면 병합 전 상태로 되돌아갈 수 있다.

3. Revert

3.1. 명령어

  • git revert [커밋ID]

    • 특정 커밋의 변경 사항을 정반대로 수행하는 새로운 커밋을 만든다.
    • 기존 이력을 훼손하지 않으므로 이미 원격 저장소에 공유된 커밋을 되돌릴 때 안전하다.
  • 범위 지정

    • git revert [최신커밋]..[과거커밋]
    • 범위 연산자(..)를 사용해 여러 커밋을 한 번에 리버트할 수도 있다.

3.2. 병합(Merge) 리버트

병합된 커밋(부모가 2개 이상인 커밋)을 리버트할 때는 어떤 부모 브랜치를 기준으로 남길지 지정해야 한다.

  • 명령어

    • git revert -m 1 [병합커밋ID] (--mainline 옵션 사용)
    • 숫자 1은 보통 병합 당시에 기준이 되었던 브랜치(예: master)를 의미한다.
  • 특징

    • 병합을 리버트하면 병합으로 인해 들어왔던 코드는 사라지지만,
    • 이력상으로는 병합되었다가 다시 빠진 것으로 기록된다.

4. Summary

리셋(reset)과 리버트(revert)는 과거로 돌아간다는 목적은 같지만, 사용 환경에 따라 명확히 구분해서 사용해야 한다.

  1. 리셋(Reset)

    • 과거로 돌아가며 이력을 삭제
    • 이력이 깔끔해지지만, 협업 시 충돌을 유발할 수 있음
    • 사용 권장: 나만 작업하는 로컬 저장소, 아직 공유되지 않은 커밋을 수정할 때
  2. 리버트(Revert)

    • 과거의 내용을 상쇄하는 새 커밋을 추가함 (이력 보존)
    • 이력이 지저분해질 수 있으나, 협업 시 안전함
    • 사용 권장: 이미 외부에 공유된(Push된) 저장소, 협업 중인 브랜치에서 변경 사항을 취소할 때

Dev.

cf. 커밋한 경우: git reset

git reset --soft HEAD~3
git commit -m update
git push origin main --force

cf. Restore

  • git restore: 커밋하지 않은 변경사항을 취소한다.
    • --staged: Staging을 취소한다.