일을 하다보면 모든 단계에서 어떤 것은 되돌리고(Undo) 싶을 때가 있다. 이번에는 우리가 한 일을 되돌리는 방법을 살펴본다. 한 번 되돌리면 복구할 수 없기에 주의해야 한다. Git을 사용하면 우리가 저지른 실수는 대부분 복구할 수 있지만 되돌린 것은 복구할 수 없다.
종종 완료한 커밋을 수정해야 할 때가 있다. 너무 일찍 커밋했거나 어떤 파일을 빼먹었을 때 그리고 커밋 메시지를 잘못 적었을 때 한다.
다시 커밋하고 싶으면 파일 수정 작업을 하고 Staging Area에 추가한 다음 --amend
옵션을 사용하여 커밋을 재작성 할 수 있다.
$ git commit --amend
이 명령은 Staging Area를 사용하여 커밋한다. 만약 마지막으로 커밋하고 나서 수정한 것이 없다면(커밋하자마자 바로 이 명령을 실행하는 경우) 조금 전에 한 커밋과 모든 것이 같다. 이때는 커밋 메시지만 수정한다.
편집기가 실행되면 이전 커밋 메시지가 자동으로 포함된다. 메시지를 수정하지 않고 그대로 커밋해도 기존의 커밋을 덮어쓴다.
커밋을 했는데 Stage 하는 것을 깜빡하고 빠트린 파일이 있으면 아래와 같이 고칠 수 있다.
$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend
여기서 실행한 명령어 3개는 모두 커밋 한 개로 기록된다. 두 번째 커밋은 첫 번째 커밋을 덮어쓴다.
Note
|
이렇게
|
다음은 Staging Area와 워킹 디렉토리 사이를 넘나드는 방법을 설명한다.
두 영역의 상태를 확인할 때마다 변경된 상태를 되돌리는 방법을 알려주기 때문에 매우 편리하다.
예를 들어 파일을 두 개 수정하고서 따로따로 커밋하려고 했지만, 실수로 git add *
라고 실행해 버렸다. 두 파일 모두 Staging Area에 들어 있다.
이제 둘 중 하나를 어떻게 꺼낼까?
우선 git status
명령으로 확인해보자.
$ git add *
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: README.md -> README
modified: CONTRIBUTING.md
Changes to be commited
밑에 git reset HEAD <file>…
메시지가 보인다.
이 명령으로 Unstaged 상태로 변경할 수 있다. CONTRIBUTING.md
파일을 Unstaged 상태로 변경해보자.
$ git reset HEAD CONTRIBUTING.md
Unstaged changes after reset:
M CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: README.md -> README
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: CONTRIBUTING.md
명령어가 낮설게 느껴질 수도 있지만 잘 동작한다.
CONTRIBUTING.md
파일은 Unstaged 상태가 됐다.
Note
|
|
지금까지 살펴본 내용이 git reset
명령에 대해 알아야 할 대부분의 내용이다.
reset
명령이 정확히는 어떻게 동작하는지, 어떻게 전문적으로 활용하는지는 ch07-git-tools.asc 부분에서 자세히 살펴보기로 한다.
어떻게 해야 CONTRIBUTING.md 파일을 수정하고 나서 다시 되돌릴 수 있을까?
그러니까 최근 커밋된 버전으로(아니면 처음 Clone 했을 때처럼 워킹 디렉토리에 처음 Checkout 한 그 내용으로) 되돌리는 방법이 무얼까?
git status
명령이 친절하게 알려준다.
바로 위에 있는 예제에서 Unstaged 부분을 보자.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: CONTRIBUTING.md
위의 메시지는 수정한 파일을 되돌리는 방법을 꽤 정확하게 알려준다. 알려주는 대로 한 번 해보자.
$ git checkout -- CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: README.md -> README
정상적으로 복원된 것을 알 수 있다.
Important
|
|
변경한 내용을 쉽게 버릴수는 없고 하지만 당장은 되돌려야만 하는 상황이라면 Stash와 Branch를 사용하자. ch03-git-branching.asc 에서 다루는 이 방법들이 훨씬 낫다.
Git으로 커밋 한 모든 것은 언제나 복구할 수 있다.
삭제한 브랜치에 있었던 것도, --amend
옵션으로 다시 커밋한 것도 복구할 수 있다(자세한 것은 ch10-git-internals.asc 에서 다룬다).
하지만 커밋하지 않고 잃어버린 것은 절대로 되돌릴 수 없다.