git restore 사용법

git restore 사용법

git restore는 작업 디렉토리(working directory)나 스테이징 영역(staging area)에 있는 파일을 이전 상태로 되돌릴 때 사용하는 Git 명령어입니다. Git 2.23 버전(2019년 8월)에서 처음 도입되었는데요, 기존 git checkout의 파일 복원 기능을 좀 더 명확하고 안전하게 쓸 수 있도록 만들어졌습니다.

레거시 명령어인 git checkout에 대해서는 별도의 포스팅에서 다루고 있으니 참고 바랍니다.

작업 디렉토리의 변경사항 되돌리기

코드를 수정하다 보면 변경한 내용이 마음에 들지 않아서 마지막 커밋 상태로 되돌리고 싶을 때가 있죠. 이럴 때 git restore 명령어를 사용하면 됩니다.

$ git restore <파일명>

가령 src/app.js 파일을 수정했는데 원래대로 되돌리고 싶다면 이렇게 하면 됩니다.

$ git restore src/app.js

여러 파일을 한 번에 되돌릴 수도 있습니다.

$ git restore src/app.js src/index.js

현재 디렉토리 아래의 모든 변경사항을 되돌리려면 .을 사용합니다.

$ git restore .

이 명령어를 사용하면 작업 디렉토리에서 수정한 내용이 영구적으로 손실됩니다. 아직 커밋하지 않은 변경사항은 복구할 수 없으니 정말로 되돌릴 건지 한 번 더 확인하는 습관을 들이는 게 좋겠습니다.

스테이징 취소

git add 명령어로 파일을 스테이징 영역에 올렸는데, 다시 내리고 싶을 때가 있잖아요. 이런 상황에서 --staged 옵션을 사용하면 스테이징 영역에 있는 파일을 작업 디렉토리로 되돌릴 수 있습니다.

$ git restore --staged <파일명>

예를 들어 README.md 파일을 스테이징한 후에 커밋에서 빼고 싶다면 아래처럼 하면 돼요.

$ git add README.md
$ git restore --staged README.md

스테이징된 모든 파일을 한꺼번에 내리려면 .을 사용합니다.

$ git restore --staged .

--staged 옵션을 사용하면 스테이징만 취소되고 작업 디렉토리에 있는 변경 내용은 그대로 유지됩니다. 파일의 수정 내용은 사라지지 않으니 안심하고 사용해도 됩니다.

참고로 git status를 실행하면 Git이 스테이징 취소 방법을 친절하게 안내해 주고 있습니다.

$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   README.md

스테이징과 작업 디렉토리 동시에 되돌리기

스테이징 영역과 작업 디렉토리의 변경사항을 한꺼번에 되돌리고 싶다면 --staged--worktree 옵션을 함께 사용하면 됩니다.

$ git restore --staged --worktree <파일명>

src/app.js 파일을 수정하고 스테이징까지 했는데 전부 취소하고 싶다면 이렇게 하면 됩니다.

$ git restore --staged --worktree src/app.js

이 명령어를 실행하면 스테이징도 취소되고 작업 디렉토리의 변경사항도 마지막 커밋 상태로 되돌아갑니다. --staged만 사용했을 때와 달리 파일의 수정 내용까지 사라지므로 신중하게 사용해야겠죠.

특정 커밋에서 파일 복원

기본적으로 git restore는 마지막 커밋(HEAD) 상태로 파일을 복원하는데요. --source 옵션을 사용하면 특정 커밋이나 브랜치에서 파일을 가져올 수 있습니다.

$ git restore --source <커밋-해시 또는 브랜치> <파일명>

예를 들어 2개 커밋 이전의 config.js 파일을 현재 작업 디렉토리로 가져오고 싶다면요.

$ git restore --source HEAD~2 config.js

다른 브랜치에 있는 파일을 가져올 수도 있습니다.

$ git restore --source main README.md

--source 옵션과 --staged 옵션을 함께 쓰면 특정 커밋의 파일 내용을 스테이징 영역에 바로 올릴 수도 있습니다.

$ git restore --source HEAD~1 --staged src/app.js

이렇게 하면 해당 커밋 시점의 파일 내용이 스테이징 영역에 올라가기 때문에 바로 git commit을 실행하여 이전 버전의 파일로 새로운 커밋을 만들 수 있습니다.

Git에서 HEAD가 무엇을 의미하는지에 대해서는 별도의 포스팅에서 자세히 다루고 있으니 참고 바랍니다.

삭제된 파일 복원

실수로 파일을 삭제했을 때도 git restore로 복원할 수 있습니다.

$ rm src/utils.js
$ git restore src/utils.js

삭제된 파일뿐만 아니라 수정된 파일이 섞여 있어도 git restore .을 실행하면 전부 원래 상태로 되돌아갑니다.

# 파일 삭제와 수정이 동시에 발생한 상황
$ git status
Changes not staged for commit:
        deleted:    src/utils.js
        modified:   src/app.js

# 모든 변경사항 되돌리기
$ git restore .

패턴으로 여러 파일 복원

와일드카드 패턴을 사용하면 특정 조건에 맞는 여러 파일을 한 번에 복원할 수 있습니다.

모든 JavaScript 파일의 변경사항을 되돌리려면 이렇게요.

$ git restore '*.js'

특정 디렉토리 아래의 모든 파일을 되돌릴 수도 있고요.

$ git restore src/

쉘이 와일드카드를 먼저 해석하지 않도록 따옴표로 감싸주는 것이 좋습니다.

git checkout과 비교

예전에는 파일을 복원하려면 git checkout 명령어를 사용해야 했습니다. 그런데 git checkout은 브랜치 전환과 파일 복원을 모두 담당하다 보니 혼란스러운 상황이 종종 발생했죠.

# 이게 브랜치 전환인지 파일 복원인지 헷갈릴 수 있음
$ git checkout feature

feature가 브랜치 이름인지 파일 이름인지에 따라 완전히 다른 동작을 하기 때문입니다. 그래서 git checkout에서는 -- 기호를 사용하여 파일명임을 명시해야 했습니다.

$ git checkout -- src/app.js

git restore는 오직 파일 복원만 담당하므로 이런 혼란이 없습니다.

작업git checkoutgit restore
작업 디렉토리 복원git checkout -- <파일>git restore <파일>
스테이징 취소git reset HEAD <파일>git restore --staged <파일>
특정 커밋에서 복원git checkout <커밋> -- <파일>git restore --source <커밋> <파일>
스테이징 + 작업 디렉토리(두 명령어 조합 필요)git restore --staged --worktree <파일>

확실히 git restore 쪽이 옵션도 직관적이고 역할도 깔끔하게 나눠져 있죠.

브랜치 전환 기능은 git switch가 담당하고 있으니 함께 살펴보시면 좋겠습니다.

마치며

git restore는 파일 복원이라는 하나의 목적에 충실한 명령어입니다. 작업 디렉토리의 변경사항을 되돌리거나 스테이징을 취소하는 건 물론이고, 특정 커밋에서 파일을 가져올 수도 있습니다.

git checkout에 익숙한 분들도 점차 git restore로 갈아타 보세요.

커밋 단위로 되돌리고 싶다면 git reset 사용법도 함께 살펴보시면 좋겠습니다.

더 자세한 내용은 Git 공식 문서를 참고하세요.

This work is licensed under CC BY 4.0 CC BY

Discord