개인 프로젝트를 하다가 가끔 이런 상황 만나지 않으세요? 원격 저장소(origin)에 이미 올려버린(push) 내용을 "아차!" 싶어서 이전 상태로 되돌리고 싶을 때 말이에요. 저도 얼마 전에 Next.js 프로젝트 하다가 그런 일이 있었어요.😅
VS Code의 Git 확장 프로그램으로 GUI 써서 간단하게 revert
하고 다시 push
했죠. 그리고는 프로젝트 돌리고 있는 서버에 가서 git pull
을 딱 받았어요.
그런데... 문제가 터졌습니다! 😱 서버에서 pull
받고 npm run build
하려는데 에러가 뙇! 제가 원했던 시점으로 revert
가 제대로 안 됐던 거더라고요. 혼자 쓰는 레포지토리였고, 되돌린 기록(revert 커밋) 남는 게 좀 지저분해 보여서 로컬에서 그냥 git reset --hard <돌아가고_싶은_커밋_ID>
명령어로 확 되돌려 버렸어요. 그리고 원격 저장소에 다시 push
를 했죠 (아마 이때 push --force
옵션을 썼을 수도 있어요, 과거를 바꾸는 거니까요!).
자, 이제 다시 서버로 가서 git pull
을 했는데... "이미 최신 버전입니다 (Already up to date)." 라는 메시지만 덩그러니 뜨는 거예요. 완전 당황했죠! 😳 분명히 내 로컬에서 작업하고 원격 저장소에 반영했는데, 서버에서는 업데이트가 안 된다니?
그래서 git log
로 서버의 상태를 확인해 봤더니 이런 상태였어요. 커밋 메시지 앞에 chore:
, revert:
, feat:
, fix:
같은 접두어는 어떤 종류의 작업이었는지 나타내는 표시(Conventional Commits 규칙)예요.
commit 6416f7dd99dc3d724cc434d367241437b424c665 (HEAD -> main) // <- 서버의 현재 상태 (HEAD)
Author: Aiden Hong <brain1401@gmail.com>
Date: Thu Aug 10 06:09:37 2023 +0900
chore: 포트번호 3002번으로 번경
commit 9eae814cc70675781a81dd301b8a91887fb5f72c
Author: Aiden Hong <brain1401@gmail.com>
Date: Thu Aug 10 06:07:46 2023 +0900
revert: Revert "feat: PostDetail PC화면 개선"
This reverts commit de433a195fc346dfc6b759dfc2c5fc2f21c09710.
commit 47dbafafcf7c88223be1b8528b8f176151a82436
Author: Aiden Hong <brain1401@gmail.com>
Date: Thu Aug 10 02:08:57 2023 +0900
feat: vercel analytics 추가
commit de433a195fc346dfc6b759dfc2c5fc2f21c09710 (origin/main) // <- 원격 저장소의 최신 상태 (origin/main) 가 여기?!
Author: Aiden Hong <brain1401@gmail.com>
Date: Thu Aug 10 02:02:50 2023 +0900
feat: PostDetail PC화면 개선
commit b1354c842a1a51baff0888b9b8b012632e656dea
Author: Aiden Hong <brain1401@gmail.com>
Date: Thu Jul 27 06:52:26 2023 +0900
feat: 유저 페이지 모바일 UI 개선
commit 2fe39f89ce008bae3fe46ce9b68c5a9a6af8d996
Author: Aiden Hong <brain1401@gmail.com>
Date: Thu Jul 27 06:24:20 2023 +0900
feat: navbar 모바일 UI 개선
commit 547a19a2416b4f210961892ffe817ce9db237786
Author: Aiden Hong <brain1401@gmail.com>
Date: Thu Jul 27 00:59:54 2023 +0900
feat: postDetail 모바일 반응형 개선
commit f438fae28e4bccde0661cab9fbfdda8c82f62418
Author: Aiden Hong <brain1401@gmail.com>
Date: Wed Jul 26 05:59:01 2023 +0900
fix: 반응형 적용 안됨 수정
commit 26dd2183cb77102f5d03ed7867ac86a8ab422097
Author: Aiden Hong <brain1401@gmail.com>
Date: Wed Jul 26 03:51:35 2023 +0900
feat: navbar 제외하고 전체 페이지 반응형 구현
보이시나요? 서버의 HEAD -> main
(현재 로컬 상태) 이 원격 저장소의 최신 상태인 origin/main
보다 더 예전 커밋을 가리키고 있어요! 제가 로컬에서 reset
하고 강제로 push
하면서 원격 저장소의 히스토리가 바뀌었는데, 서버는 아직 그 이전 히스토리 위에 있었던 거죠. 이러니 pull
이 안 될 수밖에요. 😭
이런 상황, 생각보다 종종 마주칠 수 있는데요, 혼자서 사용하는 레포지토리라면 해결 방법은 의외로 간단해요! 서버(또는 pull
이 안 되는 다른 로컬 환경)에서 아래 과정을 따라 하면 돼요.
먼저, 지금 원격 저장소(origin)에 어떤 최신 정보가 있는지 알아봐야 해요. 아래 명령어를 사용하면 돼요.
git fetch origin
이 명령어는 원격 저장소의 최신 변경 내역 정보를 가져오기만 하고, 아직 내 로컬 코드에 합치지는(merge) 않아요. 일단 최신 정보가 뭔지 구경만 하는 단계라고 생각하시면 돼요. 👀
이제 가장 중요한 단계예요. 내 로컬 main
브랜치 상태를 방금 Workspace
로 확인한 원격 origin/main
브랜치의 상태와 완전히 똑같이 만들어 버리는 거예요. 아래 명령어를 사용하면 됩니다.
git reset --hard origin/main
이 명령어는 현재 내 로컬 main
브랜치가 가리키는 커밋 위치를 강제로 origin/main
이 가리키는 최신 커밋 위치로 옮겨버리고, 작업 디렉토리의 파일 내용까지 그 상태로 싹 바꿔버려요.
⚠️ 진짜 진짜 중요! 경고! ⚠️
reset --hard
명령어는 매우 강력하고 위험해요! 만약 이 명령어를 실행하는 서버(또는 로컬 환경)에 원격 저장소에는 없는 로컬만의 변경 사항이나 커밋이 있었다면, 그 내용이 전부! 완전히! 영원히! 사라져요! 복구도 거의 불가능하고요. 😱
그러니 이 명령어를 쓰기 전에는 반드시 현재 작업 내용을 백업하거나, 다른 브랜치에 임시로 커밋해두는 등 안전 조치를 꼭 취해야 해요! 지금 우리가 처한 문제는 원격 저장소의 내용을 그대로 따라가야 해결되는 상황이라 이 명령어를 쓰는 거지만, 항상 위험성을 인지하고 조심 또 조심해야 합니다!
마지막으로, 로컬 브랜치가 원격 브랜치와 잘 맞춰졌는지 git log
명령어로 다시 한번 확인해보세요.
git log
이제 HEAD -> main
과 origin/main
이 같은 커밋을 가리키고 있다면 성공이에요! 🎉
위에서 설명한 reset --hard
후 push --force
(또는 reset --hard origin/main
) 방법은 혼자 쓰는 레포지토리에서나 어쩔 수 없이 쓰는 방법이에요. 만약 팀원들과 함께 작업하는 공유 브랜치(예 main
, develop
, master
)에서 이런 문제가 발생했다면 절대! 네버! reset --hard
나 push --force
를 사용하면 안 돼요! 🙅♀️🙅♂️
왜냐고요? 내가 원격 저장소의 히스토리를 강제로 바꿔버리면, 다른 팀원들이 작업하던 내용과 충돌이 나거나, 심하면 팀원들의 로컬 저장소가 완전히 꼬여버릴 수 있어요. 그럼 모든 팀원이 각자 자기 로컬 저장소를 수동으로 복구해야 하는 끔찍한 상황이 벌어질 수 있답니다. (마치 위에서 서버 고쳤던 것처럼요!)
그럼 협업 중에는 어떻게 해야 할까요?
git revert
사용하기 (강력 추천!)git revert <되돌릴_커밋_ID>
를 사용하는 거예요. revert
는 문제가 된 커밋을 없애는 게 아니라, 그 커밋의 변경 사항을 취소하는 새로운 커밋을 만들어요. 이렇게 하면 기존 히스토리는 그대로 유지되면서 문제만 해결할 수 있어서, 다른 팀원들에게 영향을 주지 않아요. 만약 처음 revert
가 잘 안 됐다면, 왜 안 됐는지 원인을 찾거나, revert 커밋 자체를 다시 revert 하는 방법을 고민하는 게 훨씬 안전해요!main
등)에 합치는(merge) 방식을 사용하는 것이 좋아요. 이렇게 하면 문제가 있는 코드가 중요한 공유 브랜치에 바로 반영되는 것을 막을 수 있답니다.reset --hard
후 push --force
로 꼬여버린 상황에서 git fetch
와 git reset --hard origin/main
으로 로컬 저장소를 복구하는 방법을 알아봤어요. 하지만 이 방법은 혼자 작업할 때 정말 어쩔 수 없는 경우에만 사용하는 비상 수단이라는 점! 그리고 로컬 변경 사항이 날아갈 수 있는 위험한 작업이라는 점을 꼭 기억해주세요!
협업할 때는 무조건 git revert
를 사용하고, 팀원들과 충분히 소통하는 것이 훨씬 안전하고 바람직한 방법이라는 것도 잊지 마시고요! Git은 강력한 도구지만, 올바르게 사용해야 그 힘을 제대로 발휘할 수 있답니다. 😉