본문 바로가기
IT & 비즈니스

깃 되돌리기 마스터: 실수에서 안전하게 복구하기

by notes9107 2026. 9. 29.

되돌리기 전에 먼저 현재 상태를 기록하기

저는 깃을 처음 사용할 때 실수를 고치는 일보다 실수를 숨기려는 마음이 더 위험하다는 사실을 늦게 배웠습니다. 파일을 잘못 수정한 뒤 곧바로 여러 명령어를 연달아 입력하면 무엇이 사라졌는지 확인하기가 어려워집니다. 그래서 지금은 문제가 생기면 먼저 git status와 git log --oneline --decorate -5를 실행합니다. 현재 브랜치, 커밋 위치, 아직 커밋하지 않은 파일을 눈으로 확인한 뒤에야 다음 명령을 선택합니다. 화면에 나온 내용을 복사해 별도 메모장에 남기는 습관도 생겼습니다.

작업 중인 파일이 많을 때는 되돌리기 전에 임시 커밋을 남기거나 패치 파일을 만들어 둡니다. 예를 들어 수정 내용을 잠시 보관해야 한다면 git diff > before-recovery.patch처럼 차이를 파일로 저장할 수 있습니다. 아직 완성되지 않은 작업이라 커밋하고 싶지 않을 때는 git stash push -u -m "recovery-before"를 사용할 수도 있습니다. 다만 스태시는 오래 보관하면 무엇을 저장했는지 잊기 쉬워서, 저는 복구가 끝난 뒤 목록을 확인하고 필요 없는 항목을 정리합니다. 되돌리기의 첫 단계는 명령어를 고르는 일이 아니라 원래 상태를 붙잡아 두는 일이라고 생각합니다.

아직 공유하지 않은 커밋은 reset으로 다루기

로컬에서만 만든 커밋을 없애고 싶을 때 저는 git reset을 먼저 검토합니다. 예전에 파일 하나를 고친 뒤 커밋 메시지를 잘못 적어 두 개의 커밋을 합치려다가, 옵션 차이를 제대로 확인하지 않고 git reset --hard HEAD~2를 실행한 적이 있습니다. 당시에는 원격 저장소에 올리지 않은 상태였지만, 마지막 커밋 이후 수정한 내용까지 작업 폴더에서 사라졌습니다. 다행히 git reflog에서 이전 HEAD 위치를 찾아 복구했지만, 그 과정에서 한 시간 넘게 파일을 비교해야 했습니다.

--soft, --mixed, --hard는 결과가 꽤 다릅니다. --soft는 커밋 기록만 옮기고 변경 내용을 스테이징 상태로 남기며, 기본값인 --mixed는 커밋과 스테이징을 되돌리지만 파일 수정 내용은 작업 폴더에 남깁니다. 반면 --hard는 지정한 위치 이후의 커밋과 작업 폴더 변경을 함께 버릴 수 있습니다. 저는 이제 --hard를 입력하기 전에 반드시 git diff, git diff --cached, 그리고 백업 파일을 확인합니다. 한 글자 차이로 복구 난도가 크게 달라질 수 있기 때문입니다.

이미 공유한 커밋은 revert로 되돌리기

원격 저장소에 이미 올린 커밋을 없애고 싶을 때는 reset보다 revert가 더 안전한 경우가 많았습니다. 제가 맡았던 작은 웹 화면에서 환경 설정 파일을 잘못 반영한 적이 있는데, 그 커밋은 동료들이 이미 내려받은 뒤였습니다. 처음에는 기록을 깔끔하게 만들고 싶어 reset 후 강제 업로드를 떠올렸지만, 그렇게 하면 다른 사람의 로컬 기록과 충돌할 수 있다는 설명을 듣고 멈췄습니다. 대신 git revert 커밋해시로 반대 변경을 담은 새 커밋을 만들었고, 기존 기록은 그대로 보존했습니다.

revert는 실수를 없던 일로 만드는 명령이 아니라, 실수를 상쇄하는 새 기록을 추가하는 방식입니다. 그래서 여러 커밋을 한꺼번에 되돌릴 때는 순서와 충돌을 확인해야 합니다. 특히 병합 커밋은 일반 커밋과 달라 git revert -m 1 병합커밋해시처럼 기준 부모를 지정해야 할 수 있습니다. 저는 이 명령을 실행한 뒤 바로 업로드하지 않고, 변경 파일 목록과 실제 화면을 확인한 다음 별도의 브랜치에서 결과를 살펴봅니다. 기록을 감추는 것보다 다른 사람이 이해할 수 있는 복구 과정을 남기는 편이 협업에서는 훨씬 수월했습니다.

커밋 자체가 아니라 특정 파일의 수정만 취소하고 싶을 때도 구분이 필요합니다. 아직 커밋하지 않은 파일이라면 git restore 파일명으로 최근 커밋 상태로 돌릴 수 있지만, 이 명령은 현재 작업 내용을 버립니다. 스테이징만 해제하려면 git restore --staged 파일명을 사용하고, 과거 커밋의 파일을 가져오려면 상황에 따라 git restore --source=커밋해시 -- 파일명처럼 범위를 명확히 적습니다. 예전에 파일 이름을 생략한 채 restore를 실행해 여러 파일의 수정이 함께 사라질 뻔한 일이 있었습니다. 그 뒤로는 명령어 마지막에 파일 경계를 나타내는 --를 넣고, 대상 파일을 하나씩 지정합니다.

복구가 끝났다고 느껴져도 저는 바로 원격 저장소에 올리지 않습니다. 먼저 git diff HEAD~1로 새 커밋이 의도한 반대 변경을 담고 있는지 보고, 필요한 경우 애플리케이션을 직접 실행해 화면과 설정값을 확인합니다. 충돌이 발생했다면 파일 안의 충돌 표시를 지운 뒤 git add와 git revert --continue를 순서대로 진행합니다. 중간에 판단이 서지 않으면 git revert --abort로 작업을 취소하고 처음 상태로 돌아가는 편이 낫습니다. 빠르게 끝내려다 확인 단계를 건너뛰면 한 번의 실수가 두 번째 실수로 이어진다는 점을 여러 번 경험했습니다.

저에게 깃 되돌리기는 명령어 암기보다 상황을 구분하는 연습에 가깝습니다. 아직 공유하지 않은 기록인지, 이미 다른 사람이 받은 기록인지, 커밋 전 파일인지에 따라 선택지가 달라집니다. 먼저 상태와 로그를 확인하고, 보존할 자료를 따로 남긴 다음, 영향 범위가 작은 방법부터 시도하면 당황하는 일이 줄어듭니다. 복구 과정에서 기록이 조금 지저분해지는 것은 괜찮지만, 무엇을 왜 되돌렸는지 설명할 수 없는 상태가 되는 것은 피해야 합니다. 저는 지금도 명령어를 입력하기 전 한 줄짜리 메모로 목적을 적습니다. 그 짧은 습관이 성급한 강제 작업을 막아 주었습니다.

실전에서 겪은 시행착오

저는 두 개의 커밋을 합치려다 git reset --hard HEAD~2 를 실행해 작업 폴더의 수정 내용까지 잃었지만, git reflog 에서 이전 HEAD 위치를 찾아 한 시간 동안 파일을 비교한 끝에 복구했습니다.

환경 설정 파일을 잘못 반영한 커밋을 동료들이 이미 내려받은 뒤에는 강제 업로드 대신 git revert 커밋해시 로 반대 변경을 담은 새 커밋을 만들고, 별도 브랜치에서 화면과 변경 파일 목록을 확인했습니다.

적용 전 꼭 확인할 주의사항

  • git reset --hard HEAD~2 는 마지막 커밋 이후 작업 폴더의 변경까지 버릴 수 있으므로 실행 전에 git diff , git diff --cached , 백업 파일을 확인해야 합니다.
  • 아직 커밋하지 않은 파일에서 git restore 파일명 을 실행하면 현재 작업 내용이 사라질 수 있으므로 대상 파일과 파일 경계를 나타내는 -- 를 명확히 지정해야 합니다.
  • 병합 커밋을 git revert 로 되돌릴 때는 일반 커밋과 달리 git revert -m 1 병합커밋해시 처럼 기준 부모를 지정해야 할 수 있고, 충돌이 나면 git add 뒤에 git revert --continue 를 실행해야 합니다.