현재 작업 디렉토리의 변경 사항으로 git 패치를 만듭니다.


878

작업 디렉토리에 커밋되지 않은 변경 사항이 있다고 가정합니다. 커밋을 만들지 않고 어떻게 패치를 만들 수 있습니까?


29
두 번째 답변이 거의 4 배 더 인기가 있기 때문에 허용되는 답변을 변경해야합니다.
Tim Ogilvy 2014

5
@TimOgilvy는 동의했다. OP 가해 야합니다. 두 번째 답변은 훨씬 더 대중적이고 더 많은 정보를 제공합니다
John Demetriou

1
나는 제목의 커밋되지 않은 변경 사항으로부터 패치가 필요하다고 언급 할 가치가 있다고 생각합니다.
2i3r

답변:


401

git diff비 단계적 변경. git diff --cached단계별 변경


12
yup, git diff는 git apply의 역수입니다.
Spike Gronim

33
git format-patch이진 diff 및 일부 메타 정보도 포함합니다. 실제로 이것은 패치를 만드는 데 가장 좋은 방법이지만 소스 / 변경 사항에 대해서만 작동합니다.
Eric

20
때때로 현재 디렉토리에 상대적인 패치를 작성하는 것이 유용 할 수 있습니다. 이를 위해git diff --relative
ejboy

30
git diff> a.patch
qasimzee

139
비꼬는 말로 경계를 좁 히면 아래 답변이 더 도움이됩니다.
Air

1865

아직 변경 사항을 커밋하지 않은 경우 :

git diff > mypatch.patch

그러나 때로는 수행중인 작업의 일부가 추적되지 않고 git diff출력에 포함 되지 않는 새 파일이 발생 합니다. 따라서 패치를 수행하는 한 가지 방법은 새 커밋 ( git add각 파일 또는 그냥 git add .)에 대한 모든 것을 준비 하지만 커밋을 수행하지 않는 것입니다.

git diff --cached > mypatch.patch

패치에 바이너리 파일 (예 : mp3 파일)을 추가하려면 'binary'옵션을 추가하십시오.

git diff --cached --binary > mypatch.patch

나중에 패치를 적용 할 수 있습니다.

git apply mypatch.patch

참고 : --staged의 동의어로 사용할 수도 있습니다 --cached.


127
예제를 주셔서 대단히 감사합니다. 받아 들여진 대답과는 반대로 당신은 단지 명령이 아니라 그것을하는 방법을 보여줍니다. 매우 유용하고 완벽하게 나를 위해 일했습니다 :)
nuala

4
나는 정확하게 그것을했고 git apply를 실행할 때 "치명적 : 인식 할 수없는 입력"을 얻었다. 이 문제의 원인과 해결 방법에 대한 아이디어가 있습니까?
Vitaly

6
@Vitaly : 텍스트 편집기로 패치를 열면 패치를 읽을 수 있습니까? 예를 들어 color.diff 설정이 설정된 경우 패치에 'git apply'가 실패 할 수있는 '컬러 문자'가있을 수 있습니다 git diff --no-color. 그렇지 않으면 인코딩 문제처럼 보입니다.
jcarballo

3
"추적되지 않은 새 파일"과 관련 : "git diff"및 "git diff --cached"는 "git add <file>"이 먼저 호출 된 경우에만 작동합니다. (나는 git을 처음 사용하고 왜 매번 빈 패치를 받았는지 궁금해했다)
Anonymous

5
이것은 아주 쉽게 이상한 병합 / REBASE 지옥의 감사 :) 저를 얻었다
존 헌트

86

git diffgit apply텍스트 파일을 작동하지만 바이너리 파일에 대해 작동하지 않습니다.

전체 바이너리 패치를 쉽게 만들 수 있지만 임시 커밋을 만들어야합니다. 임시 커밋을 만든 후에는 다음을 사용하여 패치를 만들 수 있습니다.

git format-patch <options...>

패치를 작성한 후 다음 명령을 실행하십시오.

git reset --mixed <SHA of commit *before* your working-changes commit(s)>

임시 커밋이 롤백됩니다. 최종 결과는 원래 의도 한 것과 동일한 변경 사항으로 작업 복사본을 의도적으로 더럽게 만듭니다.

수신 측에서 동일한 트릭을 사용하여 커밋 히스토리없이 작업 사본에 변경 사항을 적용 할 수 있습니다. 패치를 적용하기 만하면됩니다 git reset --mixed <SHA of commit *before* the patches>.

이 전체 옵션이 작동하려면 동기화가 잘되어 있어야합니다. 패치를 작성한 사람이 내가 한 것처럼 많은 변경 사항을 풀지 않았을 때 패치를 적용 할 때 약간의 오류가 발생했습니다. 그것을 작동시키는 방법이 있을지 모르지만, 나는 그것을 자세히 보지 않았습니다.


Tortoise Git에서 동일한 패치를 만드는 방법은 다음과 같습니다 (해당 도구를 사용하지 않는 것이 좋습니다).

  1. 작업 변경 사항 커밋
  2. 분기 루트 디렉토리를 마우스 오른쪽 단추로 클릭하고 Tortoise Git->를 클릭하십시오.Create Patch Serial
    1. 의미가있는 범위를 선택하십시오 ( Since: FETCH_HEAD동기화가 잘되면 작동합니다)
    2. 패치 만들기
  3. 분기 루트 디렉토리를 마우스 오른쪽 단추로 클릭하고 Tortise Git->를 클릭하십시오.Show Log
  4. 임시 커밋 전에 커밋을 마우스 오른쪽 단추로 클릭하고reset "<branch>" to this...
  5. Mixed옵션을 선택하십시오

그리고 그것들을 적용하는 방법 :

  1. 분기 루트 디렉토리를 마우스 오른쪽 단추로 클릭하고 Tortoise Git->를 클릭하십시오.Apply Patch Serial
  2. 올바른 패치를 선택하고 적용하십시오
  3. 분기 루트 디렉토리를 마우스 오른쪽 단추로 클릭하고 Tortise Git->를 클릭하십시오.Show Log
  4. 패치 커밋 전에 커밋을 마우스 오른쪽 단추로 클릭하고reset "<branch>" to this...
  5. Mixed옵션을 선택하십시오

5
기술적으로 이것은 OP가 피하도록 요청한 커밋을 만들어야하지만 일시적인 것이며 대답은 관계없이 유용합니다.
davenpcj

33

수정 된 파일과 새 파일 (스테이지)을 모두 사용하여 패치를 만들려면 다음을 실행하십시오.

git diff HEAD > file_name.patch

고맙습니다, 제 경우에는이 답변은 효과가 있지만 작동 git diff --cached > mypatch.patch하지 않습니다.
광업

질문이 있습니다 : 명령 file_name.patch으로 사용할 수 patch있습니까? 그들은 서로 호환됩니까?
Rakshith Ravi

git diff + git diff --cached / staged == git diff HEAD (마지막 커밋 이후의 모든 변경 사항 표시)
K. Symbol

20

나는 좋아한다 :

git format-patch HEAD~<N>

여기서 <N>패치로 저장할 마지막 커밋 수입니다.

명령 사용법에 대한 자세한 내용은 DOC에 있습니다.

UPD
여기서 적용하는 방법을 찾을 수 있습니다.

UPDformat-patch
별칭 추가에 대한 아이디어를 얻지 못한 사람들을 위해 :

git config --global alias.make-patch '!bash -c "cd ${GIT_PREFIX};git add .;git commit -m ''uncommited''; git format-patch HEAD~1; git reset HEAD~1"'

그런 다음 프로젝트 저장소의 디렉토리에서 다음을 실행하십시오.

git make-patch

이 명령은 0001-uncommited.patch현재 디렉토리에 작성 됩니다. 패치에는 다음 명령에서 볼 수있는 모든 변경 사항과 추적되지 않은 파일이 포함됩니다.

git status .

@ jcarballo : 답변을 업데이트했습니다. 당신이 가진 통지를 저에게 자유롭게 남겨주세요.
Eugen Konkov

2
커밋을 생성하고 커밋을 해제하는 것보다 간단한 방법이 있습니다. git diff --cached --binary
Gaurav Agarwal

9

바이너리를 수행 --binary하려면을 실행할 때 옵션을 제공하십시오 git diff.


0

또한 파일이 여러 디렉토리에 걸쳐있을 때 상대적으로 변경되는 파일 만 포함하도록 파일을 지정할 수도 있습니다.

git diff ~/path1/file1.ext ~/path2/file2.ext...fileN.ext > ~/whatever_path/whatever_name.patch

나는 이것이 답과 의견에 명시되어 있지 않다는 것을 알았습니다. 암시적인 것보다 명백한 것이 낫다!

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