เลิกทำการผสานโดยดึงคำขอหรือไม่


159

มีคนยอมรับคำขอดึงซึ่งพวกเขาไม่ควรมี ขณะนี้เรามีรหัสที่ใช้งานไม่ได้รวมอยู่ด้วยคุณจะยกเลิกการดึงคำขอได้อย่างไร ฉันแค่จะย้อนกลับการเปลี่ยนแปลงการกระทำก่อนที่จะรวม แต่ฉันสังเกตเห็นว่ามันรวมอยู่ในกลุ่มของการกระทำ ดังนั้นตอนนี้มีข้อผูกพันเหล่านี้จากบุคคลนี้ตั้งแต่หลายวันก่อนรวม คุณเลิกทำสิ่งนี้ได้อย่างไร


7
แม้จะมีคำแนะนำของคำตอบที่ยอมรับแล้วก็ตามโปรดอย่าบังคับให้ไปยังที่เก็บหากมีการแบ่งปัน repo กับคนอื่น คุณเสี่ยงต่อการทำลายงานที่คนอื่นทำและ GitHub อาจแสดงคำขอดึงดังกล่าวเมื่อรวมเข้าด้วยกัน อีกคำตอบสำหรับคำถามนี้อธิบายวิธีที่ปลอดภัยกว่าในการเลิกทำการร้องขอการดึง
alxndr

2
หมายเหตุ: อย่างน้อยตอนนี้ (มิถุนายน 2014) GitHub เสนอปุ่ม "เปลี่ยนกลับ" ในเว็บ GUI ดึงคำขอของพวกเขา ดูคำตอบของฉันด้านล่าง
VonC

1
ปัญหาของปุ่มเปลี่ยนกลับคือสร้างการส่งมอบใหม่เป็นผกผันกับคำขอดึงซึ่งหมายความว่าหากคุณต้องการรวมการเปลี่ยนแปลงเหล่านี้ในที่สุดการใช้ปุ่ม "เปลี่ยนกลับ" อาจทำให้ยากขึ้น
FluffySamurai

คำตอบ:


159

มีคำตอบที่ดีกว่าสำหรับปัญหานี้ถึงแม้ว่าฉันจะสามารถทำลายมันทีละขั้นตอนได้

คุณจะต้องดึงข้อมูลและตรวจสอบการเปลี่ยนแปลงอัปสตรีมล่าสุดเช่น:

git fetch upstream
git checkout upstream/master -b revert/john/foo_and_bar

เมื่อดูที่บันทึกการกระทำคุณควรพบสิ่งที่คล้ายกับสิ่งนี้:

commit b76a5f1f5d3b323679e466a1a1d5f93c8828b269
Merge: 9271e6e a507888
Author: Tim Tom <tim@tom.com>
Date:   Mon Apr 29 06:12:38 2013 -0700

    Merge pull request #123 from john/foo_and_bar

    Add foo and bar

commit a507888e9fcc9e08b658c0b25414d1aeb1eef45e
Author: John Doe <john@doe.com>
Date:   Mon Apr 29 12:13:29 2013 +0000

    Add bar

commit 470ee0f407198057d5cb1d6427bb8371eab6157e
Author: John Doe <john@doe.com>
Date:   Mon Apr 29 10:29:10 2013 +0000

    Add foo

ตอนนี้คุณต้องการย้อนคำขอดึงทั้งหมดด้วยความสามารถในการยกเลิกในภายหลัง การทำเช่นนั้นคุณจะต้องใช้ ID ของผสานกระทำ

ในตัวอย่างข้างต้นที่ผสานกระทำเป็นหนึ่งในด้านบนที่มันว่า"ผสานคำขอดึง # 123 ..."

ทำสิ่งนี้เพื่อย้อนกลับการเปลี่ยนแปลงทั้งสองอย่าง ( "เพิ่มบาร์"และ"เพิ่ม foo" ) และคุณจะได้รับคำขอคืนค่าการดึงทั้งหมดซึ่งคุณสามารถยกเลิกในภายหลังและรักษาประวัติการเปลี่ยนแปลงให้สะอาดอยู่เสมอ:

git revert -m 1 b76a5f1f5d3b323679e466a1a1d5f93c8828b269

6
นี่ควรเป็นคำตอบที่ถูกต้อง มีการอ้างอิงในหน้าคนคอมไพล์ย้อนไปที่รายละเอียดเพิ่มเติมจากคอมไพล์รายการจดหมายของที่นี่คือkernel.org/pub/software/scm/git/docs/howto/...
จัสติน hamade

2
ทำไมgit checkout upstream/master -b revert/john/foo_and_bar? มันทำอะไรกันแน่?
Magne

4
@Magne - คุณกำลังสร้างสาขาใหม่เพื่อทำการแปลงกลับซึ่งคุณสามารถเลือกที่จะรวมการพลิกกลับ โดยทั่วไปจะช่วยให้คุณควบคุมสิ่งที่จะทำกับสาขาได้มากขึ้น ในกรณีของฉันฉันส่งคำขอดึงใหม่จากสาขา "คงที่" ที่มีการพลิกกลับไปที่สาขาพัฒนาของเราซึ่งหมายความว่าคำขอดึงใหม่ของฉันสามารถเปลี่ยนกลับได้หากจำเป็น สิ่งนี้ทำเพื่อการเผยแพร่ที่เราตัดสินใจที่จะดึงร่างฉบับแรกของคุณลักษณะที่มีการจัดกำหนดการใหม่ ไม่มีรหัสที่ไม่ดีเพียง แต่ไม่ปล่อยในรุ่นนี้
Daniel Nalbach

3
ฉันเรียนรู้บทเรียนที่หนักหน่วงในบทเรียนนี้ เราผลักดันคุณลักษณะให้กับสาขาที่กำลังพัฒนาของเรา แต่ตระหนักว่ามีปัญหาข้อมูลและย้อนกลับไปสู่การพัฒนาโดยตรง ต่อมาเมื่อสิ่งต่าง ๆ ได้รับการแก้ไขเราต้องการที่จะเพิ่มฟีเจอร์ใหม่ที่พัฒนาขึ้นกลับไปที่สาขานี้เพื่อทดสอบความเข้ากันได้กับฟีเจอร์นี้ก่อนที่จะผลักดันดังนั้นฉันจึงผสานการพัฒนากลับไปที่สาขาฟีเจอร์ สิ่งนี้ยังใช้การมอบหมายการพลิกกลับซึ่งยกเลิกการบันทึกการเปลี่ยนแปลงทุกรายการที่เกิดขึ้นกับสาขาคุณลักษณะ > <
Greg

86

ดูกราฟการกระทำของคุณ (พร้อม gitk หรือโปรแกรมที่คล้ายกัน) คุณจะเห็นคอมมิชชันจากคำขอการดึงและคุณจะเห็นคอมมิทของคุณเองและการคอมมิชชันรวม (ถ้าไม่ใช่การผสานแบบกรอไปข้างหน้า) คุณเพียงแค่ต้องค้นหาการกระทำสุดท้ายของตัวคุณเองก่อนทำการผสานและรีเซ็ตสาขาให้เป็นการกระทำนี้

(ถ้าคุณมี reflog ของสาขามันจะง่ายกว่าถ้าหาคอมมิทก่อนการรวม)


(แก้ไขหลังจากข้อมูลเพิ่มเติมในความคิดเห็น :)

เอาล่ะมาดูกราฟกัน:

สกรีนช็อต 1

ฉันถือว่าการกระทำครั้งสุดท้าย (ขวาสุด) เป็นการรวมที่ไม่ถูกต้องของคุณด้วยคำขอดึงซึ่งผสานเส้นสีน้ำเงินที่เห็นที่นี่ ความมุ่งมั่นสุดท้ายของคุณจะเป็นสิ่งที่เกิดขึ้นก่อนหน้านี้บนเส้นสีดำโดยที่นี่จะมีเครื่องหมายสีแดง:

ป้อนคำอธิบายรูปภาพที่นี่

รีเซ็ตการกระทำนี้และคุณควรจะดี

ซึ่งหมายความว่าในสำเนาการทำงานในพื้นที่ของคุณทำสิ่งนี้ (หลังจากตรวจสอบให้แน่ใจว่าคุณไม่มีสิ่งใดที่ปราศจากข้อผูกมัดเช่น git stash):

git checkout master
git reset --hard 7a62674ba3df0853c63539175197a16122a739ef
gitk 

ตอนนี้ยืนยันว่าคุณอยู่ในความมุ่งมั่นที่ฉันทำเครื่องหมายไว้ที่นั่นและคุณจะไม่เห็นสิ่งที่ถูกดึงในบรรพบุรุษของมัน

git push -f origin master

(หากรีโมต Github ของคุณชื่อorigin- มิฉะนั้นให้เปลี่ยนชื่อ)

ตอนนี้ทุกอย่างควรดูขวาบน GitHub เช่นกัน ความมุ่งมั่นจะยังคงอยู่ในที่เก็บของคุณ แต่ไม่สามารถเข้าถึงได้โดยสาขาใด ๆ ดังนั้นจึงไม่ควรทำอันตรายใด ๆ ที่นั่น (และพวกเขาจะยังอยู่ในที่เก็บของ RogerPaladin แน่นอน)

(อาจมีวิธีการเฉพาะเว็บ Github เฉพาะในการทำสิ่งเดียวกัน แต่ฉันไม่คุ้นเคยกับ Github และระบบการจัดการคำขอดึงข้อมูลของมันเกินไป)

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

หากเป็นไปได้ว่าสิ่งนี้เกิดขึ้นหรือคุณเพียงแค่ต้องการหลีกเลี่ยงปัญหาใด ๆ ให้ใช้git revertคำสั่งแทนgit resetเพื่อย้อนกลับการเปลี่ยนแปลงด้วยคอมมิตใหม่แทนที่จะตั้งค่ากลับไปเป็นเวอร์ชันเก่ากว่า (บางคนคิดว่าคุณไม่ควรทำการรีเซ็ตด้วยสาขาที่เผยแพร่) ดูคำตอบสำหรับคำถามนี้เกี่ยวกับวิธีการทำเช่นนี้

สำหรับอนาคต:

หากคุณต้องการเพียงบางส่วนของกระทำของสาขา RogerPaladin ฯ พิจารณาใช้แทนcherry-pick mergeหรือสื่อสารกับ RogerPaladin เพื่อย้ายไปยังสาขาอื่นและส่งคำขอดึงใหม่


แต่เรามีข้อผูกมัดมากมายระหว่างการผสานกับการกระทำแรกของเขา เช่นเดียวกับที่เรามีความมุ่งมั่นผสานความมุ่งมั่นของเราเองและจากนั้นอีกความมุ่งมั่นของเขา ดูเหมือนว่ามันจะรวมอยู่ในการกระทำที่เก่าแก่ของเขา
Will

ใช่มันจะรวมทุกอย่างที่เป็นบรรพบุรุษของการรวมที่กระทำ (และไม่ได้เป็นบรรพบุรุษของการกระทำของคุณ) สิ่งนี้ไม่ควรขัดขวางคุณจากการรีเซ็ต - คอมมิชชันจะไม่ถูกจัดลำดับใหม่ด้วยตัวเองหากคุณไม่ได้รีบาวด์ภายหลัง
Paŭlo Ebermann

1
ใช่ตอนนี้มันดูถูกต้อง (นอกเหนือจากการผสานที่แปลกเข้าไปในตัวเอง - แต่นี่อาจเป็นข้อผิดพลาดในซอฟต์แวร์กราฟของเครือข่าย) :-) ฉันดีใจที่ฉันสามารถช่วย
Paŭlo Ebermann

6
ฉันคิดว่านี่อาจเป็นปัญหาถ้ามีคนดึงคำมั่นสัญญาที่ไม่ดีและพวกเขาส่งคำขอดึงที่มีการกระทำที่ไม่ดีเหมือนกันดังนั้นพวกเขาจึงแอบเข้าไปใน repo มันจะไม่ปลอดภัยกว่าหรือถ้าจะสร้างการผูกมัดใหม่ ด้วยวิธีนี้หากดึงความมุ่งมั่นที่ไม่ดีไปยังสาขา / ส้อมอื่น ๆ พวกเขาจะถูกลบอย่างมีประสิทธิภาพโดยการดึงอื่นไปที่สาขา / ส้อมอื่น ๆ ? ฉันไม่ได้ระบุว่านี่เป็นความจริงนี่คือสิ่งที่ฉันคิดว่าอาจเป็นจริงอยู่ในตำแหน่งเดียวกับ OP และใช้เวลาหนึ่งชั่วโมงหรือมากกว่านั้นในการพิจารณาทางเลือกของฉัน
Myles McDonnell

4
@ ฉันจะแนะนำให้ไม่ยอมรับคำตอบนี้ นี่เป็นสิ่งที่ดีสำหรับรหัสที่ยังไม่ได้ส่ง (ในกรณีนี้เป็นคำถาม SO ที่เกี่ยวข้องมากกว่า แต่สำหรับรหัสที่แชร์แบบสาธารณะให้ทำคำสั่ง git ที่เขียนประวัติใหม่ (ในกรณีนี้reset --hardและการกดบังคับคือ การปฏิบัติที่เลวร้ายมาก) คำตอบโดย @errordeveloper ด้านล่างแสดงวิธีการทำเช่นนี้โดยไม่ต้องมีการเขียนประวัติหรือบังคับให้กด
asmeurer

34

ถ้าดึงเป็นสิ่งสุดท้ายที่เขาทำแล้ว

git reset --hard HEAD~1

3
ระวังการปฏิบัติตามคำแนะนำนี้จริง ๆ แล้วมันทำให้ฉันกลับมา 2 ขั้นตอนไม่ใช่หนึ่ง
szeitlin

1
@szeitlin มันจะเกิดขึ้นได้อย่างไรว่ามันนำคุณกลับมา 2 ขั้นตอนไม่ใช่แค่หนึ่งขั้น? ฉันรู้ว่าความคิดเห็นนี้ถูกทิ้งไว้ 4+ ปีที่แล้ว แต่ฉันอยากรู้ว่าใครรู้คำตอบว่ามันจะเกิดขึ้นได้อย่างไร สิ่งนี้สำคัญมากสำหรับฉัน ขอบคุณ
Haradzieniec

ฉันจำไม่ได้แล้ว แต่ฉันคิดว่ามันอาจเกิดขึ้นได้หากฉันได้รับมอบหมายใหม่เมื่อฉันพยายามรีเซ็ต ฉันแค่จะทดสอบกับตัวแทนจำลองถ้าคุณกังวลเกี่ยวกับมัน
szeitlin

อันนี้ใช้ได้ดีสำหรับฉัน มันลบคำขอดึงที่ผสานเมื่อเร็ว ๆ นี้ หลังจากนั้นgit reset --hard HEAD~1ฉันใช้git push origin -fเพื่ออัปเดตที่เก็บระยะไกล แต่ระวังระวังก่อนทำเช่นนี้
เดนิสโอลูก้า

24

ตั้งแต่วันที่ 24 มิถุนายน 2014 คุณสามารถลองยกเลิกการประชาสัมพันธ์ได้อย่างง่ายดาย (ดู "การเปลี่ยนคำขอดึงกลับ ") ด้วย:

แนะนำปุ่มย้อนกลับ

คุณสามารถเปลี่ยนคำขอดึงกลับบน GitHub ได้อย่างง่ายดายโดยคลิกเปลี่ยนกลับ:

https://camo.githubusercontent.com/0d3350caf2bb1cba53123ffeafc00ca702b1b164/68747470733a2f2f6769746875622d696d616765732e73332e616d617a6f6e6177732e636f6d2f68656c702f70756c6c5f72657175657374732f7265766572742d70756c6c2d726571756573742d6c696e6b2e706e67

คุณจะได้รับแจ้งให้สร้างคำขอดึงใหม่พร้อมการเปลี่ยนแปลงที่ย้อนกลับ:

https://camo.githubusercontent.com/973efae3cc2764fc1353885a6a45b9a518d9b78b/68747470733a2f2f6769746875622d696d616765732e73332e616d617a6f6e6177732e636f6d2f68656c702f70756c6c5f72657175657374732f7265766572742d70756c6c2d726571756573742d6e65772d70722e706e67

มันจะยังคงได้รับการทดสอบแม้ว่าจะเปลี่ยนกลับใช้-mหรือไม่ (สำหรับการคืนค่าการรวมเช่นกัน)

แต่Adil H Razaเพิ่มในความคิดเห็น (ธันวาคม 2019):

masterนั่นคือพฤติกรรมที่คาดหวังก็สร้างสาขาใหม่และคุณสามารถสร้างการประชาสัมพันธ์จากสาขาใหม่นี้เพื่อคุณ วิธีนี้ในอนาคตคุณสามารถยกเลิกการย้อนกลับไปเปลี่ยนกลับถ้าจำเป็นต้องเป็นมันเป็นตัวเลือกที่ปลอดภัยที่สุดและไม่มีการเปลี่ยนแปลงของคุณโดยตรง
master


คำเตือน : Korayemชี้ให้เห็นในความคิดเห็นที่:

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

Korayem อ้างถึงเราว่า " Github: การเปลี่ยนแปลงที่ถูกเพิกเฉยหลังจากเปลี่ยนกลับ ( git cherry-pick, git rebase) " เป็นจำนวนมาก


ฉันลองทำสิ่งนี้แล้วมันจะสร้างสาขาใหม่แทนที่จะเลิกทำการประชาสัมพันธ์เกี่ยวกับเจ้านาย?
Грозный

แปลก. คุณสามารถถามคำถามใหม่เพื่ออธิบายพฤติกรรมนั้นได้หรือไม่
VonC

นั่นคือพฤติกรรมที่คาดหวังมันสร้างสาขาใหม่และคุณสามารถสร้าง PR จากสาขาใหม่นี้ให้กับเจ้านายของคุณ วิธีนี้ในอนาคตคุณสามารถยกเลิกการคืนกลับถ้าจำเป็นมันเป็นตัวเลือกที่ปลอดภัยที่สุดและไม่เปลี่ยนเจ้านายของคุณโดยตรง
Adil H. Raza

1
@ AdilH.Raza ขอบคุณ ฉันได้รวมความคิดเห็นของคุณไว้ในคำตอบเพื่อให้มองเห็นได้ชัดเจนขึ้น
VonC

1
@VonC ใช้นิ้วมือนี้จะช่วยให้นักพัฒนาทั่วโลกจากความทุกข์ทรมานและเสียเวลามากเกินไป
Korayem

8

ในการเลิกทำการร้องขอการดึง github ด้วยการกระทำที่คุณไม่ต้องการลบคุณต้องเรียกใช้:

git reset --hard --merge <commit hash>

ด้วยการแฮชการกระทำที่เป็นความมุ่งมั่นก่อนที่จะรวมคำขอดึง การดำเนินการนี้จะลบการกระทำทั้งหมดจากคำขอดึงโดยไม่ส่งผลต่อการกระทำใด ๆ ในประวัติ

วิธีที่ดีในการค้นหาสิ่งนี้คือไปที่คำขอดึงแบบปิดในขณะนี้และค้นหาช่องนี้:

ดึงภาพคำขอ ดึงภาพคำขอ

หลังจากที่คุณเรียกgit resetใช้รัน a:

git push origin --force <branch name>

สิ่งนี้ควรย้อนกลับสาขาก่อนที่จะมีการร้องขอการดึงโดยไม่มีผลต่อการกระทำใด ๆ ในสาขาที่มีประวัติการกระทำระหว่างการกระทำจากการร้องขอการดึง

แก้ไข:

หากคุณต้องคลิกปุ่มเปลี่ยนกลับในคำขอดึงสิ่งนี้จะสร้างการส่งข้อมูลเพิ่มเติมในสาขา มันไม่ได้ผิดปกติหรือหลุดออก ซึ่งหมายความว่าหากคุณต้องกดปุ่มเปลี่ยนกลับคุณไม่สามารถเปิดคำขอดึงใหม่เพื่อเพิ่มรหัสนี้ทั้งหมดอีกครั้ง


วิธีที่ยอดเยี่ยมในการทำให้สิ่งต่าง ๆ ถูกยืดออกโดยไม่จำเป็นต้องมีการคืนค่าที่บ้าคลั่งหรือการเก็บเชอร์รี่
Cumulo Nimbus

ขอบคุณ! นั่นคือสิ่งที่ฉันวางแผนที่จะทำ แต่จะมีประมาณ 200 ถึงข้อตกลงที่จะเลือกเชอร์รี่
FluffySamurai

1

ฉันใช้สถานที่นี้ตลอดเวลาขอบคุณ

ฉันค้นหาวิธียกเลิกการดึงและมาที่นี่

ฉันเพิ่งgit reset --hardจะ "นานมาแล้ว" และเดินหน้าย้อนกลับอย่างรวดเร็วไปยังจุดที่ฉันอยู่ก่อนที่จะทำการร้องขอการดึง

นอกจากดูที่นี่ฉันยังถามเพื่อนร่วมงานของฉันว่าเขาจะทำอะไรและเขาก็มีคำตอบที่ดีโดยทั่วไป: ใช้ตัวอย่างผลลัพธ์ในคำตอบแรกข้างต้น:

git reset --hard 9271e6e

เช่นเดียวกับสิ่งต่าง ๆ ส่วนใหญ่ใน Git ถ้าคุณทำในลักษณะที่ไม่ง่ายคุณอาจทำผิด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.