diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt
index aa02e462244..57357221718 100644
--- a/Documentation/git-bisect.txt
+++ b/Documentation/git-bisect.txt
@@ -19,14 +19,14 @@ on the subcommand:
  git bisect start [--term-(new|bad)=<term-new> --term-(old|good)=<term-old>]
 		  [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] [<paths>...]
  git bisect (bad|new|<term-new>) [<rev>]
- git bisect (good|old|<term-old>) [<rev>...]
+ git bisect (good|old|<term-old>) [-f] [<rev>...]
  git bisect terms [--term-good | --term-bad]
  git bisect skip [(<rev>|<range>)...]
  git bisect reset [<commit>]
  git bisect (visualize|view)
  git bisect replay <logfile>
  git bisect log
- git bisect run <cmd> [<arg>...]
+ git bisect run [-f] <cmd> [<arg>...]
  git bisect help
 
 This command uses a binary search algorithm to find which commit in
@@ -381,6 +381,15 @@ ignored.
 This option is particularly useful in avoiding false positives when a merged
 branch contained broken or non-buildable commits, but the merge itself was OK.
 
+-f::
+--force::
++
+Throw away any local changes and untracked files before moving to the next
+bisection step.
++
+This option may be useful if the repository state changes when testing a
+revision.
+
 EXAMPLES
 --------
 
diff --git a/bisect.c b/bisect.c
index 985b96ed132..72ce09f2015 100644
--- a/bisect.c
+++ b/bisect.c
@@ -713,7 +713,7 @@ static int is_expected_rev(const struct object_id *oid)
 }
 
 enum bisect_error bisect_checkout(const struct object_id *bisect_rev,
-				  int no_checkout)
+				  int no_checkout, int force_checkout)
 {
 	struct commit *commit;
 	struct pretty_print_context pp = {0};
@@ -728,8 +728,13 @@ enum bisect_error bisect_checkout(const struct object_id *bisect_rev,
 		struct child_process cmd = CHILD_PROCESS_INIT;
 
 		cmd.git_cmd = 1;
-		strvec_pushl(&cmd.args, "checkout", "-q",
-			     oid_to_hex(bisect_rev), "--", NULL);
+		if (force_checkout) {
+			strvec_pushl(&cmd.args, "checkout", "-f", "-q",
+					oid_to_hex(bisect_rev), "--", NULL);
+		} else {
+			strvec_pushl(&cmd.args, "checkout", "-q",
+					oid_to_hex(bisect_rev), "--", NULL);
+		}
 		if (run_command(&cmd))
 			/*
 			 * Errors in `run_command()` itself, signaled by res < 0,
@@ -850,7 +855,7 @@ static enum bisect_error check_merge_bases(int rev_nr, struct commit **rev, int
 			handle_skipped_merge_base(mb);
 		} else {
 			printf(_("Bisecting: a merge base must be tested\n"));
-			res = bisect_checkout(mb, no_checkout);
+			res = bisect_checkout(mb, no_checkout, 0);
 			if (!res)
 				/* indicate early success */
 				res = BISECT_INTERNAL_SUCCESS_MERGE_BASE;
@@ -1002,7 +1007,7 @@ void read_bisect_terms(const char **read_bad, const char **read_good)
  * the end of bisect_helper::cmd_bisect__helper() helps bypassing
  * all the code related to finding a commit to test.
  */
-enum bisect_error bisect_next_all(struct repository *r, const char *prefix)
+enum bisect_error bisect_next_all(struct repository *r, const char *prefix, int force_checkout)
 {
 	struct strvec rev_argv = STRVEC_INIT;
 	struct rev_info revs = REV_INFO_INIT;
@@ -1104,7 +1109,7 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix)
 	/* Clean up objects used, as they will be reused. */
 	repo_clear_commit_marks(r, ALL_REV_FLAGS);
 
-	res = bisect_checkout(bisect_rev, no_checkout);
+	res = bisect_checkout(bisect_rev, no_checkout, force_checkout);
 cleanup:
 	release_revisions(&revs);
 	strvec_clear(&rev_argv);
diff --git a/bisect.h b/bisect.h
index ee3fd65f3bd..6f972365faa 100644
--- a/bisect.h
+++ b/bisect.h
@@ -71,7 +71,7 @@ struct bisect_state {
 	unsigned int nr_bad;
 };
 
-enum bisect_error bisect_next_all(struct repository *r, const char *prefix);
+enum bisect_error bisect_next_all(struct repository *r, const char *prefix, int force_checkout);
 
 int estimate_bisect_steps(int all);
 
@@ -80,6 +80,6 @@ void read_bisect_terms(const char **bad, const char **good);
 int bisect_clean_state(void);
 
 enum bisect_error bisect_checkout(const struct object_id *bisect_rev,
-				  int no_checkout);
+				  int no_checkout, int force_checkout);
 
 #endif
diff --git a/builtin/bisect.c b/builtin/bisect.c
index 47fcce59ff7..99c16d57942 100644
--- a/builtin/bisect.c
+++ b/builtin/bisect.c
@@ -29,7 +29,7 @@ static GIT_PATH_FUNC(git_path_bisect_run, "BISECT_RUN")
 	   "    [--no-checkout] [--first-parent] [<bad> [<good>...]] [--]" \
 	   "    [<pathspec>...]")
 #define BUILTIN_GIT_BISECT_STATE_USAGE \
-	N_("git bisect (good|bad) [<rev>...]")
+	N_("git bisect (good|bad) [-f] [<rev>...]")
 #define BUILTIN_GIT_BISECT_TERMS_USAGE \
 	"git bisect terms [--term-good | --term-bad]"
 #define BUILTIN_GIT_BISECT_SKIP_USAGE \
@@ -45,7 +45,7 @@ static GIT_PATH_FUNC(git_path_bisect_run, "BISECT_RUN")
 #define BUILTIN_GIT_BISECT_LOG_USAGE \
 	"git bisect log"
 #define BUILTIN_GIT_BISECT_RUN_USAGE \
-	N_("git bisect run <cmd> [<arg>...]")
+	N_("git bisect run [-f] <cmd> [<arg>...]")
 
 static const char * const git_bisect_usage[] = {
 	BUILTIN_GIT_BISECT_START_USAGE,
@@ -651,7 +651,7 @@ static int bisect_successful(struct bisect_terms *terms)
 	return res;
 }
 
-static enum bisect_error bisect_next(struct bisect_terms *terms, const char *prefix)
+static enum bisect_error bisect_next(struct bisect_terms *terms, const char *prefix, int force_checkout)
 {
 	enum bisect_error res;
 
@@ -662,7 +662,7 @@ static enum bisect_error bisect_next(struct bisect_terms *terms, const char *pre
 		return BISECT_FAILED;
 
 	/* Perform all bisection computation */
-	res = bisect_next_all(the_repository, prefix);
+	res = bisect_next_all(the_repository, prefix, force_checkout);
 
 	if (res == BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND) {
 		res = bisect_successful(terms);
@@ -674,14 +674,14 @@ static enum bisect_error bisect_next(struct bisect_terms *terms, const char *pre
 	return res;
 }
 
-static enum bisect_error bisect_auto_next(struct bisect_terms *terms, const char *prefix)
+static enum bisect_error bisect_auto_next(struct bisect_terms *terms, const char *prefix, int force_checkout)
 {
 	if (bisect_next_check(terms, NULL)) {
 		bisect_print_status(terms);
 		return BISECT_OK;
 	}
 
-	return bisect_next(terms, prefix);
+	return bisect_next(terms, prefix, force_checkout);
 }
 
 static enum bisect_error bisect_start(struct bisect_terms *terms, int argc,
@@ -875,7 +875,7 @@ static enum bisect_error bisect_start(struct bisect_terms *terms, int argc,
 	if (res)
 		return res;
 
-	res = bisect_auto_next(terms, NULL);
+	res = bisect_auto_next(terms, NULL, 0);
 	if (!is_bisect_success(res))
 		bisect_clean_state();
 	return res;
@@ -917,7 +917,7 @@ static enum bisect_error bisect_state(struct bisect_terms *terms, int argc,
 				      const char **argv)
 {
 	const char *state;
-	int i, verify_expected = 1;
+	int i, force_checkout = 0, verify_expected = 1;
 	struct object_id oid, expected;
 	struct oid_array revs = OID_ARRAY_INIT;
 
@@ -934,6 +934,13 @@ static enum bisect_error bisect_state(struct bisect_terms *terms, int argc,
 
 	argv++;
 	argc--;
+
+	if (argc > 0 && (!strcmp(argv[0], "--force") || !strcmp(argv[0], "-f"))) {
+		force_checkout = 1;
+		argv++;
+		argc--;
+	}
+
 	if (argc > 1 && !strcmp(state, terms->term_bad))
 		return error(_("'git bisect %s' can take only one argument."), terms->term_bad);
 
@@ -989,7 +996,7 @@ static enum bisect_error bisect_state(struct bisect_terms *terms, int argc,
 	}
 
 	oid_array_clear(&revs);
-	return bisect_auto_next(terms, NULL);
+	return bisect_auto_next(terms, NULL, force_checkout);
 }
 
 static enum bisect_error bisect_log(void)
@@ -1078,7 +1085,7 @@ static enum bisect_error bisect_replay(struct bisect_terms *terms, const char *f
 	if (res)
 		return BISECT_FAILED;
 
-	return bisect_auto_next(terms, NULL);
+	return bisect_auto_next(terms, NULL, 0);
 }
 
 static enum bisect_error bisect_skip(struct bisect_terms *terms, int argc,
@@ -1173,7 +1180,7 @@ static int do_bisect_run(const char *command)
 	return run_command(&cmd);
 }
 
-static int verify_good(const struct bisect_terms *terms, const char *command)
+static int verify_good(const struct bisect_terms *terms, const char *command, int force_checkout)
 {
 	int rc;
 	enum bisect_error res;
@@ -1189,13 +1196,13 @@ static int verify_good(const struct bisect_terms *terms, const char *command)
 	if (read_ref(no_checkout ? "BISECT_HEAD" : "HEAD", &current_rev))
 		return -1;
 
-	res = bisect_checkout(&good_rev, no_checkout);
+	res = bisect_checkout(&good_rev, no_checkout, force_checkout);
 	if (res != BISECT_OK)
 		return -1;
 
 	rc = do_bisect_run(command);
 
-	res = bisect_checkout(&current_rev, no_checkout);
+	res = bisect_checkout(&current_rev, no_checkout, force_checkout);
 	if (res != BISECT_OK)
 		return -1;
 
@@ -1209,6 +1216,7 @@ static int bisect_run(struct bisect_terms *terms, int argc, const char **argv)
 	const char *new_state;
 	int temporary_stdout_fd, saved_stdout;
 	int is_first_run = 1;
+	int force_checkout = 0;
 
 	if (bisect_next_check(terms, NULL))
 		return BISECT_FAILED;
@@ -1218,8 +1226,14 @@ static int bisect_run(struct bisect_terms *terms, int argc, const char **argv)
 		return BISECT_FAILED;
 	}
 
+	if (argc > 0 && (!strcmp(argv[0], "--force") || !strcmp(argv[0], "-f"))) {
+		force_checkout = 1;
+		argv++;
+		argc--;
+	}
 	sq_quote_argv(&command, argv);
 	strbuf_ltrim(&command);
+
 	while (1) {
 		res = do_bisect_run(command.buf);
 
@@ -1231,7 +1245,7 @@ static int bisect_run(struct bisect_terms *terms, int argc, const char **argv)
 		 * missing or non-executable script.
 		 */
 		if (is_first_run && (res == 126 || res == 127)) {
-			int rc = verify_good(terms, command.buf);
+			int rc = verify_good(terms, command.buf, force_checkout);
 			is_first_run = 0;
 			if (rc < 0 || 128 <= rc) {
 				error(_("unable to verify %s on good"
@@ -1271,7 +1285,11 @@ static int bisect_run(struct bisect_terms *terms, int argc, const char **argv)
 		saved_stdout = dup(1);
 		dup2(temporary_stdout_fd, 1);
 
-		res = bisect_state(terms, 1, &new_state);
+		if (force_checkout) {
+			res = bisect_state(terms, 2, (const char *[]){ new_state, "--force" });
+		} else {
+			res = bisect_state(terms, 1, &new_state);
+		}
 
 		fflush(stdout);
 		dup2(saved_stdout, 1);
@@ -1342,7 +1360,7 @@ static int cmd_bisect__next(int argc, const char **argv UNUSED, const char *pref
 		return error(_("'%s' requires 0 arguments"),
 			     "git bisect next");
 	get_terms(&terms);
-	res = bisect_next(&terms, prefix);
+	res = bisect_next(&terms, prefix, 0);
 	free_terms(&terms);
 	return res;
 }
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 561080bf240..eb17cc58a16 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -1259,4 +1259,113 @@ test_expect_success 'verify correct error message' '
 	grep "git bisect good.*exited with error code" error
 '
 
+test_expect_success 'bisect dirty, explicit ref' '
+	test_when_finished "git bisect reset" &&
+    add_line_into_file "Commit 1" file &&
+    add_line_into_file "Commit 2" file &&
+    add_line_into_file "Commit 3" file &&
+	git bisect start &&
+	git bisect bad HEAD &&
+	echo "modified state" >file &&
+	test_when_finished "git checkout -- file" &&
+	test_must_fail git bisect good HEAD~2
+'
+
+test_expect_success 'bisect dirty good force, explicit ref' '
+	test_when_finished "git bisect reset" &&
+    add_line_into_file "Commit 1" file &&
+    add_line_into_file "Commit 2" file &&
+    add_line_into_file "Commit 3" file &&
+	git bisect start &&
+	git bisect bad HEAD &&
+	echo "modified state" >file &&
+	test_when_finished "git checkout -- file" &&
+	git bisect good --force HEAD~2
+'
+
+test_expect_success 'bisect dirty, implicit ref' '
+	test_when_finished "git bisect reset" &&
+    add_line_into_file "Commit 1" file &&
+    add_line_into_file "Commit 2" file &&
+    add_line_into_file "Commit 3" file &&
+    add_line_into_file "Commit 4" file &&
+    add_line_into_file "Commit 5" file &&
+	git bisect start &&
+	git bisect bad HEAD &&
+	git bisect good HEAD~4 &&
+	echo "modified state" >file &&
+	test_when_finished "git checkout -- file" &&
+	test_must_fail git bisect good &&
+	test_must_fail git bisect bad
+'
+
+test_expect_success 'bisect dirty good force, implicit ref' '
+	test_when_finished "git bisect reset" &&
+    add_line_into_file "Commit 1" file &&
+    add_line_into_file "Commit 2" file &&
+    add_line_into_file "Commit 3" file &&
+    add_line_into_file "Commit 4" file &&
+    add_line_into_file "Commit 5" file &&
+	git bisect start &&
+	git bisect bad HEAD &&
+	git bisect good HEAD~4 &&
+	echo "modified state" >file &&
+	test_when_finished "git checkout -- file" &&
+	git bisect good --force
+'
+
+test_expect_success 'bisect dirty bad force, implicit ref' '
+	test_when_finished "git bisect reset" &&
+    add_line_into_file "Commit 1" file &&
+    add_line_into_file "Commit 2" file &&
+    add_line_into_file "Commit 3" file &&
+    add_line_into_file "Commit 4" file &&
+    add_line_into_file "Commit 5" file &&
+	git bisect start &&
+	git bisect bad HEAD &&
+	git bisect good HEAD~4 &&
+	echo "modified state" >file &&
+	test_when_finished "git checkout -- file" &&
+	git bisect bad --force
+'
+
+test_expect_success 'bisect run dirty' '
+	test_when_finished "git bisect reset" &&
+	test_when_finished "git checkout -- file" &&
+    add_line_into_file "Bisect run 1" file &&
+    add_line_into_file "Bisect run 2" file &&
+    add_line_into_file "Bisect run 3" file &&
+    add_line_into_file "Bisect run 4" file &&
+    add_line_into_file "Bisect run 5" file &&
+	write_script test_script.sh <<-\EOF &&
+	! echo "modified state" >file
+	! grep "Bisect run 3" || exit 126 >/dev/null
+	EOF
+	git bisect start &&
+	git bisect bad HEAD &&
+	git bisect good HEAD~4 &&
+	test_must_fail git bisect run ./test_script.sh
+'
+
+test_expect_success 'bisect run dirty force' '
+	test_when_finished "git bisect reset" &&
+	test_when_finished "git checkout -- file" &&
+    add_line_into_file "Bisect run 1" file &&
+    add_line_into_file "Bisect run 2" file &&
+    add_line_into_file "Bisect run 3" file &&
+    add_line_into_file "Bisect run 4" file &&
+    add_line_into_file "Bisect run 5" file &&
+	write_script test_script.sh <<-\EOF &&
+	! echo "modified state" >file
+	! grep "Bisect run 3" || exit 126 >/dev/null
+	EOF
+	HASH5=$(git rev-parse --verify HEAD) &&
+	git bisect start &&
+	git bisect bad HEAD &&
+	git bisect good HEAD~4 &&
+	echo "doing run\n" &&
+	git bisect run --force ./test_script.sh >my_bisect_log.txt &&
+	grep "$HASH5 is the first bad commit" my_bisect_log.txt
+'
+
 test_done
