bisect--helper: reimplement `bisect_replay` shell function in C
Reimplement the `bisect_replay` shell function in C and also add `--bisect-replay` subcommand to `git bisect--helper` to call it from git-bisect.sh Using `--bisect-replay` subcommand is a temporary measure to port shell function to C so as to use the existing test suite. Mentored-by: Lars Schneider <larsxschneider@gmail.com> Mentored-by: Christian Couder <chriscool@tuxfamily.org> Mentored-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> Signed-off-by: Pranit Bauva <pranit.bauva@gmail.com> Signed-off-by: Tanushree Tumane <tanushreetumane@gmail.com> Signed-off-by: Miriam Rubio <mirucam@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Pranit Bauva committed
Feb 3, 2021 at 22:54 UTC
2b1fd947f6d81ae772ebb75ef2e668866ab38c55
2 files changed
+84
-34
builtin/bisect--helper.c
+83
-1
@@ -31,6 +31,7 @@ static const char * const git_bisect_helper_usage[] = {
31
N_("git bisect--helper --bisect-auto-next"),
32
N_("git bisect--helper --bisect-state (bad|new) [<rev>]"),
33
N_("git bisect--helper --bisect-state (good|old) [<rev>...]"),
34
+ N_("git bisect--helper --bisect-replay <filename>"),
35
NULL
36
};
37
@@ -921,6 +922,78 @@ static enum bisect_error bisect_log(void)
922
return status ? BISECT_FAILED : BISECT_OK;
923
}
924
925
+static int process_replay_line(struct bisect_terms *terms, struct strbuf *line)
926
+{
927
+ const char *p = line->buf + strspn(line->buf, " \t");
928
+ char *word_end, *rev;
929
+
930
+ if ((!skip_prefix(p, "git bisect", &p) &&
931
+ !skip_prefix(p, "git-bisect", &p)) || !isspace(*p))
932
+ return 0;
933
+ p += strspn(p, " \t");
934
+
935
+ word_end = (char *)p + strcspn(p, " \t");
936
+ rev = word_end + strspn(word_end, " \t");
937
+ *word_end = '\0'; /* NUL-terminate the word */
938
+
939
+ get_terms(terms);
940
+ if (check_and_set_terms(terms, p))
941
+ return -1;
942
+
943
+ if (!strcmp(p, "start")) {
944
+ struct strvec argv = STRVEC_INIT;
945
+ int res;
946
+ sq_dequote_to_strvec(rev, &argv);
947
+ res = bisect_start(terms, argv.v, argv.nr);
948
+ strvec_clear(&argv);
949
+ return res;
950
+ }
951
+
952
+ if (one_of(p, terms->term_good,
953
+ terms->term_bad, "skip", NULL))
954
+ return bisect_write(p, rev, terms, 0);
955
+
956
+ if (!strcmp(p, "terms")) {
957
+ struct strvec argv = STRVEC_INIT;
958
+ int res;
959
+ sq_dequote_to_strvec(rev, &argv);
960
+ res = bisect_terms(terms, argv.nr == 1 ? argv.v[0] : NULL);
961
+ strvec_clear(&argv);
962
+ return res;
963
+ }
964
+ error(_("'%s'?? what are you talking about?"), p);
965
+
966
+ return -1;
967
+}
968
+
969
+static enum bisect_error bisect_replay(struct bisect_terms *terms, const char *filename)
970
+{
971
+ FILE *fp = NULL;
972
+ enum bisect_error res = BISECT_OK;
973
+ struct strbuf line = STRBUF_INIT;
974
+
975
+ if (is_empty_or_missing_file(filename))
976
+ return error(_("cannot read file '%s' for replaying"), filename);
977
+
978
+ if (bisect_reset(NULL))
979
+ return BISECT_FAILED;
980
+
981
+ fp = fopen(filename, "r");
982
+ if (!fp)
983
+ return BISECT_FAILED;
984
+
985
+ while ((strbuf_getline(&line, fp) != EOF) && !res)
986
+ res = process_replay_line(terms, &line);
987
+
988
+ strbuf_release(&line);
989
+ fclose(fp);
990
+
991
+ if (res)
992
+ return BISECT_FAILED;
993
+
994
+ return bisect_auto_next(terms, NULL);
995
+}
996
+
997
int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
998
{
999
enum {
@@ -934,7 +1007,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
1007
BISECT_NEXT,
1008
BISECT_AUTO_NEXT,
1009
BISECT_STATE,
937
- BISECT_LOG
1010
+ BISECT_LOG,
1011
+ BISECT_REPLAY
1012
} cmdmode = 0;
1013
int res = 0, nolog = 0;
1014
struct option options[] = {
@@ -958,6 +1032,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
1032
N_("mark the state of ref (or refs)"), BISECT_STATE),
1033
OPT_CMDMODE(0, "bisect-log", &cmdmode,
1034
N_("list the bisection steps so far"), BISECT_LOG),
1035
+ OPT_CMDMODE(0, "bisect-replay", &cmdmode,
1036
+ N_("replay the bisection process from the given file"), BISECT_REPLAY),
1037
OPT_BOOL(0, "no-log", &nolog,
1038
N_("no log for BISECT_WRITE")),
1039
OPT_END()
@@ -1025,6 +1101,12 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
1101
return error(_("--bisect-log requires 0 arguments"));
1102
res = bisect_log();
1103
break;
1104
+ case BISECT_REPLAY:
1105
+ if (argc != 1)
1106
+ return error(_("no logfile given"));
1107
+ set_terms(&terms, "bad", "good");
1108
+ res = bisect_replay(&terms, argv[0]);
1109
+ break;
1110
default:
1111
BUG("unknown subcommand %d", cmdmode);
1112
}
git-bisect.sh
+1
-33
@@ -77,38 +77,6 @@ bisect_visualize() {
77
eval '"$@"' --bisect -- $(cat "$GIT_DIR/BISECT_NAMES")
78
}
79
80
-bisect_replay () {
81
- file="$1"
82
- test "$#" -eq 1 || die "$(gettext "No logfile given")"
83
- test -r "$file" || die "$(eval_gettext "cannot read \$file for replaying")"
84
- git bisect--helper --bisect-reset || exit
85
- oIFS="$IFS" IFS="$IFS$(printf '\015')"
86
- while read git bisect command rev tail
87
- do
88
- test "$git $bisect" = "git bisect" || test "$git" = "git-bisect" || continue
89
- if test "$git" = "git-bisect"
90
- then
91
- rev="$command"
92
- command="$bisect"
93
- fi
94
- get_terms
95
- git bisect--helper --check-and-set-terms "$command" "$TERM_GOOD" "$TERM_BAD" || exit
96
- get_terms
97
- case "$command" in
98
- start)
99
- eval "git bisect--helper --bisect-start $rev $tail" ;;
100
- "$TERM_GOOD"|"$TERM_BAD"|skip)
101
- git bisect--helper --bisect-write "$command" "$rev" "$TERM_GOOD" "$TERM_BAD" || exit;;
102
- terms)
103
- git bisect--helper --bisect-terms $rev || exit;;
104
- *)
105
- die "$(gettext "?? what are you talking about?")" ;;
106
- esac
107
- done <"$file"
108
- IFS="$oIFS"
109
- git bisect--helper --bisect-auto-next || exit
110
-}
111
-
80
bisect_run () {
81
git bisect--helper --bisect-next-check $TERM_GOOD $TERM_BAD fail || exit
82
@@ -203,7 +171,7 @@ case "$#" in
171
reset)
172
git bisect--helper --bisect-reset "$@" ;;
173
replay)
206
- bisect_replay "$@" ;;
174
+ git bisect--helper --bisect-replay "$@" || exit;;
175
log)
176
git bisect--helper --bisect-log || exit ;;
177
run)