n 커밋이있는 Git 저장소가 있습니다.
필요한 파일이 있고 저장소에 있던 파일이 있는데 갑자기 "아! 그 파일은 어디로 갔습니까?"
"file really_needed.txt가 커밋 n-13에서 삭제되었다"고 알려주는 일련의 Git 명령이 있습니까?
즉, 모든 개별 커밋을 보지 않고 내 Git 저장소에 모든 파일의 변경 사항이 있음을 알지 못하면 해당 파일이있는 마지막 커밋을 신속하게 찾을 수 있으므로 다시 가져올 수 있습니까?
n 커밋이있는 Git 저장소가 있습니다.
필요한 파일이 있고 저장소에 있던 파일이 있는데 갑자기 "아! 그 파일은 어디로 갔습니까?"
"file really_needed.txt가 커밋 n-13에서 삭제되었다"고 알려주는 일련의 Git 명령이 있습니까?
즉, 모든 개별 커밋을 보지 않고 내 Git 저장소에 모든 파일의 변경 사항이 있음을 알지 못하면 해당 파일이있는 마지막 커밋을 신속하게 찾을 수 있으므로 다시 가져올 수 있습니까?
답변:
git log --full-history -- [file path]
파일의 변경 사항을 표시하고 파일이 삭제 된 경우에도 작동합니다.
예:
git log --full-history -- myfile
파일을 삭제 한 마지막 커밋 만 보려면 -1을 추가로 사용하십시오 (예 : git log --full-history -1 -- [file path]
참조 어떤 파일을 삭제 커밋
git log -- */<<filename>>.<<file extension>>
전체 파일 경로를 모르면서 검색 할 수있었습니다 .
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
이 사용 사례에는 항상 플래그를 사용하십시오 .
git log
출력 자체에서 마지막 커밋이 파일 을 삭제 했는지 확실하지 않습니다 . 나는 또한 시도 git log --name-status --full-history -- file_name
하고 git log -p --stat --full-history -- file_name
있지만, 최신 커밋으로도 명시 적으로 파일이 삭제 된 것을 나타냅니다. 이것은 버그 인 것 같습니다.
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와 로그 출력에 나를 위해. 출력에 해당 줄이 보이지 않습니까? 어떤 버전이 있습니까?
git version 2.15.1
예, 명령 순서는 D bar
및을 보고 A bar
합니다. 아마도 내 문제는 파일 기록과 관련이 있습니다. 나는 .htaccess
gitignore'ed되고 제거 된 파일 의 역사를 추적하고있었습니다 . 나는 마침내 그것을 알아 내고 파일을 다시 추가했습니다. 내가 포함하면 --name-status
에 git log
명령, 저는 두 볼 A .htaccess
(I 추가 이후 커밋 최근에 백업)하지만 항목을 D .htaccess
. 따라서 파일이 저장소에서 제거되었지만 git log
명시 적 D file_name
항목이 표시되지 않는 경우 가 있습니다.
.htaccess
커밋 X에 추가되었지만 X를 마스터로 가져온 병합 커밋에 포함되지 않았 는지 궁금합니다 . 그건 내가 아마도 주장 할 수 있다고 생각할 수있는 유일한 일이 마땅 추가 된 파일처럼 보이도록 결코 삭제되지 그럼에도 불구하고 아직 존재하지. MCVE를 알아 낸 다음 Git 버그인지 여부와 그렇지 않은 경우 귀하의 사례를 처리하기 위해 답변을 조정할 수 있는지 여부를 알아내는 것이 흥미로울 것입니다.
힘내 로그하지만 경로 앞에 접두사를 붙여야합니다. --
예 :
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
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 }
sed: 1: "/^commit/h;/\/some_dir\ ...": bad flag in substitute command: '}'
sed
는 명령 분리 자로 세미콜론을 사용하는 것이 항상 좋은 것은 아닙니다. 그것들을 개행 문자로 바꾸거나sed -n -e '/^commit/h' -e '\:/some_dir/:{' -e G -e 's/\ncommit \(.*\)/ \1/gp' -e }
git log --diff-filter=D --summary | sed -n -e '/^commit/h' -e '\:/:{' -e G -e 's/\ncommit \(.*\)/ \1/gp' -e }
OSX에서 나를 위해 일했다.