특정 커밋에 대한 git 패치를 생성하는 방법은 무엇입니까?


1231

SHA1 커밋 번호 목록에 대한 패치를 생성하는 스크립트를 작성해야합니다.

을 사용하려고 시도했지만 git format-patch <the SHA1>해당 SHA1 이후 각 커밋에 대한 패치가 생성되었습니다. 수백 개의 패치가 생성 된 후 프로세스를 종료해야했습니다.

특정 SHA1에 대해서만 패치를 생성하는 방법이 있습니까?

답변:


1989

시험:

git format-patch -1 <sha>

또는

git format-patch -1 HEAD

위의 문서 링크에 따르면, -1플래그는 git에게 패치에 얼마나 많은 커밋을 포함시켜야하는지 알려줍니다.

-<n>

     최상위 커밋에서 패치를 준비하십시오.


다음 명령으로 패치를 적용하십시오.

git am < file.patch

210
패치 적용 : git apply --stat file.patch# show stats. git apply --check file.patch# 적용하기 전에 오류를 확인하십시오. git am < file.patch# 마지막으로 패치를 적용하십시오.
Adrian

3
마지막 커밋이 다른 브랜치의 병합 인 경우 작동하지 않는 것 같습니다.
Lex Li

2
CRLF 줄 끝을 사용하여 파일에 패치를 적용하려면 :git am --keep-cr < mypatch.patch
Michael Schmeißer

40
여기에서 찾은 이후 (또는 수동으로 편집)를 git am -3 < file.patch사용하여 충돌을 해결할 수있는 3 방향 병합을 사용 하여 적용하는 데 사용 하십시오 . git mergetool
Matt

6
이 명령은 또한 커밋에서 특정 파일에 대해서만 작동합니다. git format-patch -1 <sha> path/to/file.js이렇게하면 file.js의 diff 만 포함하는 패치가 만들어집니다.
Kristóf Dombi

281

특정 sha1 해시에서 최상위 커밋에서 패치를 생성하는 경우 :

git format-patch -<n> <SHA1>

단일 패치 파일에서 헤드의 마지막 10 개 패치 :

git format-patch -10 HEAD --stdout > 0001-last-10-commits.patch

2
첫 번째 명령에 대한 예를 제공 할 수있을만큼 친절 할 수 있습니까
Kasun Siyambalapitiya

1
git format-patch -1 HEAD가장 최근의 패치를 생성합니다 커밋
스리 람 무랄리

1
이 질문에 대한 실례합니다, 그래서 때 -2대부분의 최근 2 커밋을 위해이 패치를 생성하고, 설명이 명령이기 때문에 한가지 더 got format-patch -2 HEAD라인과 동일git format-patch HEAD~2
Kasun Siyambalapitiya

85

커밋 1 후에 커밋 ID 2가 있다고 가정하면 다음을 실행할 수 있습니다.

git diff 2 1 > mypatch.diff

여기서 2와 1은 SHA 해시입니다.


답장을 보내 주셔서 감사합니다. 즉, 관심있는 커밋보다 먼저 커밋을 찾으려면 스크립트가 필요합니다.이를 피할 수 있기를 바랐습니다.
elle

11
@elle, 아니, 당신은하지 않습니다- git diff hash^ hash. "hash ^"는 선행 커밋을 제공합니다. (물론 manojlds의 답변이 더 낫습니다)
J-16 SDiZ

2
git show HEAD > mypatch.diff커밋하는 동안 똑같이해야합니다.
andho

1
@dookehester는 정확합니까 아니면 다른 방법 git diff 1 2
입니까

1
diff에 바이너리 파일이 포함되지 않습니다.
stuckj

55

이 명령은 이미 @ Naftuli Tzvi Kay가 제안한대로 :

git format-patch -1 HEAD

바꾸다 HEAD특정 해시 또는 범위로 .

UNIX 편지함 형식과 유사한 형식으로 최신 커밋에 대한 패치 파일을 생성합니다.

-<n> -최상위 커밋에서 패치를 준비하십시오.

그런 다음 다음을 통해 패치 파일을 메일 박스 형식으로 다시 적용 할 수 있습니다.

git am -3k 001*.patch

참조 : man git-format-patch.


감사! 패치를 적용하면 [PATCH]라는 접두사 커밋 메시지가 포함 된 커밋이 만들어 질 것입니다. 그래도 쉽게 고칠 수 있습니다
Mike S

2
경이로운. OP, 당신은 이것을 받아들이지 않았습니다. 왜냐하면 ...? @MikeS 아니요, git적어도 사용자가 올바른 방식으로 적용하면 다른 형식의 패치와는 다릅니다 .
underscore_d

2
@MikeS 실제로 이유를 조사하지는 않았지만 -k플래그 ( git am -3)를 남겨두면 이 양식을 수정했습니다 ( PATCH[0/10]커밋 메시지 없음 ). 힘내 버전 2.20.1.windows.1
jannis

30
git format-patch commit_Id~1..commit_Id  
git apply patch-file-name

빠르고 간단한 솔루션.


5
또한 git apply --check patch-file-name패치를 적용하기 전에 전화하는 것을 잊지 마십시오 . 이것은 문제를 피하는 데 도움이됩니다.
iamantony

16

특정 커밋 위에 (싱글 커밋) 패치가 적용되도록하려면 새로운 git 2.9 (2016 년 6 월) 옵션을 사용할 수 있습니다 git format-patch --base

git format-patch --base=COMMIT_VALUE~ -M -C COMMIT_VALUE~..COMMIT_VALUE

# or
git format-patch --base=auto -M -C COMMIT_VALUE~..COMMIT_VALUE

# or
git config format.useAutoBase true
git format-patch -M -C COMMIT_VALUE~..COMMIT_VALUE

참조 bb52995 커밋 , 3de6651 커밋 , fa2ab86 커밋 , 커밋 ded2c09 에 의해 (2016 4월 26일) Xiaolong 예 (``) .
( Junio ​​C gitsterHamano 에 의해 병합 -- 커밋 72ce3ff , 2016 년 5 월 23 일)

format-patch: --base기본 트리 정보를 기록하려면 ' '옵션 추가

관리자 또는 타사 테스터는 패치 시리즈가 적용되는 정확한 기본 트리를 알고 싶어 할 수 있습니다. 가르쳐 git format-patch '--base '옵션을 가르쳐서 기본 트리 정보를 기록하고 첫 번째 메시지의 끝 (표지 또는 시리즈의 첫 번째 패치)에 추가하십시오.

기본 트리 정보는 "기타 커밋"으로, 모든 사람이 작업을 수행하는 프로젝트 히스토리의 안정적인 부분의 일부인 잘 알려진 커밋과 잘 알려진 "전제 조건 패치"로 구성됩니다. 패치가 적용되기 전에 아직 "기본 커밋"의 일부가 아닌 "베이스 커밋"의 위상이 "순서 커밋"위에 적용되는 패치.

"기본 커밋"은 " base-commit:"다음에 커밋 개체 이름의 40 진수로 표시됩니다.
"전제 조건 패치"는 ""로 표시되고 prerequisite-patch-id:그 뒤에 40 "헥스"패치 ID "가 표시되며 " git patch-id --stable"명령을 통해 패치를 전달하면 얻을 수 있습니다 .


Git 2.23 (Q3 2019)은 " --base"옵션이 " format-patch" patch-ids전제 조건 패치를 불안정한 방식으로 계산하여 " git patch-id --stable" 과 호환되는 방식으로 계산되도록 업데이트 되었기 때문에 개선 될 것입니다 .

Stephen Boyd ( )의 commit a8f6855 , commit 6f93d26 (2019 년 4 월 26 일)을 참조하십시오 . ( Junio ​​C Hamano의해 병합 -- 커밋 8202d12 , 2019 년 6 월 13 일)akshayka
gitster

format-patch: --base patch-id출력을 안정적으로 만듭니다.

patch-id생성 코드에서 덩어리를 처리 할 때마다 컨텍스트를 비우지 diff.c않았지만 ' patch-id'도구를 사용하여 "안정한"patch-id를 생성 할 때이를 수행했습니다 .

하자의 포트 유사한 논리 그 이상에서 patch-id.cdiff.c우리가 같은 해시를 얻을 수 있도록하는 경우 '에 대한 우린 발생 패치-IDS format-patch --base=명령 호출의 유형'.


Git 2.24 (2019 년 4 분기) 이전에 " git format-patch -o <outdir>"는 " mkdir <outdir>"not "mkdir -p <outdir> " .

Bert Wesarg ( )의 commit edefc31 (2019 년 10 월 11 일)을 참조하십시오 . (의해 병합 Junio C 하마노 - -커밋 f1afbb0 18 시월 2019)bertwesarg
gitster

format-patch: 출력 디렉토리의 주요 구성 요소 작성

서명자 : Bert Wesarg

'git format-patch -o'는 수정중인 'mkdir -p'가 아닌 'mkdir'에 해당합니다.

adjust_shared_perm보안에 영향을 줄 수있는 주요 디렉토리에서 ' '를 사용하지 마십시오 . ' config.sharedRepository'like ' git init' 를 일시적으로 사용 중지하여 달성합니다 .


Git 2.25 (Q1 2020)에서는 " git rebase"가 제대로 작동하지 않을 때format.useAutoBase 구성 변수가 설정되어 수정 된 .

참조 cae0bc0 커밋 , 945dc55 커밋 , 700e006 커밋 , a749d01 커밋 , 0c47e06 커밋 에 의해 (2019 12월 4일) 덴튼 리우 ( Denton-L) .
( Junio ​​C gitsterHamano 에 의해 병합 -- 커밋 71a7de7 , 2019 년 12 월 16 일)

rebase: format.useAutoBase파손 수정

보고자 : Christian Biesinger
서명자 : Denton Liu

format.useAutoBase = truerebase를 실행하면 오류가 발생했습니다.

fatal: failed to get upstream, if you want to record base commit automatically,
please use git branch --set-upstream-to to track a remote branch.
Or you could specify base commit by --base=<base-commit-id> manually
error:
git encountered an error while preparing the patches to replay
these revisions:

ede2467cdedc63784887b587a61c36b7850ebfac..d8f581194799ae29bf5fa72a98cbae98a1198b12

As a result, git cannot rebase them.

--no-baserebase에서 format-patch 로 항상 전달하여이 효과를 무시하도록 수정하십시오 format.useAutoBase.


8

마지막 커밋이 아닌 특정 커밋에서 경로를 생성하려면 :

git format-patch -M -C COMMIT_VALUE~1..COMMIT_VALUE

4

지정된 파일을 diff하려는 경우 다음을 수행 할 수 있습니다.

git diff master 766eceb-connections /> 000-mysql-connector.patch


0

내 머큐리얼 배경으로 나는 사용하려고했다 :

git log --patch -1 $ID > $file

그러나 git format-patch -1 $ID지금 사용을 고려하고 있습니다.


-5

특정 SHA1에 대해서만 패치를 생성하는 방법은 무엇입니까?

아주 간단합니다 :

옵션 1. git show commitID > myFile.patch

옵션 2. git commitID~1..commitID > myFile.patch

참고 : commitID실제 커밋 ID (SHA1 커밋 코드)로 바꾸십시오.


3
옵션 1은 완전히 틀 렸으며 질문과 관련이 없습니다.
Anshuman Manral

3
옵션 2도 유효하지 않은 명령입니다. 다음과 같은 오류가 발생합니다 .git a5f4bcaeb7fa7de27ae79d9522332e872889bbf0 ~ 1..a5f4bcaeb7fa7de27ae79d9522332e872889bbf0 git : 'a5f4bcaeb7fa7de27ae79d9522332e872889bbf4f7b27. 'git --help'를 참조하십시오. 답변을 게시하기 전에
유죄
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.