되돌리기 — Ctrl+Z 가 안 먹는 자리에서
Article
문서를 고치다가 잘못 건드리면 Ctrl+Z 를 누릅니다. 한 번, 두 번, 계속 누르면 원래대로 돌아옵니다.
그런데 이게 안 통하는 자리가 있습니다. 저장하고 창을 닫아버린 뒤입니다. 다시 열면 Ctrl+Z 를 아무리 눌러도 아무 일도 일어나지 않습니다. 되돌릴 기록이 편집기 안에만 있었는데, 창을 닫는 순간 그게 통째로 사라졌기 때문입니다.
이번 시간에는 편집기 밖에 되돌릴 지점을 만들어두면 무슨 일이 생기는지 봅니다. 우리는 이미 만들어뒀습니다. 커밋 세 개가 그것입니다.
일부러 망가뜨려봅니다
말로 설명하는 것보다 직접 겪는 게 빠릅니다. memo.txt 를 열어서 내용을 통째로 지우고 아무 글자나 채운 다음 저장합니다. 편집기 창도 닫아버립니다. 이제 Ctrl+Z 로는 못 돌아옵니다.
git status 를 칩니다.
- $ git status
- On branch master
- Changes not staged for commit:
- (use "git add <file>..." to update what will be committed)
- (use "git restore <file>..." to discard changes in working directory)
- modified: memo.txt
- no changes added to commit (use "git add" and/or "git commit -a")
여기서 중요한 건 괄호 안의 두 번째 줄입니다.
시키는 대로 쳐봅니다.
- 01
git restore memo.txt아무 메시지도 안 나옵니다. 깃은 잘 됐을 때 조용합니다
- 02
memo.txt를 다시 엽니다7강에서 커밋했던 세 줄이 그대로 돌아와 있습니다
- 03
git statusnothing to commit, working tree clean이 나옵니다. 고친 흔적 자체가 사라졌습니다
어디로 돌아간 건가
restore 가 어디서 내용을 꺼내온 것인지 알아야 이 명령을 안심하고 씁니다.
git restore 가 하는 일- 마지막 커밋7강에서 남긴 그 상태. 깃이 안전하게 들고 있다
- 꺼내서 덮어쓴다폴더에 있는 지금 파일을 그 내용으로 갈아끼운다
- 폴더의 파일커밋 시점의 모습으로 돌아온다. 그 뒤에 고친 건 전부 사라진다
되살리는 것처럼 보이지만 실제로는 덮어쓰는 것입니다. 그래서 편리한 만큼 위험합니다.
파일을 아예 지워버렸다면
고치는 것보다 더 심한 경우입니다. memo.txt 를 삭제해봅니다. 탐색기에서 지워도 되고, 휴지통까지 비워도 됩니다.
git status 를 칩니다.
- $ git status
- On branch master
- Changes not staged for commit:
- (use "git add/rm <file>..." to update what will be committed)
- (use "git restore <file>..." to discard changes in working directory)
- deleted: memo.txt
- no changes added to commit (use "git add" and/or "git commit -a")
modified 자리에 deleted 가 들어갔을 뿐, 나머지는 아까와 똑같습니다. 괄호 줄도 같습니다. 그러니 하는 일도 같습니다.
- $ git restore memo.txt
- $ ls
- memo.txt
지운 파일이 돌아왔습니다. 휴지통을 비웠어도 상관없습니다. 깃이 들고 있는 건 휴지통이 아니라 커밋이기 때문입니다.
add 까지 해버렸다면
한 걸음 더 갔을 때입니다. 잘못 고친 파일을 장바구니에 담기까지 했습니다. 이때 git status 를 치면 괄호 줄이 달라집니다.
- $ git add memo.txt
- $ git status
- On branch master
- Changes to be committed:
- (use "git restore --staged <file>..." to unstage)
- modified: memo.txt
git restore 뒤에 --staged 가 붙었습니다. unstage 는 장바구니에서 도로 뺀다는 뜻입니다.
--staged 가 붙고 안 붙고의 차이git restore memo.txt
폴더의 파일을 되돌린다
- 고친 내용이 사라진다
- 되돌릴 수 없다
- "이건 없던 일로 하자" 일 때
git restore --staged memo.txt
장바구니에서 빼기만 한다
- 고친 내용은 그대로 남는다
- 안전하다. 담기 전 상태로만 돌아간다
- "이번 커밋에는 안 넣겠다" 일 때
담은 것까지 완전히 없던 일로 하려면 두 번 칩니다. git restore --staged memo.txt 로 장바구니에서 빼고, git restore memo.txt 로 파일을 되돌립니다.
| 지금 상황 | 칠 명령 | 결과 |
|---|---|---|
| 고치고 저장했는데 없던 일로 하고 싶다 | git restore 파일이름 | 마지막 커밋 모습으로 돌아간다 |
| 파일을 지워버렸다 | git restore 파일이름 | 파일이 되살아난다 |
add 했는데 이번 커밋엔 빼고 싶다 | git restore --staged 파일이름 | 장바구니에서만 빠진다. 내용은 그대로 |
add 한 것도, 고친 것도 다 버리고 싶다 | --staged 로 빼고 → 다시 restore | 완전히 마지막 커밋 상태로 |
이미 commit 까지 해버렸다 | 이번 강 범위 밖 | 26강에서 다룬다 |
이미 커밋까지 한 것을 되돌리는 건 다루는 게 달라집니다. 남의 기록을 건드리는 문제가 끼어들기 때문입니다. 26강에서 실무 상황과 함께 다룹니다. 지금은 커밋 전이면 restore 로 다 해결된다까지만 가져갑니다.
정리하면
- 저장하고 창을 닫으면
Ctrl+Z는 끝입니다. 커밋은 그 밖에 있어서 살아남습니다 git restore 파일이름— 고친 것을 마지막 커밋 상태로 되돌립니다- 지워버린 파일도 같은 명령으로 돌아옵니다. 휴지통을 비웠어도 상관없습니다
- 복구가 아니라 덮어쓰기입니다. 커밋 이후에 한 작업은 전부 사라지고, 이건 취소할 수 없습니다
- 그래서 커밋을 자주 남겨야 합니다. 커밋에 없는 것은 깃도 못 살립니다
--staged를 붙이면 장바구니에서 빼기만 합니다. 파일 내용은 안 건드립니다git status괄호 안의 줄에 다음에 칠 명령어가 적혀 있습니다. 이 줄부터 읽습니다- 이미 커밋까지 한 것을 되돌리는 건 방법이 다릅니다. 26강에서 다룹니다
다음 9강에서는 올리면 안 되는 파일을 다룹니다. 집들이 전에 안방 문을 닫아두는 것과 같습니다. 손님에게 보여줄 방과 안 보여줄 방이 따로 있는데, 지금 우리 폴더는 문이 전부 열려 있습니다. secret.txt 를 하나 만들어놓고, 깃이 그 파일만 못 본 척하게 만들어봅니다.