Git의 특정 개정판에서 단일 파일을 검색하는 방법은 무엇입니까?


831

Git 저장소가 있고 몇 개월 전에 일부 파일이 어떻게 보이는지 확인하고 싶습니다. 그 날짜에 개정판을 찾았습니다. 그것은이다 27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8. 하나의 파일이 어떤 모양인지 확인하고 파일을 ""새 "파일로 저장해야합니다.

를 사용하여 파일을 볼 수는 gitk있지만 저장할 수있는 옵션이 없습니다. 나는 가장 가까운 명령 줄 도구를 사용해 보았습니다.

git-show 27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8 my_file.txt

그러나이 명령은 파일 내용이 아니라 diff를 표시합니다. 나중에 비슷한 것을 사용하고 PAGER=cat출력을 파일로 리디렉션 할 수 있다는 것을 알고 있지만 실제 파일 내용을 얻는 방법을 모르겠습니다.

기본적으로 svn cat 과 같은 것을 찾고 있습니다.


73
여기서 중요한 것은 : git show(무의미한) 콜론과 다른 구문을 사용합니다. git show 2c7cf:my_file.txt
Steve Bennett

4
더 명확히하기 위해 위의 명령은 git에게 수정본과 파일이라는 두 개의 개별 객체를 표시하도록 요청합니다. 두 항목 사이에 콜론을 사용하는 아래의 허용되는 답변은 특정 개정판에서 특정 파일을 요구합니다.
jhclark

2
* nix에서 스크립트에서 당신은, PAGER에게 필요한 쉘 출력 리디렉션하지 않습니다>
콘스탄틴 Pelepelin


Checat에는 컨텐츠를 일부 파일로 내보내려는 사람들에게 중요한 설명이 있습니다. git show {sha} : my_file.txt> old_my_file.txt
ormurin

답변:


743

자신의 답변을 완성하기 위해 구문은 실제로

git show object
git show $REV:$FILE
git show somebranch:from/the/root/myfile.txt
git show HEAD^^^:test/test.py

이 명령은 일반적인 수정 스타일을 사용하므로 다음 중 하나를 사용할 수 있습니다.

  1. 지점 이름 (같은 제안 에 의해 )
  2. HEAD+ x ^
  3. 주어진 개정의 SHA1 해시
  4. 주어진 SHA1 해시의 처음 몇 문자 (아마도 5 자)

" git show" 를 사용할 때는 항상 현재 디렉토리 위치가 아닌 저장소 루트의 경로를 지정 하십시오.

( Mike Morearty 는 적어도 git 1.7.5.4에서는 경로 ./의 시작 부분에 " "를 넣어 상대 경로를 지정할 수 있다고 언급합니다. 예를 들면 다음과 같습니다.

git show HEAD^^:./test.py

)


Git 2.23+ (2019 년 8 월)에서는 혼동 명령git restore 을 대체 할 수 있습니다.git checkout

git restore -s <SHA1>     -- afile
git restore -s somebranch -- afile

이것은 "source"( -s) commit SHA1 또는 branch에 있는 파일 만 작업 트리에서 복원합니다 somebranch.
색인도 복원하려면 다음을 수행하십시오.

git restore -s <SHA1> -SW -- afile

( -SW: 짧음 --staged --worktree)


git1.5.x 이전에는 약간의 배관 작업이있었습니다.

git ls-tree <rev>
커밋 내에서 하나 이상의 'blob'객체 목록 표시

git cat-file blob <file-SHA1>
특정 개정판 내에서 커밋 된 파일 (svn cat과 유사) git ls-tree를 사용하여 주어진 파일의 값을 검색하십시오

git cat-file -p $(git-ls-tree $REV $file | cut -d " " -f 3 | cut -f 1)::

git-ls-tree는 $ REV 개정판에서 $ file에 대한 객체 ID를 나열합니다. 이것은 출력에서 ​​잘라내어 git-cat-file에 대한 인수로 사용되며, 실제로는 git-cat-object라고하며 덤프 만합니다. stdout에 해당 객체.


참고 : Git 2.11 (Q4 2016)부터 git cat-file출력에 콘텐츠 필터를 적용 할 수 있습니다 !

참조 3,214,594 커밋 , 7bcf341 커밋 (2016 9월 9일)를 7bcf341 커밋 (2016 년 9 월 09), 및 b9e62f6 커밋 , 16dcc29 커밋 에 의해 (2016년 8월 24일) 요하네스 Schindelin을 ( dscho) .
( Junio ​​C gitsterHamano 에 의해 합병 -- 커밋 7889ed2 , 2016 년 9 월 21 일)

cat-file: 지원 --textconv/ --filters배치 모드

git hash-objects온 파일 시스템 데이터 스트림을 가져 와서 Git 객체 저장소에 넣는 도구 인 ""( ")가"out-world-to-Git "변환 (예 : end-of-line 변환 및 응용 프로그램)을 수행 할 수 있음에도 불구 하고 이 필터는 초기 초기부터 기본적으로 기능이 설정되어 있으며 역 작업 " git cat-file"은 Git 객체 저장소에서 객체를 가져와 외부 세계의 소비를 위해 외부화합니다. "Git-to-Outside World"를 운영

git config diff.txt.textconv "tr A-Za-z N-ZA-Mn-za-m <"
git cat-file --textconv --batch

참고 : " git cat-file --textconv"최근에 segfaulting을 시작했습니다 (2017). Git 2.15 (2017 년 4 분기)에서 수정되었습니다.

Jeff King ( )의 커밋 cc0ea7c (2017 년 9 월 21 일)를 참조하십시오 . (의해 병합 Junio C 하마노 - -커밋 bfbc2fc 28 구월 2017)peff
gitster


과거의 내용으로 파일 을 덮어 쓰거나 바꾸려면 더 이상 혼란스러운 git checkout명령을 사용 하지 말고 git restore(Git 2.23+, 2019 년 8 월)

git restore -s <SHA1> -- afile

그러면 "소스"( -s) 커밋 SHA1에 있는 파일 만 작업 트리에서 복원됩니다 .
색인도 복원하려면 다음을 수행하십시오.

git restore -s <SHA1> -SW -- afile

( -SW: 짧음 --staged --worktree)


6
@Oscar는 git show본질적으로 stdout(표준 출력) 의 내용을 덤프하므로 해당 출력을 원하는 파일 ( tldp.org/LDP/abs/html/io-redirection.html )로 리디렉션 할 수 있습니다.
VonC 2016 년

8
git checkout [branch | revision] filepath올바른 명령입니다
Gaui

12
@Gaui하지만 git checkout보다 우선 반대로, 다른 버전의 파일을 git show당신이 얻을하고 볼 수 있도록 당신이 순서에 다른 이름으로 저장할 수있는 (현재 버전과 이전 버전). OP가 현재 버전을 이전 버전으로 교체 하려는지 여부는 확실하지 않습니다 .
VonC 2016

9
나는 ^^^일반적으로 ~~~또는 더 나은 것으로 쓰여질 수 있다는 점에 주목하고 싶다 ~3. 물결표를 사용하면 일부 쉘 (예 : zsh)의 파일 이름 일치를 트리거하지 않는 이점도 있습니다.
Eric O Lebigot 2018 년

2
1.5.x 이전 버전에서 구문을 git rev-parse처리 rev:path합니까? (보다 최근의 git에서는 할 수 있습니다 git cat-file -p $REV:path. 그러나 git show디렉토리 경로에서도 작동하므로 짧지 않고 일반적으로 원하는 것에 더 가깝습니다.)
torek

510

현재 분기의 파일 내용을 이전 커밋 또는 다른 분기의 파일 내용 으로 바꾸거나 덮어 쓰 려면 다음 명령을 사용하면됩니다.

git checkout 08618129e66127921fbfcbc205a06153c92622fe path/to/file.txt

또는

git checkout mybranchname path/to/file.txt

그런 다음 현재 브랜치에서 변경 사항을 적용하려면 해당 변경 사항을 커밋해야합니다.


4
가장 간단한 해결책은 git-checkout이 설계된 것입니다. 경로 이름을 지정하면 일치하는 파일 만 체크 아웃됩니다. 자식 체크 아웃 매뉴얼 페이지에서 : 자식 체크 아웃 마스터 ~ 2 Makefile
RichVel

1
그런 다음이 명령을 실행하기 전에 어떻게 이전 상태로 돌아 갑니까?
Flint

@Flint HEAD 상태에서 오는 경우 git checkout HEAD-[full path]와 같이 간단합니다.
Tiago Espinha

72
이 방법은 해당 경로의 기존 파일을 덮어 git show SHA1:PATH쓰지만 솔루션은 stdout으로 만 인쇄합니다.
Flimm

좋은! 나는을 보면서 이것을 알아낼 수 없었을 것 git help checkout입니다. 특정 날짜를 기준으로 하위 디렉토리를 체크 아웃해야 git checkout @{YYYY-MM-DD} sub-dir
했으며이

150

파일의 전체 경로를 제공해야합니다.

git show 27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8:full/repo/path/to/my_file.txt

7
전체 경로 일 필요는 없습니다. 자식 루트 디렉토리 경로 (에 온 사람들은 git show --name-only너무 충분하다
모흐센

7
저장소 루트의 전체 경로 내가 제시 한 예를 더 잘 살펴보십시오. "full"앞에는 슬래시가 없습니다.
밀라노 Babuškov

7
참고로 하위 디렉토리에 있으면 ./filename.ext도 성공적으로 사용할 수 있습니다.
Traveler

요점은 당신이에 full/repo/path/to있고 시도하면 : git show 27cf8e84:my_file.txt, 치명적인 : 경로 'full / repo / path / to / my_file.txt'는 존재하지만 'my_file.txt'는 아니라는 메시지가 나타납니다. . '27cf8e84 : full / repo / path / to / my_file.txt'또는 '27cf8e84 : ./ my_file.txt'를 의미 했습니까? 마치 Git이 직접 도움을 줄 수 있었지만 여기에서 pedantic로 선택했습니다.
Ed Randall

101

가장 쉬운 방법은 작성하는 것입니다 :

git show HASH:file/path/name.ext > some_new_name.ext

어디:

  • 해시 는 Git 개정판 SHA-1 해시 번호입니다
  • file / path / name.ext 는 찾고있는 파일의 이름입니다
  • some_new_name.ext 는 이전 파일을 저장해야하는 경로 및 이름입니다.

git show 27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8:my_file.txt > my_file.txt.OLD

이 저장됩니다 my_file.txt 개정에서 27cf8e을 이름으로 새 파일로 my_file.txt.OLD

Git 2.4.5로 테스트되었습니다.

삭제 된 파일 을 검색 하려면 사용할 수 있습니다 HASH~1(지정된 HASH 전에 하나의 커밋).

예:

git show 27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8~1:deleted_file.txt > deleted_file.txt

1
추가 정보 : 당신은 해시 자식 로그를 예를 들면 얻을 수 있습니다
xotix

@xotix 감사합니다. 다음을 사용하여 특정 파일에 대한 모든 HASH 기록을 얻었습니다.git log file/path/name.ext
Sriram Kannan

11

Git Bash를 사용하는 Windows의 경우 :

  • 작업 공간에서 dir을 파일이있는 폴더로 변경하십시오.
  • git show cab485c83b53d56846eb883babaaf4dff2f2cc46:./your_file.ext > old.ext

8

그리고 파일로 멋지게 덤프하려면 (적어도 Windows에서는)-Git Bash :

$ echo "`git show 60d8bdfc:src/services/LocationMonitor.java`" >> LM_60d8bdfc.java

"은 줄 바꿈을 유지하므로 따옴표가 필요하다.


좋은데 +1. git show위에서 언급 한 구문 에 대한 좋은 추가 .
VonC

23
나는 따옴표가 있거나없는 에코를 왜 사용 해야하는지 이해하지 못합니다. 그리고 왜 추가 형식의 출력 리디렉션을 원하는지 이해하지 못합니다. git show 60d8bdfc : src / services / LocationMonitor.java> LM_60d8bdfc.java 어떤 이유로 인해 실제로 dos 스타일 줄 끝을 강제하고 싶다면 unix2dos를 통해 파이프 할 수 있습니다. 그러나 Windows에서 사용한 메모장 이외의 텍스트 도구는 유닉스 스타일의 줄을 잘 처리하기 때문에 Windows에서 행 줄 끝을 유지하는 것이 가장 유용한 방법은 결코 찾지 못했습니다.
sootsnoot

4
git show 60d8bdfc : src / services / LocationMonitor.java >> LM_60d8bdfc.java가 나를 위해 일했습니다.
Mike6679

@ 마이크 : 당신은 창문에 있습니까?
Mr_and_Mrs_D

2
쉘 변수 (예 : $ LANG)처럼 보이는 파일 문자가 바뀌면 큰 따옴표를 사용하지 마십시오. @ LưuVĩnhPhúc는 보호기입니다. 또한 사용하지 마십시오 >> 파일이 있으면 파일을 추가하고 오류가 발생할 수 있습니다.
theguy

3

이렇게하면 경로를 지정하지 않고 커밋간에 삭제 된 모든 파일을 가져올 수 있습니다. 삭제 된 파일이 많은 경우 유용합니다.

git diff --name-only --diff-filter=D $commit~1 $commit | xargs git checkout $commit~1

1
git checkout {SHA1} -- filename

이 명령은 특정 커밋에서 복사 된 파일을 가져옵니다.


-2

이전 커밋 및 복사 파일을 체크 아웃하여 이전 커밋에서 파일을 가져옵니다.

  • 현재 어느 브랜치인지 확인하십시오 : git branch
  • 원하는 이전 커밋을 확인하십시오. git checkout 27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8
  • 원하는 파일을 임시 위치에 복사
  • 시작한 지점을 확인하십시오. git checkout theBranchYouNoted
  • 임시 위치에 배치 한 파일로 복사
  • git로 변경 사항을 커밋하십시오. git commit -m "added file ?? from previous commit"
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.