Git에서 파일이 삭제 된시기 찾기


1035

n 커밋이있는 Git 저장소가 있습니다.

필요한 파일이 있고 저장소에 있던 파일이 있는데 갑자기 "아! 그 파일은 어디로 갔습니까?"

"file really_needed.txt가 커밋 n-13에서 삭제되었다"고 알려주는 일련의 Git 명령이 있습니까?

즉, 모든 개별 커밋을 보지 않고 내 Git 저장소에 모든 파일의 변경 사항이 있음을 알지 못하면 해당 파일이있는 마지막 커밋을 신속하게 찾을 수 있으므로 다시 가져올 수 있습니까?



2
Pedro가 공유 한 링크에는 내 질문에 대한 답변이 있습니다. 경로를 기억하지 못할 때 삭제 된 파일을 찾는 방법.
Gordon Bean

답변:


1127

git log --full-history -- [file path] 파일의 변경 사항을 표시하고 파일이 삭제 된 경우에도 작동합니다.

예:

git log --full-history  -- myfile

파일을 삭제 한 마지막 커밋 만 보려면 -1을 추가로 사용하십시오 (예 : git log --full-history -1 -- [file path]

참조 어떤 파일을 삭제 커밋


16
패턴을 검색 할 수 있습니까? 파일의 전체 이름을 잊어 버렸습니다 = (아마도 모든 삭제 로그를 얻을 수 있습니까?
wutzebaer


6
PowerShell을 사용하는 경우 하이픈을 이스케이프해야합니다 (git log '-'[file path]). 바라건대 이것은 다른 누군가와 이빨을 same 수 있기를 바랍니다.
A. Wilson

68
git log -- */<<filename>>.<<file extension>>전체 파일 경로를 모르면서 검색 할 수있었습니다 .
Tom Howard

2
@MERose 대괄호는 실제 파일 경로의 자리 표시 자로 사용됩니다.
Emile Bergeron

229

짧은 답변:

git log --full-history -- your_file

병합 커밋을 포함하여 리포지토리의 모든 커밋을 표시합니다 your_file. 마지막 (맨 위)은 파일을 삭제 한 것입니다.

몇 가지 설명 :

--full-history여기 의 깃발이 중요합니다. 파일이 없으면 Git은 파일의 로그를 요청할 때 "기록 단순화"를 수행합니다. 문서는 이것이 어떻게 작동하는지에 대한 세부 사항에 대해 밝고 소스 코드에서 파악하는 데 필요한 그릿과 용기가 없지만 git-log 문서 에는 다음과 같은 내용이 많이 있습니다.

기본 모드

트리의 최종 상태를 설명하는 가장 간단한 히스토리로 히스토리를 단순화합니다. 최종 결과가 동일한 경우 일부 사이드 브랜치를 제거하므로 가장 간단합니다 (예 : 동일한 컨텐츠의 브랜치 병합)

삭제 된 파일의 최종 상태를 설명하는 가장 간단한 히스토리는 히스토리아니기 때문에 원하는 히스토리가있는 파일이 삭제되는 시기와 관련이 있습니다 . 있는 위험이 git log없이는 --full-history단순히 파일을 만든 적이라고 주장한다은? 불행히도, 그렇습니다. 데모는 다음과 같습니다.

mark@lunchbox:~/example$ git init
Initialised empty Git repository in /home/mark/example/.git/
mark@lunchbox:~/example$ touch foo && git add foo && git commit -m "Added foo"
[master (root-commit) ddff7a7] Added foo
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 foo
mark@lunchbox:~/example$ git checkout -b newbranch
Switched to a new branch 'newbranch'
mark@lunchbox:~/example$ touch bar && git add bar && git commit -m "Added bar"
[newbranch 7f9299a] Added bar
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 bar
mark@lunchbox:~/example$ git checkout master
Switched to branch 'master'
mark@lunchbox:~/example$ git rm foo && git commit -m "Deleted foo"
rm 'foo'
[master 7740344] Deleted foo
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 foo
mark@lunchbox:~/example$ git checkout newbranch
Switched to branch 'newbranch'
mark@lunchbox:~/example$ git rm bar && git commit -m "Deleted bar"
rm 'bar'
[newbranch 873ed35] Deleted bar
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 bar
mark@lunchbox:~/example$ git checkout master
Switched to branch 'master'
mark@lunchbox:~/example$ git merge newbranch
Already up-to-date!
Merge made by the 'recursive' strategy.
mark@lunchbox:~/example$ git log -- foo
commit 77403443a13a93073289f95a782307b1ebc21162
Author: Mark Amery 
Date:   Tue Jan 12 22:50:50 2016 +0000

    Deleted foo

commit ddff7a78068aefb7a4d19c82e718099cf57be694
Author: Mark Amery 
Date:   Tue Jan 12 22:50:19 2016 +0000

    Added foo
mark@lunchbox:~/example$ git log -- bar
mark@lunchbox:~/example$ git log --full-history -- foo
commit 2463e56a21e8ee529a59b63f2c6fcc9914a2b37c
Merge: 7740344 873ed35
Author: Mark Amery 
Date:   Tue Jan 12 22:51:36 2016 +0000

    Merge branch 'newbranch'

commit 77403443a13a93073289f95a782307b1ebc21162
Author: Mark Amery 
Date:   Tue Jan 12 22:50:50 2016 +0000

    Deleted foo

commit ddff7a78068aefb7a4d19c82e718099cf57be694
Author: Mark Amery 
Date:   Tue Jan 12 22:50:19 2016 +0000

    Added foo
mark@lunchbox:~/example$ git log --full-history -- bar
commit 873ed352c5e0f296b26d1582b3b0b2d99e40d37c
Author: Mark Amery 
Date:   Tue Jan 12 22:51:29 2016 +0000

    Deleted bar

commit 7f9299a80cc9114bf9f415e1e9a849f5d02f94ec
Author: Mark Amery 
Date:   Tue Jan 12 22:50:38 2016 +0000

    Added bar

git log -- bar위의 터미널 덤프에서 결과적으로 문자가 출력되지 않는 방법 에 주목 하십시오. 힘내 역사 bar는 존재하지 않는 허구로 역사를 "단순화"하고 있습니다 . git log --full-history -- bar반면에, 우리는 생성 bar한 커밋과 삭제 한 커밋을 제공합니다.

분명히 :이 문제는 단지 이론적 인 것이 아닙니다. 삭제 된 파일을 추적하려고하는 실제 저장소에서 실패 --full-history했기 때문에 문서 만 살펴보고 플래그를 발견 git log -- some_file했습니다. 히스토리 단순화는 현재 존재하는 파일이 현재 상태가 된 방법을 이해하려고 할 때 도움이 될 수 있지만 파일 삭제 를 추적하려고 할 때 관심있는 커밋을 숨겨서 문제를 일으킬 가능성이 더 큽니다. . --full-history이 사용 사례에는 항상 플래그를 사용하십시오 .


4
현재 브랜치와 관련된 히스토리 만 검색합니다 ( '전체 리포지토리 히스토리'아님). 즉, 현재 브랜치에서 파일이 아직 삭제되지 않았지만 다른 브랜치에있는 파일은 삭제 커밋을 찾지 못합니다. 파일이 이미 삭제 된 지점 에 있어야합니다 . 어쩌면 그것에 대해 생각할 때 분명 할 수도 있지만 처음에는 나를 따라 잡았습니다.
Anentropic

1
이 대답은 효과가 있습니다. 그러나 git log출력 자체에서 마지막 커밋이 파일 을 삭제 했는지 확실하지 않습니다 . 나는 또한 시도 git log --name-status --full-history -- file_name하고 git log -p --stat --full-history -- file_name있지만, 최신 커밋으로도 명시 적으로 파일이 삭제 된 것을 나타냅니다. 이것은 버그 인 것 같습니다.
Martin_W

@Martin_ATS은 mkdir somedir && cd somedir && git init && touch foo && git add foo && git commit -m "Added foo" && git checkout -b newbranch && touch bar && git add bar && git commit -m "Added bar" && git checkout master && git rm foo && git commit -m "Deleted foo" && git checkout newbranch && git rm bar && git commit -m "Deleted bar" && git checkout master && git merge newbranch && git log --name-status --full-history -- bar포함 D bar하고 A bar힘내 2.12.2와 로그 출력에 나를 위해. 출력에 해당 줄이 보이지 않습니까? 어떤 버전이 있습니까?
Mark Amery

git version 2.15.1예, 명령 순서는 D bar및을 보고 A bar합니다. 아마도 내 문제는 파일 기록과 관련이 있습니다. 나는 .htaccessgitignore'ed되고 제거 된 파일 의 역사를 추적하고있었습니다 . 나는 마침내 그것을 알아 내고 파일을 다시 추가했습니다. 내가 포함하면 --name-statusgit log명령, 저는 두 볼 A .htaccess(I 추가 이후 커밋 최근에 백업)하지만 항목을 D .htaccess. 따라서 파일이 저장소에서 제거되었지만 git log명시 적 D file_name항목이 표시되지 않는 경우 가 있습니다.
Martin_W

@Martin_ATS 궁금합니다. 아마도 .htaccess커밋 X에 추가되었지만 X를 마스터로 가져온 병합 커밋에 포함되지 않았 는지 궁금합니다 . 그건 내가 아마도 주장 할 수 있다고 생각할 수있는 유일한 일이 마땅 추가 된 파일처럼 보이도록 결코 삭제되지 그럼에도 불구하고 아직 존재하지. MCVE를 알아 낸 다음 Git 버그인지 여부와 그렇지 않은 경우 귀하의 사례를 처리하기 위해 답변을 조정할 수 있는지 여부를 알아내는 것이 흥미로울 것입니다.
Mark Amery

84

힘내 로그하지만 경로 앞에 접두사를 붙여야합니다. --

예 :

dan-mac:test dani$ git log file1.txt
fatal: ambiguous argument 'file1.txt': unknown revision or path not in the working tree.

dan-mac:test dani$ git log -- file1.txt
 commit 0f7c4e1c36e0b39225d10b26f3dea40ad128b976
 Author: Daniel Palacio <danpal@gmail.com>
 Date:   Tue Jul 26 23:32:20 2011 -0500

 foo

31

regexp를 사용하여 삭제 된 파일의 커밋을 찾는 솔루션을 여기에 추가했습니다 (git에 저장소에 삭제 된 모든 파일을 나열하는 방법이 있습니까?) .

git log --diff-filter=D --summary | sed -n '/^commit/h;/\/some_dir\//{G;s/\ncommit \(.*\)/ \1/gp}'

some_dir(cascading) 이라는 디렉토리에서 삭제 된 모든 것을 반환합니다 . sed regexp \/some_dir\/는 어디에서 할 것인가.

OSX (@triplee 및 @keif 덕분에)

git log --diff-filter=D --summary | sed -n -e '/^commit/h' -e '\:/:{' -e G -e 's/\ncommit \(.*\)/ \1/gp' -e }

1
좋은. OS X에서 떠들썩한 파티에서 일부 불일치 :sed: 1: "/^commit/h;/\/some_dir\ ...": bad flag in substitute command: '}'
브렌트 파우스트

@BrentFoust 그것은 그것을 테스트 할 수없는 tty입니다 ... 끝에 공백을 추가하십시오 (중괄호 뒤에 그러나 작은 따옴표 전에), 온라인 맨 페이지는 그것에 대해 명확하지 않습니다 ...
estani

좋은 제안입니다. 그러나 작은 따옴표 앞에 공백을 추가해도 도움이되지 않았습니다. 닫는 괄호 앞에 공백도 없었습니다.
브렌트 파우스트

1
BSD / OSX sed는 명령 분리 자로 세미콜론을 사용하는 것이 항상 좋은 것은 아닙니다. 그것들을 개행 문자로 바꾸거나sed -n -e '/^commit/h' -e '\:/some_dir/:{' -e G -e 's/\ncommit \(.*\)/ \1/gp' -e }
tripleee

1
나는 그것을 테스트하고 git log --diff-filter=D --summary | sed -n -e '/^commit/h' -e '\:/:{' -e G -e 's/\ncommit \(.*\)/ \1/gp' -e }OSX에서 나를 위해 일했다.
keif

21

다음과 같이 파일을 삭제 한 마지막 커밋을 찾을 수 있습니다.

git rev-list -n 1 HEAD -- [file_path]

자세한 내용은 여기를 참조하십시오


11
기본 upvoted 솔루션은 나에게 효과가 없었지만 이것은 효과가있었습니다.
Nick Heiner

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.