ฉันจะใช้ git bisect เพื่อค้นหาข้อตกลง GOOD แรกได้อย่างไร


97

ฉันมีปัญหาต่อไปนี้:

  • เวอร์ชันที่ใช้masterงานได้ดี
  • เวอร์ชันของแท็กสุดท้ายก่อนmaster(พูดlast) มีข้อบกพร่อง
  • เพื่อนร่วมงานต้องการแพทช์สำหรับlastการแก้ไขข้อบกพร่องบางอย่าง

ตกลง. ลองถามเพื่อนของเราgit bisectเกี่ยวกับการแก้ไขที่แก้ไขข้อบกพร่อง:

git bisect start
git bisect bad last
git bisect good master

แต่มันจะไม่ได้ผล:

revs ที่ดีบางตัวไม่ใช่บรรพบุรุษของ rev ที่ไม่ดี
git bisect ไม่สามารถทำงานได้อย่างถูกต้องในกรณีนี้
บางทีคุณอาจเข้าใจผิดว่าดีและไม่ดี?

คำแนะนำใด ๆ ที่จะเอาชนะสิ่งนี้? ฉันพลาดบางอย่างในเอกสารหรือไม่?


1
ฉันกำลังดำเนินgit bisect run ...การแบ่งส่วนโดยอัตโนมัติ ดังนั้นฉันจึงไม่มีโอกาสเพียงแค่สลับคำgoodและbad(ซึ่งชัดเจนเกินไป) วิธีใช้runเพื่อค้นหาการแก้ไขที่ดีครั้งแรก?
Daniel Böhmer

@ DanielBöhmer: คุณต้องสลับคำในสคริปต์ของคุณที่กำลังทำงานอยู่ใช่ไหม
eckes

สคริปต์ที่รันโดยgit bisect runส่งคืนค่าดีหรือไม่ดีเป็นรหัสออกไม่ใช่เป็นสตริง ดูคำตอบของฉันที่ฉันโพสต์ไว้ด้านล่าง
Daniel Böhmer

@ DanielBöhmer: ในกรณีนี้คุณจะต้องกลับรหัสส่งคืนใช่ไหม
eckes

ถูกต้องนั่นคือสิ่งที่อธิบายไว้ในคำตอบของฉัน
Daniel Böhmer

คำตอบ:


102

ใน git 2.7 คุณสามารถใช้อาร์กิวเมนต์ --term-old และ --term-new

ตัวอย่างเช่นคุณสามารถระบุข้อตกลงในการแก้ไขปัญหาได้ดังนี้:

git bisect start --term-new=fixed --term-old=unfixed
git bisect fixed master
git bisect unfixed $some-old-sha1

ในขณะที่คุณทดสอบให้พูดgit bisect fixedหรือgit bisect unfixedตามความเหมาะสม

คำตอบเก่าสำหรับ git เวอร์ชันก่อนหน้า 2.7

แทนที่จะฝึกตัวเองชั่วคราวให้คิดว่าความหมายที่ไม่ดีหมายถึงดีและดีหมายถึงไม่ดีทำไมไม่สร้างชื่อแทน

ในการ~/.gitconfigเพิ่มสิ่งต่อไปนี้:

[alias]
        bisect-fixed = bisect bad
        bisect-unfixed = bisect good

คุณสามารถเริ่มระบุข้อตกลงการแก้ไขปัญหาได้ดังนี้:

$ git bisect start
$ git bisect-fixed master
$ git bisect-unfixed $some-old-sha1

ในขณะที่คุณทดสอบให้พูดgit bisect-fixedหรือgit bisect-unfixedตามความเหมาะสม


5
นอกจากนี้ git ไม่อนุญาตให้คุณสร้างนามแฝงของคำสั่งย่อย ดังนั้นขีดกลาง หากเป็นไปได้จริง (หรือถูกสร้างขึ้น) หวังว่าจะมีคนอัปเดตคำตอบ
Michael Wolf

3
แม้ว่าคุณจะใช้นามแฝง แต่ผลลัพธ์จาก git จะไม่ได้ดังนั้นมันจะยังคงรายงาน foo is the first bad commitดังนั้นดูเหมือนว่าการฝึกอบรมชั่วคราวยังจำเป็นอยู่ใช่ไหม?
ThomasW

2
จุดยุติธรรม (เพิ่มคะแนนความคิดเห็นของคุณ) แม้ว่าจะเป็นเช่นนั้นหวังว่าอย่างน้อยก็มีภาระด้านความรู้ความเข้าใจเพิ่มเติมที่จะจัดการน้อยลงเล็กน้อยและในฐานะโปรแกรมเมอร์เรามีมากมายอยู่แล้ว
Michael Wolf

1
ขอแนะนำให้ใช้นามแฝง "before" และ "after" ด้วยวิธีนี้คุณจะไม่มีค่าใช้จ่ายในการรับรู้ในการผกผัน "เมื่อฉันเห็นจุดบกพร่องฉันควรเขียนว่า 'ดี'"; แต่คุณมีเพียงค่าใช้จ่ายที่น่าจะเล็กกว่าเท่านั้นในการจดจำว่าคุณกำลังมองหาลักษณะที่ปรากฏ / การหายไปของข้อบกพร่อง (เช่นการจดจำว่าคุณกำลังมองหาการเปลี่ยนแปลงแบบใด - "ก่อนอะไร")
Jonas Kölker

1
@ JonasKölkerนั่นเป็นความคิดที่ดี ฉันใช้นามแฝงที่แนะนำในคำตอบรวมทั้งbisect-after = bisect badและbisect-before = bisect goodตามคำแนะนำของคุณ ตอนนี้ฉันสามารถใช้นามแฝงชุดใดก็ได้ เราจะดูว่าฉันชอบอะไรมากขึ้นหลังจากใช้งานไม่กี่ครั้ง
Gabriel Staples

47

ฉันแค่ "โกง" คอมไพล์และแลกเปลี่ยนความหมายของดี <=> ไม่ดี

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

ความดีและความเลวเป็นแนวคิดส่วนตัวใช่มั้ย? :)

git bisect start
git bisect good last
git bisect bad master

2
ถ้าคุณคิดว่ามันไม่มีความหมายทั่วไปว่าดีหรือไม่ดีคืออะไร (อาจไม่ใช่ในศาสนาด้วยซ้ำ) .. มันขึ้นอยู่กับวัตถุประสงค์ของคุณ วิธีนี้ไม่ใช่การโกงจริงๆ - แต่อาจเป็น Git's Sin (เพื่อให้อยู่ในหัวข้อทางศาสนา: D คือการเลือกใช้คำที่ถกเถียงกันมากกว่า "เป้าหมาย" / "ที่มา" ที่เป็นกลางกว่า .. แต่ใช่ปรัชญาสามารถเป็นใจได้ - เหลือเชื่อ ;-)
inger

นี่ต้องเป็นครั้งแรกที่ฉันได้ยินว่าข้อบกพร่องสามารถ "ดี" ได้
MarcH

1
นั่นคือสิ่งที่ฉันทำก่อนที่จะพบคำถามนี้ ฉันจะไม่ทำอีกแล้ว จำไว้ว่าต้องตอบผิดเพียงคำตอบเดียวก่อนที่การแบ่งส่วนทั้งหมดจะผิดพลาด อย่าบิดความคิด
proski

22

หากคุณใช้git bisect runเหมือนที่ฉันเคยทำกับproveคำสั่งของ Perl (ซึ่งเรียกใช้การทดสอบอัตโนมัติ) คุณไม่มีโอกาสเพียงแค่สลับgoodและbad. ความสำเร็จของการทดสอบจะรายงานเป็นรหัสทางออก

ฉันพบไวยากรณ์ Bash ที่ถูกต้องเพื่อลบล้างรหัสออกของโปรแกรมที่รันโดยgit bisect run:

git bisect start
git bisect bad HEAD                 # last revision known to PASS the tests
git bisect good $LAST_FAIL_REVISION # last revision known to FAIL the tests
git bisect run bash -c "! prove"

นี้ให้ฉันแก้ไขแรกที่ผ่านproveการทดสอบที่ดำเนินการโดย


1
ฉันยอมรับฉันไม่อยากแก้ไขกรณีทดสอบของฉันเพื่อให้นี่สมบูรณ์แบบ
seanlinsley

8

Git ตอนนี้ช่วยให้คุณใช้oldและnewโดยไม่ได้กำหนดให้พวกเขา คุณต้องโทรgit bisect startโดยไม่ถือเป็นข้อโต้แย้งเพิ่มเติมจากนั้นเริ่มการแบ่งส่วนอย่างถูกต้องโดยการโทร

git bisect old <rev>
git bisect new <rev>

https://git-scm.com/docs/git-bisect#_alternate_terms

นี่คือสิ่งที่ @MarcH แนะนำว่าควรนำไปใช้


1
นี่คือคำตอบที่ตรงประเด็นที่สุด (สำหรับคอมไพล์สมัยใหม่) และคำสั่ง start ควรเป็น (ตามลิงค์ที่คุณแชร์):git bisect start --term-new fixed --term-old broken
Sam Protsenko

จริง. ตัวเลือกเหล่านี้ถูกนำมาใช้เมื่อใด ฉันต้องการอัปเดตคำตอบของฉัน
Michael Wolf

@MichaelWolf พวกเขาปรากฏตัวในเวอร์ชัน 2.7.0
GKFX

6

นามแฝง Git เป็นความคิดที่ดีอย่างไรก็ตามข้อกำหนดfixedและunfixedมีปัญหาเดียวกันกว่าgoodและbad: คุณไม่สามารถกำหนดให้เข้ากันได้กับทั้งการถอยหลังและความก้าวหน้า เป็นเรื่องง่ายที่จะค้นหาคำที่ใช้งานได้ทั้งสองวิธี: เพียงแค่เลือกคำเหล่านี้จากคำศัพท์การค้นหาแบบไบนารีดั้งเดิมซึ่งเป็นกลางโดยไม่มีการเข้าใจล่วงหน้าว่าอะไรดีหรือไม่ดี ตัวอย่างเช่น:

git config --global alias.bisect-high 'bisect bad'
git config --global alias.bisect-low  'bisect good'

ด้วยเงื่อนไขที่เป็นกลางเช่นนี้คุณก็สามารถพิมพ์: git bisect-high(หรือgit bisect-upperหรือgit-bisect max... ทางเลือกของคุณ) ไม่ว่าคุณกำลังมองหาการถดถอยหรือแก้ไข

น่าเสียดายที่นักพัฒนา git bisect ไม่สามารถใช้คำศัพท์ที่มีอยู่ซ้ำได้ อินเทอร์เฟซผู้ใช้ไม่ใช่ข้อกังวลของ git โดยทั่วไป: http://stevebennett.me/2012/02/24/10-things-i-hate-about-git/


From: git.github.io/rev_news/2015/07/08/edition-5 "ซีรีส์แพตช์บางส่วนกำลังขัดเงาเพื่อให้คอมไพล์ทวิสต์ใช้คู่คำตามอำเภอใจแทนดีและไม่ดี, ... "
MarcH
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.