Git 실수 되돌리기: 커밋 취소·지운 파일 복구·push 전후 차이

Git으로 작업하다 보면 엉뚱한 파일을 add하거나, 커밋 메시지에 오타를 내거나, 필요한 파일을 지워 버리는 일이 생깁니다. 대부분은 명령 한 줄로 되돌릴 수 있는데, 어떤 명령을 쓸지는 지금 어느 단계인지, 특히 push를 했는지에 따라 갈립니다.

먼저 지금 어느 단계인지 보기

뭔가 잘못됐다 싶으면 다른 명령보다 git status부터 입력하세요. 아무것도 바꾸지 않는 명령이라 몇 번을 쳐도 안전하고, 출력에 쓸 만한 명령까지 함께 나옵니다. 그다음 아래 표에서 내 상황을 찾으면 됩니다.

상황 쓸 명령 push한 뒤라면
엉뚱한 파일까지 add했다 git restore --staged 파일 add만 한 상태는 올라가지 않습니다
커밋 메시지에 오타를 냈다 git commit --amend 쓰지 않습니다
방금 한 커밋을 취소하고 싶다 git reset --soft HEAD~1 쓰지 않습니다
커밋 전에 파일을 지웠다 git restore 파일 해당 없음
커밋한 변경을 되돌리고 싶다 git revert 커밋 이 방법을 씁니다

push 열이 따로 있는 이유는 amend와 reset이 커밋 기록 자체를 바꾸기 때문입니다. 이미 올라가 다른 사람이 받아 간 기록을 바꾸면 그쪽과 어긋나기 때문에, Git 공식 안내서도 push하지 않은 로컬 커밋만 amend하라고 적어 둡니다.

엉뚱한 파일까지 add했을 때

index.html만 커밋하려다 개인 메모 파일까지 add했다고 해 보겠습니다. 아래 출력은 실제 실행 결과에서 필요한 줄만 남긴 것이고, 커밋 번호는 사람마다 다릅니다.

$ git add index.html memo.txt
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   index.html
	new file:   memo.txt

괄호 안에 답이 이미 적혀 있습니다. 빼고 싶은 파일에 git restore --staged를 붙이면 되고, 파일 내용은 그대로 남습니다.

$ git restore --staged memo.txt
$ git status --short
M  index.html
?? .gitignore
?? memo.txt

memo.txt 앞이 ??(추적하지 않는 파일)로 바뀌었으면 성공이고, 계속 올리지 않을 파일이면 .gitignore에 적어 두세요.

방금 한 커밋이 잘못됐을 때

메시지에 오타를 냈다면 --amend로 바로 고칩니다.

$ git commit -m "add abuot"
[main 62efaf2] add abuot
$ git commit --amend -m "add about"
[main ff00e61] add about

커밋 번호가 62efaf2에서 ff00e61로 바뀐 게 보이시나요? amend는 기존 커밋을 고치는 게 아니라 새 커밋으로 바꿔 끼우는 것이라, push한 커밋에 쓰면 원격 기록과 어긋납니다. 빠뜨린 파일이 있을 때도 그 파일을 add한 뒤 amend하면 같은 커밋에 합쳐집니다.

커밋 자체를 취소하고 싶다면 reset --soft를 씁니다.

$ git reset --soft HEAD~1
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   index.html

HEAD~1은 커밋 하나 전이라는 뜻이고, --soft는 커밋만 취소하고 고친 내용은 add된 상태로 둡니다. index.html이 커밋 대기 목록에 남아 있으면 성공이니, 다듬어서 다시 커밋하면 됩니다. 같은 자리에 --hard를 쓰면 고친 내용까지 지워지니 처음에는 --soft만 기억해 두세요.

파일을 지워 버렸을 때

아직 커밋하지 않았다면 마지막 커밋에 있던 내용으로 다시 꺼내면 됩니다.

$ rm style.css
$ git status --short
 D style.css
?? .gitignore
?? memo.txt
$ git restore style.css
$ git status --short
?? .gitignore
?? memo.txt

D 줄이 사라졌으면 돌아온 겁니다. 다만 마지막 커밋 시점으로 꺼내는 것이라, 그 뒤에 고쳤다가 커밋하지 않은 내용은 돌아오지 않습니다. 지운 것을 커밋까지 했다면 아래 revert를 쓰면 됩니다.

이미 push했다면 revert로

push한 커밋은 지우는 대신, 그 커밋을 거꾸로 되돌리는 새 커밋을 하나 더 쌓는 git revert로 되돌립니다. style.css를 지운 커밋(acce00c)을 되돌리면 이렇게 나옵니다.

$ git revert --no-edit HEAD
[main 0c86755] Revert "remove style"
 1 file changed, 1 insertion(+)
 create mode 100644 style.css
$ git log --oneline
0c86755 Revert "remove style"
acce00c remove style
ff49d32 add about
fcd76ee first page

create mode 줄이 파일이 되살아났다는 표시이고, 기록에는 지운 커밋과 되돌린 커밋이 둘 다 남습니다. 기존 기록을 건드리지 않으니 평소처럼 push하면 되고, 작업 중인 변경이 없을 때만 실행된다는 점만 기억하세요.

AI에게 git 문제를 물을 때 붙일 것

“커밋 취소하는 법”만 물으면 내 상황과 맞지 않는 명령이 돌아오기 쉽습니다. 세 명령의 출력을 함께 붙이면 지금 어느 단계인지가 드러나 답이 구체적이 됩니다. 제가 만든 틀이라 효과를 따로 재 보지는 않았습니다.

git 상태가 꼬였어. 아래 출력으로 지금 상황을 먼저 설명하고, 되돌릴 명령을 알려 줘.
- 하고 싶은 것: (예: 방금 커밋을 취소하되 고친 내용은 살리고 싶음)
- push 여부: (했음 / 안 했음 / 모름)
고친 내용이 지워질 수 있는 명령(reset --hard, push --force 등)은 경고를 붙여 따로 표시해 줘.

[git status]
[git log --oneline -5]
[git branch -vv]
(각 출력을 붙여넣기)

git branch -vv는 원격 브랜치와의 관계를 보여 줘서 push 여부가 헷갈릴 때 도움이 되고, 붙이기 전에 키 같은 값이 섞이지 않았는지만 훑어보면 됩니다.

자주 막히는 곳

  • 되돌리다가 커밋이 사라진 것 같다면 git reflog를 보세요. 내 컴퓨터에서 HEAD가 움직인 기록이라, amend로 바꿔 끼운 커밋이나 reset으로 취소한 커밋도 번호가 남아 있습니다. 아래에서 62efaf2(오타 커밋)와 ff00e61(reset 전 커밋)이 그대로 보입니다. 되찾을 번호를 골라 git branch rescue ff00e61처럼 새 브랜치를 만들면 그 시점이 다시 생깁니다.
$ git reflog
0c86755 HEAD@{0}: revert: Revert "remove style"
acce00c HEAD@{1}: commit: remove style
ff49d32 HEAD@{2}: commit: add about
fcd76ee HEAD@{3}: reset: moving to HEAD~1
ff00e61 HEAD@{4}: commit (amend): add about
62efaf2 HEAD@{5}: commit: add abuot
  • reflog에도 없다면 한 번도 커밋하지 않은 변경일 가능성이 큽니다. Git 안내서도 커밋한 것은 거의 언제나 되찾을 수 있지만 커밋하지 않고 잃은 것은 다시 보기 어렵다고 적습니다. reflog도 기본 90일, 어느 브랜치에서도 닿지 않는 기록은 30일이 지나면 정리되니 미루지 마세요.
  • 비밀번호나 키가 든 커밋을 push했다면 revert로는 해결되지 않습니다. 이전 커밋에 값이 남아 있으니, GitHub 문서 안내대로 그 키부터 폐기하거나 바꾸세요.

되돌리기 전 체크리스트

Git 실수는 생각보다 쉽게 되돌아오는데, 그 전제는 지금 상태를 먼저 확인하는 것과 커밋을 자주 해 두는 것입니다. push 전이면 amend와 reset으로 고치고, push한 뒤면 revert로 기록을 하나 더 쌓는다는 구분만 지켜도 크게 꼬일 일은 드뭅니다. 오늘은 연습용 폴더에서 위 명령을 한 번씩 따라 쳐 두면, 실제로 실수했을 때 훨씬 덜 당황합니다.

출처

Similar Posts

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다