วิธีสร้าง patch git สำหรับการคอมมิทเฉพาะ


1231

ฉันต้องเขียนสคริปต์ที่สร้างแพตช์สำหรับรายการ SHA1 ที่ส่งหมายเลข

ฉันพยายามใช้ git format-patch <the SHA1>แต่มันสร้าง patch สำหรับแต่ละการกระทำตั้งแต่ 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เพื่อนำไปใช้โดยใช้การผสานสามทางที่จะช่วยให้คุณแก้ปัญหาความขัดแย้งโดยใช้git mergetoolหลังจากนั้น (หรือแก้ไขด้วยตนเอง) พบได้ที่นี่
แมตต์

6
คำสั่งนี้ใช้ได้กับไฟล์เฉพาะจากการคอมมิทด้วย: git format-patch -1 <sha> path/to/file.jsสิ่งนี้จะสร้างแพตช์ที่มี diffs สำหรับ file.js เท่านั้น
Kristóf Dombi

281

สำหรับการสร้างแพตช์จากการกระทำสูงสุดจากแฮช sha1 ที่เฉพาะเจาะจง:

git format-patch -<n> <SHA1>

10 patch ล่าสุดจาก head ในไฟล์ patch เดียว:

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

2
คุณช่วยกรุณาใจดีพอที่จะเป็นตัวอย่างสำหรับคำสั่งแรก
Kasun Siyambalapitiya

1
git format-patch -1 HEADจะสร้างแพทช์สำหรับการคอมมิทล่าสุด
Sriram Murali

1
ให้อภัยฉันเพื่อขอสิ่งนี้ดังนั้นเมื่อมัน-2สร้างแพตช์สำหรับ 2 คอมมิชชันล่าสุดคือมันและอีกสิ่งหนึ่งสำหรับการชี้แจงคือคำสั่งgot format-patch -2 HEADเหมือนกับบรรทัดgit format-patch HEAD~2
Kasun Siyambalapitiya

85

สมมติว่าคุณมีการส่งมอบรหัส 2 หลังจากส่งมอบ 1 คุณจะสามารถเรียกใช้:

git diff 2 1 > mypatch.diff

โดยที่ 2 และ 1 คือแฮช SHA


ขอบคุณ dookehster สำหรับคำตอบ นั่นหมายความว่าฉันต้องการสคริปต์เพื่อค้นหาสิ่งที่ทำก่อนหน้าสิ่งที่ฉันสนใจฉันหวังว่าฉันจะหลีกเลี่ยงสิ่งนั้นได้
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
Kasun Siyambalapitiya

1
สิ่งนี้จะไม่รวมไฟล์ไบนารีใด ๆ ในส่วนต่าง
30114 stickj

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
มหัศจรรย์ โอปคุณไม่ได้ยอมรับสิ่งนี้เพราะ ... ? @MikeS ไม่มันไม่ได้เป็นอย่างอื่นอีกต่อไปกว่าgitแพตช์ที่ฟอร์แมตแล้วอื่น ๆอย่างน้อยถ้าผู้ใช้งานใช้ในวิธีที่ถูกต้อง
underscore_d

2
@ MikeS ฉันไม่ได้ตรวจสอบสาเหตุจริงๆ แต่ออกจาก-kธง ( git am -3) แก้ไขแบบฟอร์มนี้ฉัน (ไม่มีPATCH[0/10]ข้อความยืนยัน) Git เวอร์ชั่น 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) ใหม่ 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 (26 เมษายน 2016) โดยXiaolong Ye ( ``)
(ผสานโดยJunio ​​C Hamano - gitster-ในการกระทำ 72ce3ff , 23 พฤษภาคม 2016)

format-patch: เพิ่ม--baseตัวเลือก '' เพื่อบันทึกข้อมูลทรีฐาน

ผู้ดูแลหรือผู้ทดสอบบุคคลที่สามอาจต้องการทราบแผนผังฐานที่แน่นอนที่ใช้กับชุดข้อมูลแก้ไข สอน git format-patch a '--base ' ตัวเลือกเพื่อบันทึกข้อมูลทรีฐานและต่อท้ายข้อความแรก (ทั้งจดหมายปะหน้าหรือแพทช์แรกในซีรีส์)

ข้อมูลทรีฐานประกอบด้วย "การกระทำฐาน" ซึ่งเป็นที่รู้จักกันดีว่าเป็นส่วนหนึ่งของส่วนที่มีเสถียรภาพของประวัติศาสตร์โครงการทุกคนทำงานออกมาและเป็นศูนย์หรือมากกว่า "แพทช์เบื้องต้น" ซึ่งเป็นที่รู้จักกันดี แพทช์ในเที่ยวบินที่ยังไม่ได้เป็นส่วนหนึ่งของ "ฐานกระทำ" ที่จำเป็นต้องนำมาใช้ด้านบนของ "ฐานกระทำ" ตามลำดับทอพอโลยีก่อนที่จะนำไปใช้เป็นหย่อม ๆ

"การกระทำพื้นฐาน" แสดงเป็น " base-commit:" ตามด้วยฐานสิบหก 40 ของชื่อวัตถุกระทำ
"prerequisite patch" แสดงเป็น " prerequisite-patch-id:" แล้วตามด้วย 40-hex "patch id" ซึ่งสามารถรับได้โดยผ่าน patch ผ่านgit patch-id --stableคำสั่ง ""


Git 2.23 (ไตรมาสที่ 3 ปี 2019) จะปรับปรุงให้ดีขึ้นเพราะ--baseตัวเลือก "" ของ " format-patch" คำนวณpatch-idsสำหรับแพตช์ที่จำเป็นต้องมีก่อนในแบบที่ไม่เสถียรซึ่งได้รับการปรับปรุงเพื่อคำนวณในแบบที่เข้ากันได้กับ " git patch-id --stable"

ดูกระทำ a8f6855 , กระทำ 6f93d26 (26 เมษายน 2019) โดยสตีเฟ่นบอยด์ (akshayka )
(ผสานโดยJunio ​​C Hamano -gitster -ในการส่ง 8202d12 , 13 Jun 2019)

format-patch: ทำให้--base patch-idผลผลิตมีเสถียรภาพ

เราไม่ได้ล้างข้อมูลบริบททุกครั้งที่เราประมวลผลก้อนใหญ่ใน patch-idรหัสการสร้างในdiff.cแต่เราก็ทำอย่างนั้นเมื่อเราสร้าง patch-id "เสถียร" ด้วยpatch-idเครื่องมือ ''

พอร์ต Let 's ตรรกะที่คล้ายกันจากการpatch-id.cเข้าdiff.cเพื่อที่เราจะได้แฮชเดียวกันเมื่อเราสร้าง patch-ids สำหรับformat-patch --base=การเรียกใช้คำสั่งชนิด ''


ก่อน Git 2.24 (Q4 2019) "git format-patch -o <outdir> " ทำหน้าที่เทียบเท่า " mkdir <outdir>" ไม่ใช่ "mkdir -p <outdir> " ซึ่งกำลังแก้ไข

ดูกระทำ edefc31 (11 ตุลาคม 2019) โดยเบิร์ต Wesarg (bertwesarg )
(ผสานโดยJunio ​​C Hamano - gitster- in f1afbb0 , 18 ต.ค. 2019)

format-patch: สร้างองค์ประกอบชั้นนำของไดเรกทอรีออก

ลงชื่อออกโดย: Bert Wesarg

'git format-patch -o' เทียบเท่ากับ 'mkdir' ไม่ใช่ 'mkdir -p' ซึ่งกำลังแก้ไขอยู่

หลีกเลี่ยงการใช้ ' adjust_shared_perm' ในไดเรกทอรีชั้นนำซึ่งอาจมีผลกระทบด้านความปลอดภัย ทำได้โดยการปิดการใช้งาน ' config.sharedRepository' like ' git init' เป็นการชั่วคราว


ด้วย Git 2.25 (ไตรมาสที่ 1 ปี 2020) " git rebase" ทำงานได้ไม่ดีเมื่อformat.useAutoBaseตั้งค่าตัวแปรการตั้งค่าซึ่งได้รับการแก้ไขแล้ว

ดูกระทำ cae0bc0 , กระทำ 945dc55 , กระทำ 700e006 , กระทำ a749d01 , กระทำ 0c47e06 (4 ธันวาคม 2019) โดยDenton หลิว (Denton-L )
(ผสานโดยJunio ​​C Hamano - gitster-ในการคอมมิชชัน 71a7de7 , 16 Dec 2019)

rebase: แก้ไขปัญหาformat.useAutoBaseการแตก

รายงานโดย: Christian Biesinger
ลงชื่อออกโดย: Denton Liu

ด้วยการformat.useAutoBase = trueใช้การรีบูตทำให้เกิดข้อผิดพลาด:

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-baseไปยัง format-patch จาก rebase เสมอเพื่อให้เอฟเฟกต์format.useAutoBaseถูกทำให้เป็นโมฆะ


8

ในการสร้างเส้นทางจากการกระทำที่เฉพาะเจาะจง

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

4

หากคุณต้องการ diff ไฟล์ที่ระบุคุณสามารถ:

git diff master 766eceb - การเชื่อมต่อ /> 000-mysql-connector.patch


0

ด้วยพื้นหลังของ mercurial ฉันจะใช้:

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ด้วยรหัสการกระทำจริง (รหัสการยอมรับ SHA1)


3
ตัวเลือก 1 ผิดอย่างสิ้นเชิงและไม่เกี่ยวข้องกับคำถาม
Anshuman Manral

3
ตัวเลือก 2 ยังเป็นคำสั่งที่ไม่ถูกต้อง คุณจะได้รับข้อผิดพลาดเช่น: git a5f4bcaeb7fa7de27ae79d9522332e872889bbf0 ~ 1.897797797797797897797797797797797797797797797797797797797797797797797797d3a.de คุณจะได้รับข้อผิดพลาดเช่น: g1 ดู 'git --help' โปรดตรวจสอบก่อนโพสต์คำตอบ
Anshuman Manral
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.