const-tommy.dev
기록을 불러오는 중입니다
HEAD, origin/main, git reset, git reflog, git push --force-with-lease, Protected branches, credential.helperHEAD와 origin/main
HEAD: 맨 꼭대기가 아니라 지금 내가 서 있는 위치를 가리키는 포인터main: 로컬 main 브랜치가 가리키는 커밋origin/main: 원격 main 자체가 아니라 마지막으로 fetch/pull/push했을 때 기억한 원격 위치origin/HEAD: 원격 저장소의 기본 브랜치 표시히스토리를 바꾸는 명령어 비교
| 명령어 | 하는 일 | 사용 상황 |
|---|---|---|
reset | 브랜치를 과거 커밋으로 이동 | 커밋을 없애거나 되돌릴 때 |
rebase | 내 커밋들을 다른 커밋 위로 옮겨 붙임 | 최신 main 반영, 일직선 히스토리 |
cherry-pick | 특정 커밋 하나를 복사해서 새 커밋으로 붙임 | 일부 커밋만 가져올 때 |
revert | 되돌리는 새 커밋을 추가 | 공유 브랜치에서 안전하게 되돌릴 때 |
reset 모드
--soft: 커밋만 취소, 변경사항은 staged로 남음--mixed(기본): 커밋 취소, 변경사항은 수정된 파일로 남음--hard: 변경사항까지 버림 (단, 한 번도 add되지 않은 untracked 파일은 지우지 않음)git reflog: HEAD 이동 기록
6b00b20 HEAD@{0}: reset: moving to 6b00b209... ← 로컬만 되돌림
5795533 HEAD@{2}: commit (amend): ✨ [feat] d번째 커밋 ← 메시지 수정, 해시 변경 (이후 push)
dd89a8b HEAD@{3}: commit: ✨ [feat] 첫번째 커밋
596f2d0 HEAD@{4}: commit: 🎉 [start] 첫번째 커밋
6b00b20 HEAD@{5}: clone: from https://gitlab.com/...
일반 push vs 강제 push
git push: 원격 커밋 위에 내 커밋을 추가(fast-forward) 하는 것만 허용rejected (non-fast-forward) 또는 아무 변화 없음--force-with-lease가 필요함GitLab 보호 브랜치 (Protected branches)
main)가 자동으로 보호되어 강제 push가 금지됨You are not allowed to force push code to a protected branch / pre-receive hook declinedmain의 Allowed to force push 켜기GitLab HTTPS 인증
credential.helper가 없으면 인증 정보를 저장하지 않아 매번 입력을 요구함# 1. 로컬을 Initial commit으로 되돌리기
git reset --hard 6b00b209ed15a2073b54636658402e84b36f5ab1
# 2. 로컬/원격 전체 히스토리 확인 (git log는 HEAD 이전만 보여줌)
git log --oneline --all
# 3. (선택) 내가 어떤 작업을 했는지 기록 확인
git reflog -10
# 4. 원격을 로컬 상태로 덮어쓰기
git push --force-with-lease origin main
# → 보호 브랜치 에러 시 GitLab에서 Allowed to force push 켜고 재실행
# 성공 메시지: + 5795533...6b00b20 main -> main (forced update)
# 5. 성공 시 한 줄만 남음
# 6b00b20 (HEAD -> main, origin/main, origin/HEAD) Initial commit
Q. reset 했는데 왜 원격엔 테스트 커밋이 남아 있지?
Q. --force 대신 --force-with-lease를 쓰는 이유는?
Q. cherry-pick으로 커밋을 지울 수 있을까?
Q. GitLab 웹에서 커밋을 지울 수 있을까?
Q. 공유 브랜치에 강제 push해도 될까?
Q. 강제 push하면 커밋이 서버에서 완전히 사라질까?
Q. push할 때 입력도 안 받고 바로 인증 실패하는 이유는?
git credential fill로 확인하고 erase로 삭제 후 다시 입력하면 해결됨Q. 내가 어떤 명령어를 쳐서 이 상태가 됐는지 어떻게 알 수 있을까?
git reflog로 HEAD 이동 기록을 확인. 단, push는 기록되지 않으므로 origin/main의 위치로 push 시점을 추론함Q. reset 모드(soft/mixed/hard)는 reflog에서 알 수 있을까?
git status에 되돌린 커밋의 변경사항이 남아 있으면 soft/mixed, 없으면 hardQ. reset 후 그냥 git push 하면 원격도 되돌아갈까?
Q. 강제 push가 pre-receive hook declined로 거절되는 이유는?
HEAD는 "현재 위치", origin/main은 "마지막으로 기억한 원격 위치"reset, 옮기기는 rebase, 복사는 cherry-pick, 안전한 되돌리기는 revertreset 후 git push --force-with-leasegit reflog는 HEAD 이동 기록이자 git의 휴지통 (push는 기록되지 않음)main은 기본적으로 보호 브랜치라 강제 push 전 Allowed to force push를 켜고, 끝나면 다시 끄기credential.helper osxkeychain으로 저장하면 매번 입력하지 않아도 됨