สร้างโปรแกรมแก้ไข git จากการเปลี่ยนแปลงในไดเรกทอรีการทำงานปัจจุบัน


879

กล่าวว่าฉันมีการเปลี่ยนแปลงที่ไม่มีข้อผูกมัดในไดเรกทอรีทำงานของฉัน ฉันจะสร้างโปรแกรมปะแก้จากผู้ที่ไม่ต้องสร้างการผูกมัดได้อย่างไร?


29
คำตอบที่ยอมรับอาจมีการเปลี่ยนแปลงเนื่องจากคำตอบที่สองนั้นได้รับความนิยมเกือบสี่เท่า
Tim Ogilvy

5
@TimOgilvy เห็นด้วย OP ควรทำ คำตอบที่สองนั้นได้รับความนิยมมากกว่าและให้ข้อมูลเพิ่มเติม
John Demetriou

1
ฉันคิดว่ามันคุ้มค่าที่จะพูดถึงว่าคุณต้องการแพทช์จากการเปลี่ยนแปลงที่ไม่มีข้อผูกมัดในชื่อ
2i3r

คำตอบ:


401

git diffสำหรับการเปลี่ยนแปลงที่ไม่จัดเตรียม git diff --cachedสำหรับการเปลี่ยนแปลงฉาก


12
yup, git diff เป็นค่าผกผันของ git
Spike Gronim

33
git format-patchยังรวมถึง diffs แบบไบนารีและข้อมูลเมตาบางส่วน ที่จริงแล้วจะเป็นทางออกที่ดีที่สุดสำหรับการสร้างแพทช์ แต่ afaik ใช้งานได้กับการตรวจสอบในแหล่งที่มา / การเปลี่ยนแปลงเท่านั้นใช่มั้ย
Eric

20
บางครั้งมันอาจมีประโยชน์ในการสร้างแพทช์เทียบกับไดเรกทอรีปัจจุบัน เพื่อให้บรรลุนี้ใช้git diff --relative
ejboy

30
git diff> a.patch เขียนลงไฟล์
qasimzee

139
Terse ที่ล้อมรอบประชดประชันคำตอบด้านล่างนี้มีประโยชน์มากกว่า
อากาศ

1865

หากคุณยังไม่ได้ทำการเปลี่ยนแปลงใด ๆ :

git diff > mypatch.patch

แต่บางครั้งมันก็เกิดขึ้นส่วนหนึ่งของสิ่งที่คุณทำคือไฟล์ใหม่ที่ไม่ได้ติดตามและจะไม่อยู่ในgit diffผลลัพธ์ของคุณ ดังนั้นวิธีหนึ่งในการทำแพทช์คือการทำทุกอย่างเพื่อคอมมิชชันใหม่ ( git addแต่ละไฟล์หรือเพียงแค่git add .) แต่อย่าทำการคอมมิทแล้ว:

git diff --cached > mypatch.patch

เพิ่มตัวเลือก 'binary' หากคุณต้องการเพิ่มไฟล์ไบนารีลงในแพทช์ (เช่นไฟล์ mp3):

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

คุณสามารถใช้โปรแกรมแก้ไขในภายหลัง:

git apply mypatch.patch

หมายเหตุ: คุณยังสามารถใช้เป็นไวพจน์ของ--staged--cached


128
ขอบคุณมากสำหรับตัวอย่าง ตรงข้ามกับคำตอบที่ยอมรับคุณแสดงคำสั่งวิธีการทำไม่ใช่แค่พูด มีประโยชน์มากและทำงานได้อย่างไร้ที่ติสำหรับฉัน :)
nuala

4
ฉันทำอย่างนั้นและได้รับ "ร้ายแรง: อินพุตที่ไม่รู้จัก" เมื่อใช้ git ในการดำเนินการ มีความคิดอะไรที่ทำให้เกิดสิ่งนี้และจะแก้ไขได้อย่างไร
Vitaly

6
@Vitaly: แพทช์ของคุณสามารถอ่านได้ถ้าคุณเปิดมันด้วยโปรแกรมแก้ไขข้อความ? มันควรจะทำความสะอาดด้วยไม่มีตัวละครที่แปลกประหลาดเช่นถ้าตั้งค่า color.diff มีการตั้งค่าแพทช์ของคุณจะมีบางตัวอักษรสี 'ที่สามารถทำให้ 'คอมไพล์ใช้' git diff --no-colorล้มเหลวในการที่กรณีลอง มิฉะนั้นดูเหมือนว่าปัญหาการเข้ารหัส
jcarballo

3
เกี่ยวข้องกับ "ไฟล์ใหม่ที่ไม่ได้ติดตาม": "git diff" และ "git diff --cached" จะใช้งานได้ก็ต่อเมื่อมีการเรียก "git add <file>" ก่อน (ฉันใหม่สำหรับคอมไพล์และสงสัยว่าทำไมฉันได้รับแพทช์ที่ว่างเปล่าทุกครั้ง)
ไม่ระบุตัวตน

5
นี้มีฉันออกมาจากนรกผสาน / rebase แปลกสวยได้อย่างง่ายดายขอบคุณ :)
จอห์นฮันท์

86

git diffและgit applyจะใช้งานได้กับไฟล์ข้อความ แต่จะไม่ทำงานสำหรับไฟล์ไบนารี

คุณสามารถสร้างแพทช์ไบนารีแบบเต็มได้อย่างง่ายดาย แต่คุณจะต้องสร้างการคอมมิตชั่วคราว เมื่อคุณดำเนินการชั่วคราวแล้วคุณสามารถสร้างแพตช์ด้วย:

git format-patch <options...>

หลังจากที่คุณได้ทำการแก้ไขเรียกใช้คำสั่งนี้:

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

สิ่งนี้จะย้อนกลับการกระทำชั่วคราวของคุณ ผลลัพธ์สุดท้ายทำให้สำเนาทำงานของคุณ (โดยเจตนา) สกปรกด้วยการเปลี่ยนแปลงแบบเดิมที่คุณมี

ในด้านการรับคุณสามารถใช้กลอุบายเดียวกันเพื่อใช้การเปลี่ยนแปลงกับสำเนาการทำงานโดยไม่ต้องมีประวัติการส่งมอบ เพียงแค่ใช้แพทช์ (e) 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 ที่
นี่คุณสามารถค้นหาวิธีการใช้งานได้

UPDสำหรับผู้ที่ไม่ได้รับแนวคิดในการformat-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ที่ไดเรกทอรีปัจจุบันของคุณ Patch จะมีการเปลี่ยนแปลงทั้งหมดและไฟล์ที่ไม่ได้ติดตามซึ่งสามารถมองเห็นได้ในคำสั่งถัดไป:

git status .

@jcarballo: ฉันได้อัพเดตคำตอบแล้ว รู้สึกอิสระที่จะวางฉันประกาศใด ๆ ที่คุณมี
Eugen Konkov

2
มีวิธีที่ง่ายกว่าการสร้างการผูกมัดและการไม่ผูกมัด git diff --cached - ไบนารี
Gaurav Agarwal

9

หากคุณต้องการที่จะทำไบนารีให้ตัวเลือกเมื่อคุณเรียกใช้--binarygit 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.