git bisect run
स्वचालित बिस्किट
यदि आपके पास एक स्वचालित ./test
स्क्रिप्ट है जिसमें बाहर निकलने की स्थिति है 0 यदि परीक्षण ठीक है, तो आप स्वचालित रूप से बग को ढूंढ सकते हैं bisect run
:
git checkout KNOWN_BAD_COMMIT
git bisect start
# Confirm that our test script is correct, and fails on the bad commit.
./test
# Should output != 0.
echo $?
# Tell Git that the current commit is bad.
git bisect bad
# Same for a known good commit in the past.
git checkout KNOWN_GOOD_COMMIT
./test
# Should output 0.
echo $?
# After this, git automatically checks out to the commit
# in the middle of KNOWN_BAD_COMMIT and KNOWN_GOOD_COMMIT.
git bisect good
# Bisect automatically all the way to the first bad or last good rev.
git bisect run ./test
# End the bisect operation and checkout to master again.
git bisect reset
यह निश्चित रूप से पता चलता है कि यदि परीक्षण स्क्रिप्ट ./test
को ट्रैक किया जाता है, तो यह द्विभाजन के दौरान कुछ पूर्व प्रतिबद्ध पर गायब नहीं होता है।
मैंने पाया है कि बहुत बार आप इन-ट्री स्क्रिप्ट को पेड़ से बाहर की नकल करके, और संभवत: इसी PATH
तरह के चर के साथ खेल सकते हैं और इसके बजाय वहां से भाग सकते हैं।
बेशक, अगर टेस्ट इन्फ्रास्ट्रक्चर जिस पर test
निर्भर करता है, पुराने कमिट पर टूटता है, तो कोई समाधान नहीं है, और आपको मैन्युअल रूप से चीजों को करना होगा, यह निर्णय लेते हुए कि परीक्षण कैसे एक-एक करके करना है।
मैंने पाया है कि इस स्वचालन का उपयोग अक्सर काम करता है, और आपके कार्यों के बैकलॉग में पड़े हुए धीमी परीक्षणों के लिए एक विशाल समय बचाने वाला हो सकता है, जहां आप इसे रात भर चलने दे सकते हैं, और संभवतः अगली सुबह तक आपकी बग की पहचान हो सकती है, यह लायक है कोशिश करो।
अधिक सुझाव
वापस जाने के बजाय बायसेक्ट के बाद पहली असफलता पर बने रहें master
:
git bisect reset HEAD
start
+ प्रारंभिक bad
और good
एक बार में:
git bisect start KNOWN_BAD_COMMIT KNOWN_GOOD_COMMIT~
के समान है:
git checkout KNOWN_BAD_COMMIT
git bisect start
git bisect bad
git bisect good KNOWN_GOOD_COMMIT
देखें कि अब तक क्या परीक्षण किया गया है (मैनुअल good
और bad
या run
):
git bisect log
नमूना उत्पादन:
git bisect log
git bisect start
# bad: [00b9fcdbe7e7d2579f212b51342f4d605e53253d] 9
git bisect bad 00b9fcdbe7e7d2579f212b51342f4d605e53253d
# good: [db7ec3d602db2d994fe981c0da55b7b85ca62566] 0
git bisect good db7ec3d602db2d994fe981c0da55b7b85ca62566
# good: [2461cd8ce8d3d1367ddb036c8f715c7b896397a5] 4
git bisect good 2461cd8ce8d3d1367ddb036c8f715c7b896397a5
# good: [8fbab5a3b44fd469a2da3830dac5c4c1358a87a0] 6
git bisect good 8fbab5a3b44fd469a2da3830dac5c4c1358a87a0
# bad: [dd2c05e71c246f9bcbd2fbe81deabf826c54be23] 8
git bisect bad dd2c05e71c246f9bcbd2fbe81deabf826c54be23
# bad: [c536b1b7242d5fcf92cd87e9a534bedb1c0c9c05] 7
git bisect bad c536b1b7242d5fcf92cd87e9a534bedb1c0c9c05
# first bad commit: [c536b1b7242d5fcf92cd87e9a534bedb1c0c9c0
समय की बेहतर धारणा पाने के लिए git लॉग पर अच्छे और बुरे रेफरी दिखाएँ:
git log --decorate --pretty=fuller --simplify-by-decoration master
यह केवल एक संबंधित रेफरी के साथ कमिट करता है, जो शोर को कम करता है, लेकिन इसमें प्रकार के ऑटोजेनरेटेड रेफरी शामिल हैं:
refs/bisect/good*
refs/bisect/bad*
जो हमें बताता है कि हमने कौन सा अच्छा या बुरा के रूप में चिह्नित किया है।
यदि आप कमांड के साथ खेलना चाहते हैं तो इस टेस्ट रेपो पर विचार करें ।
असफलता तेज है, सफलता धीमी है
कभी कभी:
- विफलता तेजी से होती है, जैसे पहले परीक्षणों में से एक टूट जाता है
- सफलता में थोड़ा समय लगता है, जैसे कि टूटी हुई परीक्षा पास करना, और अन्य सभी परीक्षण जिनका हम पालन नहीं करते हैं
उन मामलों के लिए, उदाहरण के लिए विफलता को हमेशा 5 सेकंड के साथ पूरा करना होता है, और यदि हम परीक्षण को और अधिक विशिष्ट बनाने के लिए आलसी हैं, जैसा कि हमें वास्तव में करना चाहिए, तो हम निम्नानुसार उपयोग कर सकते हैं timeout
:
#!/usr/bin/env bash
timeout 5 test-command
if [ $? -eq 1 ]; then
exit 1
fi
इस के बाद से काम करता है timeout
बाहर निकलता है 124
की विफलता है, जबकि test-command
बाहर निकलता है 1
।
जादू से बाहर निकलने की स्थिति
git bisect run
बाहर निकलने की स्थिति के बारे में थोड़ा अचार है:
127 से ऊपर की कुछ भी चीज कुछ इस तरह से विफल हो जाती है:
git bisect run failed:
exit code 134 from '../test -aa' is < 0 or >= 128
विशेष रूप से, एक सी की assert(0)
ओर जाता है SIGABRT
और स्थिति 134 से बाहर निकलता है, बहुत कष्टप्रद होता है।
125 मैजिक है और रन को छोड़ देता है git bisect skip
।
इसका उद्देश्य असंबंधित कारणों से टूटे हुए बिल्ड को छोड़ने में मदद करना है।
देखें man git-bisect
जानकारी के लिए।
तो आप कुछ इस तरह का उपयोग करना चाहते हैं:
#!/usr/bin/env bash
set -eu
./build
status=0
./actual-test-command || status=$?
if [ "$status" -eq 125 ] || [ "$status" -gt 127 ]; then
status=1
fi
exit "$status"
2.16.1 पर परीक्षण किया गया।