다른 지점에서 하나의 파일 만 얻는 방법


1261

git을 사용하고 마스터 브랜치에서 작업 중입니다. 이 지점에는이라는 파일이 app.js있습니다.

나는 experiment많은 변화와 많은 커밋 을 한 지점이 있습니다. 이제 모든 변경 사항 을 지점 app.js에서 지점 으로 가져오고 싶습니다 .experimentmaster

어떻게합니까?

다시 한번 나는 병합을 원하지 않는다. 지점 app.js에서 experiment지점으로 모든 변경 사항을 가져오고 싶습니다 master.



1
오늘의 답변과 다른 사람들을 제외하고 파일의 내용을 복사하는 방법에 대한 답변은 그 파일을 찾을 때 내가 원했던 것입니다. 그러나 정확하게 읽으면 Nick은 전체 텍스트가 아닌 변경 사항을 가져 오려고했으며 파일이에서 master분기 될 experiment수 있습니다. 예를 들어 파일에서 손실 될 다른 분기에서 병합 된 변경 사항이 복사 될 수 있습니다. 반면에 PS는 병합하고 싶지 않지만 git merge용어는 특정 파일이 아닌 분기 전용이므로 여기서 모순되지 않습니다.
Alexei Martianov

답변:


1600
git checkout master               # first get back to master
git checkout experiment -- app.js # then copy the version of app.js 
                                  # from branch "experiment"

git 하나의 파일 변경을 취소하는 방법 도 참조하십시오 .


2019 년 8 월 업데이트, Git 2.23

새로운 명령 git switchgit restore명령을 사용하면 다음 과 같습니다.

git switch master
git restore -s experiment -- app.js

기본적으로 작업 트리 만 복원됩니다.
당신은뿐만 아니라 인덱스를 업데이트 할 경우 (파일 내용을 복원 의미 하나의 명령으로 인덱스에 추가)

git restore -s experiment --staged --worktree -- app.js
# shorter:
git restore -s experiment -WS -- app.js

Jakub Narębski 가 주석에서 언급 한 것처럼 :

git show experiment:path/to/app.js > path/to/app.js

SO 질문 " Git의 특정 개정판에서 단일 파일을 검색하는 방법? "에 설명 된대로, 리포지토리 의 루트 디렉토리에서 전체 경로를 사용해야합니다.
따라서 그의 예제에서 Jakub이 사용한 경로 /to/app.js.

서리가 언급에서 언급 했듯이 :

가장 최근의 app.js 상태 만 얻을 수 있습니다

그러나 git checkout또는의 git show경우 SO 질문 " git gui의 파일의 git checkout 개정 "에 설명 된 것처럼 실제로 원하는 개정을 참조 할 수 있습니다 .

$ git show $REVISION:$FILENAME
$ git checkout $REVISION -- $FILENAME

$ FILENAME은 버전 파일 의 전체 경로 입니다.

$REVISION다음과 같이 될 수 있습니다 git rev-parse:

experiment@{yesterday}:app.js # app.js as it was yesterday 
experiment^:app.js            # app.js on the first commit parent
experiment@{2}:app.js         # app.js two commits ago

등등.

schmijos주석에 다음을 추가합니다 .

당신은 또한 은닉에서 이것을 할 수 있습니다 :

git checkout stash -- app.js

이것은 두 가지에서 일하고 있고 커밋하지 않으려는 경우에 매우 유용합니다.


13
한 가지 참고 사항 : 가장 최신 상태의 app.js 만 가져오고 실험 브랜치에서 이력을 가져 가지 않습니다.
Frosty

2
@ThomasReggi 모든 브랜치에서 현재 브랜치로 파일을 가져 오기 (체크 아웃) 할 수 있어야합니다. 당신이 할 수 없다면, 정확한 오류 메시지, Git 및 OS 버전과 같은 특정 세부 정보와 함께 여기에 질문하는 것이 좋습니다.
VonC 2016 년

2
하위 디렉토리에서을 사용할 수도 있습니다 experiment:./app.js. (전체 경로를 지정할 필요는 없습니다.) git이 내게 준 매우 유용한 오류 메시지 덕분에 이것을 배웠습니다. " 'mybranch : full / path / to / my / file.xsl'aka 'mybranch : ./file.xsl '? " 그래, 내가 했어! 치명적인 오류 메시지에 너무 기뻐했다고 생각하지 않습니다.
Evan Lenz

1
@TomaszGandor 예, stackoverflow.com/a/21066489/6309 에서 git show는 색인을 수정하지 않지만 git checkout은 색인을 수정합니다.
VonC

1
@FriedBrice 내 답변보기 : 요즘은git restore -s new-feature path/to/app.js
VonC

359

모든 것이 훨씬 간단합니다 .git checkout을 사용하십시오.

분기를 수행 you're on master하기 위해 app.js from new-feature분기 를 가정하십시오 .

git checkout new-feature path/to/app.js

// note that there is no leading slash in the path!

원하는 파일의 내용이 나타납니다. 항상 그렇듯이, 새로운 기능 브랜치 이름 대신 sha1의 일부를 사용 하여 파일을 해당 커밋에있는 것처럼 가져올 수 있습니다.

참고 : 원격 지점이 아닌 로컬 지점 new-feature이어야합니다 .


76
git checkout origin/source_branch path/to/file로컬 리포지토리의 소스 분기를 업데이트하지 않으면 파일의 이전 버전을 얻을 수 있기 때문에 항상 원점을 지정하는 것이 도움이된다는 것을 알고 있습니다. ;)
talyric

2
문제는 리모컨을 언급하지 않았다 @Mymozaaa, 따라서 그것은 순전히 지역의 repo 가정이다
드미트리 Avtonomov

1
이 명령은 파일의 히스토리 또는 파일의 마지막 버전 만 가져 옵니까?
user1366265

1
@ user1366265이 명령은 지정한 특정 커밋 또는 지정한 브랜치의 헤드에있는 그대로 파일을 넣습니다. "파일 히스토리"와 같은 것은 없으며 모든 히스토리 정보는 브랜치에만 저장됩니다.
Dmitry Avtonomov

3
이것은 체크 아웃 된 파일을 자동으로 스테이징하는 것 같습니다. 준비하지 않고 동일한 작업을 수행 할 수 있습니까?
bluenote10

44
git checkout branch_name file_name

예:

git checkout master App.java

지점 이름에 마침표가 있으면 작동하지 않습니다.

git checkout "fix.june" alive.html
error: pathspec 'fix.june' did not match any file(s) known to git.

@PhilipRego이 답변은 정확합니다. 지점에 다른 대문자 또는 문장 부호가 있거나 로컬 지점이 아닌 원격 지점 만 있다고 생각합니다. 자식 체크 아웃 문서를 참조하십시오 : git-scm.com/docs/git-checkout#Documentation/…
Bret

@Bret 지점 이름에 마침표가 있으면 작동하지 않는다는 것을 알았습니다. 나는 편집을 제안했다
Philip Rego

이것이 가장 좋은 대답입니다. 이 답변이 가장 높은 등급을 받기를 바랍니다. 현재 가장 높은 사람은 매우 혼란하고 간단하지 않습니다
러셀 레고

41

VonC 및 chhh의 답변에 보충.

git show experiment:path/to/relative/app.js > app.js
# If your current working directory is relative than just use
git show experiment:app.js > app.js

또는

git checkout experiment -- app.js

2
멋있는! 긴 경로를 지정하는 것이 싫습니다. --분기 이름과 경로 사이 의 이중 대시 ( )는 선택 사항입니까? 대시로 시작하는 경로가 옵션 / 스위치로 처리되지 않도록 방지하는 것입니까?
Tomasz Gandor

솔직히 모르겠다. 나는 당신이 이것을 지적 할 때까지 이중 대시를 잊어 버린 것을조차 알지 못했습니다.
AlexLordThorsen

6
@TomaszGandor The --는 선택 사항이지만 지점 이름과의 충돌을 피하는 것이 더 유용합니다. 예를 들어, git checkout -- foo수단 (예.에 덮어 쓰기 로컬 변경 "HEAD에서 파일 foo는 체크 아웃" foo는 .의 일부를, 즉 git reset --hard), 그러나 git checkout foo것을 의미 할 수 있었다 또는 "하자가 지점으로 이동 foo는 ".
Alois Mahdal

8

또는 다른 지점의 모든 파일을 원할 경우 :

git checkout <branch name> -- .

24
초기 질문은 "단지 하나의 파일"을 포함합니다.
greatvovan

1
이것은 병합하는 대신 기존 파일을 대체합니다
Amare

3
이것은 .큰 차이를 만듭니다. 다른 브랜치로 이동하는 대신 여전히 현재 브랜치를 유지하면서 거기에서 모든 파일을 복사합니다. 다른 지점에서 들어 가지 않고 내용을 얻습니다.
Xeverous

4

github에서 파일을 검토하고 거기서 가져옵니다.

이것은 OP에 직접 응답하지 않는 실용적인 접근 방식이지만 일부는 유용한 것으로 나타났습니다.

해당 분기가 GitHub에있는 경우 GitHub에서 제공하는 많은 도구 중 하나를 사용하여 원하는 분기 및 파일로 이동 한 다음 'Raw'를 클릭하여 일반 텍스트를보고 (선택 사항) 텍스트를 복사하여 붙여 넣기 원하는.

이 접근 방식을 사용하면 원격 파일을 로컬 시스템으로 가져 오기 전에 전체 파일을 볼 수 있습니다.


2
그러나 원시 파일을 복사하여 붙여 넣으면 git diff에서 원하지 않는 문자 변경이 발생할 수 있습니다. 변경 사항이 없도록 파일을 프로젝트에 직접 저장하는 것이 더 안전합니다.
Philip Rego 2016 년

0

특정 커밋 (모든 브랜치)에서 파일을 원하면 06f8251f라고 말하십시오.

git checkout 06f8251f path_to_file

예를 들어, Windows에서 :

자식 체크 아웃 06f8251f C : \ A \ B \ C \ D \ file.h


1
답변 해 주셔서 감사합니다! 그러나 이것은 그 질문에 대한 답이 아니며, 매우 자세한 답변은 이미 9 년 전에 게시되었습니다. 질문을 부딪 칠 필요가 없습니다.
Nathan

이것은 유효한 실제 시나리오입니다. 대답은 지점을 올바르게 다루지 만 지점의 특정 커밋을 보는 것은 어떻습니까?
arupjbasu

0

다른 방법은 차이점이있는 패치를 만들어 마스터 브랜치에 적용하는 것입니다. app.js 작업을 시작하기 전의 마지막 커밋은 00000aaaaa이고 원하는 버전의 커밋 포함은 00000bbbbb라고 가정 해 봅시다.

실험 브랜치에서 이것을 실행합니다.

git diff 00000aaaaa 00000bbbbb app.js > ~/app_changes.git

그러면 app.js에 대한 두 커밋 간의 차이점이 모두있는 파일이 만들어져 원하는 곳에서 적용 할 수 있습니다. 프로젝트 외부 어디에서나 해당 파일을 유지할 수 있습니다

그런 다음 마스터에서 다음을 실행하십시오.

git apply ~/app_changes.git

이제 프로젝트를 수동으로 만든 것처럼 변경 사항을 볼 수 있습니다.


-3
git checkout master               -go to the master branch first
git checkout <your-branch> -- <your-file> --copy your file data from your branch.

git show <your-branch>:path/to/<your-file> 

이것이 도움이되기를 바랍니다. 문의 사항이 있으시면 알려주십시오.

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