1. 가장 최근 커밋, 가볍게 수정하기 (commit --amend)
가장 흔하게 발생하는 실수는 방금 완료한 커밋에 오타가 있거나 파일을 빠뜨린 경우입니다. 이럴 때는 새로운 커밋을 추가하는 대신, 마지막 커밋을 간단히 수정하는 것이 가장 깔끔합니다. git commit --amend 명령어는 바로 이런 상황을 위해 존재합니다.
- 커밋 메시지만 수정할 때 방금 작성한 커밋 메시지에 오타가 있거나 내용을 보충하고 싶다면, 아래 명령어를 사용해 간단히 수정할 수 있습니다.
- 파일을 추가하거나 변경 내용을 덧붙일 때 커밋에 포함했어야 할 파일을 빠뜨렸거나, 일부 수정 사항을 추가하고 싶을 때 사용합니다. 먼저 원하는 파일을 스테이징 영역에 추가한 뒤, -no-edit 옵션을 사용하면 커밋 메시지는 그대로 둔 채 내용만 마지막 커밋에 덧붙일 수 있습니다.
2. 과거의 특정 상태로 돌아가기 (reset vs revert)
단순한 수정이 아니라 과거의 특정 시점으로 프로젝트 상태를 되돌려야 할 때가 있습니다. 이때는 git reset과 git revert라는 두 가지 선택지가 있으며, 둘의 차이를 명확히 이해하고 사용하는 것이 매우 중요합니다.
- 히스토리를 삭제하며 과거로 돌아가기: git resetreset은 브랜치가 가리키는 위치(HEAD)를 지정한 과거 커밋으로 강제로 이동시키는 강력한 명령어입니다. 즉, 지정한 과거 시점 이후의 모든 커밋 히스토리가 사라질 수 있어 주의가 필요합니다. 주로 원격 저장소에 공유되지 않은 로컬 커밋을 정리할 때 유용하며, 세 가지 옵션이 있습니다.
- 히스토리를 유지하며 변경 내용만 취소하기: git revertrevert는 reset과 달리 기존 히스토리를 삭제하지 않습니다. 대신, 특정 커밋에서 발생한 변경 사항을 되돌리는 새로운 커밋을 생성합니다. 이미 다른 팀원과 공유된 원격 저장소의 커밋을 안전하게 되돌려야 할 때 반드시 사용해야 하는 방법입니다.
3. 복잡한 히스토리, 마음대로 편집하기 (rebase -i)
여러 개의 커밋을 합치거나, 순서를 바꾸거나, 특정 커밋만 삭제하는 등 히스토리 자체를 정교하게 재구성하고 싶을 때가 있습니다. git rebase -i (대화형 리베이스)는 마치 Git의 타임머신처럼 과거의 커밋 목록을 자유자재로 편집할 수 있게 해줍니다.
- 대화형 리베이스 시작하기 아래 명령어는 현재 브랜치의 최근 3개 커밋을 대상으로 대화형 리베이스를 시작합니다.
- 커밋 편집하기 명령어를 실행하면 텍스트 편집기가 열리면서 지정한 커밋 목록과 함께 선택할 수 있는 작업들이 나타납니다.
4. 브랜치 관련 실수, 깔끔하게 해결하기
때로는 작업 내용 자체보다 작업한 브랜치가 잘못된 경우가 있습니다. 이런 상황을 해결하는 유용한 명령어 두 가지를 소개합니다.
- 다른 브랜치의 특정 커밋만 가져오기: cherry-pickfeature/A 브랜치에 작업해야 할 내용을 실수로 main 브랜치에 커밋했다면, cherry-pick을 사용하여 해당 커밋만 feature/A 브랜치로 쏙 가져올 수 있습니다.
- 작업 내용 임시로 저장하기: stash 아직 커밋하기는 애매한 작업 도중에 급하게 다른 브랜치로 이동해서 코드를 확인해야 할 때가 있습니다. 이때 git stash를 사용하면 현재 작업 내용을 임시로 저장하고 작업 디렉토리를 깨끗하게 만들 수 있습니다.
5. 원격 저장소 강제 수정 (주의 필요!)
reset이나 rebase로 로컬 히스토리를 수정한 후 원격 저장소에 반영하려면 일반적인 push로는 불가능합니다. 로컬과 원격의 히스토리가 달라졌기 때문입니다. 이때 강제로 원격 저장소를 덮어쓰는 명령어를 사용해야 하지만, 이는 팀원들과 함께 사용하는 공유 브랜치에서는 심각한 문제를 일으킬 수 있으므로 사용법을 정확히 알아야 합니다.
- 원격 저장소 강제 덮어쓰기: push --force 이 명령어는 로컬 저장소의 히스토리를 기준으로 원격 저장소의 내용을 강제로 덮어씁니다. 만약 내가 모르는 사이에 다른 팀원이 원격 브랜치에 새로운 내용을 push 했다면, 그 내용이 사라질 수 있는 매우 위험한 명령어입니다.
- 더 안전하게 강제 푸시하기: push --force-with-lease-force의 위험성을 보완한 더 안전한 대안입니다. 이 명령어는 push를 시도할 때, 내가 마지막으로 원격 저장소의 상태를 확인한 이후(fetch) 다른 누군가가 새로운 커밋을 올리지 않았는지 검사합니다. 만약 원격 브랜치에 변경 사항이 있다면 push를 거부하여 다른 사람의 작업을 덮어쓰는 위험을 막아줍니다. 개인 브랜치가 아니라면 force 대신 항상 이 명령어를 사용하는 습관을 들이는 것이 좋습니다.
6. 최후의 보루, 모든 것을 되돌리는 reflog
git reset --hard로 중요한 커밋을 날려버렸거나, rebase 도중 히스토리가 완전히 꼬여버려 어디서부터 잘못됐는지조차 알 수 없을 때가 있습니다. 이때 git reflog는 당신을 구해줄 최후의 보루입니다. 이 명령어는 브랜치, HEAD가 이동했던 모든 기록을 마치 블랙박스처럼 저장하고 있습니다.
- 모든 이동 기록 확인하기git reflog를 입력하면 commit, reset, rebase, merge 등 내가 했던 모든 작업 기록과 해당 시점의 커밋 해시가 나타납니다.
- 잃어버린 커밋으로 복구하기 로그에서 되돌아가고 싶은 상태의 커밋 해시(예: a1b2c3d)를 찾았다면, reset 명령어를 통해 해당 상태로 완벽하게 복구할 수 있습니다.
7. 특별 케이스: 외부 서비스 연동 문제 해결 (Vercel 예시)
때로는 Git 자체의 문제라기보다 Vercel과 같은 배포 자동화 서비스와의 연결이 꼬이는 경우도 있습니다. 이럴 때는 연결을 완전히 끊고 새로 설정하는 것이 가장 확실한 해결책이 될 수 있습니다.
- Vercel에서 프로젝트 연결 해제하기 Vercel 대시보드에서 해당 프로젝트의 Settings > Git 메뉴로 이동하여 'Disconnect' 버튼을 클릭합니다. 이렇게 하면 Git 저장소와의 연결이 해제되고 자동 배포가 중단됩니다.
- 로컬 Git 저장소 원격 연결 정리하기 로컬 프로젝트 폴더에서 기존 원격 저장소 연결을 제거합니다.
- Vercel에서 프로젝트 재연결하기 Vercel 대시보드에서 'New Project'를 클릭하고, 다시 연결하려는 Git 저장소를 선택하여 프로젝트를 새로 생성하고 배포 설정을 구성합니다.