git bisect run
tự động chia đôi
Nếu bạn có một ./test
tập lệnh tự động có trạng thái thoát 0 nếu kiểm tra là OK, bạn có thể tự động tìm lỗi với 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
Tất nhiên, điều này giả sử rằng nếu tập lệnh kiểm tra ./test
được theo dõi git, thì nó không biến mất trên một số cam kết trước đó trong quá trình chia đôi.
Tôi đã thấy rằng rất thường xuyên bạn có thể thoát khỏi bằng cách chỉ sao chép tập lệnh trong cây ra khỏi cây, và có thể chơi với PATH
các biến giống như, và chạy nó từ đó thay vào đó.
Tất nhiên, nếu cơ sở hạ tầng kiểm tra test
phụ thuộc vào phá vỡ các cam kết cũ hơn, thì không có giải pháp nào và bạn sẽ phải thực hiện mọi việc theo cách thủ công, quyết định cách kiểm tra từng lần một.
Tuy nhiên, tôi đã phát hiện ra rằng việc sử dụng tự động hóa này thường hoạt động và có thể tiết kiệm thời gian rất lớn cho các bài kiểm tra chậm hơn trong các công việc tồn đọng của bạn, nơi bạn có thể để nó chạy qua đêm và có thể nhận ra lỗi của bạn vào sáng hôm sau. sự cố gắng.
Thêm lời khuyên
Tiếp tục cam kết thất bại đầu tiên sau khi chia đôi thay vì quay lại master
:
git bisect reset HEAD
start
+ ban đầu bad
và good
trong một lần:
git bisect start KNOWN_BAD_COMMIT KNOWN_GOOD_COMMIT~
giống như:
git checkout KNOWN_BAD_COMMIT
git bisect start
git bisect bad
git bisect good KNOWN_GOOD_COMMIT
Xem những gì đã được thử nghiệm cho đến nay (bằng tay good
và bad
hoặc run
):
git bisect log
Đầu ra mẫu:
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
Hiển thị các giới thiệu tốt và xấu trên nhật ký git để có được khái niệm tốt hơn về thời gian:
git log --decorate --pretty=fuller --simplify-by-decoration master
Điều này chỉ hiển thị các cam kết với một ref tương ứng, giúp giảm nhiễu thực sự, nhưng không bao gồm các ref được tạo tự động của loại:
refs/bisect/good*
refs/bisect/bad*
cho chúng tôi biết những cam kết nào chúng tôi đánh dấu là tốt hay xấu.
Xem xét thử nghiệm repo này nếu bạn muốn chơi xung quanh với lệnh.
Thất bại là nhanh, thành công là chậm
Đôi khi:
- thất bại xảy ra nhanh chóng, ví dụ như một trong những thử nghiệm đầu tiên bị phá vỡ
- thành công mất một thời gian, ví dụ như bài kiểm tra bị hỏng và tất cả các bài kiểm tra khác mà chúng tôi không quan tâm theo dõi
Đối với những trường hợp đó, ví dụ: giả sử thất bại luôn xảy ra trong 5 giây và nếu chúng ta lười biếng làm cho bài kiểm tra cụ thể hơn như chúng ta thực sự nên làm, chúng ta có thể sử dụng timeout
như trong:
#!/usr/bin/env bash
timeout 5 test-command
if [ $? -eq 1 ]; then
exit 1
fi
Điều này hoạt động kể từ khi timeout
thoát 124
trong khi sự thất bại của test-command
lối thoát 1
.
Trạng thái thoát ma thuật
git bisect run
là một chút kén chọn về trạng thái thoát:
bất cứ điều gì trên 127 làm cho việc chia đôi thất bại với một cái gì đó như:
git bisect run failed:
exit code 134 from '../test -aa' is < 0 or >= 128
Cụ thể, một chữ C assert(0)
dẫn đến a SIGABRT
và thoát với trạng thái 134, rất khó chịu.
125 là ma thuật và làm cho việc chạy được bỏ qua git bisect skip
.
Mục đích của việc này là giúp bỏ qua các bản dựng bị hỏng do các lý do không liên quan.
Xem man git-bisect
để biết chi tiết.
Vì vậy, bạn có thể muốn sử dụng một cái gì đó như:
#!/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"
Đã thử nghiệm trên git 2.16.1.