@@ -1089,14 +1089,52 @@ static int bisect_visualize(struct bisect_terms *terms, const char **argv, int a
1089
1089
return res ;
1090
1090
}
1091
1091
1092
+ static int get_first_good (const char * refname , const struct object_id * oid ,
1093
+ int flag , void * cb_data )
1094
+ {
1095
+ oidcpy (cb_data , oid );
1096
+ return 1 ;
1097
+ }
1098
+
1099
+ static int verify_good (const struct bisect_terms * terms ,
1100
+ const char * * quoted_argv )
1101
+ {
1102
+ int rc ;
1103
+ enum bisect_error res ;
1104
+ struct object_id good_rev ;
1105
+ struct object_id current_rev ;
1106
+ char * good_glob = xstrfmt ("%s-*" , terms -> term_good );
1107
+ int no_checkout = ref_exists ("BISECT_HEAD" );
1108
+
1109
+ for_each_glob_ref_in (get_first_good , good_glob , "refs/bisect/" ,
1110
+ & good_rev );
1111
+ free (good_glob );
1112
+
1113
+ if (read_ref (no_checkout ? "BISECT_HEAD" : "HEAD" , & current_rev ))
1114
+ return -1 ;
1115
+
1116
+ res = bisect_checkout (& good_rev , no_checkout );
1117
+ if (res != BISECT_OK )
1118
+ return -1 ;
1119
+
1120
+ printf (_ ("running %s\n" ), quoted_argv [0 ]);
1121
+ rc = run_command_v_opt (quoted_argv , RUN_USING_SHELL );
1122
+
1123
+ res = bisect_checkout (& current_rev , no_checkout );
1124
+ if (res != BISECT_OK )
1125
+ return -1 ;
1126
+
1127
+ return rc ;
1128
+ }
1129
+
1092
1130
static int bisect_run (struct bisect_terms * terms , const char * * argv , int argc )
1093
1131
{
1094
1132
int res = BISECT_OK ;
1095
1133
struct strbuf command = STRBUF_INIT ;
1096
- struct strvec args = STRVEC_INIT ;
1097
1134
struct strvec run_args = STRVEC_INIT ;
1098
1135
const char * new_state ;
1099
1136
int temporary_stdout_fd , saved_stdout ;
1137
+ int is_first_run = 1 ;
1100
1138
1101
1139
if (bisect_next_check (terms , NULL ))
1102
1140
return BISECT_FAILED ;
@@ -1111,16 +1149,37 @@ static int bisect_run(struct bisect_terms *terms, const char **argv, int argc)
1111
1149
strvec_push (& run_args , command .buf );
1112
1150
1113
1151
while (1 ) {
1114
- strvec_clear (& args );
1115
-
1116
1152
printf (_ ("running %s\n" ), command .buf );
1117
1153
res = run_command_v_opt (run_args .v , RUN_USING_SHELL );
1118
1154
1155
+ /*
1156
+ * Exit code 126 and 127 can either come from the shell
1157
+ * if it was unable to execute or even find the script,
1158
+ * or from the script itself. Check with a known-good
1159
+ * revision to avoid trashing the bisect run due to a
1160
+ * missing or non-executable script.
1161
+ */
1162
+ if (is_first_run && (res == 126 || res == 127 )) {
1163
+ int rc = verify_good (terms , run_args .v );
1164
+ is_first_run = 0 ;
1165
+ if (rc < 0 ) {
1166
+ error (_ ("unable to verify '%s' on good"
1167
+ " revision" ), command .buf );
1168
+ res = BISECT_FAILED ;
1169
+ break ;
1170
+ }
1171
+ if (rc == res ) {
1172
+ error (_ ("bogus exit code %d for good revision" ),
1173
+ rc );
1174
+ res = BISECT_FAILED ;
1175
+ break ;
1176
+ }
1177
+ }
1178
+
1119
1179
if (res < 0 || 128 <= res ) {
1120
1180
error (_ ("bisect run failed: exit code %d from"
1121
1181
" '%s' is < 0 or >= 128" ), res , command .buf );
1122
- strbuf_release (& command );
1123
- return res ;
1182
+ break ;
1124
1183
}
1125
1184
1126
1185
if (res == 125 )
@@ -1132,8 +1191,10 @@ static int bisect_run(struct bisect_terms *terms, const char **argv, int argc)
1132
1191
1133
1192
temporary_stdout_fd = open (git_path_bisect_run (), O_CREAT | O_WRONLY | O_TRUNC , 0666 );
1134
1193
1135
- if (temporary_stdout_fd < 0 )
1136
- return error_errno (_ ("cannot open file '%s' for writing" ), git_path_bisect_run ());
1194
+ if (temporary_stdout_fd < 0 ) {
1195
+ res = error_errno (_ ("cannot open file '%s' for writing" ), git_path_bisect_run ());
1196
+ break ;
1197
+ }
1137
1198
1138
1199
fflush (stdout );
1139
1200
saved_stdout = dup (1 );
@@ -1158,16 +1219,16 @@ static int bisect_run(struct bisect_terms *terms, const char **argv, int argc)
1158
1219
res = BISECT_OK ;
1159
1220
} else if (res ) {
1160
1221
error (_ ("bisect run failed: 'git bisect--helper --bisect-state"
1161
- " %s' exited with error code %d" ), args . v [ 0 ] , res );
1222
+ " %s' exited with error code %d" ), new_state , res );
1162
1223
} else {
1163
1224
continue ;
1164
1225
}
1165
-
1166
- strbuf_release (& command );
1167
- strvec_clear (& args );
1168
- strvec_clear (& run_args );
1169
- return res ;
1226
+ break ;
1170
1227
}
1228
+
1229
+ strbuf_release (& command );
1230
+ strvec_clear (& run_args );
1231
+ return res ;
1171
1232
}
1172
1233
1173
1234
int cmd_bisect__helper (int argc , const char * * argv , const char * prefix )
0 commit comments