@@ -21,16 +21,15 @@ static GIT_PATH_FUNC(git_path_bisect_first_parent, "BISECT_FIRST_PARENT")
21
21
22
22
static const char * const git_bisect_helper_usage [] = {
23
23
N_ ("git bisect--helper --bisect-reset [<commit>]" ),
24
- N_ ("git bisect--helper --bisect-write [--no-log] <state> <revision> <good_term> <bad_term>" ),
25
- N_ ("git bisect--helper --bisect-check-and-set-terms <command> <good_term> <bad_term>" ),
26
24
N_ ("git bisect--helper --bisect-next-check <good_term> <bad_term> [<term>]" ),
27
25
N_ ("git bisect--helper --bisect-terms [--term-good | --term-old | --term-bad | --term-new]" ),
28
26
N_ ("git bisect--helper --bisect-start [--term-{new,bad}=<term> --term-{old,good}=<term>]"
29
27
" [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] [<paths>...]" ),
30
28
N_ ("git bisect--helper --bisect-next" ),
31
- N_ ("git bisect--helper --bisect-auto-next" ),
32
29
N_ ("git bisect--helper --bisect-state (bad|new) [<rev>]" ),
33
30
N_ ("git bisect--helper --bisect-state (good|old) [<rev>...]" ),
31
+ N_ ("git bisect--helper --bisect-replay <filename>" ),
32
+ N_ ("git bisect--helper --bisect-skip [(<rev>|<range>)...]" ),
34
33
NULL
35
34
};
36
35
@@ -904,28 +903,148 @@ static enum bisect_error bisect_state(struct bisect_terms *terms, const char **a
904
903
return bisect_auto_next (terms , NULL );
905
904
}
906
905
906
+ static enum bisect_error bisect_log (void )
907
+ {
908
+ int fd , status ;
909
+ const char * filename = git_path_bisect_log ();
910
+
911
+ if (is_empty_or_missing_file (filename ))
912
+ return error (_ ("We are not bisecting." ));
913
+
914
+ fd = open (filename , O_RDONLY );
915
+ if (fd < 0 )
916
+ return BISECT_FAILED ;
917
+
918
+ status = copy_fd (fd , STDOUT_FILENO );
919
+ close (fd );
920
+ return status ? BISECT_FAILED : BISECT_OK ;
921
+ }
922
+
923
+ static int process_replay_line (struct bisect_terms * terms , struct strbuf * line )
924
+ {
925
+ const char * p = line -> buf + strspn (line -> buf , " \t" );
926
+ char * word_end , * rev ;
927
+
928
+ if ((!skip_prefix (p , "git bisect" , & p ) &&
929
+ !skip_prefix (p , "git-bisect" , & p )) || !isspace (* p ))
930
+ return 0 ;
931
+ p += strspn (p , " \t" );
932
+
933
+ word_end = (char * )p + strcspn (p , " \t" );
934
+ rev = word_end + strspn (word_end , " \t" );
935
+ * word_end = '\0' ; /* NUL-terminate the word */
936
+
937
+ get_terms (terms );
938
+ if (check_and_set_terms (terms , p ))
939
+ return -1 ;
940
+
941
+ if (!strcmp (p , "start" )) {
942
+ struct strvec argv = STRVEC_INIT ;
943
+ int res ;
944
+ sq_dequote_to_strvec (rev , & argv );
945
+ res = bisect_start (terms , argv .v , argv .nr );
946
+ strvec_clear (& argv );
947
+ return res ;
948
+ }
949
+
950
+ if (one_of (p , terms -> term_good ,
951
+ terms -> term_bad , "skip" , NULL ))
952
+ return bisect_write (p , rev , terms , 0 );
953
+
954
+ if (!strcmp (p , "terms" )) {
955
+ struct strvec argv = STRVEC_INIT ;
956
+ int res ;
957
+ sq_dequote_to_strvec (rev , & argv );
958
+ res = bisect_terms (terms , argv .nr == 1 ? argv .v [0 ] : NULL );
959
+ strvec_clear (& argv );
960
+ return res ;
961
+ }
962
+ error (_ ("'%s'?? what are you talking about?" ), p );
963
+
964
+ return -1 ;
965
+ }
966
+
967
+ static enum bisect_error bisect_replay (struct bisect_terms * terms , const char * filename )
968
+ {
969
+ FILE * fp = NULL ;
970
+ enum bisect_error res = BISECT_OK ;
971
+ struct strbuf line = STRBUF_INIT ;
972
+
973
+ if (is_empty_or_missing_file (filename ))
974
+ return error (_ ("cannot read file '%s' for replaying" ), filename );
975
+
976
+ if (bisect_reset (NULL ))
977
+ return BISECT_FAILED ;
978
+
979
+ fp = fopen (filename , "r" );
980
+ if (!fp )
981
+ return BISECT_FAILED ;
982
+
983
+ while ((strbuf_getline (& line , fp ) != EOF ) && !res )
984
+ res = process_replay_line (terms , & line );
985
+
986
+ strbuf_release (& line );
987
+ fclose (fp );
988
+
989
+ if (res )
990
+ return BISECT_FAILED ;
991
+
992
+ return bisect_auto_next (terms , NULL );
993
+ }
994
+
995
+ static enum bisect_error bisect_skip (struct bisect_terms * terms , const char * * argv , int argc )
996
+ {
997
+ int i ;
998
+ enum bisect_error res ;
999
+ struct strvec argv_state = STRVEC_INIT ;
1000
+
1001
+ strvec_push (& argv_state , "skip" );
1002
+
1003
+ for (i = 0 ; i < argc ; i ++ ) {
1004
+ const char * dotdot = strstr (argv [i ], ".." );
1005
+
1006
+ if (dotdot ) {
1007
+ struct rev_info revs ;
1008
+ struct commit * commit ;
1009
+
1010
+ init_revisions (& revs , NULL );
1011
+ setup_revisions (2 , argv + i - 1 , & revs , NULL );
1012
+
1013
+ if (prepare_revision_walk (& revs ))
1014
+ die (_ ("revision walk setup failed\n" ));
1015
+ while ((commit = get_revision (& revs )) != NULL )
1016
+ strvec_push (& argv_state ,
1017
+ oid_to_hex (& commit -> object .oid ));
1018
+
1019
+ reset_revision_walk ();
1020
+ } else {
1021
+ strvec_push (& argv_state , argv [i ]);
1022
+ }
1023
+ }
1024
+ res = bisect_state (terms , argv_state .v , argv_state .nr );
1025
+
1026
+ strvec_clear (& argv_state );
1027
+ return res ;
1028
+ }
1029
+
907
1030
int cmd_bisect__helper (int argc , const char * * argv , const char * prefix )
908
1031
{
909
1032
enum {
910
1033
BISECT_RESET = 1 ,
911
- BISECT_WRITE ,
912
- CHECK_AND_SET_TERMS ,
913
1034
BISECT_NEXT_CHECK ,
914
1035
BISECT_TERMS ,
915
1036
BISECT_START ,
916
1037
BISECT_AUTOSTART ,
917
1038
BISECT_NEXT ,
918
- BISECT_AUTO_NEXT ,
919
- BISECT_STATE
1039
+ BISECT_STATE ,
1040
+ BISECT_LOG ,
1041
+ BISECT_REPLAY ,
1042
+ BISECT_SKIP
920
1043
} cmdmode = 0 ;
921
1044
int res = 0 , nolog = 0 ;
922
1045
struct option options [] = {
923
1046
OPT_CMDMODE (0 , "bisect-reset" , & cmdmode ,
924
1047
N_ ("reset the bisection state" ), BISECT_RESET ),
925
- OPT_CMDMODE (0 , "bisect-write" , & cmdmode ,
926
- N_ ("write out the bisection state in BISECT_LOG" ), BISECT_WRITE ),
927
- OPT_CMDMODE (0 , "check-and-set-terms" , & cmdmode ,
928
- N_ ("check and set terms in a bisection state" ), CHECK_AND_SET_TERMS ),
929
1048
OPT_CMDMODE (0 , "bisect-next-check" , & cmdmode ,
930
1049
N_ ("check whether bad or good terms exist" ), BISECT_NEXT_CHECK ),
931
1050
OPT_CMDMODE (0 , "bisect-terms" , & cmdmode ,
@@ -934,10 +1053,14 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
934
1053
N_ ("start the bisect session" ), BISECT_START ),
935
1054
OPT_CMDMODE (0 , "bisect-next" , & cmdmode ,
936
1055
N_ ("find the next bisection commit" ), BISECT_NEXT ),
937
- OPT_CMDMODE (0 , "bisect-auto-next" , & cmdmode ,
938
- N_ ("verify the next bisection state then checkout the next bisection commit" ), BISECT_AUTO_NEXT ),
939
1056
OPT_CMDMODE (0 , "bisect-state" , & cmdmode ,
940
1057
N_ ("mark the state of ref (or refs)" ), BISECT_STATE ),
1058
+ OPT_CMDMODE (0 , "bisect-log" , & cmdmode ,
1059
+ N_ ("list the bisection steps so far" ), BISECT_LOG ),
1060
+ OPT_CMDMODE (0 , "bisect-replay" , & cmdmode ,
1061
+ N_ ("replay the bisection process from the given file" ), BISECT_REPLAY ),
1062
+ OPT_CMDMODE (0 , "bisect-skip" , & cmdmode ,
1063
+ N_ ("skip some commits for checkout" ), BISECT_SKIP ),
941
1064
OPT_BOOL (0 , "no-log" , & nolog ,
942
1065
N_ ("no log for BISECT_WRITE" )),
943
1066
OPT_END ()
@@ -955,18 +1078,7 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
955
1078
case BISECT_RESET :
956
1079
if (argc > 1 )
957
1080
return error (_ ("--bisect-reset requires either no argument or a commit" ));
958
- return !!bisect_reset (argc ? argv [0 ] : NULL );
959
- case BISECT_WRITE :
960
- if (argc != 4 && argc != 5 )
961
- return error (_ ("--bisect-write requires either 4 or 5 arguments" ));
962
- set_terms (& terms , argv [3 ], argv [2 ]);
963
- res = bisect_write (argv [0 ], argv [1 ], & terms , nolog );
964
- break ;
965
- case CHECK_AND_SET_TERMS :
966
- if (argc != 3 )
967
- return error (_ ("--check-and-set-terms requires 3 arguments" ));
968
- set_terms (& terms , argv [2 ], argv [1 ]);
969
- res = check_and_set_terms (& terms , argv [0 ]);
1081
+ res = bisect_reset (argc ? argv [0 ] : NULL );
970
1082
break ;
971
1083
case BISECT_NEXT_CHECK :
972
1084
if (argc != 2 && argc != 3 )
@@ -989,17 +1101,26 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
989
1101
get_terms (& terms );
990
1102
res = bisect_next (& terms , prefix );
991
1103
break ;
992
- case BISECT_AUTO_NEXT :
993
- if (argc )
994
- return error (_ ("--bisect-auto-next requires 0 arguments" ));
995
- get_terms (& terms );
996
- res = bisect_auto_next (& terms , prefix );
997
- break ;
998
1104
case BISECT_STATE :
999
1105
set_terms (& terms , "bad" , "good" );
1000
1106
get_terms (& terms );
1001
1107
res = bisect_state (& terms , argv , argc );
1002
1108
break ;
1109
+ case BISECT_LOG :
1110
+ if (argc )
1111
+ return error (_ ("--bisect-log requires 0 arguments" ));
1112
+ res = bisect_log ();
1113
+ break ;
1114
+ case BISECT_REPLAY :
1115
+ if (argc != 1 )
1116
+ return error (_ ("no logfile given" ));
1117
+ set_terms (& terms , "bad" , "good" );
1118
+ res = bisect_replay (& terms , argv [0 ]);
1119
+ break ;
1120
+ case BISECT_SKIP :
1121
+ set_terms (& terms , "bad" , "good" );
1122
+ res = bisect_skip (& terms , argv , argc );
1123
+ break ;
1003
1124
default :
1004
1125
BUG ("unknown subcommand %d" , cmdmode );
1005
1126
}
0 commit comments