[git] Git 저장소에서 삭제 된 파일 찾기 및 복원

내가 Git 저장소에 있다고 가정 해보십시오. 파일을 삭제하고 해당 변경 사항을 커밋합니다. 나는 계속 일하고 더 커밋합니다. 그런 다음 해당 파일을 복원해야합니다.

을 사용하여 파일을 체크 아웃 할 수는 git checkout HEAD^ foo.bar있지만 그 파일이 언제 삭제되었는지는 알 수 없습니다.

  1. 주어진 파일 이름을 삭제 한 커밋을 찾는 가장 빠른 방법은 무엇입니까?
  2. 해당 파일을 작업 사본으로 되 돌리는 가장 쉬운 방법은 무엇입니까?

로그를 수동으로 탐색하고 지정된 SHA에 대한 전체 프로젝트를 체크 아웃 한 다음 해당 파일을 원래 프로젝트 체크 아웃에 수동으로 복사하지 않아도되기를 바랍니다.



답변

주어진 경로에 영향을 준 마지막 커밋을 찾으십시오. 파일이 HEAD 커밋에 없으므로이 커밋이 파일을 삭제해야합니다.

git rev-list -n 1 HEAD -- <file_path>

그런 다음 캐럿 ( ^) 기호를 사용하여 커밋에서 버전을 체크 아웃하십시오 .

git checkout <deleting_commit>^ -- <file_path>

또는 하나의 명령 $file으로 문제의 파일이있는 경우 .

git checkout $(git rev-list -n 1 HEAD -- "$file")^ -- "$file"

zsh를 사용 중이고 EXTENDED_GLOB 옵션이 활성화되어 있으면 캐럿 기호가 작동하지 않습니다. ~1대신 사용할 수 있습니다 .

git checkout $(git rev-list -n 1 HEAD -- "$file")~1 -- "$file"


답변

  1. git log --diff-filter=D --summary파일을 삭제하고 파일을 삭제 한 모든 커밋을 가져 오는 데 사용 합니다.
  2. git checkout $commit~1 path/to/file.ext삭제 된 파일을 복원하는 데 사용 합니다.

$commit1 단계에서 찾은 커밋 값은 어디에 있습니까?e4cf499627


답변

폴더에서 삭제 된 파일을 모두 복원하려면 다음 명령을 입력하십시오.

git ls-files -d | xargs git checkout --


답변

방금 삭제 한 파일을 복원하려고했지만이 변경 사항을 아직 커밋하지 않은이 질문에 왔습니다. 이 상황에 처한 경우를 대비하여 다음을 수행하면됩니다.

git checkout HEAD -- path/to/file.ext


답변

미쳤다면을 사용하십시오 git-bisect. 수행 할 작업은 다음과 같습니다.

git bisect start
git bisect bad
git bisect good <some commit where you know the file existed>

이제 자동화 된 테스트를 실행할 차례입니다. 쉘 명령 '[ -e foo.bar ]'foo.bar존재 하면 0을 , 그렇지 않으면 1을 리턴 합니다. “run”명령은 git-bisect이진 검색을 사용하여 테스트가 실패한 첫 번째 커밋을 자동으로 찾습니다. 주어진 범위의 중간에서 시작하여 지정된 테스트 결과에 따라 반으로 줄입니다.

git bisect run '[ -e foo.bar ]'

이제 당신은 그것을 삭제 한 커밋에 있습니다. 여기에서 미래로 되돌아 가서 git-revert변경 사항을 취소하는 데 사용할 수 있습니다.

git bisect reset
git revert <the offending commit>

또는 하나의 커밋으로 돌아가서 수동으로 손상을 검사 할 수 있습니다.

git checkout HEAD^
cp foo.bar /tmp
git bisect reset
cp /tmp/foo.bar .


답변

bonyiii답변 ( 위로 올라옴 )과 ” Git alias 명령에 인수 전달 “에 대한 나의 마음에 드는 별명 :

git config alias.restore '!f() { git checkout $(git rev-list -n 1 HEAD -- $1)~1 -- $(git diff --name-status $(git rev-list -n 1 HEAD -- $1)~1 | grep '^D' | cut -f 2); }; f'

몇 커밋 전에 실수로 삭제 한 파일을 잃어 버렸습니까?
빨리:

git restore my_deleted_file

위기를 피했다.

경고, Git 2.23 (Q3 2019)의 실험 명령git restore(!)입니다.
따라서이 별칭의 이름을 바꿉니다 (아래 참조).


Robert Dailey 는 의견 에서 다음과 같은 별칭을 제안합니다 .

restore-file = !git checkout $(git rev-list -n 1 HEAD -- "$1")^ -- "$1"

그리고 jegan 은 주석을 추가합니다 :

커맨드 라인에서 별칭을 설정하기 위해 다음 명령을 사용했습니다.

git config --global alias.restore "\!git checkout \$(git rev-list -n 1 HEAD -- \"\$1\")^ -- \"\$1\""


답변

파일 이름을 알고 있다면 기본 명령을 사용하는 쉬운 방법입니다.

해당 파일에 대한 모든 커밋을 나열하십시오.

git log -- path/to/file

마지막 커밋 (맨 위)은 파일을 삭제 한 커밋입니다. 따라서 마지막 커밋까지 두 번째를 복원해야합니다.

git checkout {second to last commit} -- path/to/file