전체 커밋이 아닌 하나의 파일에 대해서만 변경 사항을 선택하는 방법


108

한 지점에 도입 된 변경 사항을 다른 지점에 적용해야합니다. 체리 픽을 사용해서 할 수 있습니다. 그러나 제 경우에는 하나의 파일에만 관련된 변경 사항을 적용하고 싶기 때문에 전체 커밋을 선택할 필요가 없습니다. 그렇게하는 방법?


답변:


137

달성하고자하는 것에 따라 다양한 옵션이 있습니다.

파일 내용을 대상 분기와 동일하게하려면 git checkout <branch> -- <filename>. 그러나 이것은 단일 커밋에서 발생한 변경 사항을 "체리 선택"하지 않고 해당 파일의 결과 상태를 취합니다. 따라서 커밋에 한 줄을 추가했지만 이전 커밋이 더 많이 변경되고 다른 변경 사항없이 해당 줄만 추가하려는 경우 체크 아웃이 원하는 것이 아닙니다.

그렇지 않으면 커밋에 도입 된 패치를 단일 파일에만 적용하려는 경우 여러 옵션이 있습니다. 을 실행할 수 있습니다 git cherry-pick -n. 즉, 커밋하지 않고 커밋을 편집 할 수 있습니다 (예를 들어를 사용하여 모든 파일을 재설정 git reset -- .하고를 사용하여 실제로 변경하려는 파일 만 추가 git add <filename>). 또는 파일에 대한 diff를 만들고 diff를 적용한 다음 다음을 수행 할 수 있습니다.

git diff <branch>^..<branch> -- <filename> | git apply

22

생성 patch file하고 적용하십시오.

git diff branchname -- filename > patchfile
git apply patchfile

편집하다:

커밋에서 변경 사항을 가져와야하므로 다음과 같이 패치를 만듭니다.

git show sha1 -- filename > patchfile

1
git diff sha1(또는 git diff branch-분기가 동일한 해시를 가리키는 경우 동일 함) 해당 해시와 관련하여 현재 작업 디렉토리의 차이 만 생성하지만 자체적으로 도입 된 커밋을 변경하는 것은 아닙니다.
찌르기

옳은. 답변을 수정했습니다. 감사.
Sailesh

1
git checkout파일 이름이있는 -1 은이 못에 적합한 망치입니다. 이 두 옵션 모두 불필요하게 복잡합니다.
Rein Henrichs

7
이 특별한 경우에는 그렇습니다. 그러나 일반적으로 특정 파일에 대한 커밋에서 변경 사항을 선택하려는 경우 checkout다른 원치 않는 이전 변경 사항이 포함될 수 있으며 현재 분기에서 변경된 내용이 포함되지 않을 수 있으므로 작동하지 않습니다.
Sailesh 2013

11

또 다른 편리한 방법은 로컬에서 패치를 가져온 다음 다음을 사용하는 것입니다.

git checkout {<name_of_branch>, commit's SHA} <path to the file> 

그래도 체리 따는 것은 아닙니다.


2
경고 : @poke가 그의 대답에서 말했듯이 이것은 변경 사항을 복사하지 않습니다. 파일의 전체 상태를 복사합니다. 따라서 커밋의 변경 사항을 파일 에 추가 하려면 이와 같이 체크 아웃하면 좋지 않은 새로운 변경 사항을 덮어 쓰게 됩니다.
Alexander Bird

7

힘내는 모든 준비가되어 있습니다 :)

그냥 사용 git checkout <sha> <path-to-file>


4
파일을 전체적으로 확인하는 것은 체리 픽이 아닙니다. 목표는 커밋에서 특정 변경을 수행하는 것입니다. 종종 그것들은 같은 것이지만 때로는 그렇지 않습니다.
AndrewF

6
git checkout the_branch_with_the_change the/path/to/the/file/you/want.extension

이것은 다른 브랜치의 단일 파일을 현재 작업 브랜치로 복사하려는 경우 작동합니다.


1
주의하십시오. 다른 분기의 버전에없는 파일에서 수행 된 변경 사항은 손실됩니다.
Patrick Schlüter

그것에 동의합니다. 이것은 파일의 사본 만 필요하고 현재 브랜치에서 변경하려는 경우에 유용합니다.
Ismail Iqbal

1
glob (경로 / *)을 사용하고 둘 이상의 경로 / 파일을 지정할 수 있습니다
Todd

1

이것은 당신이 찾고있는 것입니다 :

git checkout target-branch sha1 path/to/file

sha1은 선택 사항입니다.


11
아니요, " 커밋에서 변경 사항 선택 "은 "전체 파일 선택"이 아닙니다.
Abyx 2014

1

내가하는 경향이있는 것은 git ls-tree

그냥 해:

git ls-tree -r <commit-id> |grep 'your filename'
# there will be output that shows a SHA1 of your file
git show ${SHA1 of your file} > 'your filename'

이것은 grep과 일치하는 모든 파일 이름을 인쇄하고 커밋에있는 파일의 SHA1 키를 제공합니다.

Git show는 브랜치 외부의 파일에서도 사용할 수 있습니다. >쉘에서 사용하여 출력을 파일로 파이프하면 원하는 결과를 얻을 수 있습니다.


0

이 작업을 시도 할 수 있습니다.

git show COMMIT_ID -- path/to/specific-file | git apply

예를 들면 :

git show 3feaf20 -- app/views/home/index.html | git apply

-9
git reset HEAD~1

파일을 사전 커밋 단계로 이동

git stash

메모리에서 제거

이제 분기가 꽤 깨끗합니다 (이전 커밋으로 되돌림).

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