THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

Git Source Code Mirror - This is a publish-only repository and all pull requests are ignored. Please follow Documentation/SubmittingPatches procedure for any of your improvements.
git
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

349 lines
8.1KB

  1. #!/bin/sh
  2. USAGE='[help|start|bad|good|new|old|terms|skip|next|reset|visualize|view|replay|log|run]'
  3. LONG_USAGE='git bisect help
  4. print this long help message.
  5. git bisect start [--term-{old,good}=<term> --term-{new,bad}=<term>]
  6. [--no-checkout] [<bad> [<good>...]] [--] [<pathspec>...]
  7. reset bisect state and start bisection.
  8. git bisect (bad|new) [<rev>]
  9. mark <rev> a known-bad revision/
  10. a revision after change in a given property.
  11. git bisect (good|old) [<rev>...]
  12. mark <rev>... known-good revisions/
  13. revisions before change in a given property.
  14. git bisect terms [--term-good | --term-bad]
  15. show the terms used for old and new commits (default: bad, good)
  16. git bisect skip [(<rev>|<range>)...]
  17. mark <rev>... untestable revisions.
  18. git bisect next
  19. find next bisection to test and check it out.
  20. git bisect reset [<commit>]
  21. finish bisection search and go back to commit.
  22. git bisect (visualize|view)
  23. show bisect status in gitk.
  24. git bisect replay <logfile>
  25. replay bisection log.
  26. git bisect log
  27. show bisect log.
  28. git bisect run <cmd>...
  29. use <cmd>... to automatically bisect.
  30. Please use "git help bisect" to get the full man page.'
  31. OPTIONS_SPEC=
  32. . git-sh-setup
  33. _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
  34. _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
  35. TERM_BAD=bad
  36. TERM_GOOD=good
  37. bisect_head()
  38. {
  39. if test -f "$GIT_DIR/BISECT_HEAD"
  40. then
  41. echo BISECT_HEAD
  42. else
  43. echo HEAD
  44. fi
  45. }
  46. bisect_autostart() {
  47. test -s "$GIT_DIR/BISECT_START" || {
  48. gettextln "You need to start by \"git bisect start\"" >&2
  49. if test -t 0
  50. then
  51. # TRANSLATORS: Make sure to include [Y] and [n] in your
  52. # translation. The program will only accept English input
  53. # at this point.
  54. gettext "Do you want me to do it for you [Y/n]? " >&2
  55. read yesno
  56. case "$yesno" in
  57. [Nn]*)
  58. exit ;;
  59. esac
  60. bisect_start
  61. else
  62. exit 1
  63. fi
  64. }
  65. }
  66. bisect_start() {
  67. git bisect--helper --bisect-start $@ || exit
  68. #
  69. # Change state.
  70. # In case of mistaken revs or checkout error, or signals received,
  71. # "bisect_auto_next" below may exit or misbehave.
  72. # We have to trap this to be able to clean up using
  73. # "bisect_clean_state".
  74. #
  75. trap 'git bisect--helper --bisect-clean-state' 0
  76. trap 'exit 255' 1 2 3 15
  77. #
  78. # Check if we can proceed to the next bisect state.
  79. #
  80. get_terms
  81. bisect_auto_next
  82. trap '-' 0
  83. }
  84. bisect_skip() {
  85. all=''
  86. for arg in "$@"
  87. do
  88. case "$arg" in
  89. *..*)
  90. revs=$(git rev-list "$arg") || die "$(eval_gettext "Bad rev input: \$arg")" ;;
  91. *)
  92. revs=$(git rev-parse --sq-quote "$arg") ;;
  93. esac
  94. all="$all $revs"
  95. done
  96. eval bisect_state 'skip' $all
  97. }
  98. bisect_state() {
  99. bisect_autostart
  100. state=$1
  101. git bisect--helper --check-and-set-terms $state $TERM_GOOD $TERM_BAD || exit
  102. get_terms
  103. case "$#,$state" in
  104. 0,*)
  105. die "Please call 'bisect_state' with at least one argument." ;;
  106. 1,"$TERM_BAD"|1,"$TERM_GOOD"|1,skip)
  107. bisected_head=$(bisect_head)
  108. rev=$(git rev-parse --verify "$bisected_head") ||
  109. die "$(eval_gettext "Bad rev input: \$bisected_head")"
  110. git bisect--helper --bisect-write "$state" "$rev" "$TERM_GOOD" "$TERM_BAD" || exit
  111. git bisect--helper --check-expected-revs "$rev" ;;
  112. 2,"$TERM_BAD"|*,"$TERM_GOOD"|*,skip)
  113. shift
  114. hash_list=''
  115. for rev in "$@"
  116. do
  117. sha=$(git rev-parse --verify "$rev^{commit}") ||
  118. die "$(eval_gettext "Bad rev input: \$rev")"
  119. hash_list="$hash_list $sha"
  120. done
  121. for rev in $hash_list
  122. do
  123. git bisect--helper --bisect-write "$state" "$rev" "$TERM_GOOD" "$TERM_BAD" || exit
  124. done
  125. git bisect--helper --check-expected-revs $hash_list ;;
  126. *,"$TERM_BAD")
  127. die "$(eval_gettext "'git bisect \$TERM_BAD' can take only one argument.")" ;;
  128. *)
  129. usage ;;
  130. esac
  131. bisect_auto_next
  132. }
  133. bisect_auto_next() {
  134. git bisect--helper --bisect-next-check $TERM_GOOD $TERM_BAD && bisect_next || :
  135. }
  136. bisect_next() {
  137. case "$#" in 0) ;; *) usage ;; esac
  138. bisect_autostart
  139. git bisect--helper --bisect-next-check $TERM_GOOD $TERM_BAD $TERM_GOOD|| exit
  140. # Perform all bisection computation, display and checkout
  141. git bisect--helper --next-all $(test -f "$GIT_DIR/BISECT_HEAD" && echo --no-checkout)
  142. res=$?
  143. # Check if we should exit because bisection is finished
  144. if test $res -eq 10
  145. then
  146. bad_rev=$(git show-ref --hash --verify refs/bisect/$TERM_BAD)
  147. bad_commit=$(git show-branch $bad_rev)
  148. echo "# first $TERM_BAD commit: $bad_commit" >>"$GIT_DIR/BISECT_LOG"
  149. exit 0
  150. elif test $res -eq 2
  151. then
  152. echo "# only skipped commits left to test" >>"$GIT_DIR/BISECT_LOG"
  153. good_revs=$(git for-each-ref --format="%(objectname)" "refs/bisect/$TERM_GOOD-*")
  154. for skipped in $(git rev-list refs/bisect/$TERM_BAD --not $good_revs)
  155. do
  156. skipped_commit=$(git show-branch $skipped)
  157. echo "# possible first $TERM_BAD commit: $skipped_commit" >>"$GIT_DIR/BISECT_LOG"
  158. done
  159. exit $res
  160. fi
  161. # Check for an error in the bisection process
  162. test $res -ne 0 && exit $res
  163. return 0
  164. }
  165. bisect_visualize() {
  166. git bisect--helper --bisect-next-check $TERM_GOOD $TERM_BAD fail || exit
  167. if test $# = 0
  168. then
  169. if test -n "${DISPLAY+set}${SESSIONNAME+set}${MSYSTEM+set}${SECURITYSESSIONID+set}" &&
  170. type gitk >/dev/null 2>&1
  171. then
  172. set gitk
  173. else
  174. set git log
  175. fi
  176. else
  177. case "$1" in
  178. git*|tig) ;;
  179. -*) set git log "$@" ;;
  180. *) set git "$@" ;;
  181. esac
  182. fi
  183. eval '"$@"' --bisect -- $(cat "$GIT_DIR/BISECT_NAMES")
  184. }
  185. bisect_replay () {
  186. file="$1"
  187. test "$#" -eq 1 || die "$(gettext "No logfile given")"
  188. test -r "$file" || die "$(eval_gettext "cannot read \$file for replaying")"
  189. git bisect--helper --bisect-reset || exit
  190. while read git bisect command rev
  191. do
  192. test "$git $bisect" = "git bisect" || test "$git" = "git-bisect" || continue
  193. if test "$git" = "git-bisect"
  194. then
  195. rev="$command"
  196. command="$bisect"
  197. fi
  198. get_terms
  199. git bisect--helper --check-and-set-terms "$command" "$TERM_GOOD" "$TERM_BAD" || exit
  200. get_terms
  201. case "$command" in
  202. start)
  203. cmd="bisect_start $rev"
  204. eval "$cmd" ;;
  205. "$TERM_GOOD"|"$TERM_BAD"|skip)
  206. git bisect--helper --bisect-write "$command" "$rev" "$TERM_GOOD" "$TERM_BAD" || exit;;
  207. terms)
  208. git bisect--helper --bisect-terms $rev || exit;;
  209. *)
  210. die "$(gettext "?? what are you talking about?")" ;;
  211. esac
  212. done <"$file"
  213. bisect_auto_next
  214. }
  215. bisect_run () {
  216. git bisect--helper --bisect-next-check $TERM_GOOD $TERM_BAD fail || exit
  217. test -n "$*" || die "$(gettext "bisect run failed: no command provided.")"
  218. while true
  219. do
  220. command="$@"
  221. eval_gettextln "running \$command"
  222. "$@"
  223. res=$?
  224. # Check for really bad run error.
  225. if [ $res -lt 0 -o $res -ge 128 ]
  226. then
  227. eval_gettextln "bisect run failed:
  228. exit code \$res from '\$command' is < 0 or >= 128" >&2
  229. exit $res
  230. fi
  231. # Find current state depending on run success or failure.
  232. # A special exit code of 125 means cannot test.
  233. if [ $res -eq 125 ]
  234. then
  235. state='skip'
  236. elif [ $res -gt 0 ]
  237. then
  238. state="$TERM_BAD"
  239. else
  240. state="$TERM_GOOD"
  241. fi
  242. # We have to use a subshell because "bisect_state" can exit.
  243. ( bisect_state $state >"$GIT_DIR/BISECT_RUN" )
  244. res=$?
  245. cat "$GIT_DIR/BISECT_RUN"
  246. if sane_grep "first $TERM_BAD commit could be any of" "$GIT_DIR/BISECT_RUN" \
  247. >/dev/null
  248. then
  249. gettextln "bisect run cannot continue any more" >&2
  250. exit $res
  251. fi
  252. if [ $res -ne 0 ]
  253. then
  254. eval_gettextln "bisect run failed:
  255. 'bisect_state \$state' exited with error code \$res" >&2
  256. exit $res
  257. fi
  258. if sane_grep "is the first $TERM_BAD commit" "$GIT_DIR/BISECT_RUN" >/dev/null
  259. then
  260. gettextln "bisect run success"
  261. exit 0;
  262. fi
  263. done
  264. }
  265. bisect_log () {
  266. test -s "$GIT_DIR/BISECT_LOG" || die "$(gettext "We are not bisecting.")"
  267. cat "$GIT_DIR/BISECT_LOG"
  268. }
  269. get_terms () {
  270. if test -s "$GIT_DIR/BISECT_TERMS"
  271. then
  272. {
  273. read TERM_BAD
  274. read TERM_GOOD
  275. } <"$GIT_DIR/BISECT_TERMS"
  276. fi
  277. }
  278. case "$#" in
  279. 0)
  280. usage ;;
  281. *)
  282. cmd="$1"
  283. get_terms
  284. shift
  285. case "$cmd" in
  286. help)
  287. git bisect -h ;;
  288. start)
  289. bisect_start "$@" ;;
  290. bad|good|new|old|"$TERM_BAD"|"$TERM_GOOD")
  291. bisect_state "$cmd" "$@" ;;
  292. skip)
  293. bisect_skip "$@" ;;
  294. next)
  295. # Not sure we want "next" at the UI level anymore.
  296. bisect_next "$@" ;;
  297. visualize|view)
  298. bisect_visualize "$@" ;;
  299. reset)
  300. git bisect--helper --bisect-reset "$@" ;;
  301. replay)
  302. bisect_replay "$@" ;;
  303. log)
  304. bisect_log ;;
  305. run)
  306. bisect_run "$@" ;;
  307. terms)
  308. git bisect--helper --bisect-terms "$@" || exit;;
  309. *)
  310. usage ;;
  311. esac
  312. esac